wecom.js 186 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403240424052406240724082409241024112412241324142415241624172418241924202421242224232424242524262427242824292430243124322433243424352436243724382439244024412442244324442445244624472448244924502451245224532454245524562457245824592460246124622463246424652466246724682469247024712472247324742475247624772478247924802481248224832484248524862487248824892490249124922493249424952496249724982499250025012502250325042505250625072508250925102511251225132514251525162517251825192520252125222523252425252526252725282529253025312532253325342535253625372538253925402541254225432544254525462547254825492550255125522553255425552556255725582559256025612562256325642565256625672568256925702571257225732574257525762577257825792580258125822583258425852586258725882589259025912592259325942595259625972598259926002601260226032604260526062607260826092610261126122613261426152616261726182619262026212622262326242625262626272628262926302631263226332634263526362637263826392640264126422643264426452646264726482649265026512652265326542655265626572658265926602661266226632664266526662667266826692670267126722673267426752676267726782679268026812682268326842685268626872688268926902691269226932694269526962697269826992700270127022703270427052706270727082709271027112712271327142715271627172718271927202721272227232724272527262727272827292730273127322733273427352736273727382739274027412742274327442745274627472748274927502751275227532754275527562757275827592760276127622763276427652766276727682769277027712772277327742775277627772778277927802781278227832784278527862787278827892790279127922793279427952796279727982799280028012802280328042805280628072808280928102811281228132814281528162817281828192820282128222823282428252826282728282829283028312832283328342835283628372838283928402841284228432844284528462847284828492850285128522853285428552856285728582859286028612862286328642865286628672868286928702871287228732874287528762877287828792880288128822883288428852886288728882889289028912892289328942895289628972898289929002901290229032904290529062907290829092910291129122913291429152916291729182919292029212922292329242925292629272928292929302931293229332934293529362937293829392940294129422943294429452946294729482949295029512952295329542955295629572958295929602961296229632964296529662967296829692970297129722973297429752976297729782979298029812982298329842985298629872988298929902991299229932994299529962997299829993000300130023003300430053006300730083009301030113012301330143015301630173018301930203021302230233024302530263027302830293030303130323033303430353036303730383039304030413042304330443045304630473048304930503051305230533054305530563057305830593060306130623063306430653066306730683069307030713072307330743075307630773078307930803081308230833084308530863087308830893090309130923093309430953096309730983099310031013102310331043105310631073108310931103111311231133114311531163117311831193120312131223123312431253126312731283129313031313132313331343135313631373138313931403141314231433144314531463147314831493150315131523153315431553156315731583159316031613162316331643165316631673168316931703171317231733174317531763177317831793180318131823183318431853186318731883189319031913192319331943195319631973198319932003201320232033204320532063207320832093210321132123213321432153216321732183219322032213222322332243225322632273228322932303231323232333234323532363237323832393240324132423243324432453246324732483249325032513252325332543255325632573258325932603261326232633264326532663267326832693270327132723273327432753276327732783279328032813282328332843285328632873288328932903291329232933294329532963297329832993300330133023303330433053306330733083309331033113312331333143315331633173318331933203321332233233324332533263327332833293330333133323333333433353336333733383339334033413342334333443345334633473348334933503351335233533354335533563357335833593360336133623363336433653366336733683369337033713372337333743375337633773378337933803381338233833384338533863387338833893390339133923393339433953396339733983399340034013402340334043405340634073408340934103411341234133414341534163417341834193420342134223423342434253426342734283429343034313432343334343435343634373438343934403441344234433444344534463447344834493450345134523453345434553456345734583459346034613462346334643465346634673468346934703471347234733474347534763477347834793480348134823483348434853486348734883489349034913492349334943495349634973498349935003501350235033504350535063507350835093510351135123513351435153516351735183519352035213522352335243525352635273528352935303531353235333534353535363537353835393540354135423543354435453546354735483549355035513552355335543555355635573558355935603561356235633564356535663567356835693570357135723573357435753576357735783579358035813582358335843585358635873588358935903591359235933594359535963597359835993600360136023603360436053606360736083609361036113612361336143615361636173618361936203621362236233624362536263627362836293630363136323633363436353636363736383639364036413642364336443645364636473648364936503651365236533654365536563657365836593660366136623663366436653666366736683669367036713672367336743675367636773678367936803681368236833684368536863687368836893690369136923693369436953696369736983699370037013702370337043705370637073708370937103711371237133714371537163717371837193720372137223723372437253726372737283729373037313732373337343735373637373738373937403741374237433744374537463747374837493750375137523753375437553756375737583759376037613762376337643765376637673768376937703771377237733774377537763777377837793780378137823783378437853786378737883789379037913792379337943795379637973798379938003801380238033804380538063807380838093810381138123813381438153816381738183819382038213822382338243825382638273828382938303831383238333834383538363837383838393840384138423843384438453846384738483849385038513852385338543855385638573858385938603861386238633864386538663867386838693870387138723873387438753876387738783879388038813882388338843885388638873888388938903891389238933894389538963897389838993900390139023903390439053906390739083909391039113912391339143915391639173918391939203921392239233924392539263927392839293930393139323933393439353936393739383939394039413942394339443945394639473948394939503951395239533954395539563957395839593960396139623963396439653966396739683969397039713972397339743975397639773978397939803981398239833984398539863987398839893990399139923993399439953996399739983999400040014002400340044005400640074008400940104011401240134014401540164017401840194020402140224023402440254026402740284029403040314032403340344035403640374038403940404041404240434044404540464047404840494050405140524053405440554056405740584059406040614062406340644065406640674068406940704071407240734074407540764077407840794080408140824083408440854086408740884089409040914092409340944095409640974098409941004101410241034104410541064107410841094110411141124113411441154116411741184119412041214122412341244125412641274128412941304131413241334134413541364137413841394140414141424143414441454146414741484149415041514152415341544155415641574158415941604161416241634164416541664167416841694170417141724173417441754176417741784179418041814182418341844185418641874188418941904191419241934194419541964197419841994200420142024203420442054206420742084209421042114212421342144215421642174218421942204221422242234224422542264227422842294230423142324233423442354236423742384239424042414242424342444245424642474248424942504251425242534254425542564257425842594260426142624263426442654266426742684269427042714272427342744275427642774278427942804281428242834284428542864287428842894290429142924293429442954296429742984299430043014302430343044305430643074308430943104311431243134314431543164317431843194320432143224323432443254326432743284329433043314332433343344335433643374338433943404341434243434344434543464347434843494350435143524353435443554356435743584359436043614362436343644365436643674368436943704371437243734374437543764377437843794380438143824383438443854386438743884389439043914392439343944395439643974398439944004401440244034404440544064407440844094410441144124413441444154416441744184419442044214422442344244425442644274428442944304431443244334434443544364437443844394440444144424443444444454446444744484449445044514452445344544455445644574458445944604461446244634464446544664467446844694470447144724473447444754476447744784479448044814482448344844485448644874488448944904491449244934494449544964497449844994500450145024503450445054506450745084509451045114512451345144515451645174518451945204521452245234524452545264527452845294530453145324533453445354536453745384539454045414542454345444545454645474548454945504551455245534554455545564557455845594560456145624563456445654566456745684569457045714572457345744575457645774578457945804581458245834584458545864587458845894590459145924593459445954596459745984599460046014602460346044605460646074608460946104611461246134614461546164617461846194620462146224623462446254626462746284629463046314632463346344635463646374638463946404641464246434644464546464647464846494650465146524653465446554656465746584659466046614662466346644665466646674668466946704671467246734674467546764677467846794680468146824683468446854686468746884689469046914692469346944695469646974698469947004701470247034704470547064707470847094710471147124713471447154716471747184719472047214722472347244725472647274728472947304731473247334734473547364737473847394740474147424743474447454746474747484749475047514752475347544755475647574758475947604761476247634764476547664767476847694770477147724773477447754776477747784779478047814782478347844785478647874788478947904791479247934794479547964797479847994800480148024803480448054806480748084809481048114812481348144815481648174818481948204821482248234824482548264827482848294830483148324833483448354836483748384839484048414842484348444845484648474848484948504851485248534854485548564857485848594860486148624863486448654866486748684869487048714872487348744875487648774878487948804881488248834884488548864887488848894890489148924893489448954896489748984899490049014902490349044905490649074908490949104911491249134914491549164917491849194920492149224923492449254926492749284929493049314932493349344935493649374938493949404941494249434944494549464947494849494950495149524953495449554956495749584959496049614962496349644965496649674968496949704971497249734974497549764977497849794980498149824983498449854986498749884989499049914992499349944995499649974998499950005001500250035004500550065007500850095010501150125013501450155016501750185019502050215022502350245025502650275028502950305031503250335034503550365037503850395040504150425043504450455046504750485049505050515052505350545055505650575058505950605061506250635064506550665067506850695070507150725073507450755076507750785079508050815082508350845085508650875088508950905091509250935094509550965097509850995100510151025103510451055106510751085109511051115112511351145115511651175118511951205121512251235124512551265127512851295130513151325133513451355136513751385139514051415142514351445145514651475148514951505151515251535154515551565157515851595160516151625163516451655166516751685169517051715172517351745175517651775178517951805181518251835184518551865187518851895190519151925193519451955196519751985199520052015202520352045205520652075208520952105211521252135214521552165217521852195220522152225223522452255226522752285229523052315232523352345235523652375238523952405241524252435244524552465247524852495250525152525253525452555256525752585259526052615262526352645265526652675268526952705271527252735274527552765277527852795280528152825283528452855286528752885289529052915292529352945295529652975298529953005301530253035304530553065307530853095310531153125313531453155316531753185319532053215322532353245325532653275328532953305331533253335334533553365337533853395340534153425343534453455346534753485349535053515352535353545355535653575358535953605361536253635364536553665367536853695370537153725373537453755376537753785379538053815382538353845385538653875388538953905391539253935394539553965397539853995400540154025403540454055406540754085409541054115412541354145415541654175418541954205421542254235424542554265427542854295430543154325433543454355436543754385439544054415442544354445445544654475448544954505451545254535454545554565457545854595460546154625463546454655466546754685469547054715472547354745475547654775478547954805481548254835484548554865487548854895490549154925493549454955496549754985499550055015502550355045505550655075508550955105511551255135514551555165517551855195520552155225523552455255526552755285529553055315532553355345535553655375538553955405541554255435544554555465547554855495550555155525553555455555556555755585559556055615562556355645565556655675568556955705571557255735574557555765577557855795580558155825583558455855586558755885589559055915592559355945595559655975598559956005601560256035604560556065607560856095610561156125613561456155616561756185619562056215622562356245625562656275628562956305631563256335634563556365637563856395640564156425643564456455646564756485649565056515652565356545655565656575658565956605661566256635664566556665667566856695670567156725673567456755676567756785679568056815682568356845685568656875688568956905691569256935694569556965697569856995700570157025703570457055706570757085709571057115712571357145715571657175718571957205721572257235724572557265727572857295730573157325733573457355736573757385739574057415742574357445745574657475748574957505751575257535754575557565757575857595760576157625763576457655766576757685769577057715772577357745775577657775778577957805781578257835784578557865787578857895790579157925793579457955796579757985799580058015802580358045805580658075808580958105811581258135814581558165817581858195820582158225823582458255826582758285829583058315832583358345835583658375838583958405841584258435844584558465847584858495850585158525853585458555856585758585859586058615862586358645865586658675868586958705871587258735874587558765877587858795880588158825883588458855886588758885889589058915892589358945895589658975898589959005901590259035904590559065907590859095910591159125913591459155916591759185919592059215922592359245925592659275928592959305931593259335934593559365937593859395940594159425943594459455946594759485949595059515952595359545955595659575958595959605961596259635964596559665967596859695970597159725973597459755976597759785979598059815982598359845985598659875988598959905991599259935994599559965997599859996000600160026003600460056006600760086009601060116012601360146015601660176018601960206021602260236024602560266027602860296030603160326033603460356036603760386039604060416042604360446045604660476048604960506051605260536054605560566057605860596060606160626063606460656066606760686069607060716072607360746075607660776078607960806081608260836084608560866087608860896090609160926093609460956096609760986099610061016102610361046105610661076108610961106111611261136114611561166117611861196120612161226123612461256126612761286129613061316132613361346135613661376138613961406141614261436144614561466147614861496150615161526153615461556156615761586159616061616162616361646165616661676168616961706171617261736174617561766177617861796180618161826183618461856186618761886189619061916192619361946195619661976198619962006201620262036204620562066207620862096210621162126213621462156216621762186219622062216222622362246225622662276228622962306231623262336234623562366237623862396240624162426243624462456246624762486249625062516252625362546255625662576258625962606261626262636264626562666267626862696270627162726273627462756276627762786279628062816282628362846285628662876288628962906291629262936294629562966297629862996300630163026303630463056306630763086309631063116312631363146315631663176318631963206321632263236324632563266327632863296330633163326333633463356336633763386339634063416342634363446345634663476348634963506351635263536354635563566357635863596360636163626363636463656366636763686369637063716372637363746375637663776378637963806381638263836384638563866387638863896390639163926393639463956396639763986399640064016402640364046405640664076408640964106411641264136414641564166417641864196420642164226423642464256426642764286429643064316432643364346435643664376438643964406441644264436444644564466447644864496450645164526453645464556456645764586459646064616462646364646465646664676468646964706471647264736474647564766477647864796480648164826483648464856486648764886489649064916492649364946495649664976498649965006501650265036504650565066507650865096510651165126513651465156516
  1. const win = typeof window !== 'undefined' ? window : undefined;
  2. const doc = typeof document !== 'undefined' ? document : undefined;
  3. const nav = typeof navigator !== 'undefined' ? navigator : undefined;
  4. const loc = typeof location !== 'undefined' ? location : undefined;
  5. function getHref() {
  6. return loc?.href || '';
  7. }
  8. function getTitle() {
  9. return doc?.title || '';
  10. }
  11. const ua = nav?.userAgent || '';
  12. const platform = nav?.platform || '';
  13. const wecomVersion = ua?.match(/wxwork\/([\d.]+)/i)?.[1];
  14. const isWeCom = !!wecomVersion;
  15. const isWeChat = !isWeCom && /micromessenger/i.test(ua);
  16. const isAndroid = /\bAndroid\b/i.test(ua);
  17. const isWindows = /Win/i.test(platform);
  18. const { isIOS, isMac } = getAppleDeviceType();
  19. function getAppleDeviceType() {
  20. const maxTouchPoints = nav?.maxTouchPoints ?? 1;
  21. const isMac = /Mac/i.test(platform);
  22. // https://stackoverflow.com/questions/56934826/distinguish-between-ipad-and-mac-on-ipad-with-ipados
  23. if (isMac && maxTouchPoints > 2) {
  24. return {
  25. isMac: false,
  26. isIOS: true
  27. };
  28. }
  29. return {
  30. isMac,
  31. isIOS: /\b(iPhone|iPad|iPod)\b/i.test(ua)
  32. };
  33. }
  34. let registerOptions;
  35. let corpConfigTask;
  36. let agentConfigTask;
  37. function setRegisterOptions(options) {
  38. if (!options.corpId) {
  39. throw new Error('Missing corpId');
  40. }
  41. registerOptions = options;
  42. }
  43. function getRegisterOptions() {
  44. return registerOptions;
  45. }
  46. function getCorpConfigTask() {
  47. return corpConfigTask;
  48. }
  49. function setCorpConfigTask(task) {
  50. corpConfigTask = task;
  51. }
  52. function getCorpConfigParams() {
  53. return corpConfigTask?.getResult()?.params;
  54. }
  55. function getAgentConfigTask() {
  56. return agentConfigTask;
  57. }
  58. function setAgentConfigTask(task) {
  59. agentConfigTask = task;
  60. }
  61. function getAgentConfigParams() {
  62. return agentConfigTask?.getResult()?.params;
  63. }
  64. function getConfigParams() {
  65. const registerOptions = getRegisterOptions();
  66. if (isWeCom && registerOptions?.getAgentConfigSignature) {
  67. return getAgentConfigParams();
  68. }
  69. return getCorpConfigParams();
  70. }
  71. function getConfigCorpId() {
  72. const registerOptions = getRegisterOptions();
  73. if (isWeCom && registerOptions?.getAgentConfigSignature) {
  74. const params = getAgentConfigParams();
  75. return params?.corpid;
  76. }
  77. const params = getCorpConfigParams();
  78. return params?.appId;
  79. }
  80. /**
  81. * 获取 config 或 agentConfig 传入的相关参数
  82. *
  83. * 用于外部 sdk 调用私有方法
  84. */ function getVerifyParams() {
  85. const verifyParams = getConfigParams();
  86. if (!verifyParams) {
  87. return;
  88. }
  89. const corpId = getConfigCorpId();
  90. return {
  91. appId: corpId,
  92. verifyAppId: corpId,
  93. verifySignType: 'sha1',
  94. verifyTimestamp: verifyParams.timestamp,
  95. verifyNonceStr: verifyParams.nonceStr,
  96. verifySignature: verifyParams.signature
  97. };
  98. }
  99. const webToClientJsApiMap = {
  100. config: 'preVerifyJsApi',
  101. onMenuShareTimeline: 'menu:share:timeline',
  102. onMenuShareAppMessage: 'menu:share:appmessage',
  103. onMenuShareWechat: 'menu:share:wechat',
  104. onMenuShareQQ: 'menu:share:qq',
  105. onMenuShareWeibo: 'menu:share:weiboApp',
  106. onMenuShareQZone: 'menu:share:QZone',
  107. previewImage: 'imagePreview',
  108. getLocation: 'geoLocation',
  109. openProductSpecificView: 'openProductViewWithPid',
  110. addCard: 'batchAddCard',
  111. openCard: 'batchViewCard',
  112. chooseWXPay: 'getBrandWCPayRequest',
  113. openEnterpriseRedPacket: 'getRecevieBizHongBaoRequest',
  114. startSearchBeacons: 'startMonitoringBeacons',
  115. stopSearchBeacons: 'stopMonitoringBeacons',
  116. onSearchBeacons: 'onBeaconsInRange',
  117. consumeAndShareCard: 'consumedShareCard',
  118. openAddress: 'editAddress',
  119. getBrandWCPayRequest: 'getBrandWCPayRequest'
  120. };
  121. const clientToWebJsApiMap = {};
  122. for (const key of Object.keys(webToClientJsApiMap)){
  123. clientToWebJsApiMap[webToClientJsApiMap[key]] = key;
  124. }
  125. function mapJsApiNameToClient(name) {
  126. return webToClientJsApiMap[name] || name;
  127. }
  128. function mapJsApiNameToWeb(name) {
  129. return clientToWebJsApiMap[name] || name;
  130. }
  131. function mapJsApiListToClient(list) {
  132. return list.map(mapJsApiNameToClient);
  133. }
  134. function error(...args) {
  135. console.error('[wwsdk]', ...args);
  136. }
  137. const originalHref = getHref();
  138. /**
  139. * 两个 SemVer 相减,取差的符号
  140. */ function semverSubtract(v1, v2) {
  141. const v1Seg = v1?.split('.') || [];
  142. const v2Seg = v2?.split('.') || [];
  143. for(let i = 0, ii = Math.max(v1Seg.length, v2Seg.length); i < ii; i++){
  144. const v1Num = parseInt(v1Seg[i]) || 0;
  145. const v2Num = parseInt(v2Seg[i]) || 0;
  146. if (v1Num > v2Num) {
  147. return 1;
  148. }
  149. if (v1Num < v2Num) {
  150. return -1;
  151. }
  152. }
  153. return 0;
  154. }
  155. function arrayBufferToBase64(buffer) {
  156. if (typeof Buffer !== 'undefined') {
  157. return Buffer.from(buffer).toString('base64');
  158. }
  159. let binary = '';
  160. const bytes = new Uint8Array(buffer);
  161. const len = bytes.byteLength;
  162. for(let i = 0; i < len; i++){
  163. binary += String.fromCharCode(bytes[i]);
  164. }
  165. return btoa(binary);
  166. }
  167. function base64ToArrayBuffer(base64) {
  168. if (typeof Buffer !== 'undefined') {
  169. return Buffer.from(base64, 'base64').buffer;
  170. }
  171. const binary = atob(base64);
  172. const length = binary.length;
  173. const bytes = new Uint8Array(length);
  174. for(let i = 0; i < length; i++){
  175. bytes[i] = binary.charCodeAt(i);
  176. }
  177. return bytes.buffer;
  178. }
  179. function safeRun(fn, param, thisArg) {
  180. if (!isFunction(fn)) {
  181. return;
  182. }
  183. try {
  184. return fn.call(thisArg, param);
  185. } catch (error$1) {
  186. error(error$1);
  187. }
  188. }
  189. function startsWith(str, search) {
  190. return str.slice(0, search.length) === search;
  191. }
  192. function getSignURL(original) {
  193. if (original) {
  194. return originalHref.split('#')[0];
  195. }
  196. return getHref().split('#')[0];
  197. }
  198. function extractErrMsgKeyword(errMsg) {
  199. if (!isString(errMsg)) {
  200. return '';
  201. }
  202. return errMsg.slice(errMsg.indexOf(':') + 1);
  203. }
  204. function isFalsy(val) {
  205. return val === false || val === 0;
  206. }
  207. function isObject$1(val) {
  208. if (!val) {
  209. return false;
  210. }
  211. return typeof val === 'object';
  212. }
  213. function isFunction(val) {
  214. return typeof val === 'function';
  215. }
  216. function isString(val) {
  217. return typeof val === 'string';
  218. }
  219. function joinList(list) {
  220. if (!list) {
  221. return list;
  222. }
  223. if (isString(list)) {
  224. return list;
  225. }
  226. return list.join(';');
  227. }
  228. /**
  229. * WeixinJSBridge 是否已注入到 window
  230. */ let isWeixinJSBridgeReady = !!win?.WeixinJSBridge;
  231. /**
  232. * 等待 WeixinJSBridge 注入到 window
  233. */ let onWeixinJSBridgeReady = Promise.resolve();
  234. if (!isWeixinJSBridgeReady) {
  235. onWeixinJSBridgeReady = new Promise((resolve)=>{
  236. doc?.addEventListener('WeixinJSBridgeReady', ()=>{
  237. isWeixinJSBridgeReady = true;
  238. resolve();
  239. });
  240. });
  241. }
  242. /**
  243. * 监听 JSSDK 未定义的事件
  244. *
  245. * @example
  246. * ```ts
  247. * ww.on('onBeaconsInRange', res => {
  248. * console.log(res)
  249. * })
  250. * ```
  251. *
  252. * @param name 事件名称
  253. * @param callback 监听回调
  254. */ async function on(name, callback) {
  255. if (!isWeixinJSBridgeReady) {
  256. await onWeixinJSBridgeReady;
  257. }
  258. win.WeixinJSBridge.on(name, callback);
  259. }
  260. /**
  261. * 调用 JSSDK 未定义的 JSAPI
  262. *
  263. * @example
  264. * ```ts
  265. * ww.invoke('openEnterpriseChat', params, res => {
  266. * console.log(res)
  267. * })
  268. * ```
  269. *
  270. * @param name JSAPI 名称
  271. * @param params JSAPI 参数
  272. * @param callback 回调函数
  273. * @returns JSAPI 返回值
  274. */ async function invoke(name, params = {}, callback) {
  275. if (!isWeixinJSBridgeReady) {
  276. await onWeixinJSBridgeReady;
  277. }
  278. const result = await new Promise((resolve)=>{
  279. const fullParams = {
  280. ...params,
  281. ...getVerifyParams()
  282. };
  283. win.WeixinJSBridge.invoke(name, fullParams, resolve);
  284. });
  285. if (!result.errMsg) {
  286. result.errMsg = formatErrMsg(name, result.err_msg || result.errmsg);
  287. }
  288. const keyword = extractErrMsgKeyword(result.errMsg);
  289. if (result.errCode == null) {
  290. if (result.err_code != null) {
  291. result.errCode = result.err_code;
  292. } else {
  293. result.errCode = keyword === 'ok' ? 0 : -1;
  294. }
  295. }
  296. safeRun(callback, result);
  297. if (keyword !== 'ok' && keyword !== 'yes') {
  298. throw result;
  299. }
  300. return result;
  301. }
  302. function formatErrMsg(name, errMsg) {
  303. const apiName = mapJsApiNameToWeb(name);
  304. if (!errMsg) {
  305. return `${apiName}:ok`;
  306. }
  307. let keyword = extractErrMsgKeyword(errMsg);
  308. if (keyword === 'confirm') {
  309. keyword = 'ok';
  310. }
  311. if (keyword === 'failed') {
  312. keyword = 'fail';
  313. }
  314. if (startsWith(keyword, 'failed_')) {
  315. keyword = keyword.slice(7);
  316. }
  317. if (startsWith(keyword, 'fail_')) {
  318. keyword = keyword.slice(5);
  319. }
  320. keyword = keyword.replace(/_/g, '').toLowerCase();
  321. if (keyword === 'access denied' || keyword === 'no permission to execute') {
  322. keyword = 'permission denied';
  323. }
  324. if (apiName === 'config' && keyword === 'function not exist') {
  325. keyword = 'ok';
  326. }
  327. if (!keyword) {
  328. keyword = 'fail';
  329. }
  330. return `${apiName}:${keyword}`;
  331. }
  332. class SDKError extends Error {
  333. constructor(message){
  334. super(`SDK Error: ${message}`);
  335. }
  336. }
  337. class AbortError extends SDKError {
  338. constructor(){
  339. super('Aborted');
  340. }
  341. }
  342. function _define_property(obj, key, value) {
  343. if (key in obj) {
  344. Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true });
  345. } else obj[key] = value;
  346. return obj;
  347. }
  348. const CONFIG_TYPE_CORP = 1;
  349. const CONFIG_TYPE_AGENT = 2;
  350. class ConfigTask {
  351. checkValid() {
  352. if (isWeCom && this.url !== getSignURL(this.useOriginalURL)) {
  353. this.error = new AbortError();
  354. }
  355. return !this.error;
  356. }
  357. getResult() {
  358. if (this.checkValid()) {
  359. return this.result;
  360. }
  361. }
  362. async awaitPromise(promise) {
  363. try {
  364. this.result = await promise;
  365. return this.result;
  366. } catch (error) {
  367. this.error = error;
  368. throw error;
  369. }
  370. }
  371. constructor(type, factory){
  372. _define_property(this, "type", void 0);
  373. _define_property(this, "url", void 0);
  374. _define_property(this, "promise", void 0);
  375. _define_property(this, "result", void 0);
  376. _define_property(this, "error", void 0);
  377. _define_property(this, "useOriginalURL", void 0);
  378. this.type = type;
  379. this.useOriginalURL = isWeChat && !isWindows && !isMac && type === CONFIG_TYPE_CORP;
  380. this.url = getSignURL(this.useOriginalURL);
  381. this.promise = this.awaitPromise(factory(this.url));
  382. }
  383. }
  384. /**
  385. * 触发或等待 config 返回
  386. */ async function ensureCorpConfigReady() {
  387. const originalTask = getCorpConfigTask();
  388. if (originalTask?.checkValid()) {
  389. return originalTask.promise;
  390. }
  391. const task = new ConfigTask(CONFIG_TYPE_CORP, async (url)=>{
  392. const registerOptions = getRegisterOptions();
  393. if (!registerOptions?.getConfigSignature) {
  394. throw new SDKError('Missing getConfigSignature');
  395. }
  396. // 1. 获取 config 签名参数
  397. const data = await registerOptions.getConfigSignature(url);
  398. if (!task.checkValid()) {
  399. throw new AbortError();
  400. }
  401. // 2. 构建参数
  402. const params = buildCorpConfigParams(registerOptions, data);
  403. // 3. 调用 JSAPI
  404. const result = await invoke('preVerifyJSAPI', {
  405. appId: params.appId,
  406. verifyJsApiList: params.jsApiList,
  407. verifyOpenTagList: params.openTagList,
  408. verifyAppId: params.appId,
  409. verifySignType: 'sha1',
  410. verifyTimestamp: params.timestamp,
  411. verifyNonceStr: params.nonceStr,
  412. verifySignature: params.signature
  413. });
  414. if (!task.checkValid()) {
  415. throw new AbortError();
  416. }
  417. return {
  418. params,
  419. result
  420. };
  421. });
  422. task.promise.then((res)=>{
  423. const registerOptions = getRegisterOptions();
  424. safeRun(registerOptions?.onConfigSuccess, res.result);
  425. safeRun(registerOptions?.onConfigComplete, res.result);
  426. }, (error)=>{
  427. const registerOptions = getRegisterOptions();
  428. safeRun(registerOptions?.onConfigFail, error);
  429. safeRun(registerOptions?.onConfigComplete, error);
  430. });
  431. setCorpConfigTask(task);
  432. return task.promise;
  433. }
  434. function buildCorpConfigParams(options, data) {
  435. return {
  436. appId: options.corpId,
  437. timestamp: `${data.timestamp}`,
  438. nonceStr: data.nonceStr,
  439. signature: data.signature,
  440. jsApiList: mapJsApiListToClient(options.jsApiList || [
  441. 'config'
  442. ]),
  443. openTagList: mapJsApiListToClient(options.openTagList || [])
  444. };
  445. }
  446. /**
  447. * 触发或等待 agentConfig 返回
  448. */ async function ensureAgentConfigReady() {
  449. const originalTask = getAgentConfigTask();
  450. if (originalTask?.checkValid()) {
  451. return originalTask.promise;
  452. }
  453. const task = new ConfigTask(CONFIG_TYPE_AGENT, async (url)=>{
  454. // 1. 若为低版本企业微信,agentConfig 需要在 config 成功后执行
  455. let configPromise;
  456. if (isWeCom && semverSubtract(wecomVersion, '3.0.24') < 0) {
  457. configPromise = ensureCorpConfigReady();
  458. }
  459. // 2. 等待 config 成功的时候同时获取 agentConfig 签名参数
  460. const [params] = await Promise.all([
  461. resolveAgentConfigParams(url),
  462. configPromise
  463. ]);
  464. if (!task.checkValid()) {
  465. throw new AbortError();
  466. }
  467. // 4. 调用 JSAPI
  468. const result = await invoke('agentConfig', params);
  469. if (!task.checkValid()) {
  470. throw new AbortError();
  471. }
  472. return {
  473. params,
  474. result
  475. };
  476. });
  477. task.promise.then((res)=>handleAgentConfigSuccess(res.result), (error)=>handleAgentConfigFail(error));
  478. setAgentConfigTask(task);
  479. return task.promise;
  480. }
  481. async function resolveAgentConfigParams(url) {
  482. const registerOptions = getRegisterOptions();
  483. if (!registerOptions?.getAgentConfigSignature) {
  484. throw new SDKError('Missing getAgentConfigSignature');
  485. }
  486. const data = await registerOptions.getAgentConfigSignature(url);
  487. return {
  488. corpid: registerOptions.corpId,
  489. agentid: `${registerOptions.agentId}`,
  490. timestamp: `${data.timestamp}`,
  491. nonceStr: data.nonceStr,
  492. signature: data.signature,
  493. jsApiList: mapJsApiListToClient(registerOptions.jsApiList || [
  494. 'agentConfig'
  495. ])
  496. };
  497. }
  498. function handleAgentConfigSuccess(result) {
  499. const registerOptions = getRegisterOptions();
  500. safeRun(registerOptions?.onAgentConfigSuccess, result);
  501. safeRun(registerOptions?.onAgentConfigComplete, result);
  502. }
  503. function handleAgentConfigFail(error) {
  504. const registerOptions = getRegisterOptions();
  505. safeRun(registerOptions?.onAgentConfigFail, error);
  506. safeRun(registerOptions?.onAgentConfigComplete, error);
  507. }
  508. /**
  509. * 触发或等待 config、agentConfig 完成
  510. *
  511. * @example
  512. * ```ts
  513. * await ww.ensureConfigReady()
  514. * ```
  515. */ function ensureConfigReady() {
  516. const registerOptions = getRegisterOptions();
  517. if (isWeCom && registerOptions?.getAgentConfigSignature) {
  518. return ensureAgentConfigReady();
  519. }
  520. return ensureCorpConfigReady();
  521. }
  522. /**
  523. * 在提供了 registerOptions 的情况下保证 config、agentConfig 完成
  524. *
  525. * @private
  526. */ function tryEnsureConfigReady() {
  527. const registerOptions = getRegisterOptions();
  528. if (!registerOptions) {
  529. return;
  530. }
  531. if (isWeCom && registerOptions.getAgentConfigSignature) {
  532. return ensureAgentConfigReady();
  533. }
  534. if (registerOptions.getConfigSignature) {
  535. return ensureCorpConfigReady();
  536. }
  537. }
  538. /**
  539. * 注册应用信息。
  540. *
  541. * @example
  542. * ```ts
  543. * ww.register({
  544. * corpId: 'ww7ca4776b2a70000',
  545. * jsApiList: ['getExternalContact'],
  546. * getConfigSignature
  547. * })
  548. * ```
  549. */ function register(options) {
  550. setRegisterOptions(options);
  551. if (isWeChat || isWeCom) {
  552. tryEnsureConfigReady();
  553. }
  554. }
  555. /**
  556. * 透传 JSAPI 调用
  557. */ async function passthrough(name, params, jsapiParams = params) {
  558. return promiseToCallback(params, async ()=>{
  559. await tryEnsureConfigReady();
  560. return invoke(name, jsapiParams);
  561. });
  562. }
  563. /**
  564. * 绑定事件
  565. */ async function bindShare(name, params, handler) {
  566. await tryEnsureConfigReady();
  567. on(name, ()=>{
  568. promiseToCallback(params, handler);
  569. });
  570. }
  571. /**
  572. * 把 promise 转为 success/fail callbacak 回调
  573. */ function promiseToCallback(params, factory) {
  574. return factory(params).then((result)=>{
  575. safeRun(params?.success, result);
  576. safeRun(params?.complete, result);
  577. return result;
  578. }, (error)=>{
  579. const keyword = extractErrMsgKeyword(error.errMsg);
  580. if (keyword === 'cancel') {
  581. safeRun(params?.cancel, error);
  582. } else {
  583. safeRun(params?.fail, error);
  584. }
  585. safeRun(params?.complete, error);
  586. throw error;
  587. });
  588. }
  589. var Proximity;
  590. (function(Proximity) {
  591. /**
  592. * CLProximityUnknown
  593. */ Proximity["CLProximityUnknown"] = "0";
  594. /**
  595. * CLProximityImmediate
  596. */ Proximity["CLProximityImmediate"] = "1";
  597. /**
  598. * CLProximityNear
  599. */ Proximity["CLProximityNear"] = "2";
  600. /**
  601. * CLProximityFar
  602. */ Proximity["CLProximityFar"] = "3";
  603. })(Proximity || (Proximity = {}));
  604. /**
  605. * 开启查找周边 iBeacon 设备。
  606. *
  607. * @see https://developers.weixin.qq.com/doc/offiaccount/OA_Web_Apps/JS-SDK.html
  608. * @compat WeChat
  609. */ function startSearchBeacons(params = {}) {
  610. return passthrough('startMonitoringBeacons', params);
  611. }
  612. /**
  613. * 关闭查找周边 iBeacon 设备。
  614. *
  615. * @see https://developers.weixin.qq.com/doc/offiaccount/OA_Web_Apps/JS-SDK.html
  616. * @compat WeChat
  617. */ function stopSearchBeacons(params = {}) {
  618. return passthrough('stopMonitoringBeacons', params);
  619. }
  620. /**
  621. * 监听周边 iBeacon 设备接口。
  622. *
  623. * @see https://developers.weixin.qq.com/doc/offiaccount/OA_Web_Apps/JS-SDK.html
  624. * @compat WeChat
  625. */ function onSearchBeacons(callback) {
  626. on('onBeaconsInRange', callback);
  627. }
  628. /**
  629. * 连接低功耗蓝牙设备。
  630. *
  631. * @note
  632. * - 安卓手机上如果多次调用 createBLEConnection 创建连接,有可能导致系统持有同一设备多个连接的实例,导致调用 closeBLEConnection 的时候并不能真正的断开与设备的连接。因此请保证尽量成对的调用 create 和 close 接口
  633. * - 蓝牙链接随时可能断开,建议监听 onBLEConnectionStateChange 回调事件,当蓝牙设备断开时按需执行重连操作
  634. * - 若对未连接的设备或已断开连接的设备调用数据读写操作的接口,会返回 10006 错误,建议进行重连操作
  635. *
  636. * @compat WeCom
  637. *
  638. * @example
  639. * ```ts
  640. * ww.createBLEConnection({
  641. * deviceId: deviceId
  642. * })
  643. * ```
  644. */ function createBLEConnection(params) {
  645. return passthrough('createBLEConnection', params);
  646. }
  647. /**
  648. * 断开与低功耗蓝牙设备的连接。
  649. *
  650. * @compat WeCom
  651. *
  652. * @example
  653. * ```ts
  654. * ww.closeBLEConnection({
  655. * deviceId: deviceId
  656. * })
  657. * ```
  658. */ function closeBLEConnection(params) {
  659. return passthrough('closeBLEConnection', params);
  660. }
  661. /**
  662. * 监听低功耗蓝牙连接状态的改变事件,包括开发者主动连接或断开连接,设备丢失,连接异常断开等等。
  663. *
  664. * @compat WeCom
  665. *
  666. * @example
  667. * ```ts
  668. * ww.onBLEConnectionStateChange(function(event) {
  669. * console.log(event)
  670. * })
  671. * ```
  672. */ function onBLEConnectionStateChange(callback) {
  673. on('onBLEConnectionStateChange', callback);
  674. }
  675. /**
  676. * 获取蓝牙设备所有 service(服务)。
  677. *
  678. * @compat WeCom
  679. *
  680. * @example
  681. * ```ts
  682. * ww.getBLEDeviceServices({
  683. * deviceId: deviceId
  684. * })
  685. * ```
  686. */ function getBLEDeviceServices(params) {
  687. return passthrough('getBLEDeviceServices', params);
  688. }
  689. /**
  690. * 获取蓝牙设备某个服务中的所有 characteristic(特征值)。
  691. *
  692. * @compat WeCom
  693. *
  694. * @example
  695. * ```ts
  696. * ww.getBLEDeviceCharacteristics({
  697. * deviceId: deviceId,
  698. * serviceId: serviceId
  699. * })
  700. * ```
  701. */ function getBLEDeviceCharacteristics(params) {
  702. return passthrough('getBLEDeviceCharacteristics', params);
  703. }
  704. /**
  705. * 读取低功耗蓝牙设备的特征值的二进制数据值。
  706. *
  707. * @note
  708. * - 设备的特征值必须支持 read 才可以成功调用,具体参照 characteristic 的 properties 属性
  709. * - 并行调用多次读写接口存在读写失败的可能性
  710. * - 接口读取到的信息需要在 onBLECharacteristicValueChange 的回调中获取
  711. *
  712. * @compat WeCom
  713. *
  714. * @example
  715. * ```ts
  716. * ww.readBLECharacteristicValue({
  717. * deviceId: deviceId,
  718. * serviceId: serviceId,
  719. * characteristicId: characteristicId
  720. * })
  721. * ```
  722. */ function readBLECharacteristicValue(params) {
  723. return passthrough('readBLECharacteristicValue', params);
  724. }
  725. /**
  726. * 向低功耗蓝牙设备特征值中写入二进制数据。
  727. *
  728. * @note
  729. * - 设备的特征值必须支持 write 才可以成功调用,具体参照 characteristic 的 properties 属性
  730. * - 并行调用多次读写接口存在读写失败的可能性
  731. * - 接口不会对写入数据包大小做限制,但系统与蓝牙设备会确定蓝牙 4.0 单次传输的数据大小,超过最大字节数后会发生写入错误,建议每次写入不超过 20 字节
  732. * - 安卓平台上,在调用 notify 成功后立即调用 write 接口,在部分机型上会发生 10008 系统错误
  733. * - 若单次写入数据过长,iOS 平台上存在系统不会有任何回调的情况(包括错误回调)
  734. *
  735. * @compat WeCom
  736. *
  737. * @example
  738. * ```ts
  739. * ww.writeBLECharacteristicValue({
  740. * deviceId: deviceId,
  741. * serviceId: serviceId,
  742. * characteristicId: characteristicId,
  743. * value: arrayBufferValue
  744. * })
  745. * ```
  746. */ function writeBLECharacteristicValue(params) {
  747. return passthrough('writeBLECharacteristicValue', params, {
  748. deviceId: params.deviceId,
  749. serviceId: params.serviceId,
  750. characteristicId: params.characteristicId,
  751. value: arrayBufferToBase64(params.value)
  752. });
  753. }
  754. /**
  755. * 启用低功耗蓝牙设备特征值变化时的 notify 功能,订阅特征值。
  756. *
  757. * @note
  758. * - 设备的特征值必须支持 notify 或者 indicate 才可以成功调用,具体参照 characteristic 的 properties 属性
  759. * - 订阅操作成功后需要设备主动更新特征值的 value 才会触发 onBLECharacteristicValueChange 回调
  760. * - 安卓平台上,在调用 notify 成功后立即调用 write 接口,在部分机型上会发生 10008 系统错误
  761. *
  762. * @compat WeCom
  763. *
  764. * @example
  765. * ```ts
  766. * ww.notifyBLECharacteristicValueChange({
  767. * deviceId: deviceId,
  768. * serviceId: serviceId,
  769. * characteristicId: characteristicId,
  770. * state: true
  771. * })
  772. * ```
  773. */ function notifyBLECharacteristicValueChange(params) {
  774. return passthrough('notifyBLECharacteristicValueChange', params);
  775. }
  776. /**
  777. * 监听低功耗蓝牙设备的特征值变化。
  778. *
  779. * 必须先启用 notify 才能接收到设备推送的 notification。
  780. *
  781. * @compat WeCom
  782. *
  783. * @example
  784. * ```ts
  785. * ww.onBLECharacteristicValueChange(function(event) {
  786. * console.log(event)
  787. * })
  788. * ```
  789. */ function onBLECharacteristicValueChange(callback) {
  790. on('onBLECharacteristicValueChange', (event)=>{
  791. if (typeof event?.value === 'string') {
  792. event.value = base64ToArrayBuffer(event.value);
  793. }
  794. callback(event);
  795. });
  796. }
  797. /**
  798. * 初始化蓝牙模块。
  799. *
  800. * @compat WeCom
  801. *
  802. * @example
  803. * ```ts
  804. * ww.openBluetoothAdapter()
  805. * ```
  806. */ function openBluetoothAdapter(params = {}) {
  807. return passthrough('openBluetoothAdapter', params);
  808. }
  809. /**
  810. * 关闭蓝牙模块。
  811. *
  812. * @note
  813. * - 调用该方法将断开所有已建立的链接并释放系统资源
  814. *
  815. * @compat WeCom
  816. *
  817. * @example
  818. * ```ts
  819. * ww.closeBluetoothAdapter()
  820. * ```
  821. */ function closeBluetoothAdapter(params = {}) {
  822. return passthrough('closeBluetoothAdapter', params);
  823. }
  824. /**
  825. * 获取本机蓝牙适配器状态。
  826. *
  827. * @compat WeCom
  828. *
  829. * @example
  830. * ```ts
  831. * ww.getBluetoothAdapterState()
  832. * ```
  833. */ function getBluetoothAdapterState(params = {}) {
  834. return passthrough('getBluetoothAdapterState', params);
  835. }
  836. /**
  837. * 监听蓝牙适配器状态变化。
  838. *
  839. * @compat WeCom
  840. *
  841. * @example
  842. * ```ts
  843. * ww.onBluetoothAdapterStateChange(function(event) {
  844. * console.log(event)
  845. * })
  846. * ```
  847. */ function onBluetoothAdapterStateChange(callback) {
  848. on('onBluetoothAdapterStateChange', callback);
  849. }
  850. /**
  851. * 开始搜寻附近的蓝牙外围设备。
  852. *
  853. * @compat WeCom
  854. *
  855. * @example
  856. * ```ts
  857. * ww.startBluetoothDevicesDiscovery({
  858. * services: ['FEE7']
  859. * })
  860. * ```
  861. */ function startBluetoothDevicesDiscovery(params = {}) {
  862. return passthrough('startBluetoothDevicesDiscovery', params);
  863. }
  864. /**
  865. * 停止搜寻附近的蓝牙外围设备。
  866. *
  867. * 若已经找到需要的蓝牙设备并不需要继续搜索时,建议调用该接口停止蓝牙搜索。
  868. *
  869. * @compat WeCom
  870. *
  871. * @example
  872. * ```ts
  873. * ww.stopBluetoothDevicesDiscovery()
  874. * ```
  875. */ function stopBluetoothDevicesDiscovery(params = {}) {
  876. return passthrough('stopBluetoothDevicesDiscovery', params);
  877. }
  878. /**
  879. * 获取在蓝牙模块生效期间所有已发现的蓝牙设备。
  880. *
  881. * @note
  882. * - 该接口获取到的设备列表为蓝牙模块生效期间所有搜索到的蓝牙设备,若在蓝牙模块使用流程结束后未及时调用 closeBluetoothAdapter 释放资源,调用该接口可能会返回之前蓝牙使用流程中搜索到的蓝牙设备,可能设备已经不在用户身边,无法连接
  883. * - 蓝牙设备在被搜索到时,系统返回的 name 字段一般为广播包中的 LocalName 字段中的设备名称,而如果与蓝牙设备建立连接,系统返回的 name 字段会改为从蓝牙设备上获取到的 GattName。若需要动态改变设备名称并展示,建议使用 localName 字段
  884. *
  885. * @compat WeCom
  886. *
  887. * @example
  888. * ```ts
  889. * ww.getBluetoothDevices()
  890. * ```
  891. */ function getBluetoothDevices(params = {}) {
  892. return promiseToCallback(params, async ()=>{
  893. await tryEnsureConfigReady();
  894. const res = await invoke('getBluetoothDevices');
  895. for (const device of res.devices || []){
  896. normalizeBluetoothDevice(device);
  897. }
  898. return res;
  899. });
  900. }
  901. /**
  902. * 监听寻找到新设备。
  903. *
  904. * @note
  905. * - 若在该接口中回调了某个设备,则此设备会添加到 getBluetoothDevices 接口返回的设备列表中
  906. *
  907. * @compat WeCom
  908. *
  909. * @example
  910. * ```ts
  911. * ww.onBluetoothDeviceFound(function(event) {
  912. * console.log(event)
  913. * })
  914. * ```
  915. */ function onBluetoothDeviceFound(callback) {
  916. on('onBluetoothDeviceFound', (res)=>{
  917. for (const device of res.devices || []){
  918. normalizeBluetoothDevice(device);
  919. }
  920. callback(res);
  921. });
  922. }
  923. /**
  924. * 根据 uuid 获取处于已连接状态的设备。
  925. *
  926. * @compat WeCom
  927. *
  928. * @example
  929. * ```ts
  930. * ww.getConnectedBluetoothDevices({
  931. * services: ['FEE7']
  932. * })
  933. * ```
  934. */ function getConnectedBluetoothDevices(params) {
  935. return passthrough('getConnectedBluetoothDevices', params);
  936. }
  937. function normalizeBluetoothDevice(device) {
  938. if (typeof device.advertisData === 'string') {
  939. device.advertisData = base64ToArrayBuffer(device.advertisData);
  940. }
  941. /**
  942. * @desc 客户端返回字段为 serviceDataV2,sdk 统一转换为 serviceData 字段后对外返回
  943. */ if (device.serviceDataV2) {
  944. const finalServiceData = device.serviceDataV2;
  945. for (const key of Object.keys(finalServiceData)){
  946. if (typeof finalServiceData[key] === 'string') {
  947. finalServiceData[key] = base64ToArrayBuffer(finalServiceData[key]);
  948. }
  949. }
  950. device.serviceData = finalServiceData;
  951. delete device.serviceDataV2;
  952. }
  953. }
  954. /**
  955. * 设置系统剪贴板的内容。
  956. *
  957. * @compat WeCom iOS, Android >= 2.4.16; WeCom PC, Mac >= 3.1.2
  958. *
  959. * @example
  960. * ```ts
  961. * ww.setClipboardData({
  962. * data: 'data'
  963. * })
  964. * ```
  965. */ function setClipboardData(params) {
  966. return passthrough('setClipboardData', params);
  967. }
  968. /**
  969. * 获取系统剪贴板内容。
  970. *
  971. * @compat WeCom >= 3.1.2
  972. *
  973. * @example
  974. * ```ts
  975. * ww.getClipboardData()
  976. * ```
  977. */ function getClipboardData(params = {}) {
  978. return passthrough('getClipboardData', params);
  979. }
  980. /**
  981. * 开始搜索附近的 iBeacon 设备。
  982. *
  983. * @compat WeCom
  984. *
  985. * @example
  986. * ```ts
  987. * ww.startBeaconDiscovery({
  988. * uuids: ['uuid']
  989. * })
  990. * ```
  991. */ function startBeaconDiscovery(params) {
  992. return passthrough('startBeaconDiscovery', params);
  993. }
  994. /**
  995. * 停止搜索附近的 iBeacon 设备。
  996. *
  997. * @compat WeCom
  998. *
  999. * @example
  1000. * ```ts
  1001. * ww.stopBeaconDiscovery()
  1002. * ```
  1003. */ function stopBeaconDiscovery(params = {}) {
  1004. return passthrough('stopBeaconDiscovery', params);
  1005. }
  1006. /**
  1007. * 获取所有已搜索到的 iBeacon 设备。
  1008. *
  1009. * @compat WeCom
  1010. *
  1011. * @example
  1012. * ```ts
  1013. * ww.getBeacons()
  1014. * ```
  1015. */ function getBeacons(params = {}) {
  1016. return passthrough('getBeacons', params);
  1017. }
  1018. /**
  1019. * 监听 iBeacon 设备的更新事件。
  1020. *
  1021. * @compat WeCom
  1022. *
  1023. * @example
  1024. * ```ts
  1025. * ww.onBeaconUpdate(function(event) {
  1026. * console.log(event)
  1027. * })
  1028. * ```
  1029. */ function onBeaconUpdate(callback) {
  1030. on('onBeaconUpdate', callback);
  1031. }
  1032. /**
  1033. * 监听 iBeacon 服务的状态变化。
  1034. *
  1035. * @compat WeCom
  1036. *
  1037. * @example
  1038. * ```ts
  1039. * ww.onBeaconServiceChange(function(event) {
  1040. * console.log(event)
  1041. * })
  1042. * ```
  1043. */ function onBeaconServiceChange(callback) {
  1044. on('onBeaconServiceChange', callback);
  1045. }
  1046. var LocationType;
  1047. (function(LocationType) {
  1048. /**
  1049. * gps 坐标
  1050. */ LocationType["wgs84"] = "wgs84";
  1051. /**
  1052. * 火星坐标
  1053. */ LocationType["gcj02"] = "gcj02";
  1054. })(LocationType || (LocationType = {}));
  1055. /**
  1056. * 使用企业微信内置地图查看位置。
  1057. *
  1058. * @example
  1059. * ```ts
  1060. * ww.openLocation({
  1061. * latitude: 0,
  1062. * longitude: 0,
  1063. * name: 'name',
  1064. * address: 'address',
  1065. * scale: 1
  1066. * })
  1067. * ```
  1068. */ function openLocation(params) {
  1069. return passthrough('openLocation', params, {
  1070. latitude: params.latitude,
  1071. longitude: params.longitude,
  1072. name: params.name || '',
  1073. address: params.address || '',
  1074. scale: params.scale || 28,
  1075. infoUrl: params.infoUrl || ''
  1076. });
  1077. }
  1078. /**
  1079. * 获取地理位置。
  1080. *
  1081. * @example
  1082. * ```ts
  1083. * ww.getLocation({
  1084. * type: 'wgs84'
  1085. * })
  1086. * ```
  1087. */ function getLocation(params = {}) {
  1088. return promiseToCallback(params, async ()=>{
  1089. await tryEnsureConfigReady();
  1090. const res = await invoke('geoLocation', {
  1091. type: params.type || 'wgs84'
  1092. });
  1093. delete res.type;
  1094. return res;
  1095. });
  1096. }
  1097. /**
  1098. * 打开持续定位。
  1099. *
  1100. * @compat WeCom >= 2.4.20
  1101. *
  1102. * @example
  1103. * ```ts
  1104. * ww.startAutoLBS({
  1105. * type: 'gcj02'
  1106. * })
  1107. * ```
  1108. */ function startAutoLBS(params) {
  1109. return passthrough('startAutoLBS', params);
  1110. }
  1111. /**
  1112. * 停止持续定位。
  1113. *
  1114. * @compat WeCom >= 2.4.20
  1115. *
  1116. * @example
  1117. * ```ts
  1118. * ww.stopAutoLBS()
  1119. * ```
  1120. */ function stopAutoLBS(params = {}) {
  1121. return passthrough('stopAutoLBS', params);
  1122. }
  1123. /**
  1124. * 监听地理位置的变化。
  1125. *
  1126. * @limit
  1127. * - 需要提前调用 startAutoLBS
  1128. * - 需要用户停留在当前页面
  1129. *
  1130. * @compat WeCom >= 2.4.20
  1131. *
  1132. * @example
  1133. * ```ts
  1134. * ww.onLocationChange(function(event) {
  1135. * console.log(event)
  1136. * })
  1137. * ```
  1138. *
  1139. * @throws
  1140. * | errMsg | 说明 | 兼容性 |
  1141. * | --- | --- | --- |
  1142. * | auto:location:report:ok | 执行成功 | |
  1143. * | auto:location:report:fail, gps closed. | 用户关闭了 GPS | 企业微信 3.0.26 |
  1144. */ function onLocationChange(callback) {
  1145. on('auto:location:report', callback);
  1146. }
  1147. var NetworkType;
  1148. (function(NetworkType) {
  1149. /**
  1150. * wifi
  1151. */ NetworkType["wifi"] = "wifi";
  1152. /**
  1153. * 2g
  1154. */ NetworkType["network2g"] = "2g";
  1155. /**
  1156. * 3g
  1157. */ NetworkType["network3g"] = "3g";
  1158. /**
  1159. * 4g
  1160. */ NetworkType["network4g"] = "4g";
  1161. /**
  1162. * 无网络
  1163. */ NetworkType["none"] = "none";
  1164. /**
  1165. * Android下不常见的网络类型
  1166. */ NetworkType["unknown"] = "unknown";
  1167. })(NetworkType || (NetworkType = {}));
  1168. /**
  1169. * 获取网络状态。
  1170. *
  1171. * @compat WeCom iOS, Android; WeChat
  1172. *
  1173. * @example
  1174. * ```ts
  1175. * ww.getNetworkType()
  1176. * ```
  1177. */ function getNetworkType(params = {}) {
  1178. return passthrough('getNetworkType', params);
  1179. }
  1180. /**
  1181. * 监听网络状态变化。
  1182. *
  1183. * @compat WeCom iOS, Android
  1184. *
  1185. * @example
  1186. * ```ts
  1187. * ww.onNetworkStatusChange(function(event) {
  1188. * console.log(event)
  1189. * })
  1190. * ```
  1191. */ function onNetworkStatusChange(callback) {
  1192. on('onNetworkStatusChange', callback);
  1193. }
  1194. /**
  1195. * 初始化 Wi-Fi 模块。
  1196. *
  1197. * @compat WeCom iOS, Android >= 2.4.16
  1198. *
  1199. * @example
  1200. * ```ts
  1201. * ww.startWifi()
  1202. * ```
  1203. */ function startWifi(params = {}) {
  1204. return passthrough('startWifi', params);
  1205. }
  1206. /**
  1207. * 关闭 Wi-Fi 模块。
  1208. *
  1209. * @compat WeCom iOS, Android >= 2.4.16
  1210. *
  1211. * @example
  1212. * ```ts
  1213. * ww.stopWifi()
  1214. * ```
  1215. */ function stopWifi(params = {}) {
  1216. return passthrough('stopWifi', params);
  1217. }
  1218. /**
  1219. * 连接 Wi-Fi。
  1220. *
  1221. * @compat WeCom iOS, Android >= 2.4.16
  1222. *
  1223. * @example
  1224. * ```ts
  1225. * ww.connectWifi({
  1226. * SSID: 'vincenthome',
  1227. * BSSID: '8c:a6:df:c8:f7:4b',
  1228. * password: 'test1234',
  1229. * })
  1230. * ```
  1231. */ function connectWifi(params) {
  1232. return passthrough('connectWifi', params);
  1233. }
  1234. /**
  1235. * 获取 Wi-Fi 列表。
  1236. *
  1237. * @compat WeCom iOS, Android >= 2.4.16
  1238. *
  1239. * @example
  1240. * ```ts
  1241. * ww.getWifiList()
  1242. * ```
  1243. */ function getWifiList(params = {}) {
  1244. return passthrough('getWifiList', params);
  1245. }
  1246. /**
  1247. * 监听 Wi-Fi 列表更新。
  1248. *
  1249. * @compat WeCom iOS, Android >= 2.4.16
  1250. *
  1251. * @example
  1252. * ```ts
  1253. * ww.onGetWifiList(function(event) {
  1254. * console.log(event)
  1255. * })
  1256. * ```
  1257. */ function onGetWifiList(callback) {
  1258. on('onGetWifiList', callback);
  1259. }
  1260. /**
  1261. * 监听 Wi-Fi 连接成功。
  1262. *
  1263. * @compat WeCom iOS, Android >= 2.4.16
  1264. *
  1265. * @example
  1266. * ```ts
  1267. * ww.onWifiConnected(function(event) {
  1268. * console.log(event)
  1269. * })
  1270. * ```
  1271. */ function onWifiConnected(callback) {
  1272. on('onWifiConnected', callback);
  1273. }
  1274. /**
  1275. * 获取已连接中的 Wi-Fi 信息。
  1276. *
  1277. * @compat WeCom iOS, Android >= 2.4.16
  1278. *
  1279. * @example
  1280. * ```ts
  1281. * ww.getConnectedWifi()
  1282. * ```
  1283. */ function getConnectedWifi(params = {}) {
  1284. return passthrough('getConnectedWifi', params);
  1285. }
  1286. /**
  1287. * 预览文件
  1288. *
  1289. * @compat WeCom iOS, Android
  1290. *
  1291. * @note
  1292. * 本接口将 URL 对应的文件下载后,在内置浏览器中预览。目前支持图片、音频、视频、文档等格式的文件。
  1293. * 从 2.4.6 版本开始,iOS 版企业微信浏览器升级为 WkWebView,企业微信原生层面的网络请求读取不到WKWebview中设置的cookie,即使域名是相同的。
  1294. * **问题说明:**
  1295. * 如果页面的资源或图片存储的服务器依赖校验Cookie来返回数据的情况,在切换到WKWebview后,在企业微信内长按保存,或者点击预览文件时,原生层面发起的网络请求将不会完整地带上所设置的Cookie,会导致图片保存失败或预览失败。
  1296. * **适配建议:**
  1297. * 建议静态资源cookie free。如果确实有信息需要传递,可通过业务后台存储需要传递的信息,然后给页面一个存储信息相对应的access_token加密码,再通过Url中加入自己业务的access_token进行页面间信息传递。
  1298. *
  1299. * @example
  1300. * ```ts
  1301. * ww.previewFile({
  1302. * url: 'http://open.work.weixin.qq.com/wwopen/downloadfile/wwapi.zip',
  1303. * name: 'Android开发工具包集合',
  1304. * size: 22189
  1305. * })
  1306. * ```
  1307. */ function previewFile(params) {
  1308. return passthrough('previewFile', params);
  1309. }
  1310. var ChooseMessageFileType;
  1311. (function(ChooseMessageFileType) {
  1312. /**
  1313. * 仅选择视频文件
  1314. */ ChooseMessageFileType["video"] = "video";
  1315. /**
  1316. * 仅选择图片文件
  1317. */ ChooseMessageFileType["image"] = "image";
  1318. /**
  1319. * 可选择除了图片和视频之外的其它的文件
  1320. */ ChooseMessageFileType["file"] = "file";
  1321. /**
  1322. * 可同时选择视频与图片
  1323. */ ChooseMessageFileType["video_and_image"] = "video_and_image";
  1324. })(ChooseMessageFileType || (ChooseMessageFileType = {}));
  1325. var TempFileType;
  1326. (function(TempFileType) {
  1327. /**
  1328. * 视频文件
  1329. */ TempFileType["video"] = "video";
  1330. /**
  1331. * 图片文件
  1332. */ TempFileType["image"] = "image";
  1333. /**
  1334. * 除图片和视频的文件
  1335. */ TempFileType["file"] = "file";
  1336. })(TempFileType || (TempFileType = {}));
  1337. /**
  1338. * 从企业微信会话中选择文件,用户选择文件之后,返回临时文件 localId,可再调用 [getLocalFileData](#56784) 获取文件内容。
  1339. *
  1340. * @compat WeCom iOS, Android >= 4.0.20
  1341. *
  1342. * @limit
  1343. * - 本接口必须使用应用身份进行注册
  1344. * - 当前成员必须在应用的可见范围之中
  1345. *
  1346. * @example
  1347. * ```ts
  1348. * ww.chooseMessageFile({
  1349. * count: 10,
  1350. * type: 'image',
  1351. * })
  1352. * ```
  1353. */ function chooseMessageFile(params) {
  1354. return passthrough('chooseMessageFile', params);
  1355. }
  1356. /**
  1357. * 获取 chooseMessageFile 返回的 localId 对应的文件内容。
  1358. *
  1359. * @compat WeCom iOS, Android >= 4.0.20
  1360. *
  1361. * @limit
  1362. * - 本接口必须使用应用身份进行注册
  1363. * - 当前成员必须在应用的可见范围之中
  1364. *
  1365. * @example
  1366. * ```ts
  1367. * ww.getLocalFileData({
  1368. * localId: '',
  1369. * })
  1370. * ```
  1371. *
  1372. * @throws
  1373. * | errMsg | 说明 |
  1374. * | --- | --- |
  1375. * | getLocalFileData:ok | 执行成功 |
  1376. * | no permission | 应用签名校验失败,或成员不在应用的可见范围内 |
  1377. * | no such file | localId不存在或者文件已删除 |
  1378. * | file exceed size limit | 不支持超过20M的文件 |
  1379. */ function getLocalFileData(params) {
  1380. return passthrough('getLocalFileData', params);
  1381. }
  1382. var SizeType;
  1383. (function(SizeType) {
  1384. /**
  1385. * 原图
  1386. */ SizeType["original"] = "original";
  1387. /**
  1388. * 压缩后的图片
  1389. */ SizeType["compressed"] = "compressed";
  1390. })(SizeType || (SizeType = {}));
  1391. var SourceType;
  1392. (function(SourceType) {
  1393. /**
  1394. * 相册
  1395. */ SourceType["album"] = "album";
  1396. /**
  1397. * 相机,企业微信 2.3 及以后版本支持相机连拍
  1398. */ SourceType["camera"] = "camera";
  1399. })(SourceType || (SourceType = {}));
  1400. var CameraMode;
  1401. (function(CameraMode) {
  1402. /**
  1403. * 单拍
  1404. */ CameraMode["normal"] = "normal";
  1405. /**
  1406. * 连拍
  1407. *
  1408. * @compat WeCom >= 2.3.0
  1409. */ CameraMode["batch"] = "batch";
  1410. /**
  1411. * 前置摄像头单拍
  1412. *
  1413. * @compat WeCom >= 3.0.26
  1414. */ CameraMode["front"] = "front";
  1415. /**
  1416. * 前置摄像头连拍
  1417. *
  1418. * @compat WeCom >= 3.0.26
  1419. */ CameraMode["batch_front"] = "batch_front";
  1420. })(CameraMode || (CameraMode = {}));
  1421. /**
  1422. * 拍照或从手机相册中选图。
  1423. *
  1424. * @compat WeCom iOS, Android; WeChat
  1425. *
  1426. * @example
  1427. * ```ts
  1428. * ww.chooseImage({
  1429. * count: 1,
  1430. * sizeType: ['original', 'compressed'],
  1431. * sourceType: ['album', 'camera'],
  1432. * defaultCameraMode: 'batch',
  1433. * isSaveToAlbum: true
  1434. * })
  1435. * ```
  1436. */ function chooseImage(params = {}) {
  1437. return promiseToCallback(params, async ()=>{
  1438. await tryEnsureConfigReady();
  1439. const res = await invoke('chooseImage', {
  1440. scene: '1|2',
  1441. count: params.count || 9,
  1442. sizeType: params.sizeType || [
  1443. 'original',
  1444. 'compressed'
  1445. ],
  1446. sourceType: params.sourceType || [
  1447. 'album',
  1448. 'camera'
  1449. ],
  1450. defaultCameraMode: params.defaultCameraMode || 'normal',
  1451. isSaveToAlbum: isFalsy(params.isSaveToAlbum) ? 0 : 1
  1452. });
  1453. if (isAndroid && res.localIds) {
  1454. res.localIds = res.localIds || '[]';
  1455. try {
  1456. res.localIds = JSON.parse(res.localIds);
  1457. } catch (error) {
  1458. // noop
  1459. }
  1460. }
  1461. return res;
  1462. });
  1463. }
  1464. /**
  1465. * 预览图片
  1466. *
  1467. * @note
  1468. * 从2.4.6版本开始,IOS版企业微信浏览器升级为WkWebView,企业微信原生层面的网络请求读取不到WKWebview中设置的cookie,即使域名是相同的。
  1469. * **问题说明:**
  1470. * 如果页面的资源或图片存储的服务器依赖校验Cookie来返回数据的情况,在切换到WKWebview后,在企业微信内长按保存,或者点击预览大图时,原生层面发起的网络请求将不会完整地带上所设置的Cookie,会导致图片保存失败或预览失败。
  1471. * **适配建议**
  1472. * 建议静态资源cookie free。如果确实有信息需要传递,可通过业务后台存储需要传递的信息,然后给页面一个存储信息相对应的access_token加密码,再通过Url中加入自己业务的access_token进行页面间信息传递。
  1473. *
  1474. * @example
  1475. * ```ts
  1476. * ww.previewImage({
  1477. * current: imgURL,
  1478. * urls: [imgURL]
  1479. * });
  1480. * ```
  1481. */ function previewImage(params) {
  1482. return passthrough('imagePreview', params);
  1483. }
  1484. /**
  1485. * 上传图片。
  1486. *
  1487. * @note
  1488. * 上传的图片有效期 3 天,可用[素材管理](#10115)接口下载图片到自己的服务器,此处获得的 serverId 即 media_id。
  1489. *
  1490. * @example
  1491. * ```ts
  1492. * ww.uploadImage({
  1493. * localId: localId,
  1494. * isShowProgressTips: true
  1495. * })
  1496. * ```
  1497. */ function uploadImage(params) {
  1498. return passthrough('uploadImage', params, {
  1499. localId: params.localId,
  1500. isShowProgressTips: isFalsy(params.isShowProgressTips) ? 0 : 1
  1501. });
  1502. }
  1503. /**
  1504. * 下载图片。
  1505. *
  1506. * @example
  1507. * ```ts
  1508. * ww.downloadImage({
  1509. * serverId: serverId,
  1510. * isShowProgressTips: true
  1511. * })
  1512. * ```
  1513. */ function downloadImage(params) {
  1514. return passthrough('downloadImage', params, {
  1515. serverId: params.serverId,
  1516. isShowProgressTips: isFalsy(params.isShowProgressTips) ? 0 : 1
  1517. });
  1518. }
  1519. /**
  1520. * 获取本地图片内容。
  1521. *
  1522. * @limit
  1523. * 仅在 iOS WKWebView 下支持。
  1524. *
  1525. * @compat WeCom iOS >= 2.4.6
  1526. *
  1527. * @example
  1528. * ```ts
  1529. * ww.getLocalImgData({
  1530. * localId: localId
  1531. * })
  1532. * ```
  1533. */ function getLocalImgData(params) {
  1534. return passthrough('getLocalImgData', params);
  1535. }
  1536. /**
  1537. * 开始录音。
  1538. *
  1539. * @example
  1540. * ```ts
  1541. * ww.startRecord()
  1542. * ```
  1543. */ function startRecord(params = {}) {
  1544. return passthrough('startRecord', params);
  1545. }
  1546. /**
  1547. * 停止录音。
  1548. *
  1549. * @example
  1550. * ```ts
  1551. * ww.stopRecord()
  1552. * ```
  1553. */ function stopRecord(params = {}) {
  1554. return passthrough('stopRecord', params);
  1555. }
  1556. /**
  1557. * 监听录音自动停止。
  1558. *
  1559. * @note
  1560. * 录音时间超过一分钟没有停止的时候会执行 complete 回调
  1561. *
  1562. * @example
  1563. * ```ts
  1564. * ww.onVoiceRecordEnd(function(event) {
  1565. * console.log(event)
  1566. * })
  1567. * ```
  1568. */ function onVoiceRecordEnd(callback) {
  1569. on('onVoiceRecordEnd', callback);
  1570. }
  1571. /**
  1572. * 播放语音。
  1573. *
  1574. * @example
  1575. * ```ts
  1576. * ww.playVoice({
  1577. * localId: localId
  1578. * })
  1579. * ```
  1580. */ function playVoice(params) {
  1581. return passthrough('playVoice', params);
  1582. }
  1583. /**
  1584. * 暂停播放。
  1585. *
  1586. * @example
  1587. * ```ts
  1588. * ww.pauseVoice({
  1589. * localId: localId
  1590. * })
  1591. * ```
  1592. */ function pauseVoice(params) {
  1593. return passthrough('pauseVoice', params);
  1594. }
  1595. /**
  1596. * 停止播放。
  1597. *
  1598. * @example
  1599. * ```ts
  1600. * ww.stopVoice({
  1601. * localId: localId
  1602. * })
  1603. * ```
  1604. */ function stopVoice(params) {
  1605. return passthrough('stopVoice', params);
  1606. }
  1607. /**
  1608. * 监听语音播放完毕。
  1609. *
  1610. * @example
  1611. * ```ts
  1612. * ww.onVoicePlayEnd(function(event) {
  1613. * console.log(event)
  1614. * })
  1615. * ```
  1616. */ function onVoicePlayEnd(callback) {
  1617. on('onVoicePlayEnd', callback);
  1618. }
  1619. /**
  1620. * 上传语音。
  1621. *
  1622. * @note
  1623. * 上传语音有效期 3 天,可以通过[素材管理](https://developer.work.weixin.qq.com/document/path/91054)接口下载语音到自己的服务器,接口返回的的 `serverId` 即 `media_id`。
  1624. *
  1625. * @example
  1626. * ```ts
  1627. * ww.uploadVoice({
  1628. * localId: localId,
  1629. * isShowProgressTips: true
  1630. * })
  1631. * ```
  1632. */ function uploadVoice(params) {
  1633. return passthrough('uploadVoice', params, {
  1634. localId: params.localId,
  1635. isShowProgressTips: isFalsy(params.isShowProgressTips) ? 0 : 1
  1636. });
  1637. }
  1638. /**
  1639. * 下载语音。
  1640. *
  1641. * @example
  1642. * ```ts
  1643. * ww.downloadVoice({
  1644. * serverId: serverId,
  1645. * isShowProgressTips: true
  1646. * })
  1647. * ```
  1648. */ function downloadVoice(params) {
  1649. return passthrough('downloadVoice', params, {
  1650. serverId: params.serverId,
  1651. isShowProgressTips: isFalsy(params.isShowProgressTips) ? 0 : 1
  1652. });
  1653. }
  1654. /**
  1655. * 语音转文字。
  1656. *
  1657. * @compat WeCom iOS, Android >= 2.7.5
  1658. *
  1659. * @example
  1660. * ```ts
  1661. * ww.translateVoice({
  1662. * localId: localId,
  1663. * isShowProgressTips: true
  1664. * })
  1665. * ```
  1666. */ function translateVoice(params) {
  1667. return passthrough('translateVoice', params, {
  1668. localId: params.localId,
  1669. isShowProgressTips: isFalsy(params.isShowProgressTips) ? 0 : 1
  1670. });
  1671. }
  1672. var LiveType;
  1673. (function(LiveType) {
  1674. /**
  1675. * 通用直播
  1676. */ LiveType[LiveType["common"] = 0] = "common";
  1677. /**
  1678. * 企业培训
  1679. */ LiveType[LiveType["corp_training"] = 1] = "corp_training";
  1680. /**
  1681. * 大班课
  1682. */ LiveType[LiveType["edu_normal_class"] = 2] = "edu_normal_class";
  1683. /**
  1684. * 小班课
  1685. */ LiveType[LiveType["edu_small_class"] = 3] = "edu_small_class";
  1686. })(LiveType || (LiveType = {}));
  1687. function startLiving(params = {}) {
  1688. return passthrough('startLiving', params);
  1689. }
  1690. /**
  1691. * 调起直播间回放页面。
  1692. *
  1693. * @limit
  1694. * - 本接口必须使用应用身份进行注册
  1695. * - 应用需具有直播使用权限,参考[配置可使用直播的应用](#25967/配置可使用直播的应用)
  1696. *
  1697. * @compat WeCom >= 3.1.0
  1698. *
  1699. * @example
  1700. * ```ts
  1701. * ww.replayLiving({
  1702. * livingId: 'LIVINGID'
  1703. * })
  1704. * ```
  1705. *
  1706. * @throws
  1707. * | errMsg | 说明 |
  1708. * | --- | --- |
  1709. * | replayLiving:ok | 执行成功 |
  1710. * | replayLiving:fail no permission | 应用签名校验失败,或应用不具备直播权限 |
  1711. * | replayLiving:fail invalid living id | 不合法的直播ID |
  1712. * | replayLiving:fail not allow to cross corp | 不可跨企业使用直播ID |
  1713. * | replayLiving:fail not allow to cross app | 不可跨应用使用直播ID |
  1714. * | replayLiving:fail living has no replay | 不存在直播回放 |
  1715. * | replayLiving:fail replay is beging creating | 正在直播中,或回放正在生成中,稍后观看回放 |
  1716. * | replayLiving:fail create replay failed | 回放创建失败 |
  1717. * | replayLiving:fail invalid parameter | 参数不合法 |
  1718. */ function replayLiving(params) {
  1719. return passthrough('replayLiving', params);
  1720. }
  1721. /**
  1722. * 调起直播回放下载页面。
  1723. *
  1724. * @limit
  1725. * - 本接口必须使用应用身份进行注册
  1726. * - 应用需具有直播使用权限,参考[配置可使用直播的应用](#25967/配置可使用直播的应用)
  1727. * - 只允许直播的发起人下载直播回放
  1728. *
  1729. * @compat WeCom PC >= 3.1.0
  1730. *
  1731. * @example
  1732. * ```ts
  1733. * ww.downloadLivingReplay({
  1734. * livingId: 'LIVINGID'
  1735. * })
  1736. * ```
  1737. *
  1738. * @throws
  1739. * | errMsg | 说明 |
  1740. * | --- | --- |
  1741. * | downloadLivingReplay:ok | 执行成功 |
  1742. * | downloadLivingReplay:fail no permission | 应用签名校验失败,或应用不具备直播权限 |
  1743. * | downloadLivingReplay:fail invalid living id | 不合法的直播ID |
  1744. * | downloadLivingReplay:fail not allow to cross corp | 不可跨企业使用直播ID |
  1745. * | downloadLivingReplay:fail not allow to cross app | 不可跨应用使用直播ID |
  1746. * | downloadLivingReplay:fail invalid parameter | 参数不合法 |
  1747. * | downloadLivingReplay:fail living has no replay | 不存在直播回放 |
  1748. * | downloadLivingReplay:fail replay is beging creating | 正在直播中,或回放正在生成中,稍后观看回放 |
  1749. * | downloadLivingReplay:fail create replay failed | 回放创建失败 |
  1750. * | downloadLivingReplay:fail invalid operator | 只允许直播的发起人下载直播回放 |
  1751. */ function downloadLivingReplay(params) {
  1752. return passthrough('downloadLivingReplay', params);
  1753. }
  1754. function startMeeting(params = {}) {
  1755. return passthrough('startMeeting', params);
  1756. }
  1757. /**
  1758. * 新建文档、表格或者收集表。
  1759. *
  1760. * @limit
  1761. * - 本接口必须使用应用身份进行注册
  1762. * - 签名应用必须具有文档使用权限
  1763. * - 当前用户必须在应用的可见范围之内
  1764. * - 在 Mac 端使用时,macOS 版本需 > 10.12
  1765. *
  1766. * @compat WeCom >= 4.1.0
  1767. *
  1768. * @example
  1769. * ```
  1770. * ww.createDoc({
  1771. * docType: 3
  1772. * })
  1773. * ```
  1774. *
  1775. * @throws
  1776. * | errMsg | 说明 |
  1777. * | --- | --- |
  1778. * | createDoc:ok | 执行成功 |
  1779. * | createDoc:fail no permission | 应用签名校验失败,或成员不在应用的可见范围内,或应用未开启文档使用权限 |
  1780. * | createDoc:fail doc app closed. | 基础应用“文档”如果未启用 |
  1781. * | createDoc:fail form app closed. | 基础应用“收集表”如果没有启用 |
  1782. */ function createDoc(params) {
  1783. return passthrough('createDoc', params);
  1784. }
  1785. var WedocSelectedFileType;
  1786. (function(WedocSelectedFileType) {
  1787. /**
  1788. * 其他
  1789. */ WedocSelectedFileType[WedocSelectedFileType["other"] = 0] = "other";
  1790. /**
  1791. * 文档
  1792. */ WedocSelectedFileType[WedocSelectedFileType["doc"] = 3] = "doc";
  1793. /**
  1794. * 表格
  1795. */ WedocSelectedFileType[WedocSelectedFileType["sheet"] = 4] = "sheet";
  1796. /**
  1797. * 收集表
  1798. */ WedocSelectedFileType[WedocSelectedFileType["form"] = 5] = "form";
  1799. /**
  1800. * 幻灯片
  1801. */ WedocSelectedFileType[WedocSelectedFileType["slide"] = 6] = "slide";
  1802. /**
  1803. * 思维导图
  1804. */ WedocSelectedFileType[WedocSelectedFileType["mindmap"] = 7] = "mindmap";
  1805. /**
  1806. * 流程图
  1807. */ WedocSelectedFileType[WedocSelectedFileType["flowchart"] = 8] = "flowchart";
  1808. /**
  1809. * 智能表格
  1810. */ WedocSelectedFileType[WedocSelectedFileType["smartsheet"] = 10] = "smartsheet";
  1811. })(WedocSelectedFileType || (WedocSelectedFileType = {}));
  1812. /**
  1813. * 选择一个或多个文档,返回对应文档的 URL。
  1814. *
  1815. * @limit
  1816. * - 本接口必须使用应用身份进行注册,签名应用必须具有文档使用权限
  1817. * - 当前用户必须在应用的可见范围之内
  1818. * - Mac 端使用时,macOS 版本需 > 10.12
  1819. *
  1820. * @compat WeCom >= 4.0.12
  1821. *
  1822. * @example
  1823. * ```
  1824. * ww.wedocSelectDoc({
  1825. * selectedFileNum: 1
  1826. * })
  1827. * ```
  1828. *
  1829. * @throws
  1830. * | errMsg | 说明 |
  1831. * | --- | --- |
  1832. * | wedocSelectDoc:ok | 执行成功 |
  1833. * | wedocSelectDoc:cancel | 取消选择 |
  1834. * | wedocSelectDoc:fail no permission | 应用签名失败,或应用无文档使用权限,或用户不在应用可见范围内 |
  1835. * | wedocSelectDoc:fail param error | 参数错误 |
  1836. * | wedocSelectDoc:fail context error | 选择器异常 |
  1837. * | wedocSelectDoc:fail not supported system version| 低系统版本不支持 |
  1838. */ function wedocSelectDoc(params) {
  1839. return passthrough('wedocSelectDoc', params);
  1840. }
  1841. /**
  1842. * 在微盘中选择一个具有可上传权限的目录/空间,返回选中目录/空间对应的 selectedTicket。
  1843. *
  1844. * @limit
  1845. * - 本接口必须使用应用身份进行注册
  1846. * - 所使用的应用必须具有微盘权限
  1847. * - 当前成员必须在应用的可见范围之内
  1848. * - 若用户在某一目录位置不具备「上传」权限(微盘权限值为“可下载”/“仅预览”或自定义权限取消勾选“上传”权限),则无法选择该目录
  1849. * - 在 Mac 端使用时,macOS 版本需 > 10.12
  1850. *
  1851. * @compat WeCom >= 4.0.12
  1852. *
  1853. * @example
  1854. * ```
  1855. * ww.wedriveSelectDir()
  1856. * ```
  1857. *
  1858. * @throws
  1859. * | errMsg | 说明 |
  1860. * | --- | --- |
  1861. * | wedriveSelectDir:ok | 执行成功 |
  1862. * | wedriveSelectDir:cancel | 取消选择 |
  1863. * | wedriveSelectDir:fail no permission | 无权限 |
  1864. * | wedriveSelectDir:fail param error | 参数错误 |
  1865. * | wedriveSelectDir:fail context error | 选择器异常 |
  1866. * | wedriveSelectDir:fail not supported system version | 低系统版本不支持 |
  1867. */ function wedriveSelectDir(params = {}) {
  1868. return passthrough('wedriveSelectDir', params);
  1869. }
  1870. /**
  1871. * 唤起微盘选择器,选择微盘中的文件
  1872. *
  1873. * 在微盘中选择一个或多个具有可分享权限的微盘文件或在线文档,返回选中文件的 url。
  1874. *
  1875. * @compat WeCom >= 4.0.12
  1876. *
  1877. * @limit
  1878. * - 本接口必须使用应用身份进行注册
  1879. * - 所使用的应用必须具有微盘和文档使用权限
  1880. * - 当前成员必须在应用的可见范围之内
  1881. * - 若用户对某文件不具备「分享」权限(微盘自定义权限取消勾选“分享”权限),则无法选择该文件。
  1882. * - 在 Mac 端使用时,macOS 版本需 > 10.12
  1883. *
  1884. * @example
  1885. * ```
  1886. * ww.wedriveSelectFile({
  1887. * selectedFileNum: 1,
  1888. * })
  1889. * ```
  1890. *
  1891. * @throws
  1892. * | errMsg | 说明 |
  1893. * | --- | --- |
  1894. * | wedriveSelectFile:ok | 执行成功 |
  1895. * | wedriveSelectFile:cancel | 取消选择 |
  1896. * | wedriveSelectFile:fail no permission | 无权限 |
  1897. * | wedriveSelectFile:fail param error | 参数错误 |
  1898. * | wedriveSelectFile:fail context error | 选择器异常 |
  1899. * | wedriveSelectFile:fail not supported system version | 低系统版本不支持 |
  1900. */ function wedriveSelectFile(params) {
  1901. return passthrough('wedriveSelectFile', params);
  1902. }
  1903. /**
  1904. * 选择可分享的文件
  1905. *
  1906. * 在微盘中选择一个或多个具有可分享权限的微盘文件或在线文档,返回选中文件的 url。
  1907. *
  1908. * @deprecated 该接口即将废弃,请使用 wedriveSelectFile 代替
  1909. *
  1910. * @compat WeCom >= 4.0.12
  1911. */ function wedriveSelectFileForShare(params) {
  1912. return passthrough('wedriveSelectFileForShare', params);
  1913. }
  1914. /**
  1915. * 在微盘中选择一个或多个具有下载权限的文件(只能是微盘文件,不支持在线文档),返回选中文件对应的 selectedTickets 列表。
  1916. *
  1917. * @limit
  1918. * - 本接口必须使用应用身份进行注册
  1919. * - 应用必须具有微盘使用权限
  1920. * - 当前成员必须在应用的可见范围之中
  1921. * - 自建应用不支持调用
  1922. *
  1923. * @compat WeCom >= 4.0.12
  1924. *
  1925. * @example
  1926. * ```
  1927. * ww.wedriveSelectFileForDownload({
  1928. * selectedFileNum: 1
  1929. * })
  1930. * ```
  1931. *
  1932. * @throws
  1933. * | errMsg | 说明 |
  1934. * | --- | --- |
  1935. * | wedriveSelectFileForDownload:ok | 执行成功 |
  1936. * | wedriveSelectFileForDownload:cancel | 取消选择 |
  1937. * | wedriveSelectFileForDownload:fail no permission | 无权限 |
  1938. * | wedriveSelectFileForDownload:fail param error | 参数错误 |
  1939. * | wedriveSelectFileForDownload:fail context error | 选择器异常 |
  1940. * | wedriveSelectFileForDownload:fail not supported system version | 低系统版本不支持 |
  1941. */ function wedriveSelectFileForDownload(params) {
  1942. return passthrough('wedriveSelectFileForDownload', params);
  1943. }
  1944. /**
  1945. * 监听页面返回事件。
  1946. *
  1947. * @param callback 回调函数,返回 false 则表示中断此次返回操作
  1948. *
  1949. * @limit
  1950. * - 当页面左上角没有关闭按钮,不产生该事件
  1951. * - iOS 系统下使用手势返回时,不产生该事件
  1952. *
  1953. * @compat WeCom iOS, Android >= 2.2.0; WeCom PC, Mac >= 2.4.5
  1954. *
  1955. * @example
  1956. * ```ts
  1957. * ww.onHistoryBack(function() {
  1958. * return confirm('确定放弃当前页面的修改?')
  1959. * })
  1960. * ```
  1961. */ function onHistoryBack(callback) {
  1962. on('historyBack', callback);
  1963. }
  1964. /**
  1965. * 隐藏右上角菜单。
  1966. *
  1967. * @example
  1968. * ```ts
  1969. * ww.hideOptionMenu()
  1970. * ```
  1971. */ function hideOptionMenu(params = {}) {
  1972. return passthrough('hideOptionMenu', params);
  1973. }
  1974. /**
  1975. * 显示右上角菜单。
  1976. *
  1977. * @example
  1978. * ```ts
  1979. * ww.showOptionMenu()
  1980. * ```
  1981. */ function showOptionMenu(params = {}) {
  1982. return passthrough('showOptionMenu', params);
  1983. }
  1984. /**
  1985. * 关闭当前网页窗口。
  1986. *
  1987. * @example
  1988. * ```ts
  1989. * ww.closeWindow()
  1990. * ```
  1991. */ function closeWindow(params = {}) {
  1992. return passthrough('closeWindow', params);
  1993. }
  1994. /**
  1995. * 批量隐藏功能按钮。
  1996. *
  1997. * @note
  1998. * 完整功能按钮列表请参考[所有菜单项列表](#14926)。
  1999. *
  2000. * @example
  2001. * ```ts
  2002. * ww.hideMenuItems({
  2003. * menuList: ['menuItem:setFont']
  2004. * })
  2005. * ```
  2006. */ function hideMenuItems(params) {
  2007. return passthrough('hideMenuItems', params);
  2008. }
  2009. /**
  2010. * 批量显示功能按钮。
  2011. *
  2012. * @note
  2013. * 完整功能按钮列表请参考[所有菜单项列表](#14926)。
  2014. *
  2015. * @example
  2016. * ```ts
  2017. * ww.showMenuItems({
  2018. * menuList: ['menuItem:setFont']
  2019. * })
  2020. * ```
  2021. */ function showMenuItems(params) {
  2022. return passthrough('showMenuItems', params);
  2023. }
  2024. /**
  2025. * 隐藏所有非基础按钮。
  2026. *
  2027. * @example
  2028. * ```ts
  2029. * ww.hideAllNonBaseMenuItem()
  2030. * ```
  2031. */ function hideAllNonBaseMenuItem(params = {}) {
  2032. return passthrough('hideAllNonBaseMenuItem', params);
  2033. }
  2034. /**
  2035. * 显示所有功能按钮。
  2036. *
  2037. * @example
  2038. * ```ts
  2039. * ww.showAllNonBaseMenuItem()
  2040. * ```
  2041. */ function showAllNonBaseMenuItem(params = {}) {
  2042. return passthrough('showAllNonBaseMenuItem', params);
  2043. }
  2044. /**
  2045. * 使用系统浏览器打开指定 URL,支持传入 oauth2 链接,从而实现在系统浏览器内免登录的效果。
  2046. *
  2047. * @compat WeCom PC >= 2.3.0
  2048. *
  2049. * @example
  2050. * ```ts
  2051. * ww.openDefaultBrowser({
  2052. * url: 'https://work.weixin.qq.com/'
  2053. * })
  2054. * ```
  2055. */ function openDefaultBrowser(params) {
  2056. return passthrough('openDefaultBrowser', params);
  2057. }
  2058. /**
  2059. * 监听用户截屏事件。
  2060. *
  2061. * @compat WeCom iOS, Android >= 2.5.0
  2062. *
  2063. * @example
  2064. * ```ts
  2065. * ww.onUserCaptureScreen(function() {
  2066. * console.log('用户截屏了')
  2067. * })
  2068. * ```
  2069. */ function onUserCaptureScreen(callback) {
  2070. on('onUserCaptureScreen', callback);
  2071. }
  2072. /**
  2073. * 获取「转发」按钮点击状态并自定义分享内容。
  2074. *
  2075. * @note
  2076. * 微信客户端即将废弃该接口。
  2077. *
  2078. * @limit
  2079. * - 仅激活成员数超过 200 人且已经认证的企业才可在微信上调用
  2080. *
  2081. * @example
  2082. * ```ts
  2083. * ww.onMenuShareAppMessage({
  2084. * title: '企业微信',
  2085. * desc: '让每个企业都有自己的微信',
  2086. * link: 'https://work.weixin.qq.com/',
  2087. * imgUrl: 'https://res.mail.qq.com/node/ww/wwmng/style/images/index_share_logo$13c64306.png',
  2088. * success() {
  2089. * // 用户确认分享后回调
  2090. * },
  2091. * cancel() {
  2092. * // 用户取消分享后回调
  2093. * }
  2094. * })
  2095. * ```
  2096. */ function onMenuShareAppMessage(params) {
  2097. bindShare('menu:share:appmessage', params, ()=>invoke('sendAppMessage', {
  2098. title: params.title || getTitle(),
  2099. desc: params.desc || '',
  2100. link: params.link || getHref(),
  2101. img_url: params.imgUrl || '',
  2102. type: params.type || 'link',
  2103. data_url: params.dataUrl || '',
  2104. finder_feed: params.finderFeed || params.finder_feed,
  2105. finder_topic: params.finderTopic || params.finder_topic,
  2106. finder_profile: params.finderProfile || params.finder_profile,
  2107. enableIdTrans: params.enableIdTrans ? 1 : 0
  2108. }));
  2109. }
  2110. /**
  2111. * 获取「分享到朋友圈」按钮点击状态并自定义分享内容。
  2112. *
  2113. * @note
  2114. * 微信客户端即将废弃该接口。
  2115. *
  2116. * @example
  2117. * ```ts
  2118. * ww.onMenuShareTimeline({
  2119. * title: '企业微信',
  2120. * link: 'https://work.weixin.qq.com/',
  2121. * imgUrl: 'https://res.mail.qq.com/node/ww/wwmng/style/images/index_share_logo$13c64306.png',
  2122. * success() {
  2123. * // 用户确认分享后回调
  2124. * },
  2125. * cancel() {
  2126. * // 用户取消分享后回调
  2127. * }
  2128. * })
  2129. * ```
  2130. */ function onMenuShareTimeline(params) {
  2131. bindShare('menu:share:timeline', params, ()=>invoke('shareTimeline', {
  2132. title: params.title || getTitle(),
  2133. desc: params.title || getTitle(),
  2134. img_url: params.imgUrl || '',
  2135. link: params.link || getHref(),
  2136. type: params.type || 'link',
  2137. data_url: params.dataUrl || '',
  2138. enableIdTrans: params.enableIdTrans ? 1 : 0
  2139. }));
  2140. }
  2141. /**
  2142. * 获取「微信」按钮点击状态并自定义分享内容。
  2143. *
  2144. * @compat WeCom
  2145. *
  2146. * @example
  2147. * ```ts
  2148. * ww.onMenuShareWechat({
  2149. * title: '企业微信',
  2150. * desc: '让每个企业都有自己的微信',
  2151. * link: 'https://work.weixin.qq.com/',
  2152. * imgUrl: 'https://res.mail.qq.com/node/ww/wwmng/style/images/index_share_logo$13c64306.png',
  2153. * success() {
  2154. * // 用户确认分享后回调
  2155. * },
  2156. * cancel() {
  2157. * // 用户取消分享后回调
  2158. * }
  2159. * })
  2160. * ```
  2161. */ function onMenuShareWechat(params) {
  2162. bindShare('menu:share:wechat', params, ()=>invoke('shareWechat', {
  2163. title: params.title || getTitle(),
  2164. desc: params.desc || '',
  2165. link: params.link || getHref(),
  2166. img_url: params.imgUrl || '',
  2167. type: params.type || 'link',
  2168. data_url: params.dataUrl || '',
  2169. enableIdTrans: params.enableIdTrans ? 1 : 0
  2170. }));
  2171. }
  2172. /**
  2173. * 获取「分享到QQ」按钮点击状态并自定义分享内容。
  2174. *
  2175. * @note
  2176. * 微信客户端即将废弃该接口。
  2177. *
  2178. * @compat WeChat
  2179. */ function onMenuShareQQ(params) {
  2180. bindShare('menu:share:qq', params, ()=>invoke('shareQQ', {
  2181. title: params.title || getTitle(),
  2182. desc: params.desc || '',
  2183. img_url: params.imgUrl || '',
  2184. link: params.link || getHref()
  2185. }));
  2186. }
  2187. /**
  2188. * 获取「分享到微博」按钮点击状态并自定义分享内容。
  2189. *
  2190. * @compat WeChat
  2191. */ function onMenuShareWeibo(params) {
  2192. bindShare('menu:share:weiboApp', params, ()=>invoke('shareWeiboApp', {
  2193. title: params.title || getTitle(),
  2194. desc: params.desc || '',
  2195. img_url: params.imgUrl || '',
  2196. link: params.link || getHref()
  2197. }));
  2198. }
  2199. /**
  2200. * 获取「分享到QQ空间」按钮点击状态并自定义分享内容。
  2201. *
  2202. * @note
  2203. * 微信客户端即将废弃该接口。
  2204. *
  2205. * @compat WeChat
  2206. */ function onMenuShareQZone(params) {
  2207. bindShare('menu:share:QZone', params, ()=>invoke('shareQZone', {
  2208. title: params.title || getTitle(),
  2209. desc: params.desc || '',
  2210. img_url: params.imgUrl || '',
  2211. link: params.link || getHref()
  2212. }));
  2213. }
  2214. /**
  2215. * 自定义转发到会话。
  2216. *
  2217. * @compat WeCom >= 2.4.5
  2218. *
  2219. * @example
  2220. * ```ts
  2221. * ww.shareAppMessage({
  2222. * title: '企业微信',
  2223. * desc: '让每个企业都有自己的微信',
  2224. * link: 'https://work.weixin.qq.com/',
  2225. * imgUrl: 'https://res.mail.qq.com/node/ww/wwmng/style/images/index_share_logo$13c64306.png',
  2226. * })
  2227. * ```
  2228. */ function shareAppMessage(params) {
  2229. return passthrough('shareAppMessage', params);
  2230. }
  2231. /**
  2232. * 自定义转发到微信。
  2233. *
  2234. * @compat WeCom >= 2.4.5
  2235. *
  2236. * @example
  2237. * ```ts
  2238. * ww.shareWechatMessage({
  2239. * title: '企业微信',
  2240. * desc: '让每个企业都有自己的微信',
  2241. * link: 'https://work.weixin.qq.com/',
  2242. * imgUrl: 'https://res.mail.qq.com/node/ww/wwmng/style/images/index_share_logo$13c64306.png',
  2243. * })
  2244. * ```
  2245. */ function shareWechatMessage(params) {
  2246. return passthrough('shareWechatMessage', params);
  2247. }
  2248. /**
  2249. * 自定义「分享到朋友圈」及「分享到QQ空间」按钮的分享内容。
  2250. *
  2251. * @compat WeChat
  2252. */ function updateTimelineShareData(params = {}) {
  2253. return passthrough('updateTimelineShareData', params);
  2254. }
  2255. /**
  2256. * 自定义「分享给朋友」及「分享到QQ」按钮的分享内容。
  2257. *
  2258. * @compat WeChat
  2259. */ function updateAppMessageShareData(params = {}) {
  2260. return passthrough('updateAppMessageShareData', params);
  2261. }
  2262. /**
  2263. * 批量添加卡券。
  2264. *
  2265. * @see https://developers.weixin.qq.com/doc/offiaccount/OA_Web_Apps/JS-SDK.html#批量添加卡券接口
  2266. */ function addCard(params) {
  2267. return promiseToCallback(params, async ()=>{
  2268. await tryEnsureConfigReady();
  2269. const res = await invoke('batchAddCard', {
  2270. card_list: params.cardList.map((card)=>({
  2271. card_id: card.cardId,
  2272. card_ext: card.cardExt
  2273. }))
  2274. });
  2275. if (!res.card_list) {
  2276. return res;
  2277. }
  2278. for (const card of res.card_list){
  2279. card.cardId = card.card_id;
  2280. delete card.card_id;
  2281. card.cardExt = card.card_ext;
  2282. delete card.card_ext;
  2283. card.isSuccess = !!card.is_succ;
  2284. delete card.is_succ;
  2285. }
  2286. res.cardList = res.card_list;
  2287. delete res.card_list;
  2288. return res;
  2289. });
  2290. }
  2291. /**
  2292. * 拉取适用卡券列表并获取用户选择信息。
  2293. *
  2294. * @see https://developers.weixin.qq.com/doc/offiaccount/OA_Web_Apps/JS-SDK.html#拉取适用卡券列表并获取用户选择信息
  2295. */ function chooseCard(params) {
  2296. return promiseToCallback(params, async ()=>{
  2297. await tryEnsureConfigReady();
  2298. const res = await invoke('chooseCard', {
  2299. app_id: getConfigCorpId(),
  2300. location_id: params.shopId || '',
  2301. sign_type: params.signType || 'SHA1',
  2302. card_id: params.cardId || '',
  2303. card_type: params.cardType || '',
  2304. card_sign: params.cardSign,
  2305. time_stamp: `${params.timestamp}`,
  2306. nonce_str: params.nonceStr
  2307. });
  2308. res.cardList = res.choose_card_info;
  2309. delete res.choose_card_info;
  2310. return res;
  2311. });
  2312. }
  2313. /**
  2314. * 查看微信卡包中的卡券。
  2315. *
  2316. * @see https://developers.weixin.qq.com/doc/offiaccount/OA_Web_Apps/JS-SDK.html#查看微信卡包中的卡券接口
  2317. */ function openCard(params) {
  2318. return passthrough('batchViewCard', params, {
  2319. card_list: params.cardList.map((card)=>({
  2320. card_id: card.cardId,
  2321. code: card.code
  2322. }))
  2323. });
  2324. }
  2325. /**
  2326. * 核销并分享卡券。
  2327. *
  2328. * @deprecated
  2329. */ function consumeAndShareCard(params) {
  2330. return passthrough('consumedShareCard', params, {
  2331. consumedCardId: params.cardId,
  2332. consumedCode: params.code
  2333. });
  2334. }
  2335. var ProductViewType;
  2336. (function(ProductViewType) {
  2337. ProductViewType[ProductViewType["normal"] = 0] = "normal";
  2338. ProductViewType[ProductViewType["scan"] = 1] = "scan";
  2339. })(ProductViewType || (ProductViewType = {}));
  2340. /**
  2341. * 跳转微信商品页。
  2342. *
  2343. * @see https://developers.weixin.qq.com/doc/offiaccount/OA_Web_Apps/JS-SDK.html#跳转微信商品页接口
  2344. */ function openProductSpecificView(params) {
  2345. return passthrough('openProductViewWithPid', params, {
  2346. pid: params.productId,
  2347. view_type: params.viewType || 0,
  2348. ext_info: params.extInfo
  2349. });
  2350. }
  2351. /**
  2352. * 发起一个微信支付请求。
  2353. *
  2354. * @see https://developers.weixin.qq.com/doc/offiaccount/OA_Web_Apps/JS-SDK.html#发起一个微信支付请求
  2355. */ function chooseWXPay(params) {
  2356. return passthrough('getBrandWCPayRequest', params, normalizeParams(params));
  2357. }
  2358. /**
  2359. * 领取企业红包。
  2360. */ function openEnterpriseRedPacket(params) {
  2361. return passthrough('getRecevieBizHongBaoRequest', params, normalizeParams(params));
  2362. }
  2363. function normalizeParams(params) {
  2364. return {
  2365. timeStamp: `${params.timestamp}`,
  2366. nonceStr: params.nonceStr,
  2367. package: params.package,
  2368. paySign: params.paySign,
  2369. signType: params.signType || 'SHA1'
  2370. };
  2371. }
  2372. /**
  2373. * 添加设备。
  2374. *
  2375. * @limit
  2376. * - 本接口必须使用应用身份进行注册
  2377. * - 发起用户需要有设备添加权限(超级管理员/设备管理员)
  2378. *
  2379. * @compat WeCom iOS, Android >= 4.0.18
  2380. *
  2381. * @example
  2382. * ```ts
  2383. * ww.addDevice({
  2384. * type: 'qrcode',
  2385. * qrcode_url: 'https://open.work.weixin.qq.com/connect?xxx',
  2386. * })
  2387. * ```
  2388. */ function addDevice(params) {
  2389. return passthrough('addDevice', params);
  2390. }
  2391. /**
  2392. * 判断当前客户端版本是否支持指定 JS 接口。
  2393. *
  2394. * @example
  2395. * ```ts
  2396. * ww.checkJsApi({
  2397. * jsApiList: ['chooseImage']
  2398. * })
  2399. * ```
  2400. */ async function checkJsApi(params) {
  2401. return promiseToCallback(params, async ()=>{
  2402. await tryEnsureConfigReady();
  2403. const res = await invoke('checkJsApi', {
  2404. jsApiList: mapJsApiListToClient(params.jsApiList)
  2405. });
  2406. if (typeof res.checkResult === 'string') {
  2407. try {
  2408. res.checkResult = JSON.parse(res.checkResult);
  2409. } catch (error) {
  2410. res.checkResult = {};
  2411. }
  2412. }
  2413. res.checkResult = normalize(flatten(res.checkResult));
  2414. return res;
  2415. });
  2416. }
  2417. function normalize(data) {
  2418. const result = {
  2419. ...data
  2420. };
  2421. for (const key of Object.keys(data)){
  2422. result[mapJsApiNameToWeb(key)] = data[key];
  2423. }
  2424. return result;
  2425. }
  2426. function flatten(data) {
  2427. const result = {};
  2428. for (const key of Object.keys(data)){
  2429. if (!isObject$1(data[key])) {
  2430. result[key] = data[key];
  2431. continue;
  2432. }
  2433. const child = flatten(data[key]);
  2434. for (const childKey of Object.keys(child)){
  2435. result[`${key}.${childKey}`] = child[childKey];
  2436. }
  2437. }
  2438. return result;
  2439. }
  2440. /**
  2441. * 查看其他成员某段时间内日程中的闲忙状态。
  2442. *
  2443. * @limit
  2444. * - 本接口必须使用应用身份进行注册
  2445. * - 当前成员必须在应用可见范围内
  2446. * - 应用需具有日程使用权限
  2447. *
  2448. * @compat WeCom >= 4.0.20
  2449. *
  2450. * @example
  2451. * ```ts
  2452. * ww.checkSchedule({
  2453. * start_time: 1667232000,
  2454. * end_time: 1667318400,
  2455. * users: ['jack', 'jason']
  2456. * })
  2457. * ```
  2458. */ function checkSchedule(params) {
  2459. return passthrough('checkSchedule', params);
  2460. }
  2461. /**
  2462. * 拉起电子发票列表。
  2463. *
  2464. * @compat WeCom iOS, Android >= 2.1.0
  2465. *
  2466. * @example
  2467. * ```ts
  2468. * ww.chooseInvoice({
  2469. * timestamp: timestamp,
  2470. * nonceStr: nonceStr,
  2471. * signType: signType,
  2472. * cardSign: cardSign
  2473. * })
  2474. * ```
  2475. *
  2476. * @throws
  2477. * | errMsg | 说明 |
  2478. * | --- | --- |
  2479. * | choose_invoice:ok | 执行成功 |
  2480. * | choose_invoice: fail | 选取发票失败 |
  2481. * | choose_invoice: cancel | 选取发票取消 |
  2482. */ function chooseInvoice(params) {
  2483. return passthrough('chooseInvoice', params);
  2484. }
  2485. /**
  2486. * 跳转到认领班级的界面。
  2487. *
  2488. * @compat WeCom >= 3.1.8
  2489. *
  2490. * @limit 本接口必须使用应用身份进行注册
  2491. *
  2492. * @example
  2493. * ```ts
  2494. * ww.claimClassAdmin()
  2495. * ```
  2496. *
  2497. * @throws
  2498. * | errMsg | 说明 |
  2499. * | --- | --- |
  2500. * | claimClassAdmin:ok | 执行成功 |
  2501. * | claimClassAdmin:fail no permission | 应用身份鉴权失败 |
  2502. * | claimClassAdmin:fail user not in allow list | 当前成员不在应用可见范围 |
  2503. */ function claimClassAdmin(params = {}) {
  2504. return passthrough('claimClassAdmin', params);
  2505. }
  2506. /**
  2507. * 向用户申请给指定范围发送消息。
  2508. *
  2509. * 调用接口后,用户可在选人界面对群聊范围进行修改,当创建群聊成功时会返回新建的群聊 ID。
  2510. *
  2511. * @limit
  2512. * - 仅第三方应用(非通讯录应用)与代开发应用可调用
  2513. * - 本接口必须使用应用身份进行注册
  2514. *
  2515. * @compat WeCom >= 3.1.8
  2516. *
  2517. * @example
  2518. * ```ts
  2519. * ww.createChatWithMsg({
  2520. * selectedOpenUserIds: ['zhangsan','lisi'],
  2521. * selectedTickets: ['tick1','token2'],
  2522. * chatName: 'discussName',
  2523. * msg: {
  2524. * msgtype: 'link',
  2525. * link: {
  2526. * title: 'title1',
  2527. * desc: 'desc1',
  2528. * url: 'link1',
  2529. * imgUrl: 'imgurl1'
  2530. * }
  2531. * }
  2532. * })
  2533. * ```
  2534. *
  2535. * @throws
  2536. * | errMsg | 说明 |
  2537. * | --- | --- |
  2538. * | createChatWithMsg:ok | 执行成功 |
  2539. * | createChatWithMsg:fail_unsupported_msgtype | msgtype不合法 |
  2540. * | createChatWithMsg:fail_msg_link_missing_url | msg.link.url未传入 |
  2541. */ function createChatWithMsg(params) {
  2542. return passthrough('createChatWithMsg', params);
  2543. }
  2544. /**
  2545. * 创建企业互联/上下游会话。
  2546. *
  2547. * @limit
  2548. * - 本接口必须使用应用身份进行注册
  2549. * - 企业必须开启互联群功能
  2550. * - 仅局校互联和上下游企业可调用
  2551. * - 当前成员必须在应用的可见范围
  2552. * - 群成员人数不能超过 2000 人
  2553. * - 如果创建的会话有外部联系人,群成员人数不能超过 40 人
  2554. * - 当前成员为下游企业成员时,需要打开上下游空间中的“允许外部单位之间互相查看”配置,群成员中才可以包含其他下游企业成员
  2555. *
  2556. * @compat WeCom iOS, Android, PC >= 3.1.8
  2557. *
  2558. * @example
  2559. * ```ts
  2560. * ww.createCorpGroupChat({
  2561. * groupName: '讨论组',
  2562. * userIds: ['lisi', 'lisi2'],
  2563. * openUserIds: ['wabc3', 'wbcde'],
  2564. * externalUserIds: ['exid1', 'exid2'],
  2565. * corpGroupUserIds: [
  2566. * {
  2567. * corpId: 'ww3333',
  2568. * userId: 'userid123',
  2569. * openUserId: 'wx1111'
  2570. * },
  2571. * {
  2572. * corpId: 'ww4444',
  2573. * userId: 'userid123',
  2574. * openUserId: 'wx1111'
  2575. * }
  2576. * ]
  2577. * })
  2578. * ```
  2579. *
  2580. * @throws
  2581. * | errMsg | 说明 |
  2582. * | --- | --- |
  2583. * | createCorpGroupChat:ok | 执行成功 |
  2584. * | createCorpGroupChat:fail no permission | 应用签名校验失败 |
  2585. * | createCorpGroupChat:fail exceed user id list size | 超过人数上限 |
  2586. * | createCorpGroupChat:fail invalid parameter | 参数不合法 |
  2587. * | createCorpGroupChat:fail need open corp group chat | 企业未开启企业互联群功能 |
  2588. * | createCorpGroupChat:fail exceed external user id list size | 超过包含外部联系人群人数上限 |
  2589. */ function createCorpGroupChat(params) {
  2590. return passthrough('createCorpGroupChat', params, {
  2591. groupName: params.groupName || '',
  2592. userIds: params.userIds,
  2593. openUserIds: params.openUserIds,
  2594. externalUserIds: params.externalUserIds,
  2595. corpGroupUserIds: params.corpGroupUserIds
  2596. });
  2597. }
  2598. var CreateExternalPaymentType;
  2599. (function(CreateExternalPaymentType) {
  2600. /**
  2601. * 在聊天中收款
  2602. */ CreateExternalPaymentType[CreateExternalPaymentType["chat"] = 0] = "chat";
  2603. /**
  2604. * 收款码收款
  2605. */ CreateExternalPaymentType[CreateExternalPaymentType["qrcode"] = 1] = "qrcode";
  2606. })(CreateExternalPaymentType || (CreateExternalPaymentType = {}));
  2607. /**
  2608. * 发起对外收款。
  2609. *
  2610. * @limit
  2611. * - 本接口必须使用应用身份进行注册
  2612. * - 所使用的应用必须具有对外收款权限
  2613. * - 发起的用户必须在应用可见范围并实名
  2614. * - 允许第三方应用、代开发应用和自建应用调用
  2615. *
  2616. * @compat WeCom >= 4.0.12
  2617. *
  2618. * @example
  2619. * ```ts
  2620. * ww.createExternalPayment({
  2621. * paymentType: 0,
  2622. * totalFee: 300,
  2623. * description: '可乐一罐'
  2624. * })
  2625. * ```
  2626. */ function createExternalPayment(params = {}) {
  2627. return passthrough('createExternalPayment', params);
  2628. }
  2629. /**
  2630. * 发起班级收款。
  2631. *
  2632. * 用于老师对学生家长发起付款请求,接口调用成功后会通过家校通知发送付款小程序给家长。
  2633. *
  2634. * @limit
  2635. * - 本接口必须使用应用身份进行注册
  2636. * - 所使用的应用必须具有对外收款权限
  2637. * - 仅支持配置在家长可使用范围内的应用
  2638. * - 企业必须已验证或者已认证
  2639. * - 发起的用户必须在应用可见范围并实名
  2640. * - 发起的用户需在个人微信零钱账户的可用范围内
  2641. *
  2642. * @compat WeCom iOS, Android, PC >= 3.1.10
  2643. *
  2644. * @note
  2645. * - 用户可以手动调整收款金额,收款项目和收款范围
  2646. * - 通过接口发起的收款,默认收款账户为“我的微信零钱账户”,且不可修改
  2647. * - 若用户未授权个人付款码权限,会唤起授权付款码权限页面,授权完成返回页面后会返回错误信息 `'require authorize the payment qr code'`。用户授权完成后可引导用户重新发起收款
  2648. *
  2649. * @example
  2650. * ```ts
  2651. * ww.createSchoolPayment({
  2652. * projectName: '1班班费',
  2653. * amount: 100,
  2654. * payers: {
  2655. * students: ['zhagnshan', 'lisi'],
  2656. * departments: [1, 2]
  2657. * }
  2658. * })
  2659. * ```
  2660. */ function createSchoolPayment(params) {
  2661. return passthrough('createSchoolPayment', params);
  2662. }
  2663. /**
  2664. * 添加设备。
  2665. *
  2666. * @deprecated 请使用 addDevice 接口
  2667. *
  2668. * @limit
  2669. * 调用者必须为企业超级管理员
  2670. *
  2671. * @compat WeCom iOS, Android >= 2.5.8
  2672. *
  2673. * @example
  2674. * ```ts
  2675. * ww.discoverDevice({
  2676. * type: 'qrcode',
  2677. * qrcode_url: 'https://open.work.weixin.qq.com/connect?xxx'
  2678. * })
  2679. * ```
  2680. */ function discoverDevice(params) {
  2681. return passthrough('discoverDevice', params);
  2682. }
  2683. /**
  2684. * 加入视频会议。
  2685. *
  2686. * @limit
  2687. * 只能加入同企业硬件创建的视频会议。
  2688. *
  2689. * @compat WeCom >= 2.5.0
  2690. *
  2691. * @example
  2692. * ```ts
  2693. * ww.enterHWOpenTalk({
  2694. * code: code,
  2695. * ticket: ticket
  2696. * })
  2697. * ```
  2698. */ function enterHWOpenTalk(params) {
  2699. return passthrough('enterHWOpenTalk', params);
  2700. }
  2701. /**
  2702. * 跳转认证界面。
  2703. *
  2704. * @compat WeCom iOS, Android >= 2.8.7
  2705. *
  2706. * @example
  2707. * ```ts
  2708. * ww.enterpriseVerify()
  2709. * ```
  2710. */ function enterpriseVerify(params = {}) {
  2711. return passthrough('enterpriseVerify', params);
  2712. }
  2713. /**
  2714. * 获取 saveApprovalSelectedItems 保存的审批选项。
  2715. *
  2716. * 当用户打开网页后,应该先调用一次该接口获取用户已经选择的数据作为初始数据。获取到初始数据后,应该恢复已经选择的选项。
  2717. *
  2718. * @limit
  2719. * - 本接口必须使用应用身份进行注册
  2720. * - 所签名的应用必须具有审批权限
  2721. *
  2722. * @note
  2723. * - 网页应该做好深色模式适配
  2724. * - 接口仅用于审批设置外部选项场景,请勿用作其他场景
  2725. *
  2726. * @compat WeCom >= 4.0.18
  2727. *
  2728. * @example
  2729. * ```ts
  2730. * ww.getApprovalSelectedItems({
  2731. * key: 'key'
  2732. * })
  2733. * ```
  2734. */ function getApprovalSelectedItems(params) {
  2735. return promiseToCallback(params, async ()=>{
  2736. await tryEnsureConfigReady();
  2737. const res = await invoke('getApprovalSelectedItems', {
  2738. key: params.key
  2739. });
  2740. if (!res.selectedData) {
  2741. return res;
  2742. }
  2743. try {
  2744. res.selectedData = JSON.parse(res.selectedData);
  2745. } catch (error) {
  2746. res.selectedData = [];
  2747. }
  2748. return res;
  2749. });
  2750. }
  2751. var EntryType;
  2752. (function(EntryType) {
  2753. /**
  2754. * 从联系人详情进入
  2755. */ EntryType["contact_profile"] = "contact_profile";
  2756. /**
  2757. * 从单聊会话的工具栏进入
  2758. */ EntryType["single_chat_tools"] = "single_chat_tools";
  2759. /**
  2760. * 从群聊会话的工具栏进入
  2761. */ EntryType["group_chat_tools"] = "group_chat_tools";
  2762. /**
  2763. * 从会话的聊天附件栏进入
  2764. *
  2765. * @compat WeCom >= 3.1.6
  2766. */ EntryType["chat_attachment"] = "chat_attachment";
  2767. /**
  2768. * 从微信客服的工具栏进入
  2769. *
  2770. * @compat WeCom >= 3.1.10
  2771. */ EntryType["single_kf_tools"] = "single_kf_tools";
  2772. /**
  2773. * 上下游单聊会话的工具栏
  2774. *
  2775. * @compat WeCom >= 4.0.8
  2776. */ EntryType["chain_single_chat_tools"] = "chain_single_chat_tools";
  2777. /**
  2778. * 上下游群聊会话的工具栏
  2779. *
  2780. * @compat WeCom >= 4.0.8
  2781. */ EntryType["chain_group_chat_tools"] = "chain_group_chat_tools";
  2782. /**
  2783. * 从内部群群看板进入
  2784. *
  2785. * @compat WeCom >= 4.1.36
  2786. */ EntryType["internal_group_chat_board"] = "internal_group_chat_board";
  2787. /**
  2788. * 除以上场景之外进入,例如工作台,聊天会话等
  2789. */ EntryType["normal"] = "normal";
  2790. })(EntryType || (EntryType = {}));
  2791. /**
  2792. * 获取当前页面打开场景。
  2793. *
  2794. * @note
  2795. * 调用该接口可以判断用户是从哪个入口打开页面,从而决定是否可以调用客户联系相关的接口。
  2796. *
  2797. * @compat WeCom >= 3.0.24
  2798. *
  2799. * @example
  2800. * ```ts
  2801. * ww.getContext()
  2802. * ```
  2803. */ function getContext(params = {}) {
  2804. return passthrough('getContext', params);
  2805. }
  2806. /**
  2807. * 页面在聊天工具栏中打开时,获取当前上下游互联群的群 ID.
  2808. *
  2809. * @compat WeCom >= 4.0.12
  2810. *
  2811. * @limit
  2812. * - 仅支持上下游聊天工具栏中进入的页面调用,即 getContext 返回 `entry` 为 `chain_single_chat_tools` 或 `chain_group_chat_tools` 的场景
  2813. * - 本接口必须使用应用身份进行注册
  2814. * - 当前成员必须在应用的可见范围
  2815. *
  2816. * @example
  2817. * ```
  2818. * ww.getCurCorpGroupChat()
  2819. * ```
  2820. * @throws
  2821. * | errMsg | 说明 |
  2822. * | --- | --- |
  2823. * | getCurCorpGroupChat:ok| 执行成功 |
  2824. * | getCurCorpGroupChat:no permission | 应用身份鉴权失败 |
  2825. * | getCurCorpGroupChat:without context of corpgroup contact | 当前页面入口不支持调用 |
  2826. */ function getCurCorpGroupChat(params = {}) {
  2827. return passthrough('getCurCorpGroupChat', params);
  2828. }
  2829. /**
  2830. * 页面在上下游聊天工具栏中打开时,获取当前上下游联系人用户 ID。
  2831. *
  2832. * @compat WeCom >= 4.0.8
  2833. *
  2834. * @limit
  2835. * - 仅支持上下游聊天工具栏中进入的页面调用,即 getContext 返回 `entry` 为 `chain_single_chat_tools` 或 `chain_group_chat_tools` 的场景
  2836. * - 本接口必须使用应用身份进行注册
  2837. * - 当前成员必须在应用的可见范围
  2838. *
  2839. * @example
  2840. * ```
  2841. * ww.getCurCorpGroupContact()
  2842. * ```
  2843. * @throws
  2844. * | errMsg | 说明 |
  2845. * | --- | --- |
  2846. * | getCurCorpGroupContact:ok| 执行成功 |
  2847. * | getCurCorpGroupContact:no permission | 应用身份鉴权失败 |
  2848. * | getCurCorpGroupContact:without context of corpgroup contact | 当前页面入口不支持调用 |
  2849. */ function getCurCorpGroupContact(params) {
  2850. return passthrough('getCurCorpGroupContact', params);
  2851. }
  2852. /**
  2853. * 获取当前客户群的群 ID。
  2854. *
  2855. * @limit
  2856. * - 本接口必须使用应用身份进行注册
  2857. * - 从客户群或班级群的聊天工具栏进入页面时才可成功调用该接口
  2858. * - 不同的入口对应用及用户有相应的限制
  2859. * | 入口 | getContext 接口返回的 entry 值 | 自建应用 | 第三方应用 | 用户 | 兼容性 |
  2860. * | --- | --- | --- | --- | --- | --- |
  2861. * | 外部群聊工具栏 | group_chat_tools | 需有[客户联系功能权限](#13473/配置可使用客户联系接口的应用) | 需有“企业客户权限->客户基础信息”权限 | 配置了[客户联系功能](#13473/配置可使用客户联系功能的成员) | 企业微信 2.8.17 |
  2862. * | 班级群的聊天工具栏 | group_chat_tools | 所有 | 需有「家校沟通」使用权限 | 所有 | 企业微信 3.0.36 |
  2863. * | 学生群的聊天工具栏 | group_chat_tools | 所有 | 需有「家校沟通」使用权限 | 所有 | 企业微信 4.0.8 |
  2864. *
  2865. * @compat WeCom >= 2.8.17
  2866. *
  2867. * @example
  2868. * ```ts
  2869. * ww.getCurExternalChat()
  2870. * ```
  2871. *
  2872. * @throws
  2873. * | errMsg | 说明 |
  2874. * | --- | --- |
  2875. * | getCurExternalChat:ok | 执行成功 |
  2876. * | getCurExternalChat:fail no permission | 应用签名校验失败,或签名所使用的应用不满足权限要求 |
  2877. * | getCurExternalChat:fail without context of external contact | 当前页面入口不支持调用 |
  2878. */ function getCurExternalChat(params = {}) {
  2879. return passthrough('getCurExternalChat', params);
  2880. }
  2881. /**
  2882. * 获取当前外部联系人 userId。
  2883. *
  2884. * @limit
  2885. * - 本接口必须使用应用身份进行注册
  2886. * - 不同的入口对应用及用户有相应的限制,目前支持的入口有联系人详情页、外部单聊工具栏
  2887. * | getContext 接口返回的 entry 值 | 自建应用 | 第三方应用 | 用户 | 支持的最低版本 |
  2888. * | --- | --- | --- | --- | --- |
  2889. * | contact_profile | [客户联系功能权限](#13473/配置可使用客户联系接口的应用) | 需有“企业客户权限->客户基础信息”权限 | 配置了|[客户联系功能](#13473/配置可使用客户联系功能的成员) | 企业微信 2.5.8 |
  2890. * | single_chat_tools | [客户联系功能权限](#13473/配置可使用客户联系接口的应用) | 需有“企业客户权限->客户基础信息”权限 | 配置了|[客户联系功能](#13473/配置可使用客户联系功能的成员) | 企业微信 2.8.10 |
  2891. * | single_kf_tools | 所有 | 需有“微信客服权限->获取基础信息”权限 | 所有 | 企业微信 3.1.10 |
  2892. *
  2893. * @compat WeCom >= 2.5.8
  2894. *
  2895. * @example
  2896. * ```ts
  2897. * ww.getCurExternalContact()
  2898. * ```
  2899. *
  2900. * @throws
  2901. * | errMsg | 说明 |
  2902. * | --- | --- |
  2903. * | getCurExternalContact:ok | 执行成功 |
  2904. * | getCurExternalContact:fail no permission | 应用签名校验失败或应用不满足权限条件 |
  2905. * | getCurExternalContact:fail without context of external contact | 当前页面入口不支持调用 |
  2906. */ function getCurExternalContact(params = {}) {
  2907. return passthrough('getCurExternalContact', params);
  2908. }
  2909. /**
  2910. * 获取私密消息信息。
  2911. *
  2912. * @compat WeCom >= 3.1.8
  2913. *
  2914. * @limit
  2915. * 本接口必须使用应用身份进行注册
  2916. *
  2917. * @example
  2918. * ```ts
  2919. * ww.getShareInfo({
  2920. * shareTicket: 'xxx'
  2921. * })
  2922. * ```
  2923. */ function getShareInfo(params) {
  2924. return passthrough('getShareInfo', params);
  2925. }
  2926. /**
  2927. * 页面在聊天附件栏中打开时,隐藏聊天附件栏的发送按钮。开发者可以通过[分享消息到当前会话](#sendChatMessage)接口灵活适配对页面或页面中具体内容的转发。
  2928. *
  2929. * @limit
  2930. * - 仅支持聊天附件栏进入的页面调用,即 getContext 返回 `entry` 为 `chat_attachment` 的场景
  2931. * - 本接口必须使用应用身份进行注册
  2932. *
  2933. * @compat WeCom >= 3.1.6
  2934. *
  2935. * @example
  2936. * ```
  2937. * ww.hideChatAttachmentMenu({
  2938. * menuList: ["sendMessage"]
  2939. * })
  2940. * ```
  2941. *
  2942. * @throws
  2943. * | errMsg | 说明 |
  2944. * | --- | --- |
  2945. * | hideChatAttachmentMenu:ok | 执行成功 |
  2946. * | hideChatAttachmentMenu:invalid menuList | menuList不合法 |
  2947. * | hideChatAttachmentMenu:without context of chat_attachment | 未在聊天附件栏打开场景下调用 |
  2948. */ function hideChatAttachmentMenu(params) {
  2949. return passthrough('hideChatAttachmentMenu', params);
  2950. }
  2951. /**
  2952. * 跳转到小程序。
  2953. *
  2954. * @note
  2955. * 打开小程序时如果需要关闭页面,需同步调用 closeWindow,不推荐用 setTimeout 延迟关闭。
  2956. *
  2957. * @limit
  2958. * - 本接口必须使用应用身份进行注册
  2959. * - 跳转的小程序必须属于页面所属的企业
  2960. * - 跳转的小程序必须已关联到工作台
  2961. * - 应用必须与要跳转的小程序应用同属于一个企业
  2962. * - 跳转的小程序必须已经关联到工作台
  2963. *
  2964. * @compat WeCom >= 3.0.36
  2965. *
  2966. * @example
  2967. * ```ts
  2968. * ww.launchMiniprogram({
  2969. * appid: 'wx062f7a5507909000',
  2970. * path: 'pages/home/index'
  2971. * })
  2972. * ```
  2973. */ function launchMiniprogram(params) {
  2974. return passthrough('launchMiniprogram', params, {
  2975. appid: params.appid,
  2976. path: addHTMLToPath(params.path),
  2977. envVersion: params.envVersion
  2978. });
  2979. }
  2980. function addHTMLToPath(url) {
  2981. if (!url || !isString(url)) {
  2982. return;
  2983. }
  2984. const [path, ...query] = url.split('?');
  2985. if (!query.length) {
  2986. return `${path}.html`;
  2987. }
  2988. return `${path}.html?${query.join('?')}`;
  2989. }
  2990. /**
  2991. * 在企业微信内快速跳转到添加客户的界面。
  2992. *
  2993. * @limit
  2994. * - 本接口必须使用应用身份进行注册
  2995. * - 应用需有[客户联系功能权限](#13473/配置可使用客户联系接口的应用)
  2996. * - 当前成员必须配置了客户联系功能
  2997. *
  2998. * @compat WeCom iOS, Android >= 3.0.36
  2999. *
  3000. * @example
  3001. * ```ts
  3002. * ww.navigateToAddCustomer()
  3003. * ```
  3004. */ function navigateToAddCustomer(params = {}) {
  3005. return passthrough('navigateToAddCustomer', params);
  3006. }
  3007. /**
  3008. * 进入微信客服消息界面。
  3009. *
  3010. * @limit
  3011. * - 本接口必须使用应用身份进行注册
  3012. * - 应用必须具有“微信客服->获取基础信息”权限
  3013. * - 当前企业须已开启「微信客服」应用
  3014. * - 当前成员须是指定客服账号的坐席
  3015. *
  3016. * @compat WeCom iOS, Android, PC >= 3.1.12
  3017. *
  3018. * @example
  3019. * ```ts
  3020. * ww.navigateToKfChat({
  3021. * openKfId: 'wkAJ2GCAAAZSfhHCt7IFSvLKtMPxyAAA',
  3022. * externalUserId: 'wmAJ2GCAAAZSfhHCt7IFSvLKtMPxyBBB'
  3023. * })
  3024. * ```
  3025. */ function navigateToKfChat(params) {
  3026. return passthrough('navigateToKfChat', params);
  3027. }
  3028. /**
  3029. * 共享收货地址。
  3030. *
  3031. * @see https://developers.weixin.qq.com/doc/offiaccount/OA_Web_Apps/JS-SDK.html#共享收货地址接口
  3032. */ function openAddress(params = {}) {
  3033. return promiseToCallback(params, async ()=>{
  3034. await tryEnsureConfigReady();
  3035. const res = await invoke('editAddress');
  3036. res.postalCode = res.addressPostalCode;
  3037. delete res.addressPostalCode;
  3038. res.provinceName = res.proviceFirstStageName;
  3039. delete res.proviceFirstStageName;
  3040. res.cityName = res.addressCitySecondStageName;
  3041. delete res.addressCitySecondStageName;
  3042. res.countryName = res.addressCountiesThirdStageName;
  3043. delete res.addressCountiesThirdStageName;
  3044. res.detailInfo = res.addressDetailInfo;
  3045. delete res.addressDetailInfo;
  3046. return res;
  3047. });
  3048. }
  3049. /**
  3050. * 打开应用评价页面。
  3051. *
  3052. * 第三方应用可以使用该接口提供按钮,让用户快速打开应用评价页面。
  3053. *
  3054. * @compat WeCom iOS, Android, PC >= 4.0.2
  3055. *
  3056. * @limit
  3057. * - 本接口必须使用应用身份进行注册,
  3058. * - 仅第三方应用可调用
  3059. * - 对成员授权的应用,当前用户在应用可见范围内,可以进行应用评价
  3060. * - 管理员授权的应用,当前用户在可见范围内,或者当前用户为超管或有应用管理权限的分管,可以进行应用评价
  3061. *
  3062. * @example
  3063. * ```
  3064. * ww.openAppComment()
  3065. * ```
  3066. *
  3067. * @throws
  3068. * | errMsg | 说明 |
  3069. * | --- | --- |
  3070. * | openAppComment:ok| 执行成功 |
  3071. * | openAppComment:fail:no permission | 调用人身份不符合 |
  3072. * | openAppComment:fail:unknown app | 应用信息获取失败 |
  3073. * | openAppComment:fail:unsupported app type | 应用类型不符合要求 |
  3074. * | openAppComment:fail | 其它错误 |
  3075. */ function openAppComment(params = {}) {
  3076. return passthrough('openAppComment', params);
  3077. }
  3078. /**
  3079. * 获取设备数据授权。
  3080. *
  3081. * 唤起设备选择列表,企业管理员选择设备后,应用可以通过云端接口获取到设备上报的数据。
  3082. *
  3083. * @limit
  3084. * - 本接口必须使用应用身份进行注册
  3085. * - 应用必须具有智慧硬件接口权限
  3086. * - 仅第三方应用使用
  3087. *
  3088. * @compat WeCom >= 4.0.12
  3089. *
  3090. * @example
  3091. * ```ts
  3092. * ww.openAppDeviceDataAuth()
  3093. * ```
  3094. */ function openAppDeviceDataAuth(params = {}) {
  3095. return passthrough('openAppDeviceDataAuth', params);
  3096. }
  3097. var OpenAppManagePageType;
  3098. (function(OpenAppManagePageType) {
  3099. /**
  3100. * 应用权限详情页
  3101. */ OpenAppManagePageType["permission"] = "permission";
  3102. /**
  3103. * 数据与智能专区权限授权页
  3104. *
  3105. * 需要满足:
  3106. *
  3107. * - 企业访问者身份为超级管理员
  3108. * - 应用需要满足勾选了“数据与智能专区权限”(注:该权限目前灰度开放)
  3109. * - 应用类型为第三方应用/代开发应用(注:不支持上下游共享应用)
  3110. */ OpenAppManagePageType["datazone_permission"] = "datazone_permission";
  3111. })(OpenAppManagePageType || (OpenAppManagePageType = {}));
  3112. /**
  3113. * 打开应用管理页面。
  3114. *
  3115. * 应用可以使用该接口提供按钮,让企业管理员快速打开应用的管理页面。
  3116. *
  3117. * @limit
  3118. * - 本接口必须使用应用身份进行注册
  3119. * - 当前用户需要是企业超级管理员,或具有应用管理权限
  3120. *
  3121. * @compat WeCom >= 4.0.2
  3122. *
  3123. * @example
  3124. * ```
  3125. * ww.openAppManage({
  3126. * page: "permission",
  3127. * suiteId: "wwabcdefghijk",
  3128. * })
  3129. * ```
  3130. */ function openAppManage(params = {}) {
  3131. return passthrough('openAppManage', params);
  3132. }
  3133. /**
  3134. * 进入应用购买页面。
  3135. *
  3136. * 第三方应用可以使用该接口提供按钮,让用户可快速进入应用购买流程。
  3137. *
  3138. * @limit
  3139. * - 本接口必须使用应用身份进行注册
  3140. * - 当前用户应在应用的可见范围内
  3141. * - 仅第三方应用可调用
  3142. *
  3143. * @compat WeCom >= 4.1.6
  3144. *
  3145. * @example
  3146. * ```
  3147. * ww.openAppPurchase()
  3148. * ```
  3149. *
  3150. * @throws
  3151. * | errMsg | 说明 |
  3152. * | --- | --- |
  3153. * | openAppPurchase:ok | 执行成功 |
  3154. * | openAppPurchase:fail:no permission | 应用签名校验失败,或成员不在应用的可见范围内 |
  3155. * | openAppPurchase:fail | 其它错误 |
  3156. */ function openAppPurchase(params) {
  3157. return passthrough('openAppPurchase', params);
  3158. }
  3159. var EnvVersion;
  3160. (function(EnvVersion) {
  3161. EnvVersion["release"] = "release";
  3162. EnvVersion["trial"] = "trial";
  3163. EnvVersion["develop"] = "develop";
  3164. })(EnvVersion || (EnvVersion = {}));
  3165. /**
  3166. * 商户小程序跳转微信支付分小程序。
  3167. *
  3168. * @see https://pay.weixin.qq.com/wiki/doc/apiv3/payscore.php?chapter=29_3&index=3
  3169. */ function openBusinessView(params) {
  3170. return promiseToCallback(params, async ()=>{
  3171. await tryEnsureConfigReady();
  3172. const res = await invoke('openBusinessView', {
  3173. businessType: params.businessType,
  3174. queryString: params.queryString || '',
  3175. envVersion: params.envVersion
  3176. });
  3177. if (!isAndroid || !res.extraData) {
  3178. return res;
  3179. }
  3180. try {
  3181. res.extraData = JSON.parse(res.extraData);
  3182. } catch (error) {
  3183. res.extraData = {};
  3184. }
  3185. return res;
  3186. });
  3187. }
  3188. /**
  3189. * 查看设备。
  3190. *
  3191. * @limit
  3192. * 调用者必须拥有指定 deviceSn 的管理权限。
  3193. *
  3194. * @note
  3195. * 若开发者需要在 web 端引导跳转设备管理,可以构造链接跳转:`https://work.weixin.qq.com/wework_admin/frame#hardware/device?sn={{DEVICESN}}`。
  3196. *
  3197. * @compat WeCom iOS, Android >= 2.8.2
  3198. *
  3199. * @example
  3200. * ```ts
  3201. * ww.openDeviceProfile({
  3202. * deviceSn: 'QYWX001'
  3203. * })
  3204. * ```
  3205. *
  3206. * @throws
  3207. * | errMsg | 说明 |
  3208. * | --- | --- |
  3209. * | openDeviceProfile:ok | 执行成功 |
  3210. * | openDeviceProfile:fail_device_permission_denied | 管理员无设备管理权限 |
  3211. * | openDeviceProfile:fail_device_not_found | 不存在此设备 |
  3212. */ function openDeviceProfile(params) {
  3213. return passthrough('openDeviceProfile', params);
  3214. }
  3215. /**
  3216. * 打开会话。
  3217. *
  3218. * @limit
  3219. * - 内部群最多 2000 人,外部群最多 500 人
  3220. * - 若创建的会话包含微信联系人,群成员人数不能超过 40 人
  3221. * - 第三方应用与代开发应用必须使用应用身份进行注册
  3222. *
  3223. * @compat WeCom >= 2.0.0
  3224. *
  3225. * @example
  3226. * ```ts
  3227. * ww.openEnterpriseChat({
  3228. * groupName: '讨论组',
  3229. * userIds: [
  3230. * 'zhangsan',
  3231. * 'lisi'
  3232. * ],
  3233. * externalUserIds: [
  3234. * 'wmEAlECwAAHrbWYDOK5u3Bf13xlYDAAA',
  3235. * 'wmEAlECwAAHibWYDOK5u3Af13xlYDAAA'
  3236. * ]
  3237. * })
  3238. * ```
  3239. */ function openEnterpriseChat(params = {}) {
  3240. return passthrough('openEnterpriseChat', params, {
  3241. chatId: params.chatId || '',
  3242. chatname: params.groupName || '',
  3243. groupName: params.groupName || '',
  3244. useridlist: joinList(params.userIds),
  3245. userIds: joinList(params.userIds),
  3246. openIds: joinList(params.openIds),
  3247. externalUserIds: joinList(params.externalUserIds)
  3248. });
  3249. }
  3250. /**
  3251. * 打开已有群聊并可选发送一条链接消息(link消息)。支持打开企业内部群、外部群、互联群。
  3252. *
  3253. * @compat WeCom >= 3.1.8
  3254. *
  3255. * @limit
  3256. * 本接口必须使用应用身份进行注册
  3257. *
  3258. * @example
  3259. * ```ts
  3260. * ww.openExistedChatWithMsg({
  3261. * chatId: 'chatId123',
  3262. * msg: {
  3263. * msgtype: 'link',
  3264. * link: {
  3265. * title: 'title1',
  3266. * desc: 'desc1',
  3267. * url: 'link1',
  3268. * imgUrl: 'imgurl1'
  3269. * }
  3270. * }
  3271. * })
  3272. * ```
  3273. *
  3274. * @throws
  3275. * | errMsg | 说明 |
  3276. * | --- | --- |
  3277. * | openExistedChatWithMsg:ok | 执行成功 |
  3278. * | openExistedChatWithMsg:fail_unsupported_msgtype | msgtype不合法 |
  3279. * | openExistedChatWithMsg:fail_msg_link_missing_url | msg.link.url未传入 |
  3280. */ function openExistedChatWithMsg(params) {
  3281. return passthrough('openExistedChatWithMsg', params);
  3282. }
  3283. /**
  3284. * 进入应用客服会话。
  3285. *
  3286. * 第三方应用可以使用该接口提供按钮,让用户快速打开应用客服的会话。。
  3287. *
  3288. * @compat WeCom iOS, Android >= 3.1.18; WeCom PC, Mac >= 4.1.6
  3289. *
  3290. * @limit
  3291. * - 本接口必须使用应用身份进行注册
  3292. * - 仅第三方应用可调用
  3293. * - 第三方应用需要提前配置客服
  3294. * - 当前用户需要有添加外部联系人权限
  3295. *
  3296. * @example
  3297. * ```
  3298. * ww.openThirdAppServiceChat()
  3299. * ```
  3300. */ function openThirdAppServiceChat(params = {}) {
  3301. return passthrough('openThirdAppServiceChat', params);
  3302. }
  3303. var OpenUserProfileType;
  3304. (function(OpenUserProfileType) {
  3305. /**
  3306. * 企业成员
  3307. */ OpenUserProfileType[OpenUserProfileType["internal"] = 1] = "internal";
  3308. /**
  3309. * 外部联系人
  3310. */ OpenUserProfileType[OpenUserProfileType["external"] = 2] = "external";
  3311. })(OpenUserProfileType || (OpenUserProfileType = {}));
  3312. /**
  3313. * 唤起成员或外部联系人的个人信息页面。
  3314. *
  3315. * @compat WeCom >= 2.4.20
  3316. *
  3317. * @limit
  3318. * - 第三方应用调用时,需使用应用身份进行注册
  3319. *
  3320. * @example
  3321. * ```ts
  3322. * ww.openUserProfile({
  3323. * type: 1,
  3324. * userid: 'wmEAlECwAAHrbWYDetiu3Af13xlYDAAA'
  3325. * })
  3326. * ```
  3327. */ function openUserProfile(params) {
  3328. return passthrough('openUserProfile', params);
  3329. }
  3330. var PrintFileIdType;
  3331. (function(PrintFileIdType) {
  3332. /**
  3333. * mediaid
  3334. */ PrintFileIdType[PrintFileIdType["mediaid"] = 1] = "mediaid";
  3335. /**
  3336. * url
  3337. */ PrintFileIdType[PrintFileIdType["url"] = 2] = "url";
  3338. /**
  3339. * localId
  3340. *
  3341. * 可通过以下方式获得:
  3342. * 1. [从会话选择文件](#34301)
  3343. * 2. [拍照或从手机相册中选图接口](#14915)
  3344. */ PrintFileIdType[PrintFileIdType["localId"] = 4] = "localId";
  3345. })(PrintFileIdType || (PrintFileIdType = {}));
  3346. /**
  3347. * 发起文件打印。
  3348. *
  3349. * @limit
  3350. * - 本接口必须使用应用身份进行注册
  3351. * - 应用必须具有“设备信息-打印扫描设备-发起文件打印权限”授权
  3352. * - 当前触发调用人员身份需要在应用的可见范围内
  3353. * - 当前企业有安装企业微信打印设备
  3354. * - 仅第三方应用使用
  3355. *
  3356. * @compat WeCom >= 4.0.12
  3357. *
  3358. * @example
  3359. * ```ts
  3360. * ww.printFile({
  3361. * fileId: 'fileId',
  3362. * fileIdType: 1,
  3363. * fileName: 'fileName.jpg'
  3364. * })
  3365. * ```
  3366. */ function printFile(params) {
  3367. return passthrough('printFile', params);
  3368. }
  3369. var InTalkType;
  3370. (function(InTalkType) {
  3371. /**
  3372. * 当前不在任何通话中
  3373. */ InTalkType["None"] = "None";
  3374. /**
  3375. * 视频会议中
  3376. */ InTalkType["HWOpenTalk"] = "HWOpenTalk";
  3377. /**
  3378. * voip通话中
  3379. */ InTalkType["VoIP"] = "VoIP";
  3380. /**
  3381. * 系统通话中
  3382. */ InTalkType["SystemCall"] = "SystemCall";
  3383. })(InTalkType || (InTalkType = {}));
  3384. /**
  3385. * 查询当前是否在视频会议。
  3386. *
  3387. * @compat WeCom >= 2.5.0
  3388. *
  3389. * @example
  3390. * ```ts
  3391. * ww.queryCurrHWOpenTalk()
  3392. * ```
  3393. */ function queryCurrHWOpenTalk(params = {}) {
  3394. return passthrough('queryCurrHWOpenTalk', params);
  3395. }
  3396. /**
  3397. * 发起退款。
  3398. *
  3399. * @limit
  3400. * - 本接口必须使用应用身份进行注册
  3401. * - 应用必须具有对外收款权限
  3402. * - 发起的用户必须在应用可见范围并实名
  3403. * - 只允许退款由应用本身发起的收款
  3404. *
  3405. * @compat WeCom >= 4.0.12
  3406. *
  3407. * @example
  3408. * ```ts
  3409. * ww.refundExternalPayment({
  3410. * paymentId: 'xxxx',
  3411. * outTradeNo: 'yyyy',
  3412. * refundFee: 100,
  3413. * refundComment: '7天无理由退货'
  3414. * })
  3415. * ```
  3416. */ function refundExternalPayment(params) {
  3417. return passthrough('refundExternalPayment', params);
  3418. }
  3419. /**
  3420. * 保存用户选择的审批选项。
  3421. *
  3422. * 用户在网页中修改审批选项时,调用该接口保存用户的选择。
  3423. *
  3424. * @note
  3425. * - 接口仅用于审批设置外部选项场景,请勿用作其他场景
  3426. * - 网页应该做好深色模式适配
  3427. *
  3428. * @limit
  3429. * - 本接口必须使用应用身份进行注册
  3430. * - 应用必须具有审批权限
  3431. *
  3432. * @compat WeCom >= 4.0.18
  3433. *
  3434. * @example
  3435. * ```ts
  3436. * ww.saveApprovalSelectedItems({
  3437. * key: 'key',
  3438. * selectedData: [
  3439. * {
  3440. * key: 'item-1',
  3441. * value: '选项1'
  3442. * },
  3443. * {
  3444. * key: 'item-2',
  3445. * value: '选项2'
  3446. * }
  3447. * ]
  3448. * })
  3449. * ```
  3450. */ function saveApprovalSelectedItems(params) {
  3451. return passthrough('saveApprovalSelectedItems', params, {
  3452. key: params.key,
  3453. selectedData: typeof params.selectedData === 'string' ? params.selectedData : JSON.stringify(params.selectedData)
  3454. });
  3455. }
  3456. var ScanQRCodeType;
  3457. (function(ScanQRCodeType) {
  3458. /**
  3459. * 扫描二维码
  3460. */ ScanQRCodeType["qrCode"] = "qrCode";
  3461. /**
  3462. * 扫描条形码
  3463. */ ScanQRCodeType["barCode"] = "barCode";
  3464. })(ScanQRCodeType || (ScanQRCodeType = {}));
  3465. /**
  3466. * 调起企业微信扫一扫。
  3467. *
  3468. * @example
  3469. * ```ts
  3470. * ww.scanQRCode({
  3471. * needResult: true,
  3472. * scanType: ['qrCode']
  3473. * })
  3474. * ```
  3475. */ function scanQRCode(params = {}) {
  3476. return promiseToCallback(params, async ()=>{
  3477. await tryEnsureConfigReady();
  3478. const res = await invoke('scanQRCode', {
  3479. needResult: params.needResult ? 1 : 0,
  3480. scanType: params.scanType || [
  3481. 'qrCode',
  3482. 'barCode'
  3483. ]
  3484. });
  3485. if (!isIOS) {
  3486. return res;
  3487. }
  3488. const resultStr = res.resultStr;
  3489. if (!resultStr) {
  3490. return res;
  3491. }
  3492. let data;
  3493. try {
  3494. data = JSON.parse(resultStr);
  3495. } catch (error) {
  3496. // noop
  3497. }
  3498. res.resultStr = data?.scan_code?.scan_result;
  3499. return res;
  3500. });
  3501. }
  3502. var InputCorpGroupContactMode;
  3503. (function(InputCorpGroupContactMode) {
  3504. /**
  3505. * 单选
  3506. */ InputCorpGroupContactMode["single"] = "single";
  3507. /**
  3508. * 多选
  3509. */ InputCorpGroupContactMode["multi"] = "multi";
  3510. })(InputCorpGroupContactMode || (InputCorpGroupContactMode = {}));
  3511. var InputCorpGroupContactType;
  3512. (function(InputCorpGroupContactType) {
  3513. /**
  3514. * 选择部门
  3515. */ InputCorpGroupContactType["department"] = "department";
  3516. /**
  3517. * 选择成员
  3518. */ InputCorpGroupContactType["user"] = "user";
  3519. })(InputCorpGroupContactType || (InputCorpGroupContactType = {}));
  3520. /**
  3521. * 企业互联/上下游选人
  3522. *
  3523. * @limit
  3524. * - 本接口必须使用应用身份进行注册
  3525. * - 该接口仅可选择应用可见范围内的成员和部门
  3526. *
  3527. * @compat WeCom iOS, Android, PC >= 3.1.6
  3528. *
  3529. * @note
  3530. * 自建应用调用该接口时userid返回的是企业内部的userid,对于服务商该字段返回的是open_userid,同一个服务商,不同应用获取到企业内同一个成员的open_userid是相同的,最多64个字节
  3531. *
  3532. * @example
  3533. * ```ts
  3534. * ww.selectCorpGroupContact({
  3535. * fromDepartmentId: -1,
  3536. * mode: 'single',
  3537. * type: ['department', 'user'],
  3538. * selectedDepartmentIds: ['2','3'],
  3539. * selectedUserIds: ['lisi','lisi2'],
  3540. * selectedOpenUserIds: ['wabc3','wbcde'],
  3541. * selectedChainDepartmentIds: [
  3542. * {
  3543. * corpId: 'ww3333',
  3544. * departmentId: '2'
  3545. * },
  3546. * {
  3547. * corpId: 'ww4444',
  3548. * departmentId: '3'
  3549. * }
  3550. * ],
  3551. * selectedChainUserIds: [
  3552. * {
  3553. * corpId: 'ww3333',
  3554. * userId: 'userid123',
  3555. * openUserId: 'wx1111'
  3556. * },
  3557. * {
  3558. * corpId: 'ww4444',
  3559. * userId: 'userid123',
  3560. * openUserId: 'wx1111'
  3561. * }
  3562. * ],
  3563. * selectedCorpGroupDepartmentIds: [
  3564. * {
  3565. * corpId: 'ww3333',
  3566. * departmentId: '2'
  3567. * },
  3568. * {
  3569. * corpId: 'ww4444',
  3570. * departmentId: '3'
  3571. * }
  3572. * ],
  3573. * selectedCorpGroupUserIds: [
  3574. * {
  3575. * corpId: 'ww3333',
  3576. * userId: 'userid123',
  3577. * openUserId: 'wx1111'
  3578. * },
  3579. * {
  3580. * corpId: 'ww4444',
  3581. * userId: 'userid123',
  3582. * openUserId: 'wx1111'
  3583. * }
  3584. * ]
  3585. * })
  3586. * ```
  3587. * @throws
  3588. * | errMsg | 说明 |
  3589. * | --- | --- |
  3590. * | selectCorpGroupContact:ok | 执行成功 |
  3591. * | selectCorpGroupContact:fail no permission | 应用身份鉴权失败 |
  3592. *
  3593. */ function selectCorpGroupContact(params) {
  3594. return promiseToCallback(params, async ()=>{
  3595. await tryEnsureConfigReady();
  3596. const res = await invoke('selectCorpGroupContact', params);
  3597. if (!isString(res.result)) {
  3598. return res;
  3599. }
  3600. try {
  3601. res.result = JSON.parse(res.result);
  3602. } catch (error) {
  3603. // noop
  3604. }
  3605. return res;
  3606. });
  3607. }
  3608. var SelectEnterpriseContactMode;
  3609. (function(SelectEnterpriseContactMode) {
  3610. /**
  3611. * 单选
  3612. */ SelectEnterpriseContactMode["single"] = "single";
  3613. /**
  3614. * 多选
  3615. */ SelectEnterpriseContactMode["multi"] = "multi";
  3616. })(SelectEnterpriseContactMode || (SelectEnterpriseContactMode = {}));
  3617. var SelectEnterpriseContactType;
  3618. (function(SelectEnterpriseContactType) {
  3619. /**
  3620. * 选择部门
  3621. */ SelectEnterpriseContactType["department"] = "department";
  3622. /**
  3623. * 选择成员
  3624. */ SelectEnterpriseContactType["user"] = "user";
  3625. })(SelectEnterpriseContactType || (SelectEnterpriseContactType = {}));
  3626. /**
  3627. * 选择通讯录成员。
  3628. *
  3629. * @compat WeCom >= 1.3.11; WeChat iOS, Android >= 6.5.10
  3630. *
  3631. * @example
  3632. * ```ts
  3633. * ww.selectEnterpriseContact({
  3634. * fromDepartmentId: -1,
  3635. * mode: 'multi',
  3636. * type: ['department', 'user'],
  3637. * selectedDepartmentIds: ['2', '3'],
  3638. * selectedUserIds: ['lisi', 'lisi2']
  3639. * })
  3640. * ```
  3641. */ function selectEnterpriseContact(params) {
  3642. return promiseToCallback(params, async ()=>{
  3643. await tryEnsureConfigReady();
  3644. const res = await invoke('selectEnterpriseContact', params);
  3645. if (!isString(res.result)) {
  3646. return res;
  3647. }
  3648. try {
  3649. res.result = JSON.parse(res.result);
  3650. } catch (error) {
  3651. // noop
  3652. }
  3653. return res;
  3654. });
  3655. }
  3656. var SelectExternalContactType;
  3657. (function(SelectExternalContactType) {
  3658. /**
  3659. * 展示全部外部联系人列表
  3660. */ SelectExternalContactType[SelectExternalContactType["all"] = 0] = "all";
  3661. /**
  3662. * 仅展示未曾选择过的外部联系人
  3663. */ SelectExternalContactType[SelectExternalContactType["unselected"] = 1] = "unselected";
  3664. })(SelectExternalContactType || (SelectExternalContactType = {}));
  3665. /**
  3666. * 唤起该成员的外部联系人列表,并返回员工选择的外部联系人的 userId。
  3667. *
  3668. * @limit
  3669. * - 本接口必须使用应用身份进行注册
  3670. * - 应用须配置[客户联系功能权限](#13473/配置可使用客户联系接口的应用)
  3671. * - 当前成员必须配置[客户联系功能](#13473/开始开发)
  3672. *
  3673. * @compat WeCom >= 2.4.20
  3674. *
  3675. * @example
  3676. * ```ts
  3677. * ww.selectExternalContact({
  3678. * filterType: 0
  3679. * })
  3680. * ```
  3681. */ function selectExternalContact(params = {}) {
  3682. return passthrough('selectExternalContact', params);
  3683. }
  3684. var SelectPrivilegedContactMode;
  3685. (function(SelectPrivilegedContactMode) {
  3686. /**
  3687. * 单选
  3688. */ SelectPrivilegedContactMode["single"] = "single";
  3689. /**
  3690. * 多选
  3691. */ SelectPrivilegedContactMode["multi"] = "multi";
  3692. })(SelectPrivilegedContactMode || (SelectPrivilegedContactMode = {}));
  3693. /**
  3694. * 返回 ticket 的选人接口。
  3695. *
  3696. * 用于第三方应用唤起选择企业通讯录成员,用户选择的范围区分成两部分回传给第三方应用:
  3697. *
  3698. * 1. 过滤应用可见范围后的 openUserId 列表
  3699. * 2. 完整列表的 ticket,ticket 后续可用于[创建群聊](#30292) 或者[发送模板消息](#94515)
  3700. *
  3701. * @limit
  3702. * - 本接口必须使用应用身份进行注册
  3703. * - 仅第三方应用(非通讯录应用)可调用
  3704. *
  3705. * @compat WeCom >= 3.1.8
  3706. *
  3707. * @example
  3708. * ```ts
  3709. * ww.selectPrivilegedContact({
  3710. * fromDepartmentId: -1,
  3711. * mode: 'multi',
  3712. * selectedContextContact: 1
  3713. * selectedOpenUserIds: ['xxx', 'yyy'],
  3714. * selectedTickets: ['ticket1', 'ticket2']
  3715. * })
  3716. * ```
  3717. */ function selectPrivilegedContact(params) {
  3718. return passthrough('selectPrivilegedContact', params);
  3719. }
  3720. /**
  3721. * 从聊天工具栏或附件栏打开的页面中向当前会话发送消息
  3722. *
  3723. * @note
  3724. * 消息格式支持文本(“text”),图片(“image”),视频(“video”),文件(“file”),H5(“news”),小程序(“miniprogram”),菜单消息(“msgmenu”)和视频号商品(“channels_shop_product”)
  3725. *
  3726. * @limit
  3727. * - 本接口必须使用应用身份进行注册
  3728. * - 仅从特定入口进入页面才可调用,可通过 getContext 接口进行判断
  3729. * - 不同的入口对应用及用户有相应的限制
  3730. * | getContext 接口返回的 entry 值 | 自建应用 | 第三方应用 | 用户 | 支持的最低版本 |
  3731. * | --- | --- | --- | --- | --- |
  3732. * | single_chat_tools | 需有[客户联系功能权限](#13473/配置可使用客户联系接口的应用) | 需有“企业客户权限->客户基础信息”权限 | 配置了|[配置了客户联系功能](#13473/配置可使用客户联系功能的成员) | 企业微信 2.8.10 |
  3733. * | group_chat_tools | 需有[客户联系功能权限](#13473/配置可使用客户联系接口的应用) | 需有“企业客户权限->客户基础信息”权限 | 配置了|[配置了客户联系功能](#13473/配置可使用客户联系功能的成员) | 企业微信 2.8.10 |
  3734. * | group_chat_tools | 所有 | 需有「家校沟通」使用权限 | 所有 | 企业微信 3.0.36 |
  3735. * | group_chat_tools | 所有 | 需有「家校沟通」使用权限 | 所有 | 企业微信 4.0.8 |
  3736. * | chat_attachment | 所有 | 所有 | 所有 | 企业微信 3.1.6(mac 端暂不支持) |
  3737. * | single_kf_tools | 所有 | 需有“微信客服权限->获取基础信息”权限 | 所有 | 企业微信 3.1.10 |
  3738. * - 消息中的 mediaId 可通过[素材管理](#10112)接口获得,暂不支持公众平台的 mediaId
  3739. *
  3740. * @compat WeCom >= 2.8.10
  3741. *
  3742. * @example
  3743. * ```ts
  3744. * ww.sendChatMessage({
  3745. * msgtype: 'text',
  3746. * text: {
  3747. * content: '你好'
  3748. * }
  3749. * })
  3750. * ```
  3751. *
  3752. * @throws
  3753. * | errMsg | 说明 |
  3754. * | --- | --- |
  3755. * | sendChatMessage:ok | 执行成功 |
  3756. * | claimClassAdmin:fail without context of external contact | 当前页面打开的场景不支持调用 |
  3757. * | claimClassAdmin:fail no permission | 应用签名错误,或不满足权限要求 |
  3758. * | claimClassAdmin:fail invalid imgUrl | 小程序消息封面图不合法 |
  3759. */ function sendChatMessage(params) {
  3760. return passthrough('sendChatMessage', params);
  3761. }
  3762. /**
  3763. * 设置私密消息。
  3764. *
  3765. * @compat WeCom >= 3.1.8
  3766. *
  3767. * @limit
  3768. * 本接口必须使用应用身份进行注册
  3769. *
  3770. * @example
  3771. * ```ts
  3772. * ww.setShareAttr({
  3773. * withShareTicket: true,
  3774. * state: 'STATE'
  3775. * })
  3776. * ```
  3777. */ function setShareAttr(params = {}) {
  3778. return passthrough('setShareAttr', params);
  3779. }
  3780. /**
  3781. * 具有客户联系权限的企业成员,可通过该接口将文本内容和附件传递到客户群群发、发送到客户群。
  3782. *
  3783. * @limit
  3784. * - 本接口必须使用应用身份进行注册
  3785. * - 应用需有[客户联系功能权限](#13473/配置可使用客户联系接口的应用)
  3786. * - 当前成员必须配置了[客户联系功能](#13473/配置可使用客户联系功能的成员)
  3787. *
  3788. * @note
  3789. * - 为防止滥用,同一个成员每日向一个客户最多可群发一条消息,每次群发最多可选 2000 个最近活跃的客户群
  3790. *
  3791. * @compat WeCom >= 2.8.7
  3792. *
  3793. * @example
  3794. * ```ts
  3795. * // WeCom >= 3.1.6
  3796. * ww.shareToExternalChat({
  3797. * chatIds: ["wr2GCAAAXAAAaWJHDDGasdadAAA","wr2GCAAAXBBBaWJHDDGasdadBBB"],
  3798. * text: {
  3799. * content: '企业微信'
  3800. * },
  3801. * attachments: [
  3802. * {
  3803. * msgtype: 'image',
  3804. * image: {
  3805. * imgUrl: 'https://res.mail.qq.com/node/ww/wwmng/style/images/index_share_logo$13c64306.png'
  3806. * }
  3807. * }
  3808. * ]
  3809. * })
  3810. * // 或者
  3811. * ww.shareToExternalChat({
  3812. * title: '', // 消息的标题
  3813. * desc: '', // 消息的描述
  3814. * link: '', // 消息链接
  3815. * imgUrl: '' // 消息封面
  3816. * })
  3817. * ```
  3818. */ function shareToExternalChat(params) {
  3819. return passthrough('shareToExternalChat', params);
  3820. }
  3821. /**
  3822. * 具有客户联系权限的企业成员,可通过该接口将文本内容和附件传递到群发助手、发送给客户。
  3823. *
  3824. * @limit
  3825. * - 本接口必须使用应用身份进行注册
  3826. * - 应用需有[客户联系功能权限](#13473/配置可使用客户联系接口的应用)
  3827. * - 当前成员必须配置了[客户联系功能](#13473/配置可使用客户联系功能的成员)
  3828. *
  3829. * @note
  3830. * - 为防止滥用,同一个成员每日向一个客户最多可群发一条消息,每次群发最多可选 20000 个客户
  3831. *
  3832. *
  3833. * @compat WeCom >= 2.8.7
  3834. *
  3835. * @example
  3836. * ```ts
  3837. * // WeCom >= 3.1.6
  3838. * ww.shareToExternalContact({
  3839. * externalUserIds: ["wr2GCAAAXAAAaWJHDDGasdadAAA","wr2GCAAAXBBBaWJHDDGasdadBBB"],
  3840. * text: {
  3841. * content: '企业微信'
  3842. * },
  3843. * attachments: [
  3844. * {
  3845. * msgtype: 'image',
  3846. * image: {
  3847. * imgUrl: 'https://res.mail.qq.com/node/ww/wwmng/style/images/index_share_logo$13c64306.png'
  3848. * }
  3849. * }
  3850. * ]
  3851. * })
  3852. *
  3853. * // 或者
  3854. * ww.shareToExternalContact({
  3855. * title: '', // 消息的标题
  3856. * desc: '', // 消息的描述
  3857. * link: '', // 消息链接
  3858. * imgUrl: '' // 消息封面
  3859. * })
  3860. * ```
  3861. */ function shareToExternalContact(params) {
  3862. return passthrough('shareToExternalContact', params);
  3863. }
  3864. /**
  3865. * 发表内容到客户朋友圈。
  3866. *
  3867. * @limit
  3868. * - 本接口必须使用应用身份进行注册
  3869. * - 应用需有[客户联系功能权限](#13473/配置可使用客户联系接口的应用)
  3870. * - 当前成员必须配置了客户联系功能
  3871. * - 当前成员必须在客户朋友圈使用范围
  3872. * - 当前成员必须具备外部沟通管理成员使用权限
  3873. *
  3874. * @compat WeCom iOS, Android >= 3.1.12
  3875. *
  3876. * @example
  3877. * ```ts
  3878. * ww.shareToExternalMoments({
  3879. * text: {
  3880. * content: '企业微信'
  3881. * },
  3882. * attachments: [
  3883. * {
  3884. * msgtype: 'image',
  3885. * image: {
  3886. * imgUrl: 'https://res.mail.qq.com/node/ww/wwmng/style/images/index_share_logo$13c64306.png'
  3887. * }
  3888. * }
  3889. * ]
  3890. * })
  3891. * ```
  3892. */ function shareToExternalMoments(params) {
  3893. return passthrough('shareToExternalMoments', params);
  3894. }
  3895. /**
  3896. * 发起无线投屏。
  3897. *
  3898. * @compat WeCom
  3899. *
  3900. * @limit
  3901. * 仅支持第三方服务商接入。
  3902. * 需要配合硬件设备使用,硬件接入流程参考 [无线投屏](#14789)。
  3903. *
  3904. * @example
  3905. * ```ts
  3906. * ww.startWecast()
  3907. * ```
  3908. */ function startWecast(params = {}) {
  3909. return passthrough('startWecast', params);
  3910. }
  3911. var OAType;
  3912. (function(OAType) {
  3913. /**
  3914. * 发起审批
  3915. */ OAType["create_approval"] = "10001";
  3916. /**
  3917. * 查看审批详情
  3918. */ OAType["view_approval"] = "10002";
  3919. })(OAType || (OAType = {}));
  3920. var OaExtDataType;
  3921. (function(OaExtDataType) {
  3922. /**
  3923. * 链接
  3924. */ OaExtDataType["link"] = "link";
  3925. /**
  3926. * 文本
  3927. */ OaExtDataType["text"] = "text";
  3928. })(OaExtDataType || (OaExtDataType = {}));
  3929. /**
  3930. * 在应用页面中发起审批流程。之后审批流程的每次状态变化都会通知开发者,开发者可按需进行拓展开发。具体参见[审批流程引擎](#14584)。
  3931. *
  3932. * @limit
  3933. * - 本接口必须使用应用身份进行注册
  3934. * - 应用必须具有审批权限
  3935. *
  3936. * @compat WeCom >= 2.5.0
  3937. *
  3938. * @example
  3939. * ```ts
  3940. * ww.thirdPartyOpenPage({
  3941. * oaType: '10001',
  3942. * templateId: '46af67a118a6ebf000002',
  3943. * thirdNo: 'thirdNo',
  3944. * extData: {
  3945. * fieldList: [
  3946. * {
  3947. * type: 'text',
  3948. * title: '采购类型',
  3949. * value: '市场活动'
  3950. * },
  3951. * {
  3952. * type: 'link',
  3953. * title: '订单链接',
  3954. * value: 'https://work.weixin.qq.com'
  3955. * }
  3956. * ]
  3957. * }
  3958. * })
  3959. * ```
  3960. * @throws
  3961. * | errMsg | 说明 |
  3962. * | --- | --- |
  3963. * | 已存在相同的审批编号 | oaType为10001时,传入的thirdNo已经被其他审批单占用。 |
  3964. * | 审批申请不存在 | oaType为10002时,在历史记录中,传入的thirdNo对应的审批单不存在。 |
  3965. * | 审批模板ID不正确 | 调用接口时传入了错误的templateId |
  3966. * | 应用ID不正确 | 使用了错误的 agentId |
  3967. */ function thirdPartyOpenPage(params) {
  3968. return passthrough('thirdPartyOpenPage', params);
  3969. }
  3970. /**
  3971. * 变更企业互联/上下游群成员
  3972. *
  3973. * @limit
  3974. * - 本接口必须使用应用身份进行注册
  3975. * - 当前成员必须在应用的可见范围
  3976. * - 仅支持往群里添加企业内部成员/企业互联成员
  3977. * - 仅限企业互联/上下游企业可调用
  3978. * - 当前成员为下游企业成员时,需要打开上下游空间中的“允许外部单位之间互相查看”配置才可以往群里添加其他下游企业成员
  3979. *
  3980. * @compat WeCom >= 3.1.8
  3981. *
  3982. * @example
  3983. * ```ts
  3984. * ww.updateCorpGroupChat({
  3985. * chatId: 'CHATID',
  3986. * userIdsToAdd: ['lisi', 'lisi2'],
  3987. * openUserIdsToAdd: ['wabc3', 'wbcde'],
  3988. * corpGroupUserIdsToAdd: [
  3989. * {
  3990. * corpId: 'ww3333',
  3991. * userId: 'userid123',
  3992. * openUserId: 'wx1111'
  3993. * },
  3994. * {
  3995. * corpId: 'ww4444',
  3996. * userId: 'userid123',
  3997. * openUserId: 'wx1111'
  3998. * }
  3999. * ]
  4000. * })
  4001. * ```
  4002. *
  4003. * @throws
  4004. * | errMsg | 说明 |
  4005. * | --- | --- |
  4006. * | updateCorpGroupChat:ok | 执行成功 |
  4007. * | updateCorpGroupChat:fail no permission | 应用签名校验失败 |
  4008. * | updateCorpGroupChat:fail exceed user id list size | 超过人数上限 |
  4009. * | updateCorpGroupChat:fail invalid parameter | 参数不合法 |
  4010. * | updateCorpGroupChat:fail unsupported chat | 不支持群类型 |
  4011. */ function updateCorpGroupChat(params) {
  4012. return passthrough('updateCorpGroupChat', params);
  4013. }
  4014. /**
  4015. * 变更群成员。
  4016. *
  4017. * @limit
  4018. * - 本接口必须使用应用身份进行注册
  4019. * - 目前仅支持添加企业内部成员
  4020. * - 仅支持客户群调用
  4021. *
  4022. * @compat WeCom iOS, Android, PC >= 3.0.36
  4023. *
  4024. * @example
  4025. * ```ts
  4026. * ww.updateEnterpriseChat({
  4027. * chatId: 'CHATID',
  4028. * userIdsToAdd: [
  4029. * 'zhangsan',
  4030. * 'lisi'
  4031. * ]
  4032. * })
  4033. * ```
  4034. */ function updateEnterpriseChat(params) {
  4035. return passthrough('updateEnterpriseChat', params, {
  4036. chatId: params.chatId,
  4037. userIdsToAdd: joinList(params.userIdsToAdd)
  4038. });
  4039. }
  4040. /**
  4041. * 设置朋友圈封面与签名。
  4042. *
  4043. * @compat WeCom iOS, Android >= 3.1.12
  4044. *
  4045. * @limit
  4046. * - 本接口必须使用应用身份进行注册
  4047. * - 应用需有[客户联系功能权限](#13473/配置可使用客户联系接口的应用)
  4048. * - 当前成员必须配置了客户联系功能
  4049. * - 当前成员必须在客户朋友圈使用范围
  4050. * - 当前成员必须具备外部沟通管理成员使用权限
  4051. *
  4052. * @note
  4053. * 同时设置了签名跟封面url,客户端更新顺序为先更新签名,再更新封面图url(封面图若不符合要求会让用户重新调整)。
  4054. *
  4055. * @example
  4056. * ```ts
  4057. * ww.updateMomentsSetting({
  4058. * signature: '个性签名',
  4059. * imgUrl: 'https://work.weixin.qq.com/'
  4060. * })
  4061. * ```
  4062. */ function updateMomentsSetting(params) {
  4063. return passthrough('updateMomentsSetting', params);
  4064. }
  4065. /**
  4066. * 保持屏幕常亮。
  4067. *
  4068. * 在企业微信内打开 H5 页面时,调用该接口让屏幕保持常亮。
  4069. *
  4070. * @note
  4071. * 仅在当前页面生效,离开页面后设置失效。
  4072. *
  4073. * @limit
  4074. * - 本接口必须使用应用身份进行注册
  4075. * - 成员必须在应用可见范围内
  4076. *
  4077. * @compat @compat WeCom iOS, Android >= 4.0.20
  4078. *
  4079. * @example
  4080. * ```ts
  4081. * ww.setKeepScreenOn({
  4082. * keepScreenOn: true,
  4083. * })
  4084. * ```
  4085. */ function setKeepScreenOn(params) {
  4086. return passthrough('setKeepScreenOn', params);
  4087. }
  4088. /**
  4089. * **注意:页面上需要提前引入 `jwxwork-1.0.0.js`:**
  4090. *
  4091. * ```html
  4092. * <script src="https://open.work.weixin.qq.com/wwopen/js/jwxwork-1.0.0.js" referrerpolicy="origin"></script>
  4093. * ```
  4094. *
  4095. * 初始化[通讯录展示组件](#91958)。
  4096. *
  4097. * 在该接口返回成功后,可以直接调用通讯录展示组件的相关方法。
  4098. *
  4099. * @example
  4100. * ```ts
  4101. * ww.initOpenData()
  4102. * ```
  4103. */ function initOpenData(params = {}) {
  4104. return promiseToCallback(params, async ()=>{
  4105. if (!isWeCom) {
  4106. return invokeOpenDataAgentConfig();
  4107. }
  4108. const { result } = await ensureAgentConfigReady();
  4109. if (!isWindows && !win?.WeixinSandBox) {
  4110. throw new SDKError('Missing WeixinSandBox');
  4111. }
  4112. if (!win?.WWOpenData) {
  4113. await invoke('wwapp.initWwOpenData');
  4114. }
  4115. if (!win?.WWOpenData) {
  4116. throw new SDKError('Init WWOpenData failed');
  4117. }
  4118. if (win.WWOpenData.initJSSDK) {
  4119. win.WWOpenData.initJSSDK({
  4120. invoke,
  4121. ensureAgentConfigReady
  4122. });
  4123. }
  4124. return result;
  4125. });
  4126. }
  4127. async function invokeOpenDataAgentConfig() {
  4128. if (!win?.WWOpenData?.agentConfig) {
  4129. throw new SDKError('Missing WWOpenData.agentConfig');
  4130. }
  4131. const params = await resolveAgentConfigParams(getSignURL());
  4132. const promise = new Promise((success, fail)=>{
  4133. win.WWOpenData.agentConfig({
  4134. ...params,
  4135. success,
  4136. fail
  4137. });
  4138. });
  4139. promise.then(handleAgentConfigSuccess, handleAgentConfigFail);
  4140. return promise;
  4141. }
  4142. function createTransparentIFrame(el) {
  4143. const iframeEl = document.createElement('iframe');
  4144. const { style } = iframeEl;
  4145. style.display = 'block';
  4146. style.border = 'none';
  4147. style.background = 'transparent';
  4148. iframeEl.referrerPolicy = 'origin';
  4149. iframeEl.setAttribute('frameborder', '0');
  4150. iframeEl.setAttribute('allowtransparency', 'true');
  4151. const containerEl = resolveEl(el);
  4152. if (containerEl) {
  4153. containerEl.appendChild(iframeEl);
  4154. }
  4155. return iframeEl;
  4156. }
  4157. function resolveEl(el) {
  4158. if (typeof el === 'string') {
  4159. return document.querySelector(el);
  4160. }
  4161. return el;
  4162. }
  4163. const clientId = random();
  4164. let uid = 0;
  4165. function genUid() {
  4166. return `${clientId}-${uid++}`;
  4167. }
  4168. function random() {
  4169. return Math.random().toString(36).slice(2);
  4170. }
  4171. function normalizeError(error) {
  4172. if (!error || typeof error !== 'object') {
  4173. return error;
  4174. }
  4175. return {
  4176. ...error,
  4177. message: error.message,
  4178. stack: error.stack
  4179. };
  4180. }
  4181. function tryParseJSON(data) {
  4182. try {
  4183. if (typeof data === 'string') {
  4184. return JSON.parse(data);
  4185. }
  4186. return data;
  4187. } catch (error) {
  4188. // noop
  4189. }
  4190. }
  4191. function useRemoteInvoke(postMessage, callback) {
  4192. const messageMap = new Map();
  4193. function invoke(args, opts) {
  4194. if (opts?.dropResult) {
  4195. postMessage({
  4196. type: 'ww-iframe-handle:call',
  4197. args
  4198. }, opts);
  4199. return Promise.resolve(undefined);
  4200. }
  4201. return new Promise((resolve, reject)=>{
  4202. const uid = genUid();
  4203. messageMap.set(uid, {
  4204. resolve,
  4205. reject
  4206. });
  4207. postMessage({
  4208. type: 'ww-iframe-handle:call',
  4209. uid,
  4210. args
  4211. }, opts);
  4212. });
  4213. }
  4214. async function handleCallMessage(msg, event) {
  4215. if (!msg.uid) {
  4216. return callback(msg.args, event);
  4217. }
  4218. try {
  4219. postMessage({
  4220. type: 'ww-iframe-handle:response',
  4221. uid: msg.uid,
  4222. kind: 'resolve',
  4223. args: await callback(msg.args, event)
  4224. });
  4225. } catch (error) {
  4226. postMessage({
  4227. type: 'ww-iframe-handle:response',
  4228. uid: msg.uid,
  4229. kind: 'reject',
  4230. args: normalizeError(error)
  4231. });
  4232. throw error;
  4233. }
  4234. }
  4235. function handleResponseMessage(msg) {
  4236. const handle = messageMap.get(msg.uid);
  4237. if (!handle) {
  4238. return;
  4239. }
  4240. handle[msg.kind](msg.args);
  4241. messageMap.delete(msg.uid);
  4242. }
  4243. return {
  4244. invoke,
  4245. handleCallMessage,
  4246. handleResponseMessage
  4247. };
  4248. }
  4249. function useIframeClient(iframeEl, origin, callback) {
  4250. const messageQueue = [];
  4251. let iframeReady = false;
  4252. let useChannel = false;
  4253. window.addEventListener('message', handleWindowMessage);
  4254. function handleWindowMessage(event) {
  4255. if (event.origin !== origin || iframeEl.contentWindow !== event.source) {
  4256. return;
  4257. }
  4258. const msg = tryParseJSON(event.data);
  4259. if (typeof msg?.type !== 'string') {
  4260. return;
  4261. }
  4262. if (msg.type.startsWith('ww-iframe-handle:')) {
  4263. handleMessage(msg, event);
  4264. }
  4265. }
  4266. const channel = new MessageChannel();
  4267. channel.port1.onmessage = (event)=>{
  4268. const msg = tryParseJSON(event.data);
  4269. handleMessage(msg, event);
  4270. };
  4271. const { invoke, handleCallMessage, handleResponseMessage } = useRemoteInvoke(enqueueMsg, callback);
  4272. function handleMessage(msg, event) {
  4273. switch(msg.type){
  4274. case 'ww-iframe-handle:ready':
  4275. return handleReadyMessage(msg);
  4276. case 'ww-iframe-handle:call':
  4277. return handleCallMessage(msg, event);
  4278. case 'ww-iframe-handle:response':
  4279. handleResponseMessage(msg);
  4280. return;
  4281. }
  4282. }
  4283. function handleReadyMessage(msg) {
  4284. if (iframeReady) {
  4285. return;
  4286. }
  4287. iframeReady = true;
  4288. if (msg.supportChannel) {
  4289. switchToChannel();
  4290. }
  4291. for (const info of messageQueue){
  4292. postMessage(info.msg, info.opts);
  4293. }
  4294. }
  4295. iframeEl.addEventListener('load', ()=>{
  4296. if (!iframeReady) {
  4297. postMessage({
  4298. type: 'ww-iframe-handle:init'
  4299. });
  4300. }
  4301. });
  4302. function switchToChannel() {
  4303. postMessage({
  4304. type: 'ww-iframe-handle:set-port',
  4305. port: channel.port2
  4306. }, {
  4307. transfer: [
  4308. channel.port2
  4309. ],
  4310. serialize: false
  4311. });
  4312. useChannel = true;
  4313. }
  4314. function enqueueMsg(msg, opts) {
  4315. if (!iframeReady) {
  4316. messageQueue.push({
  4317. msg,
  4318. opts
  4319. });
  4320. } else {
  4321. postMessage(msg, opts);
  4322. }
  4323. }
  4324. function postMessage(msg, opts) {
  4325. const data = opts?.serialize === false ? msg : JSON.stringify(msg);
  4326. if (useChannel) {
  4327. channel.port1.postMessage(data, opts?.transfer);
  4328. } else {
  4329. iframeEl.contentWindow?.postMessage(data, origin, opts?.transfer);
  4330. }
  4331. }
  4332. function dispose() {
  4333. window.removeEventListener('message', handleWindowMessage);
  4334. channel.port1.onmessage = null;
  4335. }
  4336. return {
  4337. el: iframeEl,
  4338. invoke,
  4339. dispose
  4340. };
  4341. }
  4342. async function resolveSuiteConfigParams(url) {
  4343. const registerOptions = getRegisterOptions();
  4344. if (!registerOptions?.getSuiteConfigSignature) {
  4345. throw new SDKError('Missing getSuiteConfigSignature');
  4346. }
  4347. const data = await registerOptions.getSuiteConfigSignature(url);
  4348. return {
  4349. suiteid: registerOptions.suiteId,
  4350. timestamp: `${data.timestamp}`,
  4351. nonceStr: data.nonceStr,
  4352. signature: data.signature,
  4353. jsApiList: mapJsApiListToClient(registerOptions.jsApiList || [
  4354. 'agentConfig'
  4355. ])
  4356. };
  4357. }
  4358. function has$1(obj, key) {
  4359. return Object.prototype.hasOwnProperty.call(obj, key);
  4360. }
  4361. function handleCallMsg(msg, options, thisArg) {
  4362. safeRun(options[msg.name], msg.payload || msg.data, thisArg);
  4363. }
  4364. function createMsgDispatcher() {
  4365. const handlers = new Map();
  4366. function subscribe(type, handler) {
  4367. handlers.set(type, handler);
  4368. }
  4369. function handleMessage(msg) {
  4370. return handlers.get(msg.type)?.(msg);
  4371. }
  4372. return {
  4373. subscribe,
  4374. handleMessage
  4375. };
  4376. }
  4377. let disposeModalFrame;
  4378. function showModalFrame(url, callback) {
  4379. disposeModalFrame?.();
  4380. const iframeEl = createTransparentIFrame(document.body);
  4381. const { style } = iframeEl;
  4382. style.position = 'fixed';
  4383. style.left = '0';
  4384. style.top = '0';
  4385. style.zIndex = '1000';
  4386. style.width = '100vw';
  4387. style.height = '100vh';
  4388. iframeEl.classList.add('wecom-jssdk-modal');
  4389. iframeEl.setAttribute('src', url);
  4390. const { origin } = new URL(url);
  4391. const client = useIframeClient(iframeEl, origin, (msg)=>{
  4392. if (msg.type === 'close') {
  4393. handleCloseMsg();
  4394. }
  4395. return callback?.(msg);
  4396. });
  4397. function handleCloseMsg() {
  4398. client.dispose();
  4399. iframeEl.parentNode?.removeChild(iframeEl);
  4400. }
  4401. disposeModalFrame = handleCloseMsg;
  4402. return client;
  4403. }
  4404. const FRAME_ORIGIN$1 = 'https://login.work.weixin.qq.com';
  4405. /**
  4406. * 创建 JSAPI 触发面板。
  4407. *
  4408. * 在非企业微信内置浏览器环境下,开发者可以创建 JSAPI 触发面板。当用户点击面板时,内置的 iframe 将调起用户本地的企业微信客户端并调用指定的 JSAPI。
  4409. *
  4410. * @param name 要调用的 JSAPI 名称
  4411. *
  4412. * @limit
  4413. * - 应用必须经过 SSO 登录获取 web_token
  4414. * - 用户必须登录了企业微信桌面端且当前用户身份和页面身份一致
  4415. */ function createJSAPIPanel(name, options) {
  4416. const iframeEl = createTransparentIFrame(options.el);
  4417. const { style } = iframeEl;
  4418. style.width = '100%';
  4419. style.height = '100%';
  4420. const jsapiParamsMap = new Map();
  4421. const { subscribe, handleMessage } = createMsgDispatcher();
  4422. const { dispose } = useIframeClient(iframeEl, FRAME_ORIGIN$1, handleMessage);
  4423. subscribe('call', (msg)=>{
  4424. handleCallMsg(msg, options);
  4425. });
  4426. subscribe('getStaticOptions', ()=>{
  4427. return {
  4428. name,
  4429. options: {
  4430. ...options,
  4431. el: undefined,
  4432. params: undefined
  4433. }
  4434. };
  4435. });
  4436. subscribe('jsapiCallback', (msg)=>{
  4437. if (!jsapiParamsMap.has(msg.seq)) {
  4438. return;
  4439. }
  4440. const jsapiParams = jsapiParamsMap.get(msg.seq);
  4441. jsapiParamsMap.delete(msg.seq);
  4442. if (msg.kind === 'success') {
  4443. safeRun(jsapiParams?.success, msg.payload);
  4444. } else {
  4445. safeRun(jsapiParams?.fail, msg.payload);
  4446. }
  4447. safeRun(jsapiParams?.complete, msg.payload);
  4448. });
  4449. subscribe('getJSAPIParams', async (msg)=>{
  4450. const jsapiParams = isFunction(options.params) ? await options.params() : options.params;
  4451. const signUrl = getSignURL();
  4452. jsapiParamsMap.set(msg.seq, jsapiParams);
  4453. return {
  4454. webToken: options.webToken,
  4455. url: signUrl,
  4456. configParams: msg.payload?.skipSignature ? undefined : await resolveSignatureData(signUrl, msg.payload?.preferSignatureTypeList || [
  4457. 'agentConfig'
  4458. ]),
  4459. jsapi: name,
  4460. jsapiParams
  4461. };
  4462. });
  4463. subscribe('openModalFrame', (msg)=>{
  4464. showModalFrame(msg.payload.url);
  4465. });
  4466. iframeEl.style.opacity = '0';
  4467. iframeEl.src = 'https://login.work.weixin.qq.com/wwopen/ww-jsapi-transparent-frame';
  4468. return {
  4469. /**
  4470. * JSAPI 触发面板的 iframe 元素
  4471. */ el: iframeEl,
  4472. /**
  4473. * 卸载 JSAPI 触发面板
  4474. */ unmount () {
  4475. dispose();
  4476. iframeEl.parentNode?.removeChild(iframeEl);
  4477. }
  4478. };
  4479. }
  4480. const resolveSignatureFnMap = {
  4481. agentConfig: resolveAgentConfigParams,
  4482. suiteConfig: resolveSuiteConfigParams
  4483. };
  4484. async function resolveSignatureData(url, typeList) {
  4485. let lastError = new Error('Missing signature handler');
  4486. for (const type of typeList){
  4487. try {
  4488. if (!has$1(resolveSignatureFnMap, type)) {
  4489. continue;
  4490. }
  4491. return {
  4492. type,
  4493. params: await resolveSignatureFnMap[type](url)
  4494. };
  4495. } catch (error) {
  4496. lastError = error;
  4497. }
  4498. }
  4499. throw lastError;
  4500. }
  4501. function has(object, key) {
  4502. return Object.prototype.hasOwnProperty.call(object, key);
  4503. }
  4504. function isObject(val) {
  4505. return typeof val === 'object' && val !== null;
  4506. }
  4507. function includes(list, value) {
  4508. if (!list) {
  4509. return false;
  4510. }
  4511. return list.indexOf(value) >= 0;
  4512. }
  4513. var createIdentifier = createBuilder("Identifier" /* Types.Identifier */ , 'name');
  4514. var createLiteral = createBuilder("Literal" /* Types.Literal */ , 'value');
  4515. function createBuilder(type, key) {
  4516. return function(val) {
  4517. var _a;
  4518. return _a = {
  4519. type: type
  4520. }, _a[key] = val, _a;
  4521. };
  4522. }
  4523. function isIdentifierStart(ch) {
  4524. return isInRange(ch, 65, 90) // A-Z
  4525. || isInRange(ch, 97, 122) // a-z
  4526. || ch === 36 /* Code.dollarSign */ || ch === 95 /* Code.underscore */ ;
  4527. }
  4528. function isIdentifierPart(ch) {
  4529. return isIdentifierStart(ch) || isDecimalDigit(ch);
  4530. }
  4531. function isDecimalDigit(ch) {
  4532. return isInRange(ch, 48, 57); // 0-9
  4533. }
  4534. function isHexDigit(ch) {
  4535. return isDecimalDigit(ch) || isInRange(ch, 65, 70) // A-F
  4536. || isInRange(ch, 97, 102); // a-f
  4537. }
  4538. function isInRange(val, min, max) {
  4539. return val >= min && val <= max;
  4540. }
  4541. /**
  4542. * 12.6 Names and Keywords & 13.1 Identifiers
  4543. */ var LITERAL_NAME = {
  4544. "null": null,
  4545. "true": true,
  4546. "false": false,
  4547. NaN: NaN,
  4548. Infinity: Infinity
  4549. };
  4550. var reserveWords = ('await break case catch class const continue ' + 'debugger default delete do else enum export ' + 'extends false finally for function if import ' + 'in instanceof new null return super switch ' + 'this throw true try typeof var void while ' + 'with yield').split(' ');
  4551. var reserveWordMap = {};
  4552. for(var _i = 0, reserveWords_1 = reserveWords; _i < reserveWords_1.length; _i++){
  4553. var word = reserveWords_1[_i];
  4554. reserveWordMap[word] = true;
  4555. }
  4556. /**
  4557. * IdentifierReference
  4558. *
  4559. * https://tc39.es/ecma262/#prod-IdentifierReference
  4560. */ function parseIdentifierReference(ctx) {
  4561. var name = parseIdentifierName(ctx);
  4562. if (has(LITERAL_NAME, name)) {
  4563. return ctx.build(createLiteral(LITERAL_NAME[name]));
  4564. }
  4565. if (has(reserveWordMap, name)) {
  4566. ctx.unexpected(name);
  4567. }
  4568. return ctx.build(createIdentifier(name));
  4569. }
  4570. /**
  4571. * Identifier
  4572. *
  4573. * https://tc39.es/ecma262/#prod-Identifier
  4574. */ function parseIdentifier(ctx) {
  4575. var name = parseIdentifierName(ctx);
  4576. return ctx.build(createIdentifier(name));
  4577. }
  4578. /**
  4579. * IdentifierName
  4580. *
  4581. * https://tc39.es/ecma262/#prod-IdentifierName
  4582. */ function parseIdentifierName(ctx) {
  4583. if (!isIdentifierStart(ctx.peek())) {
  4584. ctx.unexpected();
  4585. }
  4586. var start = ctx.index;
  4587. do {
  4588. ctx.next();
  4589. }while (isIdentifierPart(ctx.peek()))
  4590. return ctx.expr.slice(start, ctx.index);
  4591. }
  4592. /**
  4593. * 12.8.3 Numeric Literals
  4594. */ /**
  4595. * NumericLiteral
  4596. *
  4597. * https://tc39.es/ecma262/#prod-NumericLiteral
  4598. */ function parseNumericLiteral(ctx) {
  4599. var number = '';
  4600. while(isDecimalDigit(ctx.peek())){
  4601. number += ctx.nextCh();
  4602. }
  4603. if (number === '0') {
  4604. // HexIntegerLiteral
  4605. // https://tc39.es/ecma262/#prod-HexIntegerLiteral
  4606. if (ctx.eat(120 /* Code.lowercaseX */ ) || ctx.eat(88 /* Code.uppercaseX */ )) {
  4607. number = '';
  4608. while(isHexDigit(ctx.peek())){
  4609. number += ctx.nextCh();
  4610. }
  4611. if (!number) {
  4612. ctx.unexpected();
  4613. }
  4614. return ctx.build(createLiteral(parseInt(number, 16)));
  4615. }
  4616. // BinaryIntegerLiteral
  4617. // https://tc39.es/ecma262/#prod-BinaryIntegerLiteral
  4618. if (ctx.eat(98 /* Code.lowercaseB */ ) || ctx.eat(66 /* Code.uppercaseB */ )) {
  4619. number = '';
  4620. while(ctx.peek() === 48 /* Code.digit0 */ || ctx.peek() === 49 /* Code.digit1 */ ){
  4621. number += ctx.nextCh();
  4622. }
  4623. if (!number) {
  4624. ctx.unexpected();
  4625. }
  4626. return ctx.build(createLiteral(parseInt(number, 2)));
  4627. }
  4628. }
  4629. if (ctx.peek() === 46 /* Code.dot */ ) {
  4630. number += ctx.nextCh();
  4631. while(isDecimalDigit(ctx.peek())){
  4632. number += ctx.nextCh();
  4633. }
  4634. }
  4635. // ExponentPart
  4636. // https://tc39.es/ecma262/#prod-ExponentPart
  4637. if (ctx.peek() === 101 /* Code.lowercaseE */ || ctx.peek() === 69 /* Code.uppercaseE */ ) {
  4638. number += ctx.nextCh();
  4639. if (ctx.peek() === 43 /* Code.plusSign */ || ctx.peek() === 45 /* Code.dash */ ) {
  4640. number += ctx.nextCh();
  4641. }
  4642. var hasDecimal = false;
  4643. while(isDecimalDigit(ctx.peek())){
  4644. hasDecimal = true;
  4645. number += ctx.nextCh();
  4646. }
  4647. if (!hasDecimal) {
  4648. ctx.unexpected();
  4649. }
  4650. }
  4651. if (isIdentifierStart(ctx.peek())) {
  4652. ctx["throw"]("Variable name cannot start with a number (".concat(number).concat(ctx.peekCh(), ")."));
  4653. }
  4654. if (ctx.peek() === 46 /* Code.dot */ || number === '.') {
  4655. ctx.unexpected();
  4656. }
  4657. return ctx.build(createLiteral(parseFloat(number)));
  4658. }
  4659. /**
  4660. * 12.8.4 String Literals
  4661. */ var ESCAPE_CHARACTER = {
  4662. n: '\n',
  4663. r: '\r',
  4664. t: '\t'
  4665. };
  4666. /**
  4667. * StringLiteral
  4668. *
  4669. * https://tc39.es/ecma262/#prod-StringLiteral
  4670. */ function parseStringLiteral(ctx) {
  4671. var quote = ctx.nextCh();
  4672. var value = '';
  4673. var ch;
  4674. while(ch = ctx.nextCh()){
  4675. if (ch === quote) {
  4676. return ctx.build(createLiteral(value));
  4677. }
  4678. if (ch !== '\\') {
  4679. value += ch;
  4680. continue;
  4681. }
  4682. ch = ctx.nextCh();
  4683. if (has(ESCAPE_CHARACTER, ch)) {
  4684. value += ESCAPE_CHARACTER[ch];
  4685. } else {
  4686. value += ch;
  4687. }
  4688. }
  4689. ctx.unexpected();
  4690. }
  4691. /**
  4692. * 13.2 Primary Expression
  4693. */ /**
  4694. * PrimaryExpression
  4695. *
  4696. * https://tc39.es/ecma262/#prod-PrimaryExpression
  4697. */ function parsePrimaryExpression(ctx) {
  4698. var code = ctx.peek();
  4699. if (isDecimalDigit(code) || code === 46 /* Code.dot */ ) {
  4700. return parseNumericLiteral(ctx);
  4701. }
  4702. if (code === 39 /* Code.singleQuote */ || code === 34 /* Code.doubleQuote */ ) {
  4703. return parseStringLiteral(ctx);
  4704. }
  4705. if (isIdentifierStart(code)) {
  4706. return parseIdentifierReference(ctx);
  4707. }
  4708. ctx.unexpected();
  4709. }
  4710. /**
  4711. * 13.3 Left-Hand-Side Expressions
  4712. */ /**
  4713. * LeftHandSideExpression
  4714. *
  4715. * https://tc39.es/ecma262/#prod-LeftHandSideExpression
  4716. */ function parseLeftHandSideExpression(ctx) {
  4717. var content = parsePrimaryExpression(ctx);
  4718. var code;
  4719. while(code = ctx.peek()){
  4720. // base [ prop ]
  4721. if (code === 91 /* Code.leftSquareBracket */ ) {
  4722. content = buildMemberExpression(ctx, content, true);
  4723. continue;
  4724. }
  4725. // base . prop
  4726. if (ctx.eat(46 /* Code.dot */ )) {
  4727. content = buildMemberExpression(ctx, content);
  4728. continue;
  4729. }
  4730. break;
  4731. }
  4732. return content;
  4733. }
  4734. /**
  4735. * MemberExpression
  4736. *
  4737. * https://tc39.es/ecma262/#prod-MemberExpression
  4738. */ function buildMemberExpression(ctx, object, computed) {
  4739. if (computed === void 0) {
  4740. computed = false;
  4741. }
  4742. var property;
  4743. if (computed) {
  4744. ctx.expect(91 /* Code.leftSquareBracket */ );
  4745. property = parseExpression(ctx);
  4746. ctx.expect(93 /* Code.rightSquareBracket */ );
  4747. } else {
  4748. property = parseIdentifier(ctx);
  4749. }
  4750. return ctx.build({
  4751. type: "MemberExpression" /* Types.MemberExpression */ ,
  4752. object: object,
  4753. property: property,
  4754. computed: computed
  4755. });
  4756. }
  4757. /**
  4758. * 13.16 Comma Operator ( , )
  4759. */ /**
  4760. * Expression
  4761. *
  4762. * https://tc39.es/ecma262/#prod-Expression
  4763. */ function parseExpression(ctx) {
  4764. return parseLeftHandSideExpression(ctx);
  4765. }
  4766. function createParserContext(expr) {
  4767. return {
  4768. expr: expr,
  4769. index: 0,
  4770. peek: function() {
  4771. return this.expr.charCodeAt(this.index);
  4772. },
  4773. peekCh: function() {
  4774. return this.expr.charAt(this.index);
  4775. },
  4776. next: function() {
  4777. this.index += 1;
  4778. },
  4779. nextCh: function() {
  4780. this.index += 1;
  4781. return this.expr.charAt(this.index - 1);
  4782. },
  4783. eat: function(ch) {
  4784. if (this.peek() !== ch) {
  4785. return false;
  4786. }
  4787. this.next();
  4788. this.skipWhitespace();
  4789. return true;
  4790. },
  4791. expect: function(ch) {
  4792. if (!this.eat(ch)) {
  4793. this.unexpected();
  4794. }
  4795. },
  4796. skip: function(length) {
  4797. this.index += length;
  4798. this.skipWhitespace();
  4799. },
  4800. skipWhitespace: function() {
  4801. var ch = expr.charCodeAt(this.index);
  4802. while(ch === 32 /* Code.space */ || ch === 9 /* Code.tab */ || ch === 13 /* Code.carriageReturn */ || ch === 10 /* Code.lineFeed */ ){
  4803. this.index += 1;
  4804. ch = expr.charCodeAt(this.index);
  4805. }
  4806. return this.index;
  4807. },
  4808. build: function(expr) {
  4809. this.skipWhitespace();
  4810. return expr;
  4811. },
  4812. unexpected: function(token) {
  4813. if (!token && this.index >= expr.length) {
  4814. throw this["throw"]('Unexpected end of input.');
  4815. }
  4816. throw this["throw"]("Unexpected token '".concat(token || this.peekCh(), "'."));
  4817. },
  4818. "throw": function(msg) {
  4819. throw new SyntaxError("".concat(msg, " (1:").concat(this.index, ")"));
  4820. }
  4821. };
  4822. }
  4823. function parseDataPath(input) {
  4824. var ctx = createParserContext(input.trim());
  4825. var ast = parseExpression(ctx);
  4826. if (ctx.index !== ctx.expr.length) {
  4827. ctx.unexpected();
  4828. }
  4829. return ast;
  4830. }
  4831. var DEFAULT_PROTECTED_KEYS = [
  4832. 'constrcutor',
  4833. 'prototype',
  4834. '__proto__'
  4835. ];
  4836. function patch(data, update, options) {
  4837. if (options === void 0) {
  4838. options = {};
  4839. }
  4840. var protectedKeys = options.protectedKeys || DEFAULT_PROTECTED_KEYS;
  4841. var set = options.set || defaultSet;
  4842. for(var _i = 0, _a = Object.keys(update); _i < _a.length; _i++){
  4843. var key = _a[_i];
  4844. if (includes(protectedKeys, key)) {
  4845. continue;
  4846. }
  4847. if (!includes(key, '[') && !includes(key, '.')) {
  4848. set(data, key, update[key]);
  4849. continue;
  4850. }
  4851. try {
  4852. var path = extractPath(parseDataPath(key), protectedKeys || []);
  4853. if (path) {
  4854. setIn(data, path, update[key], set);
  4855. } else {
  4856. set(data, key, update[key]);
  4857. }
  4858. } catch (error) {
  4859. set(data, key, update[key]);
  4860. }
  4861. }
  4862. }
  4863. function extractPath(expr, protectedKeys, path) {
  4864. if (protectedKeys === void 0) {
  4865. protectedKeys = [];
  4866. }
  4867. if (path === void 0) {
  4868. path = [];
  4869. }
  4870. if (expr.type === "Identifier" /* Types.Identifier */ ) {
  4871. path.unshift(expr.name);
  4872. return path;
  4873. }
  4874. if (expr.type !== "MemberExpression" /* Types.MemberExpression */ ) {
  4875. return;
  4876. }
  4877. var object = expr.object, property = expr.property, computed = expr.computed;
  4878. if (computed) {
  4879. if (property.type !== "Literal" /* Types.Literal */ ) {
  4880. return;
  4881. }
  4882. var value = property.value;
  4883. if (includes(protectedKeys, value)) {
  4884. return;
  4885. }
  4886. path.unshift(value);
  4887. } else {
  4888. if (property.type !== "Identifier" /* Types.Identifier */ ) {
  4889. return;
  4890. }
  4891. var name_1 = property.name;
  4892. if (includes(protectedKeys, name_1)) {
  4893. return;
  4894. }
  4895. path.unshift(name_1);
  4896. }
  4897. return extractPath(object, protectedKeys, path);
  4898. }
  4899. function setIn(data, path, value, set) {
  4900. var ptr = data;
  4901. for(var i = 0, ii = path.length - 1; i < ii; i++){
  4902. var key = path[i];
  4903. if (!has(ptr, key) || !isObject(ptr[key])) {
  4904. set(ptr, key, typeof path[i + 1] === 'string' ? {} : []);
  4905. }
  4906. ptr = ptr[key];
  4907. }
  4908. set(ptr, path[path.length - 1], value);
  4909. return ptr;
  4910. }
  4911. function defaultSet(object, key, value) {
  4912. // eslint-disable-next-line no-param-reassign
  4913. object[key] = value;
  4914. }
  4915. function cloneDeep(value) {
  4916. if (Array.isArray(value)) {
  4917. return value.map(cloneDeep);
  4918. }
  4919. if (value == null || typeof value !== 'object') {
  4920. return value;
  4921. }
  4922. const result = {};
  4923. for (const key of Object.keys(value)){
  4924. result[key] = cloneDeep(value[key]);
  4925. }
  4926. return result;
  4927. }
  4928. const contextMap = new WeakMap();
  4929. function setPluginContext(instance, internal) {
  4930. contextMap.set(instance, internal);
  4931. }
  4932. function getPluginContext(instance) {
  4933. return contextMap.get(instance);
  4934. }
  4935. function createOpenSessionInjector(params) {
  4936. return new Promise((resolve, reject)=>{
  4937. win.WWOpenData.createOpenSessionInjector(params, (error, injectOpenSession)=>{
  4938. if (error || !injectOpenSession) {
  4939. reject(error || new Error('System error'));
  4940. } else {
  4941. resolve(injectOpenSession);
  4942. }
  4943. });
  4944. });
  4945. }
  4946. function getHookNames(options) {
  4947. return Object.keys(options).filter((name)=>typeof options[name] === 'function');
  4948. }
  4949. function removeHooks(options) {
  4950. return Object.entries(options).reduce((acc, [name, value])=>{
  4951. if (typeof value !== 'function') {
  4952. acc[name] = value;
  4953. }
  4954. return acc;
  4955. }, {});
  4956. }
  4957. const FRAME_ORIGIN = 'https://open.work.weixin.qq.com';
  4958. const BUSINESS_URL = `${FRAME_ORIGIN}/wwopen/ww-open-data-frame`;
  4959. const PROTECTED_DATA_KEYS = [
  4960. 'constructor',
  4961. 'prototype',
  4962. '__proto__',
  4963. '__ob__'
  4964. ];
  4965. /**
  4966. * 创建 open-data frame 工厂对象。
  4967. *
  4968. * @compat WeCom >= 4.0.20
  4969. *
  4970. * @example
  4971. * ```ts
  4972. * const factory = ww.createOpenDataFrameFactory()
  4973. * const instance = factory.createOpenDataFrame(options)
  4974. *
  4975. * containerEl.appendChild(instance.el)
  4976. * ```
  4977. */ function createOpenDataFrameFactory(params) {
  4978. const initOpenDataPromise = isWeCom ? initOpenData() : undefined;
  4979. let openSessionInjectorPromise = createSessionInjector();
  4980. async function createSessionInjector() {
  4981. if (!isWeCom) {
  4982. return;
  4983. }
  4984. try {
  4985. await initOpenDataPromise;
  4986. return createOpenSessionInjector({
  4987. url: BUSINESS_URL
  4988. });
  4989. } catch (error) {
  4990. safeRun(params?.onError, error);
  4991. safeRun(params?.handleError, error);
  4992. throw error;
  4993. }
  4994. }
  4995. async function injectOpenSession(iframe) {
  4996. if (!isWeCom) {
  4997. return;
  4998. }
  4999. const injectSession = await openSessionInjectorPromise;
  5000. if (injectSession) {
  5001. injectSession(iframe);
  5002. }
  5003. }
  5004. function createOpenDataFrame(options) {
  5005. if (!options.template) {
  5006. throw new Error('options.template is required');
  5007. }
  5008. const iframeEl = createTransparentIFrame(options.el);
  5009. const registerOpenFramePromise = initOpenDataPromise?.then(()=>win?.WWOpenData?.registerOpenFrame(iframeEl));
  5010. const { subscribe, handleMessage } = createMsgDispatcher();
  5011. const { invoke: invoke$1, dispose } = useIframeClient(iframeEl, FRAME_ORIGIN, handleMessage);
  5012. const publicInstance = {
  5013. el: iframeEl,
  5014. data: cloneDeep(options.data) || {},
  5015. setData,
  5016. dispose: disposeComponent,
  5017. ...options.methods
  5018. };
  5019. async function setData(partialData) {
  5020. patch(publicInstance.data, partialData, {
  5021. protectedKeys: PROTECTED_DATA_KEYS
  5022. });
  5023. await invoke$1({
  5024. type: 'update',
  5025. options: {
  5026. data: partialData
  5027. }
  5028. });
  5029. }
  5030. function disposeComponent() {
  5031. dispose();
  5032. registerOpenFramePromise?.then((iframeId)=>{
  5033. win?.WWOpenData?.unregisterOpenFrame(iframeId);
  5034. });
  5035. }
  5036. setPluginContext(publicInstance, {
  5037. frame: publicInstance,
  5038. invoke: invoke$1,
  5039. subscribe
  5040. });
  5041. iframeEl.src = BUSINESS_URL;
  5042. subscribe('init', async ()=>{
  5043. return {
  5044. id: isWeCom ? await registerOpenFramePromise : undefined,
  5045. hooks: getHookNames(options),
  5046. options: removeHooks({
  5047. ...options,
  5048. el: undefined,
  5049. methods: undefined,
  5050. data: publicInstance.data
  5051. }),
  5052. config: {
  5053. support: [
  5054. 'injectSession'
  5055. ]
  5056. }
  5057. };
  5058. });
  5059. subscribe('call', (msg)=>{
  5060. let base = options;
  5061. if (msg.kind === 'method') {
  5062. base = base.methods;
  5063. }
  5064. return handleCallMsg(msg, base, publicInstance);
  5065. });
  5066. subscribe('injectSession', async ()=>{
  5067. await injectOpenSession(iframeEl);
  5068. });
  5069. subscribe('refreshSession', async ()=>{
  5070. openSessionInjectorPromise = createSessionInjector();
  5071. await injectOpenSession(iframeEl);
  5072. });
  5073. subscribe('invokeJsapi', (msg)=>{
  5074. return invoke('wwapp.invokeJsApiByCallInfo', {
  5075. callInfo: msg.callInfo
  5076. });
  5077. });
  5078. subscribe('invokeDownload', (msg)=>{
  5079. if (!msg.url.startsWith('https://open.work.weixin.qq.com/')) {
  5080. throw new Error('Invalid download url');
  5081. }
  5082. const el = document.createElement('a');
  5083. el.href = msg.url;
  5084. el.target = '_blank';
  5085. el.style.display = 'none';
  5086. el.click();
  5087. });
  5088. subscribe('agentConfig', async ()=>{
  5089. const url = getSignURL();
  5090. return {
  5091. url,
  5092. params: await resolveAgentConfigParams(url)
  5093. };
  5094. });
  5095. subscribe('modal', async (msg)=>{
  5096. const defaultPreviewType = isWeCom ? 'wecom-window' : undefined;
  5097. if (typeof options.handleModal !== 'function') {
  5098. return {
  5099. modalType: defaultPreviewType
  5100. };
  5101. }
  5102. const res = options.handleModal({
  5103. modalUrl: msg.modalUrl,
  5104. modalSize: msg.modalSize
  5105. });
  5106. return {
  5107. modalType: res === false ? 'iframe' : defaultPreviewType
  5108. };
  5109. });
  5110. return publicInstance;
  5111. }
  5112. return {
  5113. /**
  5114. * 创建 open-data frame 组件
  5115. */ createOpenDataFrame
  5116. };
  5117. }
  5118. /**
  5119. * 显示确认安全网关配置页面。
  5120. *
  5121. * 在桌面端页面以 iframe 弹窗的形式覆盖在页面上;在移动端页面将跳转至确认页面,返回后页面需要主动确认 confirm_id 的确认情况。
  5122. */ function showSecurityGatewayConfirmModal(options) {
  5123. const url = new URL('https://open.work.weixin.qq.com/wwopen/secureGateway/confirm');
  5124. url.searchParams.set('confirm_id', options.confirmId);
  5125. if (isIOS || isAndroid) {
  5126. location.href = url.href;
  5127. return;
  5128. }
  5129. url.searchParams.set('modal', 'true');
  5130. const client = showModalFrame(url.href, (msg)=>{
  5131. switch(msg.type){
  5132. case 'call':
  5133. return handleCallMsg(msg, options);
  5134. case 'close':
  5135. return;
  5136. default:
  5137. throw new Error(`Unknown message type '${msg.type}'`);
  5138. }
  5139. });
  5140. return {
  5141. /**
  5142. * 弹窗面板的 iframe 元素
  5143. */ el: client.el,
  5144. /**
  5145. * 卸载弹窗面板
  5146. */ unmount () {
  5147. client.dispose();
  5148. client.el.parentNode?.removeChild(client.el);
  5149. }
  5150. };
  5151. }
  5152. const SDK_VERSION = "2.3.1";
  5153. var WWLoginType;
  5154. (function(WWLoginType) {
  5155. /**
  5156. * [第三方应用登录](#45846)
  5157. */ WWLoginType["serviceApp"] = "ServiceApp";
  5158. /**
  5159. * [企业自建应用登录](/document/path/98151)、[服务商代开发应用登录](/document/path/98173)
  5160. */ WWLoginType["corpApp"] = "CorpApp";
  5161. })(WWLoginType || (WWLoginType = {}));
  5162. var WWLoginLangType;
  5163. (function(WWLoginLangType) {
  5164. /**
  5165. * 中文
  5166. */ WWLoginLangType["zh"] = "zh";
  5167. /**
  5168. * 英文
  5169. */ WWLoginLangType["en"] = "en";
  5170. })(WWLoginLangType || (WWLoginLangType = {}));
  5171. var WWLoginRedirectType;
  5172. (function(WWLoginRedirectType) {
  5173. /**
  5174. * 默认 `top window` 顶层页面跳转
  5175. */ WWLoginRedirectType["top"] = "top";
  5176. /**
  5177. * 通过 `onLoginSuccess` 回调用户授权 `code`,开发者自行处理跳转
  5178. */ WWLoginRedirectType["callback"] = "callback";
  5179. /**
  5180. * 登录组件跳转
  5181. */ WWLoginRedirectType["self"] = "self";
  5182. })(WWLoginRedirectType || (WWLoginRedirectType = {}));
  5183. var WWLoginPanelSizeType;
  5184. (function(WWLoginPanelSizeType) {
  5185. /**
  5186. * 默认: 480x416px
  5187. */ WWLoginPanelSizeType["middle"] = "middle";
  5188. /**
  5189. * 小尺寸: 320x380px
  5190. */ WWLoginPanelSizeType["small"] = "small";
  5191. })(WWLoginPanelSizeType || (WWLoginPanelSizeType = {}));
  5192. const PANEL_SIZE = {
  5193. [WWLoginPanelSizeType.middle]: [
  5194. '480px',
  5195. '416px'
  5196. ],
  5197. [WWLoginPanelSizeType.small]: [
  5198. '320px',
  5199. '380px'
  5200. ]
  5201. };
  5202. /**
  5203. * 初始化企业微信Web登录组件,创建登录面板。
  5204. *
  5205. * @example
  5206. * ```ts
  5207. * // 初始化登录组件
  5208. * const wwLogin = ww.createWWLoginPanel({
  5209. * el: '#ww_login',
  5210. * params: {
  5211. * login_type: 'CorpApp',
  5212. * appid: 'wwbbb6a7b539f2xxxxx',
  5213. * agentid: '10000xx',
  5214. * redirect_uri: 'https://work.weixin.qq.com',
  5215. * state: 'loginState',
  5216. * redirect_type: 'callback',
  5217. * },
  5218. * onCheckWeComLogin({ isWeComLogin }) {
  5219. * console.log(isWeComLogin)
  5220. * },
  5221. * onLoginSuccess({ code }) {
  5222. * console.log({ code })
  5223. * },
  5224. * onLoginFail(err) {
  5225. * console.log(err)
  5226. * },
  5227. * })
  5228. * ```
  5229. */ function createWWLoginPanel(options) {
  5230. const { width, height } = getPanelSize(options.params?.panel_size);
  5231. const iframeEl = createTransparentIFrame(options.el);
  5232. const { style } = iframeEl;
  5233. style.width = width;
  5234. style.height = height;
  5235. const { dispose } = useIframeClient(iframeEl, 'https://login.work.weixin.qq.com', (msg)=>{
  5236. if (msg.type === 'call') {
  5237. return handleCallMsg(msg, options);
  5238. }
  5239. throw new Error(`Unknown message type '${msg.type}'`);
  5240. });
  5241. const url = new URL('https://login.work.weixin.qq.com/wwlogin/sso/login');
  5242. for (const key of Object.keys(options.params || {})){
  5243. url.searchParams.set(key, options.params[key]);
  5244. }
  5245. url.searchParams.set('version', SDK_VERSION);
  5246. iframeEl.src = url.href;
  5247. return {
  5248. el: iframeEl,
  5249. unmount () {
  5250. dispose();
  5251. iframeEl.parentNode?.removeChild(iframeEl);
  5252. }
  5253. };
  5254. }
  5255. function getPanelSize(panelSizeType = WWLoginPanelSizeType.middle) {
  5256. const size = PANEL_SIZE[panelSizeType] || PANEL_SIZE[WWLoginPanelSizeType.middle];
  5257. return {
  5258. width: size[0],
  5259. height: size[1]
  5260. };
  5261. }
  5262. function createSingleton(factory) {
  5263. const map = new WeakMap();
  5264. return (object, ...args)=>{
  5265. if (!map.has(object)) {
  5266. map.set(object, factory(object, ...args));
  5267. }
  5268. return map.get(object);
  5269. };
  5270. }
  5271. function createWeakRef(target) {
  5272. if (typeof WeakRef !== 'undefined') {
  5273. return new WeakRef(target);
  5274. }
  5275. return {
  5276. deref: ()=>target
  5277. };
  5278. }
  5279. function createPlugin(factory) {
  5280. return createSingleton((instance)=>{
  5281. const context = getPluginContext(instance);
  5282. if (!context) {
  5283. throw new TypeError('Illegal invocation');
  5284. }
  5285. return factory(context);
  5286. });
  5287. }
  5288. const useRefManager = createPlugin(({ frame, invoke, subscribe })=>{
  5289. const refid2refMap = new Map();
  5290. const refid2eventMap = new Map();
  5291. subscribe('ref.event', (msg)=>{
  5292. const subscribers = refid2eventMap.get(msg.refId);
  5293. if (!subscribers) {
  5294. return;
  5295. }
  5296. for (const fn of subscribers){
  5297. fn(msg.data);
  5298. }
  5299. });
  5300. subscribe('refDispose', (msg)=>{
  5301. refid2refMap.delete(msg.refId);
  5302. refid2eventMap.delete(msg.refId);
  5303. });
  5304. async function getRef(name) {
  5305. const res = await invoke({
  5306. type: 'ref.get',
  5307. name
  5308. });
  5309. if (!res) {
  5310. return;
  5311. }
  5312. const ref = refid2refMap.get(res.refId)?.deref();
  5313. if (ref) {
  5314. return ref;
  5315. }
  5316. const newRef = createRef(res.refId);
  5317. refid2refMap.set(res.refId, createWeakRef(newRef));
  5318. return newRef;
  5319. }
  5320. function createRef(refId) {
  5321. if (!refid2eventMap.has(refId)) {
  5322. refid2eventMap.set(refId, []);
  5323. }
  5324. const subscribers = refid2eventMap.get(refId);
  5325. function invokeRef(name, data, opts) {
  5326. return invoke({
  5327. type: 'ref.call',
  5328. refId,
  5329. name,
  5330. data
  5331. }, opts);
  5332. }
  5333. function subscribeRef(fn) {
  5334. subscribers.push(fn);
  5335. return ()=>{
  5336. const index = subscribers.indexOf(fn);
  5337. if (index >= 0) {
  5338. subscribers.splice(index, 1);
  5339. }
  5340. };
  5341. }
  5342. return {
  5343. frame,
  5344. invoke: invokeRef,
  5345. subscribe: subscribeRef
  5346. };
  5347. }
  5348. return {
  5349. get: getRef
  5350. };
  5351. });
  5352. function createSymbolKey(name) {
  5353. if (typeof Symbol === 'function') {
  5354. return Symbol(name);
  5355. }
  5356. return name;
  5357. }
  5358. /// <reference types="../../../types/arraybuffer.d.ts" />
  5359. const MIN_PAGE_SIZE = 64 * 1024;
  5360. const MAX_PAGE_SIZE = 1024 * 1024;
  5361. class BufferList {
  5362. concat() {
  5363. if (this.list.length === 1) {
  5364. return stabilizeBufferItem(this.current);
  5365. }
  5366. const result = new Uint8Array(this.list.reduce((total, item)=>total + item.offset, 0));
  5367. this.list.reduce((offset, item)=>{
  5368. result.set(new Uint8Array(stabilizeBufferItem(item)), offset);
  5369. return offset + item.offset;
  5370. }, 0);
  5371. return result.buffer;
  5372. }
  5373. ensureCapacity(size) {
  5374. const current = this.current;
  5375. const minNewSize = current.offset + size;
  5376. if (minNewSize <= current.size) {
  5377. return;
  5378. }
  5379. const buffer = current.buffer;
  5380. if (!buffer.resizable || minNewSize > buffer.maxByteLength) {
  5381. this.current = this.createBufferItem();
  5382. this.list.push(this.current);
  5383. } else {
  5384. current.size = Math.min(current.size * 2, buffer.maxByteLength);
  5385. buffer.resize(current.size);
  5386. }
  5387. }
  5388. createBufferItem() {
  5389. const buffer = new ArrayBuffer(MIN_PAGE_SIZE, {
  5390. maxByteLength: MAX_PAGE_SIZE
  5391. });
  5392. return {
  5393. view: new DataView(buffer),
  5394. buffer,
  5395. size: buffer.byteLength,
  5396. offset: 0
  5397. };
  5398. }
  5399. constructor(){
  5400. _define_property(this, "list", void 0);
  5401. _define_property(this, "current", void 0);
  5402. this.current = this.createBufferItem();
  5403. this.list = [
  5404. this.current
  5405. ];
  5406. }
  5407. }
  5408. function stabilizeBufferItem(item) {
  5409. if (item.offset >= item.size) {
  5410. return item.buffer;
  5411. }
  5412. if (item.buffer.resizable && item.buffer.transfer) {
  5413. return item.buffer.transfer(item.offset);
  5414. }
  5415. return item.buffer.slice(0, item.offset);
  5416. }
  5417. var VariantType;
  5418. (function(VariantType) {
  5419. VariantType[VariantType["int32"] = 1] = "int32";
  5420. VariantType[VariantType["float64"] = 2] = "float64";
  5421. VariantType[VariantType["boolean"] = 3] = "boolean";
  5422. VariantType[VariantType["null"] = 4] = "null";
  5423. VariantType[VariantType["undefined"] = 5] = "undefined";
  5424. VariantType[VariantType["valueRef"] = 6] = "valueRef";
  5425. })(VariantType || (VariantType = {}));
  5426. const MIN_INT32 = -Math.pow(2, 31);
  5427. const MAX_INT32 = Math.pow(2, 31);
  5428. function create() {
  5429. return {
  5430. buffer: new BufferList(),
  5431. values: [],
  5432. stringIndexMap: new Map()
  5433. };
  5434. }
  5435. function encode(state) {
  5436. return {
  5437. buffer: state.buffer.concat(),
  5438. values: state.values
  5439. };
  5440. }
  5441. function uint8(state, value) {
  5442. state.buffer.ensureCapacity(1);
  5443. const current = state.buffer.current;
  5444. current.view.setUint8(current.offset, value);
  5445. current.offset += 1;
  5446. }
  5447. function int32(state, value) {
  5448. state.buffer.ensureCapacity(4);
  5449. const current = state.buffer.current;
  5450. current.view.setInt32(current.offset, value);
  5451. current.offset += 4;
  5452. }
  5453. function uint32(state, value) {
  5454. state.buffer.ensureCapacity(4);
  5455. const current = state.buffer.current;
  5456. current.view.setUint32(current.offset, value);
  5457. current.offset += 4;
  5458. }
  5459. function float64(state, value) {
  5460. state.buffer.ensureCapacity(8);
  5461. const current = state.buffer.current;
  5462. current.view.setFloat64(current.offset, value);
  5463. current.offset += 8;
  5464. }
  5465. function string(state, value) {
  5466. let index = state.stringIndexMap.get(value);
  5467. if (!index) {
  5468. index = state.values.push(value);
  5469. state.stringIndexMap.set(value, index);
  5470. }
  5471. uint32(state, index - 1);
  5472. }
  5473. function unknown(state, value) {
  5474. uint32(state, state.values.push(value) - 1);
  5475. }
  5476. function variant(state, value) {
  5477. if (value === null) {
  5478. uint8(state, 4);
  5479. return;
  5480. }
  5481. switch(typeof value){
  5482. case 'number':
  5483. if (isInt32(value)) {
  5484. uint8(state, 1);
  5485. int32(state, value);
  5486. break;
  5487. }
  5488. uint8(state, 2);
  5489. float64(state, value);
  5490. break;
  5491. case 'string':
  5492. uint8(state, 6);
  5493. string(state, value);
  5494. break;
  5495. case 'boolean':
  5496. uint8(state, 3);
  5497. uint8(state, value ? 1 : 0);
  5498. break;
  5499. case 'undefined':
  5500. uint8(state, 5);
  5501. break;
  5502. default:
  5503. uint8(state, 6);
  5504. unknown(state, value);
  5505. break;
  5506. }
  5507. }
  5508. function isInt32(value) {
  5509. if (!Number.isInteger(value)) {
  5510. return false;
  5511. }
  5512. return MIN_INT32 <= value && value < MAX_INT32;
  5513. }
  5514. var CommandType;
  5515. (function(CommandType) {
  5516. CommandType[CommandType["set"] = 1] = "set";
  5517. CommandType[CommandType["call"] = 2] = "call";
  5518. CommandType[CommandType["dispose"] = 3] = "dispose";
  5519. })(CommandType || (CommandType = {}));
  5520. var ValueType;
  5521. (function(ValueType) {
  5522. ValueType[ValueType["value"] = 1] = "value";
  5523. ValueType[ValueType["ref"] = 2] = "ref";
  5524. })(ValueType || (ValueType = {}));
  5525. const KEY_REFLECT_ID = createSymbolKey('__WECOM_REFLECT_ID__');
  5526. const useReflectStore = createPlugin(({ invoke })=>{
  5527. const finalizationRegistry = typeof FinalizationRegistry === 'function' ? new FinalizationRegistry(cleanup) : null;
  5528. // WHY: weakSet.has(obj) + obj[key] 速度远快于 weakMap.get(obj)
  5529. const reflectObjectSet = new WeakSet();
  5530. let nextReflectId = 1;
  5531. const flushPromise = Promise.resolve();
  5532. let flushPending = false;
  5533. let writer = create();
  5534. function bind(obj, reflectId = genReflectId()) {
  5535. if (reflectObjectSet.has(obj)) {
  5536. return obj[KEY_REFLECT_ID];
  5537. }
  5538. obj[KEY_REFLECT_ID] = reflectId;
  5539. reflectObjectSet.add(obj);
  5540. finalizationRegistry?.register(obj, reflectId);
  5541. return reflectId;
  5542. }
  5543. function set(obj, name, value) {
  5544. const refId = obj[KEY_REFLECT_ID];
  5545. if (!refId) {
  5546. throw new TypeError('Illegal invocation');
  5547. }
  5548. uint8(writer, 1);
  5549. uint32(writer, refId);
  5550. string(writer, name);
  5551. writeCustomValue(value);
  5552. enqueueFlush();
  5553. }
  5554. function call(obj, name, args, result) {
  5555. const refId = obj[KEY_REFLECT_ID];
  5556. if (!refId) {
  5557. throw new TypeError('Illegal invocation');
  5558. }
  5559. uint8(writer, 2);
  5560. uint32(writer, refId);
  5561. string(writer, name);
  5562. uint32(writer, (result ? result[KEY_REFLECT_ID] : 0) ?? 0);
  5563. uint32(writer, args.length);
  5564. args.forEach(writeCustomValue);
  5565. enqueueFlush();
  5566. }
  5567. function cleanup(refId) {
  5568. uint8(writer, 3);
  5569. uint32(writer, refId);
  5570. enqueueFlush();
  5571. }
  5572. function writeCustomValue(value) {
  5573. if (reflectObjectSet.has(value)) {
  5574. uint8(writer, 2);
  5575. uint32(writer, value[KEY_REFLECT_ID]);
  5576. } else {
  5577. uint8(writer, 1);
  5578. variant(writer, value);
  5579. }
  5580. }
  5581. function enqueueFlush() {
  5582. if (flushPending) {
  5583. return;
  5584. }
  5585. flushPending = true;
  5586. flushPromise.then(flush);
  5587. }
  5588. function flush() {
  5589. flushPending = false;
  5590. const commands = encode(writer);
  5591. writer = create();
  5592. invoke({
  5593. type: 'reflect.command',
  5594. commands
  5595. }, {
  5596. serialize: false,
  5597. dropResult: true,
  5598. transfer: [
  5599. commands.buffer
  5600. ]
  5601. });
  5602. }
  5603. function genReflectId() {
  5604. return nextReflectId++;
  5605. }
  5606. return {
  5607. genReflectId,
  5608. bind,
  5609. set,
  5610. call
  5611. };
  5612. });
  5613. function _class_apply_descriptor_get(receiver, descriptor) {
  5614. if (descriptor.get) return descriptor.get.call(receiver);
  5615. return descriptor.value;
  5616. }
  5617. function _class_extract_field_descriptor(receiver, privateMap, action) {
  5618. if (!privateMap.has(receiver)) throw new TypeError("attempted to " + action + " private field on non-instance");
  5619. return privateMap.get(receiver);
  5620. }
  5621. function _class_private_field_get(receiver, privateMap) {
  5622. var descriptor = _class_extract_field_descriptor(receiver, privateMap, "get");
  5623. return _class_apply_descriptor_get(receiver, descriptor);
  5624. }
  5625. function _check_private_redeclaration(obj, privateCollection) {
  5626. if (privateCollection.has(obj)) {
  5627. throw new TypeError("Cannot initialize the same private elements twice on an object");
  5628. }
  5629. }
  5630. function _class_private_field_init(obj, privateMap, value) {
  5631. _check_private_redeclaration(obj, privateMap);
  5632. privateMap.set(obj, value);
  5633. }
  5634. function _class_apply_descriptor_set(receiver, descriptor, value) {
  5635. if (descriptor.set) descriptor.set.call(receiver, value);
  5636. else {
  5637. if (!descriptor.writable) {
  5638. // This should only throw in strict mode, but class bodies are
  5639. // always strict and private fields can only be used inside
  5640. // class bodies.
  5641. throw new TypeError("attempted to set read only private field");
  5642. }
  5643. descriptor.value = value;
  5644. }
  5645. }
  5646. function _class_private_field_set(receiver, privateMap, value) {
  5647. var descriptor = _class_extract_field_descriptor(receiver, privateMap, "set");
  5648. _class_apply_descriptor_set(receiver, descriptor, value);
  5649. return value;
  5650. }
  5651. const wrapper2NativeMap = new WeakMap();
  5652. const native2wrapperMap = new WeakMap();
  5653. function setNativeObject(wrapped, native) {
  5654. wrapper2NativeMap.set(wrapped, native);
  5655. native2wrapperMap.set(native, wrapped);
  5656. }
  5657. function toNativeValue(wrapped) {
  5658. if (wrapper2NativeMap.has(wrapped)) {
  5659. return wrapper2NativeMap.get(wrapped);
  5660. }
  5661. return wrapped;
  5662. }
  5663. function toWrappedValue(native) {
  5664. if (native2wrapperMap.has(native)) {
  5665. return native2wrapperMap.get(native);
  5666. }
  5667. return native;
  5668. }
  5669. const PLACEHOLDER_SRC = 'data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7';
  5670. let placeholderImage = null;
  5671. function getPlaceholderImage() {
  5672. if (!placeholderImage) {
  5673. placeholderImage = new Image();
  5674. placeholderImage.src = PLACEHOLDER_SRC;
  5675. }
  5676. return placeholderImage;
  5677. }
  5678. var _src = /*#__PURE__*/ new WeakMap(), _complete = /*#__PURE__*/ new WeakMap(), _error = /*#__PURE__*/ new WeakMap();
  5679. let _KEY_REFLECT_ID$3 = KEY_REFLECT_ID;
  5680. class ImageResource {
  5681. get src() {
  5682. return _class_private_field_get(this, _src);
  5683. }
  5684. get loading() {
  5685. return !_class_private_field_get(this, _complete);
  5686. }
  5687. get complete() {
  5688. return _class_private_field_get(this, _complete);
  5689. }
  5690. get error() {
  5691. return _class_private_field_get(this, _error);
  5692. }
  5693. __handleSettled(error) {
  5694. _class_private_field_set(this, _complete, true);
  5695. _class_private_field_set(this, _error, error);
  5696. if (error) {
  5697. safeRun(this.onerror, error);
  5698. } else {
  5699. safeRun(this.onload, undefined);
  5700. }
  5701. }
  5702. constructor(src){
  5703. _define_property(this, _KEY_REFLECT_ID$3, void 0);
  5704. _define_property(this, "onload", void 0);
  5705. _define_property(this, "onerror", void 0);
  5706. _class_private_field_init(this, _src, {
  5707. writable: true,
  5708. value: void 0
  5709. });
  5710. _class_private_field_init(this, _complete, {
  5711. writable: true,
  5712. value: false
  5713. });
  5714. _class_private_field_init(this, _error, {
  5715. writable: true,
  5716. value: void 0
  5717. });
  5718. _class_private_field_set(this, _src, src);
  5719. setNativeObject(this, getPlaceholderImage());
  5720. }
  5721. }
  5722. const useImageStore = createPlugin(({ frame, invoke, subscribe })=>{
  5723. const reflectStore = useReflectStore(frame);
  5724. const imageSettledHandlerMap = new Map();
  5725. function createImage(data, type) {
  5726. const res = new ImageResource(data);
  5727. const refId = reflectStore.bind(res);
  5728. invoke({
  5729. type: 'image.load',
  5730. refId,
  5731. data: getImageInfo(data, type)
  5732. }, {
  5733. serialize: typeof data === 'string'
  5734. });
  5735. imageSettledHandlerMap.set(refId, (msg)=>{
  5736. res.__handleSettled(msg.error);
  5737. });
  5738. return res;
  5739. }
  5740. function getImageInfo(data, mime) {
  5741. if (typeof data === 'string') {
  5742. return {
  5743. type: 'url',
  5744. src: data
  5745. };
  5746. }
  5747. return {
  5748. type: 'arraybuffer',
  5749. data,
  5750. mime
  5751. };
  5752. }
  5753. subscribe('image.settled', (msg)=>{
  5754. const handler = imageSettledHandlerMap.get(msg.refId);
  5755. imageSettledHandlerMap.delete(msg.refId);
  5756. if (handler) {
  5757. handler(msg);
  5758. }
  5759. });
  5760. return {
  5761. createImage
  5762. };
  5763. });
  5764. const useRefEventManager = createSingleton((ref)=>{
  5765. const listenerMap = new Map();
  5766. ref.subscribe((msg)=>{
  5767. if (msg.type !== 'event.trigger') {
  5768. return;
  5769. }
  5770. const listeners = listenerMap.get(`${msg.capture}|${msg.name}`);
  5771. if (!listeners?.size) {
  5772. return;
  5773. }
  5774. const event = createCustomEvent(msg.event);
  5775. for (const listener of Array.from(listeners)){
  5776. safeRun(listener, event);
  5777. }
  5778. });
  5779. function addListener(name, listener, options) {
  5780. const capture = typeof options === 'boolean' ? options : !!options?.capture;
  5781. if (!listenerMap.has(`${capture}|${name}`)) {
  5782. listenerMap.set(`${capture}|${name}`, new Set());
  5783. }
  5784. const listeners = listenerMap.get(`${capture}|${name}`);
  5785. if (!listeners.size) {
  5786. ref.invoke('event.subscribe', {
  5787. name,
  5788. capture
  5789. });
  5790. }
  5791. listeners.add(listener);
  5792. }
  5793. function removeListener(name, listener, options) {
  5794. const capture = typeof options === 'boolean' ? options : !!options?.capture;
  5795. if (!listenerMap.has(`${capture}|${name}`)) {
  5796. return;
  5797. }
  5798. const listeners = listenerMap.get(`${capture}|${name}`);
  5799. listeners.delete(listener);
  5800. if (!listeners.size) {
  5801. ref.invoke('event.unsubscribe', {
  5802. name,
  5803. capture
  5804. });
  5805. }
  5806. }
  5807. return {
  5808. addListener,
  5809. removeListener
  5810. };
  5811. });
  5812. function createCustomEvent(info) {
  5813. const event = new CustomEvent(info.type, {
  5814. detail: info.detail
  5815. });
  5816. for (const key of Object.keys(info)){
  5817. if (!(key in event)) {
  5818. event[key] = info[key];
  5819. }
  5820. }
  5821. Object.defineProperties(event, {
  5822. target: {
  5823. value: info.target
  5824. },
  5825. currentTarget: {
  5826. value: info.currentTarget
  5827. }
  5828. });
  5829. return event;
  5830. }
  5831. var _store$1 = /*#__PURE__*/ new WeakMap(), _native$1 = /*#__PURE__*/ new WeakMap();
  5832. let _KEY_REFLECT_ID$2 = KEY_REFLECT_ID;
  5833. class FrameCanvasPattern {
  5834. setTransform(matrix) {
  5835. _class_private_field_get(this, _native$1).setTransform(matrix);
  5836. _class_private_field_get(this, _store$1).call(this, 'setTransform', [
  5837. matrix
  5838. ]);
  5839. }
  5840. constructor(store, native){
  5841. _define_property(this, _KEY_REFLECT_ID$2, void 0);
  5842. _class_private_field_init(this, _store$1, {
  5843. writable: true,
  5844. value: void 0
  5845. });
  5846. _class_private_field_init(this, _native$1, {
  5847. writable: true,
  5848. value: void 0
  5849. });
  5850. _class_private_field_set(this, _store$1, store);
  5851. _class_private_field_set(this, _native$1, native);
  5852. store.bind(this);
  5853. setNativeObject(this, native);
  5854. }
  5855. }
  5856. var _store1 = /*#__PURE__*/ new WeakMap(), _native1 = /*#__PURE__*/ new WeakMap();
  5857. let _KEY_REFLECT_ID1 = KEY_REFLECT_ID;
  5858. class FrameCanvasGradient {
  5859. addColorStop(offset, color) {
  5860. _class_private_field_get(this, _native1).addColorStop(offset, color);
  5861. _class_private_field_get(this, _store1).call(this, 'addColorStop', [
  5862. offset,
  5863. color
  5864. ]);
  5865. }
  5866. constructor(store, native){
  5867. _define_property(this, _KEY_REFLECT_ID1, void 0);
  5868. _class_private_field_init(this, _store1, {
  5869. writable: true,
  5870. value: void 0
  5871. });
  5872. _class_private_field_init(this, _native1, {
  5873. writable: true,
  5874. value: void 0
  5875. });
  5876. _class_private_field_set(this, _store1, store);
  5877. _class_private_field_set(this, _native1, native);
  5878. store.bind(this);
  5879. setNativeObject(this, native);
  5880. }
  5881. }
  5882. /**
  5883. * 纯样式属性
  5884. *
  5885. * 修改这些属性不会改变 CANVAS_LOCAL_METHODS 的表现,因此无需映射到 native object
  5886. */ const CANVAS_STYLE_PROPS = [
  5887. 'fillStyle',
  5888. 'filter',
  5889. 'globalAlpha',
  5890. 'globalCompositeOperation',
  5891. 'imageSmoothingEnabled',
  5892. 'imageSmoothingQuality',
  5893. 'shadowBlur',
  5894. 'shadowColor',
  5895. 'shadowOffsetX',
  5896. 'shadowOffsetY',
  5897. 'strokeStyle'
  5898. ];
  5899. const CANVAS_CONFIG_PROPS = [
  5900. 'direction',
  5901. 'font',
  5902. 'fontKerning',
  5903. 'fontStretch',
  5904. 'fontVariantCaps',
  5905. 'letterSpacing',
  5906. 'lineCap',
  5907. 'lineDashOffset',
  5908. 'lineJoin',
  5909. 'lineWidth',
  5910. 'miterLimit',
  5911. 'textAlign',
  5912. 'textBaseline',
  5913. 'textRendering',
  5914. 'wordSpacing'
  5915. ];
  5916. const CANVAS_CONFIG_METHODS = [
  5917. 'arc',
  5918. 'arcTo',
  5919. 'beginPath',
  5920. 'bezierCurveTo',
  5921. 'clip',
  5922. 'closePath',
  5923. 'ellipse',
  5924. 'lineTo',
  5925. 'moveTo',
  5926. 'quadraticCurveTo',
  5927. 'rect',
  5928. 'reset',
  5929. 'resetTransform',
  5930. 'restore',
  5931. 'rotate',
  5932. 'roundRect',
  5933. 'save',
  5934. 'scale',
  5935. 'setLineDash',
  5936. 'setTransform',
  5937. 'transform',
  5938. 'translate'
  5939. ];
  5940. const CANVAS_DRAW_METHODS = [
  5941. 'clearRect',
  5942. 'drawFocusIfNeeded',
  5943. 'drawImage',
  5944. 'fill',
  5945. 'fillRect',
  5946. 'fillText',
  5947. 'stroke',
  5948. 'strokeRect',
  5949. 'strokeText'
  5950. ];
  5951. const CANVAS_LOCAL_METHODS = [
  5952. 'getContextAttributes',
  5953. 'getLineDash',
  5954. 'getTransform',
  5955. 'isContextLost',
  5956. 'isPointInPath',
  5957. 'isPointInStroke',
  5958. 'measureText'
  5959. ];
  5960. const CANVAS_FACTORY_METHODS = [
  5961. [
  5962. 'createConicGradient',
  5963. FrameCanvasGradient
  5964. ],
  5965. [
  5966. 'createLinearGradient',
  5967. FrameCanvasGradient
  5968. ],
  5969. [
  5970. 'createPattern',
  5971. FrameCanvasPattern
  5972. ],
  5973. [
  5974. 'createRadialGradient',
  5975. FrameCanvasGradient
  5976. ]
  5977. ];
  5978. const KEY_INTERNAL = createSymbolKey('__WECOM_INTERNAL__');
  5979. const createFrameContext = createSingleton((canvas, store, native)=>new FrameCanvasRenderingContext2D(canvas, store, native));
  5980. let _KEY_INTERNAL = KEY_INTERNAL, _KEY_REFLECT_ID$1 = KEY_REFLECT_ID;
  5981. class FrameCanvasRenderingContext2D {
  5982. constructor(canvas, store, native){
  5983. _define_property(this, "canvas", void 0);
  5984. _define_property(this, _KEY_INTERNAL, void 0);
  5985. _define_property(this, _KEY_REFLECT_ID$1, void 0);
  5986. this.canvas = canvas;
  5987. this[KEY_INTERNAL] = {
  5988. store,
  5989. native,
  5990. props: Object.create(null)
  5991. };
  5992. store.bind(this);
  5993. setNativeObject(this, native);
  5994. }
  5995. }
  5996. const FrameContextProto = FrameCanvasRenderingContext2D.prototype;
  5997. for (const name of CANVAS_STYLE_PROPS){
  5998. Object.defineProperty(FrameContextProto, name, {
  5999. configurable: true,
  6000. enumerable: true,
  6001. get () {
  6002. const { native, props } = this[KEY_INTERNAL];
  6003. return props[name] ?? toWrappedValue(native[name]);
  6004. },
  6005. set (value) {
  6006. const { store, props } = this[KEY_INTERNAL];
  6007. props[name] = toNativeValue(value);
  6008. store.set(this, name, value);
  6009. }
  6010. });
  6011. }
  6012. for (const name of CANVAS_CONFIG_PROPS){
  6013. Object.defineProperty(FrameContextProto, name, {
  6014. configurable: true,
  6015. enumerable: true,
  6016. get () {
  6017. return toWrappedValue(this[KEY_INTERNAL].native[name]);
  6018. },
  6019. set (value) {
  6020. const { store, native } = this[KEY_INTERNAL];
  6021. native[name] = toNativeValue(value);
  6022. store.set(this, name, value);
  6023. }
  6024. });
  6025. }
  6026. for (const name of CANVAS_LOCAL_METHODS){
  6027. FrameContextProto[name] = function(...args) {
  6028. const { native } = this[KEY_INTERNAL];
  6029. return callNative(native, name, args);
  6030. };
  6031. }
  6032. for (const name of CANVAS_CONFIG_METHODS){
  6033. FrameContextProto[name] = function(...args) {
  6034. const { store, native } = this[KEY_INTERNAL];
  6035. callNative(native, name, args);
  6036. store.call(this, name, args);
  6037. };
  6038. }
  6039. for (const name of CANVAS_DRAW_METHODS){
  6040. FrameContextProto[name] = function(...args) {
  6041. const { store } = this[KEY_INTERNAL];
  6042. store.call(this, name, args);
  6043. };
  6044. }
  6045. for (const [name, Ctor] of CANVAS_FACTORY_METHODS){
  6046. FrameContextProto[name] = function(...args) {
  6047. const { store, native } = this[KEY_INTERNAL];
  6048. const nativeRes = callNative(native, name, args);
  6049. const frameRes = new Ctor(store, nativeRes);
  6050. store.call(this, name, args, frameRes);
  6051. return frameRes;
  6052. };
  6053. }
  6054. function callNative(native, name, args) {
  6055. switch(args.length){
  6056. case 1:
  6057. return native[name](args[0]);
  6058. case 2:
  6059. return native[name](args[0], args[1]);
  6060. case 3:
  6061. return native[name](args[0], args[1], args[2]);
  6062. case 4:
  6063. return native[name](args[0], args[1], args[2], args[3]);
  6064. case 5:
  6065. return native[name](args[0], args[1], args[2], args[3], args[4]);
  6066. case 6:
  6067. return native[name](args[0], args[1], args[2], args[3], args[4], args[5]);
  6068. default:
  6069. return native[name](...args);
  6070. }
  6071. }
  6072. var _native = /*#__PURE__*/ new WeakMap(), _store = /*#__PURE__*/ new WeakMap(), _imageStore = /*#__PURE__*/ new WeakMap(), _refEvent = /*#__PURE__*/ new WeakMap(), _context = /*#__PURE__*/ new WeakMap();
  6073. let _KEY_REFLECT_ID = KEY_REFLECT_ID;
  6074. class FrameCanvas {
  6075. /**
  6076. * canvas 元素宽度
  6077. */ get width() {
  6078. return _class_private_field_get(this, _native).width;
  6079. }
  6080. set width(value) {
  6081. _class_private_field_get(this, _native).width = value;
  6082. _class_private_field_get(this, _store).set(this, 'width', value);
  6083. }
  6084. /**
  6085. * canvas 元素高度
  6086. */ get height() {
  6087. return _class_private_field_get(this, _native).height;
  6088. }
  6089. set height(value) {
  6090. _class_private_field_get(this, _native).height = value;
  6091. _class_private_field_get(this, _store).set(this, 'height', value);
  6092. }
  6093. createImage(data, type) {
  6094. return _class_private_field_get(this, _imageStore).createImage(data, type);
  6095. }
  6096. /**
  6097. * 获取 canvas 的上下文
  6098. *
  6099. * @param type 上下文类型,目前只支持 2d
  6100. * @param attrs 渲染上下文配置
  6101. */ getContext(type, attrs) {
  6102. if (type !== '2d') {
  6103. throw new Error(`Failed to execute 'getContext' on 'FrameCanvas': The provided value '${type}' is not a valid enum value of type RenderingContextType`);
  6104. }
  6105. if (_class_private_field_get(this, _context)) {
  6106. return _class_private_field_get(this, _context);
  6107. }
  6108. const nativeContext = _class_private_field_get(this, _native).getContext(type, attrs);
  6109. _class_private_field_set(this, _context, createFrameContext(this, _class_private_field_get(this, _store), nativeContext));
  6110. _class_private_field_get(this, _store).call(this, 'getContext', [
  6111. type,
  6112. attrs
  6113. ], _class_private_field_get(this, _context));
  6114. return _class_private_field_get(this, _context);
  6115. }
  6116. addEventListener(type, listener, options) {
  6117. _class_private_field_get(this, _refEvent).addListener(type, listener, options);
  6118. }
  6119. removeEventListener(type, listener, options) {
  6120. _class_private_field_get(this, _refEvent).removeListener(type, listener, options);
  6121. }
  6122. constructor(ref, refId, info){
  6123. /** @internal */ _define_property(this, _KEY_REFLECT_ID, void 0);
  6124. _class_private_field_init(this, _native, {
  6125. writable: true,
  6126. value: void 0
  6127. });
  6128. _class_private_field_init(this, _store, {
  6129. writable: true,
  6130. value: void 0
  6131. });
  6132. _class_private_field_init(this, _imageStore, {
  6133. writable: true,
  6134. value: void 0
  6135. });
  6136. _class_private_field_init(this, _refEvent, {
  6137. writable: true,
  6138. value: void 0
  6139. });
  6140. _class_private_field_init(this, _context, {
  6141. writable: true,
  6142. value: void 0
  6143. });
  6144. _class_private_field_set(this, _native, new OffscreenCanvas(info.width, info.height));
  6145. _class_private_field_set(this, _store, useReflectStore(ref.frame));
  6146. _class_private_field_get(this, _store).bind(this, refId);
  6147. _class_private_field_set(this, _imageStore, useImageStore(ref.frame));
  6148. _class_private_field_set(this, _refEvent, useRefEventManager(ref));
  6149. setNativeObject(this, _class_private_field_get(this, _native));
  6150. }
  6151. }
  6152. const ref2canvasMap = new WeakMap();
  6153. const getCanvasId = createSingleton((ref)=>{
  6154. const { genReflectId } = useReflectStore(ref.frame);
  6155. return genReflectId();
  6156. });
  6157. /**
  6158. * 获取 open-data frame 组件内的 canvas 元素。
  6159. *
  6160. * @param instance open-data frame 组件实例
  6161. * @param refName 模板引用名称
  6162. *
  6163. * @example
  6164. * ```ts
  6165. * const canvas = await ww.getCanvas(frame, 'canvas')
  6166. * const context = canvas.getContext('2d')
  6167. * ```
  6168. */ async function getCanvas(instance, refName) {
  6169. const { get: getRef } = useRefManager(instance);
  6170. const ref = await getRef(refName);
  6171. if (!ref) {
  6172. return;
  6173. }
  6174. if (ref2canvasMap.has(ref)) {
  6175. return ref2canvasMap.get(ref);
  6176. }
  6177. const refId = getCanvasId(ref);
  6178. const info = await ref.invoke('bind', {
  6179. refId
  6180. });
  6181. if (!info) {
  6182. return;
  6183. }
  6184. if (!ref2canvasMap.has(ref)) {
  6185. ref2canvasMap.set(ref, new FrameCanvas(ref, refId, info));
  6186. }
  6187. return ref2canvasMap.get(ref);
  6188. }
  6189. const getScrollViewContext = createSingleton((ref)=>{
  6190. return {
  6191. scrollTo (options) {
  6192. ref.invoke('scrollTo', options);
  6193. },
  6194. scrollIntoView (selector, options) {
  6195. ref.invoke('scrollIntoView', {
  6196. selector,
  6197. options
  6198. });
  6199. }
  6200. };
  6201. });
  6202. /**
  6203. * 创建 open-data frame 组件内指定 scroll-view 元素的上下文。
  6204. *
  6205. * @param instance open-data frame 组件实例
  6206. * @param refName 模板引用名称
  6207. *
  6208. * @example
  6209. * ```ts
  6210. * const scrollView = await ww.createScrollViewContext(instance, 'scroll-view')
  6211. *
  6212. * scrollView.scrollTo({ top: 100 })
  6213. * ```
  6214. */ async function createScrollViewContext(instance, refName) {
  6215. const { get: getRef } = useRefManager(instance);
  6216. const ref = await getRef(refName);
  6217. if (!ref) {
  6218. return;
  6219. }
  6220. return getScrollViewContext(ref);
  6221. }
  6222. /**
  6223. * 获取节点的相关信息
  6224. *
  6225. * @param instance open-data frame 组件实例
  6226. * @param refName 模板引用名称
  6227. * @param fields 需要获取的字段
  6228. *
  6229. * @example
  6230. * ```ts
  6231. * ww.getNodeInfo(instance, 'node-ref')
  6232. * ```
  6233. */ async function getNodeInfo(instance, refName, fields) {
  6234. const { get: getRef } = useRefManager(instance);
  6235. const ref = await getRef(refName);
  6236. if (!ref) {
  6237. return;
  6238. }
  6239. return ref.invoke('nodeInfo.get', {
  6240. fields
  6241. });
  6242. }
  6243. /**
  6244. * From https://gist.github.com/schacon/12703
  6245. */ function hex_sha1(s) {
  6246. return rstr2hex(rstr_sha1(s));
  6247. }
  6248. /**
  6249. * Calculate the SHA1 of a raw string
  6250. */ function rstr_sha1(s) {
  6251. return binb2rstr(binb_sha1(rstr2binb(s), s.length * 8));
  6252. }
  6253. /**
  6254. * Convert a raw string to a hex string
  6255. */ function rstr2hex(input) {
  6256. const hex_tab = '0123456789abcdef';
  6257. let output = '';
  6258. let x;
  6259. for(let i = 0; i < input.length; i++){
  6260. x = input.charCodeAt(i);
  6261. output += hex_tab.charAt(x >>> 4 & 0x0f) + hex_tab.charAt(x & 0x0f);
  6262. }
  6263. return output;
  6264. }
  6265. /**
  6266. * Convert a raw string to an array of big-endian words
  6267. * Characters >255 have their high-byte silently ignored.
  6268. */ function rstr2binb(input) {
  6269. const output = new Array(input.length >> 2);
  6270. for(let i = 0; i < output.length; i++)output[i] = 0;
  6271. for(let i = 0; i < input.length * 8; i += 8)output[i >> 5] |= (input.charCodeAt(i / 8) & 0xff) << 24 - i % 32;
  6272. return output;
  6273. }
  6274. /**
  6275. * Convert an array of little-endian words to a string
  6276. */ function binb2rstr(input) {
  6277. let output = '';
  6278. for(let i = 0; i < input.length * 32; i += 8)output += String.fromCharCode(input[i >> 5] >>> 24 - i % 32 & 0xff);
  6279. return output;
  6280. }
  6281. /**
  6282. * Calculate the SHA-1 of an array of big-endian words, and a bit length
  6283. */ function binb_sha1(x, len) {
  6284. /* append padding */ x[len >> 5] |= 0x80 << 24 - len % 32;
  6285. x[(len + 64 >> 9 << 4) + 15] = len;
  6286. const w = new Array(80);
  6287. let a = 1732584193;
  6288. let b = -271733879;
  6289. let c = -1732584194;
  6290. let d = 271733878;
  6291. let e = -1009589776;
  6292. for(let i = 0; i < x.length; i += 16){
  6293. const olda = a;
  6294. const oldb = b;
  6295. const oldc = c;
  6296. const oldd = d;
  6297. const olde = e;
  6298. for(let j = 0; j < 80; j++){
  6299. if (j < 16) w[j] = x[i + j];
  6300. else w[j] = bit_rol(w[j - 3] ^ w[j - 8] ^ w[j - 14] ^ w[j - 16], 1);
  6301. const t = safe_add(safe_add(bit_rol(a, 5), sha1_ft(j, b, c, d)), safe_add(safe_add(e, w[j]), sha1_kt(j)));
  6302. e = d;
  6303. d = c;
  6304. c = bit_rol(b, 30);
  6305. b = a;
  6306. a = t;
  6307. }
  6308. a = safe_add(a, olda);
  6309. b = safe_add(b, oldb);
  6310. c = safe_add(c, oldc);
  6311. d = safe_add(d, oldd);
  6312. e = safe_add(e, olde);
  6313. }
  6314. return [
  6315. a,
  6316. b,
  6317. c,
  6318. d,
  6319. e
  6320. ];
  6321. }
  6322. /**
  6323. * Perform the appropriate triplet combination function for the current
  6324. * iteration
  6325. */ function sha1_ft(t, b, c, d) {
  6326. if (t < 20) return b & c | ~b & d;
  6327. if (t < 40) return b ^ c ^ d;
  6328. if (t < 60) return b & c | b & d | c & d;
  6329. return b ^ c ^ d;
  6330. }
  6331. /**
  6332. * Determine the appropriate additive constant for the current iteration
  6333. */ function sha1_kt(t) {
  6334. return t < 20 ? 1518500249 : t < 40 ? 1859775393 : t < 60 ? -1894007588 : -899497514;
  6335. }
  6336. /**
  6337. * Add integers, wrapping at 2^32. This uses 16-bit operations internally
  6338. * to work around bugs in some JS interpreters.
  6339. */ function safe_add(x, y) {
  6340. const lsw = (x & 0xffff) + (y & 0xffff);
  6341. const msw = (x >> 16) + (y >> 16) + (lsw >> 16);
  6342. return msw << 16 | lsw & 0xffff;
  6343. }
  6344. /**
  6345. * Bitwise rotate a 32-bit number to the left.
  6346. */ function bit_rol(num, cnt) {
  6347. return num << cnt | num >>> 32 - cnt;
  6348. }
  6349. function getSignature(options) {
  6350. let normalized = options;
  6351. if (typeof options === 'string') {
  6352. normalized = {
  6353. ticket: options
  6354. };
  6355. }
  6356. const nonceStr = normalized.nonceStr || random();
  6357. const timestamp = normalized.timestamp || Math.floor(Date.now() / 1000);
  6358. const url = normalized.url || getHref().split('#')[0];
  6359. const ticket = normalized.ticket;
  6360. const signature = hex_sha1(`jsapi_ticket=${ticket}&noncestr=${nonceStr}&timestamp=${timestamp}&url=${url}`);
  6361. return {
  6362. timestamp,
  6363. nonceStr,
  6364. signature
  6365. };
  6366. }
  6367. const env = {
  6368. isWeChat,
  6369. isWeCom
  6370. };
  6371. const IS_WECOM_SDK = true;
  6372. export { CameraMode, ChooseMessageFileType, CreateExternalPaymentType, EntryType, EnvVersion, FrameCanvas, IS_WECOM_SDK, InTalkType, InputCorpGroupContactMode, InputCorpGroupContactType, LiveType, LocationType, NetworkType, OAType, OaExtDataType, OpenAppManagePageType, OpenUserProfileType, PrintFileIdType, ProductViewType, Proximity, SDK_VERSION, ScanQRCodeType, SelectEnterpriseContactMode, SelectEnterpriseContactType, SelectExternalContactType, SelectPrivilegedContactMode, SizeType, SourceType, TempFileType, WWLoginLangType, WWLoginPanelSizeType, WWLoginRedirectType, WWLoginType, WedocSelectedFileType, addCard, addDevice, checkJsApi, checkSchedule, chooseCard, chooseImage, chooseInvoice, chooseMessageFile, chooseWXPay, claimClassAdmin, closeBLEConnection, closeBluetoothAdapter, closeWindow, connectWifi, consumeAndShareCard, createBLEConnection, createChatWithMsg, createCorpGroupChat, createDoc, createExternalPayment, createJSAPIPanel, createOpenDataFrameFactory, createSchoolPayment, createScrollViewContext, createWWLoginPanel, discoverDevice, downloadImage, downloadLivingReplay, downloadVoice, ensureAgentConfigReady, ensureConfigReady, ensureCorpConfigReady, enterHWOpenTalk, enterpriseVerify, env, getApprovalSelectedItems, getBLEDeviceCharacteristics, getBLEDeviceServices, getBeacons, getBluetoothAdapterState, getBluetoothDevices, getCanvas, getClipboardData, getConnectedBluetoothDevices, getConnectedWifi, getContext, getCurCorpGroupChat, getCurCorpGroupContact, getCurExternalChat, getCurExternalContact, getLocalFileData, getLocalImgData, getLocation, getNetworkType, getNodeInfo, getShareInfo, getSignature, getVerifyParams, getWifiList, hideAllNonBaseMenuItem, hideChatAttachmentMenu, hideMenuItems, hideOptionMenu, initOpenData, invoke, isWeixinJSBridgeReady, launchMiniprogram, navigateToAddCustomer, navigateToKfChat, notifyBLECharacteristicValueChange, on, onBLECharacteristicValueChange, onBLEConnectionStateChange, onBeaconServiceChange, onBeaconUpdate, onBluetoothAdapterStateChange, onBluetoothDeviceFound, onGetWifiList, onHistoryBack, onLocationChange, onMenuShareAppMessage, onMenuShareQQ, onMenuShareQZone, onMenuShareTimeline, onMenuShareWechat, onMenuShareWeibo, onNetworkStatusChange, onSearchBeacons, onUserCaptureScreen, onVoicePlayEnd, onVoiceRecordEnd, onWeixinJSBridgeReady, onWifiConnected, openAddress, openAppComment, openAppDeviceDataAuth, openAppManage, openAppPurchase, openBluetoothAdapter, openBusinessView, openCard, openDefaultBrowser, openDeviceProfile, openEnterpriseChat, openEnterpriseRedPacket, openExistedChatWithMsg, openLocation, openProductSpecificView, openThirdAppServiceChat, openUserProfile, pauseVoice, playVoice, previewFile, previewImage, printFile, queryCurrHWOpenTalk, readBLECharacteristicValue, refundExternalPayment, register, replayLiving, saveApprovalSelectedItems, scanQRCode, selectCorpGroupContact, selectEnterpriseContact, selectExternalContact, selectPrivilegedContact, sendChatMessage, setClipboardData, setKeepScreenOn, setShareAttr, shareAppMessage, shareToExternalChat, shareToExternalContact, shareToExternalMoments, shareWechatMessage, showAllNonBaseMenuItem, showMenuItems, showOptionMenu, showSecurityGatewayConfirmModal, startAutoLBS, startBeaconDiscovery, startBluetoothDevicesDiscovery, startLiving, startMeeting, startRecord, startSearchBeacons, startWecast, startWifi, stopAutoLBS, stopBeaconDiscovery, stopBluetoothDevicesDiscovery, stopRecord, stopSearchBeacons, stopVoice, stopWifi, thirdPartyOpenPage, translateVoice, updateAppMessageShareData, updateCorpGroupChat, updateEnterpriseChat, updateMomentsSetting, updateTimelineShareData, uploadImage, uploadVoice, wedocSelectDoc, wedriveSelectDir, wedriveSelectFile, wedriveSelectFileForDownload, wedriveSelectFileForShare, writeBLECharacteristicValue };