xe-utils.umd.js 112 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276227722782279228022812282228322842285228622872288228922902291229222932294229522962297229822992300230123022303230423052306230723082309231023112312231323142315231623172318231923202321232223232324232523262327232823292330233123322333233423352336233723382339234023412342234323442345234623472348234923502351235223532354235523562357235823592360236123622363236423652366236723682369237023712372237323742375237623772378237923802381238223832384238523862387238823892390239123922393239423952396239723982399240024012402240324042405240624072408240924102411241224132414241524162417241824192420242124222423242424252426242724282429243024312432243324342435243624372438243924402441244224432444244524462447244824492450245124522453245424552456245724582459246024612462246324642465246624672468246924702471247224732474247524762477247824792480248124822483248424852486248724882489249024912492249324942495249624972498249925002501250225032504250525062507250825092510251125122513251425152516251725182519252025212522252325242525252625272528252925302531253225332534253525362537253825392540254125422543254425452546254725482549255025512552255325542555255625572558255925602561256225632564256525662567256825692570257125722573257425752576257725782579258025812582258325842585258625872588258925902591259225932594259525962597259825992600260126022603260426052606260726082609261026112612261326142615261626172618261926202621262226232624262526262627262826292630263126322633263426352636263726382639264026412642264326442645264626472648264926502651265226532654265526562657265826592660266126622663266426652666266726682669267026712672267326742675267626772678267926802681268226832684268526862687268826892690269126922693269426952696269726982699270027012702270327042705270627072708270927102711271227132714271527162717271827192720272127222723272427252726272727282729273027312732273327342735273627372738273927402741274227432744274527462747274827492750275127522753275427552756275727582759276027612762276327642765276627672768276927702771277227732774277527762777277827792780278127822783278427852786278727882789279027912792279327942795279627972798279928002801280228032804280528062807280828092810281128122813281428152816281728182819282028212822282328242825282628272828282928302831283228332834283528362837283828392840284128422843284428452846284728482849285028512852285328542855285628572858285928602861286228632864286528662867286828692870287128722873287428752876287728782879288028812882288328842885288628872888288928902891289228932894289528962897289828992900290129022903290429052906290729082909291029112912291329142915291629172918291929202921292229232924292529262927292829292930293129322933293429352936293729382939294029412942294329442945294629472948294929502951295229532954295529562957295829592960296129622963296429652966296729682969297029712972297329742975297629772978297929802981298229832984298529862987298829892990299129922993299429952996299729982999300030013002300330043005300630073008300930103011301230133014301530163017301830193020302130223023302430253026302730283029303030313032303330343035303630373038303930403041304230433044304530463047304830493050305130523053305430553056305730583059306030613062306330643065306630673068306930703071307230733074307530763077307830793080308130823083308430853086308730883089309030913092309330943095309630973098309931003101310231033104310531063107310831093110311131123113311431153116311731183119312031213122312331243125312631273128312931303131313231333134313531363137313831393140314131423143314431453146314731483149315031513152315331543155315631573158315931603161316231633164316531663167316831693170317131723173317431753176317731783179318031813182318331843185318631873188318931903191319231933194319531963197319831993200320132023203320432053206320732083209321032113212321332143215321632173218321932203221322232233224322532263227322832293230323132323233323432353236323732383239324032413242324332443245324632473248324932503251325232533254325532563257325832593260326132623263326432653266326732683269327032713272327332743275327632773278327932803281328232833284328532863287328832893290329132923293329432953296329732983299330033013302330333043305330633073308330933103311331233133314331533163317331833193320332133223323332433253326332733283329333033313332333333343335333633373338333933403341334233433344334533463347334833493350335133523353335433553356335733583359336033613362336333643365336633673368336933703371337233733374337533763377337833793380338133823383338433853386338733883389339033913392339333943395339633973398339934003401340234033404340534063407340834093410341134123413341434153416341734183419342034213422342334243425342634273428342934303431343234333434343534363437343834393440344134423443344434453446344734483449345034513452345334543455345634573458345934603461346234633464346534663467346834693470347134723473347434753476347734783479348034813482348334843485348634873488348934903491349234933494349534963497349834993500350135023503350435053506350735083509351035113512351335143515351635173518351935203521352235233524352535263527352835293530353135323533353435353536353735383539354035413542354335443545354635473548354935503551355235533554355535563557355835593560356135623563356435653566356735683569357035713572357335743575357635773578357935803581358235833584358535863587358835893590359135923593359435953596359735983599360036013602360336043605360636073608360936103611361236133614361536163617361836193620362136223623362436253626362736283629363036313632363336343635363636373638363936403641364236433644364536463647364836493650365136523653365436553656365736583659366036613662366336643665366636673668366936703671367236733674367536763677367836793680368136823683368436853686368736883689369036913692369336943695369636973698369937003701370237033704370537063707370837093710371137123713371437153716371737183719372037213722372337243725372637273728372937303731373237333734373537363737373837393740374137423743374437453746374737483749375037513752375337543755375637573758375937603761376237633764376537663767376837693770377137723773377437753776377737783779378037813782378337843785378637873788378937903791379237933794379537963797379837993800380138023803380438053806380738083809381038113812381338143815381638173818381938203821382238233824382538263827382838293830383138323833383438353836383738383839384038413842384338443845384638473848384938503851385238533854385538563857385838593860386138623863386438653866386738683869387038713872387338743875387638773878387938803881388238833884388538863887388838893890389138923893389438953896389738983899390039013902390339043905390639073908390939103911391239133914391539163917391839193920392139223923392439253926392739283929393039313932393339343935393639373938393939403941394239433944394539463947394839493950395139523953395439553956395739583959396039613962396339643965396639673968396939703971397239733974397539763977397839793980398139823983398439853986398739883989399039913992399339943995399639973998399940004001400240034004400540064007400840094010401140124013401440154016401740184019402040214022402340244025402640274028402940304031403240334034403540364037403840394040404140424043404440454046404740484049405040514052405340544055405640574058405940604061406240634064406540664067406840694070407140724073407440754076407740784079408040814082408340844085408640874088408940904091409240934094409540964097409840994100410141024103410441054106410741084109411041114112411341144115411641174118411941204121412241234124412541264127412841294130413141324133413441354136413741384139414041414142414341444145414641474148414941504151415241534154415541564157415841594160416141624163416441654166416741684169417041714172417341744175417641774178417941804181418241834184418541864187418841894190419141924193419441954196419741984199420042014202420342044205420642074208420942104211421242134214421542164217421842194220422142224223422442254226422742284229423042314232423342344235423642374238423942404241424242434244424542464247424842494250425142524253425442554256425742584259426042614262426342644265426642674268426942704271427242734274427542764277427842794280428142824283428442854286428742884289429042914292429342944295429642974298429943004301430243034304430543064307430843094310431143124313431443154316431743184319432043214322432343244325432643274328432943304331433243334334433543364337433843394340434143424343434443454346434743484349435043514352435343544355435643574358435943604361436243634364436543664367436843694370437143724373437443754376437743784379438043814382438343844385438643874388438943904391439243934394439543964397439843994400440144024403440444054406440744084409441044114412441344144415441644174418441944204421442244234424442544264427442844294430443144324433443444354436443744384439444044414442444344444445444644474448444944504451445244534454445544564457445844594460446144624463446444654466446744684469447044714472447344744475447644774478447944804481448244834484448544864487448844894490449144924493449444954496449744984499450045014502450345044505450645074508450945104511451245134514451545164517451845194520452145224523452445254526452745284529453045314532453345344535453645374538453945404541454245434544454545464547454845494550455145524553455445554556455745584559456045614562456345644565456645674568456945704571457245734574457545764577457845794580458145824583458445854586458745884589459045914592459345944595459645974598459946004601460246034604460546064607460846094610461146124613461446154616461746184619462046214622462346244625462646274628462946304631463246334634463546364637463846394640464146424643464446454646464746484649465046514652465346544655465646574658465946604661466246634664466546664667466846694670467146724673467446754676467746784679468046814682468346844685468646874688468946904691469246934694469546964697469846994700470147024703470447054706470747084709471047114712471347144715471647174718471947204721472247234724472547264727472847294730473147324733473447354736473747384739474047414742474347444745474647474748474947504751475247534754475547564757475847594760476147624763476447654766476747684769477047714772477347744775477647774778477947804781478247834784478547864787478847894790479147924793479447954796479747984799480048014802480348044805480648074808480948104811481248134814481548164817481848194820482148224823482448254826482748284829483048314832483348344835483648374838483948404841484248434844484548464847484848494850485148524853485448554856485748584859486048614862486348644865486648674868486948704871487248734874487548764877487848794880488148824883488448854886488748884889489048914892489348944895489648974898489949004901490249034904490549064907490849094910491149124913491449154916491749184919492049214922492349244925492649274928492949304931493249334934493549364937493849394940494149424943494449454946494749484949
  1. /**
  2. * xe-utils.js v3.7.9
  3. * MIT License.
  4. * @preserve
  5. */
  6. (function (global, factory) {
  7. typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() :
  8. typeof define === 'function' && define.amd ? define(factory) :
  9. (global.XEUtils = factory());
  10. }(this, function () {'use strict'
  11. var setupDefaults = {
  12. keyId: 1,
  13. cookies: {
  14. path: '/'
  15. },
  16. treeOptions: {
  17. parentKey: 'parentId',
  18. key: 'id',
  19. children: 'children'
  20. },
  21. parseDateFormat: 'yyyy-MM-dd HH:mm:ss',
  22. firstDayOfWeek: 1
  23. }
  24. var XEUtils = function () {}
  25. function mixin () {
  26. arrayEach(arguments, function (methods) {
  27. each(methods, function (fn, name) {
  28. XEUtils[name] = isFunction(fn) ? function () {
  29. var result = fn.apply(XEUtils.$context, arguments)
  30. XEUtils.$context = null
  31. return result
  32. } : fn
  33. })
  34. })
  35. }
  36. function setConfig (options) {
  37. return assign(setupDefaults, options)
  38. }
  39. function getConfig () {
  40. return setupDefaults
  41. }
  42. var version = '3.7.9'
  43. XEUtils.VERSION = version
  44. XEUtils.version = version
  45. XEUtils.mixin = mixin
  46. XEUtils.setup = setConfig
  47. XEUtils.setConfig = setConfig
  48. XEUtils.getConfig = getConfig
  49. function helperCheckCopyKey (key) {
  50. return key !== '__proto__' && key !== 'constructor'
  51. }
  52. var nextStartMaps = map(range(0, 7), function (day) {
  53. return [(day + 1) % 7, (day + 2) % 7, (day + 3) % 7]
  54. })
  55. function matchWeekStartDay (time, viewStartDay) {
  56. var day = new Date(time).getDay()
  57. return includes(nextStartMaps[viewStartDay], day)
  58. }
  59. function helperCreateGetDateWeek (getStartDate, checkCrossDate) {
  60. return function (date, firstDay) {
  61. var viewStartDay = isNumber(firstDay) ? firstDay : setupDefaults.firstDayOfWeek
  62. var targetDate = toStringDate(date)
  63. if (isValidDate(targetDate)) {
  64. var targetWeekStartDate = getWhatWeek(targetDate, 0, viewStartDay, viewStartDay)
  65. var firstDate = getStartDate(targetWeekStartDate)
  66. var firstTime = helperGetDateTime(firstDate)
  67. var targetWeekStartTime = helperGetDateTime(targetWeekStartDate)
  68. var targetWeekEndTime = targetWeekStartTime + staticDayTime * 6
  69. var targetWeekEndDate = new Date(targetWeekEndTime)
  70. var firstWeekStartDate = getWhatWeek(firstDate, 0, viewStartDay, viewStartDay)
  71. var firstWeekStartTime = helperGetDateTime(firstWeekStartDate)
  72. var tempTime
  73. if (targetWeekStartTime === firstWeekStartTime) {
  74. return 1
  75. }
  76. if (checkCrossDate(targetWeekStartDate, targetWeekEndDate)) {
  77. tempTime = helperGetDateTime(getStartDate(targetWeekEndDate))
  78. for (; tempTime < targetWeekEndTime; tempTime += staticDayTime) {
  79. if (matchWeekStartDay(tempTime, viewStartDay)) {
  80. return 1
  81. }
  82. }
  83. }
  84. var firstWeekEndTime = firstWeekStartTime + staticDayTime * 6
  85. var firstWeekEndDate = new Date(targetWeekEndTime)
  86. var offsetNum = 1
  87. if (checkCrossDate(firstWeekStartDate, firstWeekEndDate)) {
  88. offsetNum = 0
  89. tempTime = firstTime
  90. for (; tempTime < firstWeekEndTime; tempTime += staticDayTime) {
  91. if (matchWeekStartDay(tempTime, viewStartDay)) {
  92. offsetNum++
  93. break
  94. }
  95. }
  96. }
  97. return Math.floor((targetWeekStartTime - firstWeekStartTime) / staticWeekTime) + offsetNum
  98. }
  99. return NaN
  100. }
  101. }
  102. function helperCreateGetObjects (name, getIndex) {
  103. var proMethod = Object[name]
  104. return function (obj) {
  105. var result = []
  106. if (obj) {
  107. if (proMethod) {
  108. return proMethod(obj)
  109. }
  110. each(obj, getIndex > 1 ? function (key) {
  111. result.push(['' + key, obj[key]])
  112. } : function () {
  113. result.push(arguments[getIndex])
  114. })
  115. }
  116. return result
  117. }
  118. }
  119. function helperCreateIndexOf (name, callback) {
  120. return function (obj, val) {
  121. if (obj) {
  122. if (obj[name]) {
  123. return obj[name](val)
  124. }
  125. if (isString(obj) || isArray(obj)) {
  126. return callback(obj, val)
  127. }
  128. for (var key in obj) {
  129. if (hasOwnProp(obj, key)) {
  130. if (val === obj[key]) {
  131. return key
  132. }
  133. }
  134. }
  135. }
  136. return -1
  137. }
  138. }
  139. function helperCreateInInObjectString (type) {
  140. return function (obj) {
  141. return '[object ' + type + ']' === objectToString.call(obj)
  142. }
  143. }
  144. /* eslint-disable valid-typeof */
  145. function helperCreateInTypeof (type) {
  146. return function (obj) {
  147. return typeof obj === type
  148. }
  149. }
  150. function helperCreateIterateHandle (prop, useArray, restIndex, matchValue, defaultValue) {
  151. return function (obj, iterate, context) {
  152. if (obj && iterate) {
  153. if (prop && obj[prop]) {
  154. return obj[prop](iterate, context)
  155. } else {
  156. if (useArray && isArray(obj)) {
  157. for (var index = 0, len = obj.length; index < len; index++) {
  158. if (!!iterate.call(context, obj[index], index, obj) === matchValue) {
  159. return [true, false, index, obj[index]][restIndex]
  160. }
  161. }
  162. } else {
  163. for (var key in obj) {
  164. if (hasOwnProp(obj, key)) {
  165. if (!!iterate.call(context, obj[key], key, obj) === matchValue) {
  166. return [true, false, key, obj[key]][restIndex]
  167. }
  168. }
  169. }
  170. }
  171. }
  172. }
  173. return defaultValue
  174. }
  175. }
  176. function helperCreateiterateIndexOf (callback) {
  177. return function (obj, iterate, context) {
  178. if (obj && isFunction(iterate)) {
  179. if (isArray(obj) || isString(obj)) {
  180. return callback(obj, iterate, context)
  181. }
  182. for (var key in obj) {
  183. if (hasOwnProp(obj, key)) {
  184. if (iterate.call(context, obj[key], key, obj)) {
  185. return key
  186. }
  187. }
  188. }
  189. }
  190. return -1
  191. }
  192. }
  193. function helperCreateMathNumber(name) {
  194. return function (num, digits) {
  195. var numRest = toNumber(num)
  196. var rest = numRest
  197. if (numRest) {
  198. digits = digits >> 0
  199. var numStr = toNumberString(numRest)
  200. var nums = numStr.split('.')
  201. var intStr = nums[0]
  202. var floatStr = nums[1] || ''
  203. var fStr = floatStr.substring(0, digits + 1)
  204. var subRest = intStr + (fStr ? ('.' + fStr) : '')
  205. if (digits >= floatStr.length) {
  206. return toNumber(subRest)
  207. }
  208. subRest = numRest
  209. if (digits > 0) {
  210. var ratio = Math.pow(10, digits)
  211. rest = Math[name](helperMultiply(subRest, ratio)) / ratio
  212. } else {
  213. rest = Math[name](subRest)
  214. }
  215. }
  216. return rest
  217. }
  218. }
  219. function helperCreateMinMax (handle) {
  220. return function (arr, iterate) {
  221. if (arr && arr.length) {
  222. var rest, itemIndex
  223. arrayEach(arr, function (itemVal, index) {
  224. if (iterate) {
  225. itemVal = isFunction(iterate) ? iterate(itemVal, index, arr) : get(itemVal, iterate)
  226. }
  227. if (!eqNull(itemVal) && (eqNull(rest) || handle(rest, itemVal))) {
  228. itemIndex = index
  229. rest = itemVal
  230. }
  231. })
  232. return arr[itemIndex]
  233. }
  234. return rest
  235. }
  236. }
  237. function helperCreatePickOmit (case1, case2) {
  238. return function (obj, callback) {
  239. var item, index
  240. var rest = {}
  241. var result = []
  242. var context = this
  243. var args = arguments
  244. var len = args.length
  245. if (!isFunction(callback)) {
  246. for (index = 1; index < len; index++) {
  247. item = args[index]
  248. result.push.apply(result, isArray(item) ? item : [item])
  249. }
  250. callback = 0
  251. }
  252. each(obj, function (val, key) {
  253. if ((callback ? callback.call(context, val, key, obj) : findIndexOf(result, function (name) {
  254. return name === key
  255. }) > -1) ? case1 : case2) {
  256. rest[key] = val
  257. }
  258. })
  259. return rest
  260. }
  261. }
  262. function helperCreateToNumber (handle) {
  263. return function (str) {
  264. if (str) {
  265. var num = handle(str && str.replace ? str.replace(/,/g, '') : str)
  266. if (!isNaN(num)) {
  267. return num
  268. }
  269. }
  270. return 0
  271. }
  272. }
  273. function helperCreateTreeFunc (handle) {
  274. return function (obj, iterate, options, context) {
  275. var opts = options || {}
  276. var optChildren = opts.children || 'children'
  277. return handle(null, obj, iterate, context, [], [], optChildren, opts)
  278. }
  279. }
  280. function helperDefaultCompare (v1, v2) {
  281. return v1 === v2
  282. }
  283. function helperDeleteProperty (obj, property) {
  284. try {
  285. delete obj[property]
  286. } catch (e) {
  287. obj[property] = undefined
  288. }
  289. }
  290. function helperEqualCompare (val1, val2, compare, func, key, obj1, obj2) {
  291. if (val1 === val2) {
  292. return true
  293. }
  294. if (val1 && val2 && !isNumber(val1) && !isNumber(val2) && !isString(val1) && !isString(val2)) {
  295. if (isRegExp(val1)) {
  296. return compare('' + val1, '' + val2, key, obj1, obj2)
  297. } if (isDate(val1) || isBoolean(val1)) {
  298. return compare(+val1, +val2, key, obj1, obj2)
  299. } else {
  300. var result, val1Keys, val2Keys
  301. var isObj1Arr = isArray(val1)
  302. var isObj2Arr = isArray(val2)
  303. if (isObj1Arr || isObj2Arr ? isObj1Arr && isObj2Arr : val1.constructor === val2.constructor) {
  304. val1Keys = keys(val1)
  305. val2Keys = keys(val2)
  306. if (func) {
  307. result = func(val1, val2, key)
  308. }
  309. if (val1Keys.length === val2Keys.length) {
  310. return isUndefined(result) ? every(val1Keys, function (key, index) {
  311. return key === val2Keys[index] && helperEqualCompare(val1[key], val2[val2Keys[index]], compare, func, isObj1Arr || isObj2Arr ? index : key, val1, val2)
  312. }) : !!result
  313. }
  314. return false
  315. }
  316. }
  317. }
  318. return compare(val1, val2, key, obj1, obj2)
  319. }
  320. function helperFormatEscaper (dataMap) {
  321. var replaceRegexp = new RegExp('(?:' + keys(dataMap).join('|') + ')', 'g')
  322. return function (str) {
  323. return toValueString(str).replace(replaceRegexp, function (match) {
  324. return dataMap[match]
  325. })
  326. }
  327. }
  328. function helperGetDateFullYear (date) {
  329. return date.getFullYear()
  330. }
  331. function helperGetDateMonth (date) {
  332. return date.getMonth()
  333. }
  334. function helperGetDateTime (date) {
  335. return date.getTime()
  336. }
  337. function helperGetHGSKeys (property) {
  338. // 以最快的方式判断数组,可忽略准确性
  339. return property ? (property.splice && property.join ? property : ('' + property).replace(/(\[\d+\])\.?/g,'$1.').replace(/\.$/, '').split('.')) : []
  340. }
  341. function helperGetLocatOrigin () {
  342. return staticLocation ? (staticLocation.origin || (staticLocation.protocol + '//' + staticLocation.host)) : ''
  343. }
  344. function helperGetUTCDateTime (resMaps) {
  345. return Date.UTC(resMaps.y, resMaps.M || 0, resMaps.d || 1, resMaps.H || 0, resMaps.m || 0, resMaps.s || 0, resMaps.S || 0)
  346. }
  347. function helperGetYMD (date) {
  348. return new Date(helperGetDateFullYear(date), helperGetDateMonth(date), date.getDate())
  349. }
  350. function helperGetYMDTime (date) {
  351. return helperGetDateTime(helperGetYMD(date))
  352. }
  353. function helperLog (type, msg) {
  354. return (console[type] || console.log)(msg)
  355. }
  356. function helperMultiply (multiplier, multiplicand) {
  357. var str1 = toNumberString(multiplier)
  358. var str2 = toNumberString(multiplicand)
  359. return parseInt(str1.replace('.', '')) * parseInt(str2.replace('.', '')) / Math.pow(10, helperNumberDecimal(str1) + helperNumberDecimal(str2))
  360. }
  361. function helperNewDate () {
  362. return new Date()
  363. }
  364. function helperNumberAdd (addend, augend) {
  365. var str1 = toNumberString(addend)
  366. var str2 = toNumberString(augend)
  367. var ratio = Math.pow(10, Math.max(helperNumberDecimal(str1), helperNumberDecimal(str2)))
  368. return (multiply(addend, ratio) + multiply(augend, ratio)) / ratio
  369. }
  370. function helperNumberDecimal (numStr) {
  371. return (numStr.split('.')[1] || '').length
  372. }
  373. function helperNumberDivide (divisor, dividend) {
  374. var str1 = toNumberString(divisor)
  375. var str2 = toNumberString(dividend)
  376. var divisorDecimal = helperNumberDecimal(str1)
  377. var dividendDecimal = helperNumberDecimal(str2)
  378. var powY = dividendDecimal - divisorDecimal
  379. var isMinus = powY < 0
  380. var multiplicand = Math.pow(10, isMinus ? Math.abs(powY) : powY)
  381. return multiply(str1.replace('.', '') / str2.replace('.', ''), isMinus ? 1 / multiplicand : multiplicand)
  382. }
  383. function helperNumberOffsetPoint (str, offsetIndex) {
  384. return str.substring(0, offsetIndex) + '.' + str.substring(offsetIndex, str.length)
  385. }
  386. function helperStringLowerCase (str) {
  387. return str.toLowerCase()
  388. }
  389. function helperStringRepeat (str, count) {
  390. if (str.repeat) {
  391. return str.repeat(count)
  392. }
  393. var list = isNaN(count) ? [] : new Array(staticParseInt(count))
  394. return list.join(str) + (list.length > 0 ? str : '')
  395. }
  396. function helperStringSubstring (str, start, end) {
  397. return str.substring(start, end)
  398. }
  399. function helperStringUpperCase (str) {
  400. return str.toUpperCase()
  401. }
  402. var staticStrUndefined = 'undefined'
  403. var staticStrLast = 'last'
  404. var staticStrFirst = 'first'
  405. var staticDayTime = 86400000
  406. var staticWeekTime = staticDayTime * 7
  407. /* eslint-disable valid-typeof */
  408. var staticLocation = typeof location === staticStrUndefined ? 0 : location
  409. /* eslint-disable valid-typeof */
  410. var staticWindow = typeof window === staticStrUndefined ? 0 : window
  411. /* eslint-disable valid-typeof */
  412. var staticDocument = typeof document === staticStrUndefined ? 0 : document
  413. var staticEncodeURIComponent = encodeURIComponent
  414. var staticDecodeURIComponent = decodeURIComponent
  415. var objectToString = Object.prototype.toString
  416. var staticParseInt = parseInt
  417. var staticEscapeMap = {
  418. '&': '&amp;',
  419. '<': '&lt;',
  420. '>': '&gt;',
  421. '"': '&quot;',
  422. "'": '&#x27;',
  423. '`': '&#x60;'
  424. }
  425. var staticHGKeyRE = /(.+)?\[(\d+)\]$/
  426. var objectAssignFns = Object.assign
  427. function handleAssign (destination, args, isClone) {
  428. var len = args.length
  429. for (var source, index = 1; index < len; index++) {
  430. source = args[index]
  431. arrayEach(keys(args[index]), isClone ? function (key) {
  432. destination[key] = clone(source[key], isClone)
  433. } : function (key) {
  434. destination[key] = source[key]
  435. })
  436. }
  437. return destination
  438. }
  439. /**
  440. * 将一个或多个源对象复制到目标对象中
  441. *
  442. * @param {Object} target 目标对象
  443. * @param {...Object}
  444. * @return {Boolean}
  445. */
  446. var assign = function (target) {
  447. if (target) {
  448. var args = arguments
  449. if (target === true) {
  450. if (args.length > 1) {
  451. target = isArray(target[1]) ? [] : {}
  452. return handleAssign(target, args, true)
  453. }
  454. } else {
  455. return objectAssignFns ? objectAssignFns.apply(Object, args) : handleAssign(target, args)
  456. }
  457. }
  458. return target
  459. }
  460. /**
  461. * 指定方法后的返回值组成的新对象
  462. *
  463. * @param {Object} obj 对象/数组
  464. * @param {Function} iterate(item, index, obj) 回调
  465. * @param {Object} context 上下文
  466. * @return {Object}
  467. */
  468. function objectMap (obj, iterate, context) {
  469. var result = {}
  470. if (obj) {
  471. if (iterate) {
  472. if (!isFunction(iterate)) {
  473. iterate = property(iterate)
  474. }
  475. each(obj, function (val, index) {
  476. result[index] = iterate.call(context, val, index, obj)
  477. })
  478. } else {
  479. return obj
  480. }
  481. }
  482. return result
  483. }
  484. function objectEach (obj, iterate, context) {
  485. if (obj) {
  486. for (var key in obj) {
  487. if (hasOwnProp(obj, key)) {
  488. iterate.call(context, obj[key], key, obj)
  489. }
  490. }
  491. }
  492. }
  493. function lastObjectEach (obj, iterate, context) {
  494. lastArrayEach(keys(obj), function (key) {
  495. iterate.call(context, obj[key], key, obj)
  496. })
  497. }
  498. function handleMerge (target, source) {
  499. if ((isPlainObject(target) && isPlainObject(source)) || (isArray(target) && isArray(source))) {
  500. each(source, function (val, key) {
  501. if (helperCheckCopyKey(key)) {
  502. target[key] = isFunction(source) ? val : handleMerge(target[key], val)
  503. }
  504. })
  505. return target
  506. }
  507. return source
  508. }
  509. /**
  510. * 将一个或多个源对象合并到目标对象中
  511. *
  512. * @param {Object} target 目标对象
  513. * @param {...Object}
  514. * @return {Boolean}
  515. */
  516. var merge = function (target) {
  517. if (!target) {
  518. target = {}
  519. }
  520. var args = arguments
  521. var len = args.length
  522. for (var source, index = 1; index < len; index++) {
  523. source = args[index]
  524. if (source) {
  525. handleMerge(target, source)
  526. }
  527. }
  528. return target
  529. }
  530. /**
  531. * 数组去重
  532. *
  533. * @param {*} array 数组
  534. * @param {*} iterate 字段或回调
  535. * @param {*} context
  536. * @returns
  537. */
  538. function uniq (array, iterate, context) {
  539. var result = []
  540. if (iterate) {
  541. if (!isFunction(iterate)) {
  542. iterate = property(iterate)
  543. }
  544. var val, valMap = {}
  545. each(array, function (item, key) {
  546. val = iterate.call(context, item, key, array)
  547. if (!valMap[val]) {
  548. valMap[val] = 1
  549. result.push(item)
  550. }
  551. })
  552. } else {
  553. each(array, function (value) {
  554. if (!includes(result, value)) {
  555. result.push(value)
  556. }
  557. })
  558. }
  559. return result
  560. }
  561. /**
  562. * 将多个数的值返回唯一的并集数组
  563. *
  564. * @param {...Array} 数组
  565. * @return {Array}
  566. */
  567. function union () {
  568. var args = arguments
  569. var result = []
  570. var index = 0
  571. var len = args.length
  572. for (; index < len; index++) {
  573. result = result.concat(toArray(args[index]))
  574. }
  575. return uniq(result)
  576. }
  577. var sortBy = orderBy
  578. var ORDER_PROP_ASC = 'asc'
  579. var ORDER_PROP_DESC = 'desc'
  580. // function handleSort (v1, v2) {
  581. // return v1 > v2 ? 1 : -1
  582. // }
  583. // '' < 数字 < 字符 < null < undefined
  584. function handleSort (v1, v2) {
  585. if (isUndefined(v1)) {
  586. return 1
  587. }
  588. if (isNull(v1)) {
  589. return isUndefined(v2) ? -1 : 1
  590. }
  591. return v1 && v1.localeCompare ? v1.localeCompare(v2) : (v1 > v2 ? 1 : -1)
  592. }
  593. function buildMultiOrders (name, confs, compares) {
  594. return function (item1, item2) {
  595. var v1 = item1[name]
  596. var v2 = item2[name]
  597. if (v1 === v2) {
  598. return compares ? compares(item1, item2) : 0
  599. }
  600. return confs.order === ORDER_PROP_DESC ? handleSort(v2, v1) : handleSort(v1, v2)
  601. }
  602. }
  603. function getSortConfs (arr, list, fieldConfs, context) {
  604. var sortConfs = []
  605. fieldConfs = isArray(fieldConfs) ? fieldConfs : [fieldConfs]
  606. arrayEach(fieldConfs, function (handle, index) {
  607. if (handle) {
  608. var field = handle
  609. var order
  610. if (isArray(handle)) {
  611. field = handle[0]
  612. order = handle[1]
  613. } else if (isPlainObject(handle)) {
  614. field = handle.field
  615. order = handle.order
  616. }
  617. sortConfs.push({
  618. field: field,
  619. order: order || ORDER_PROP_ASC
  620. })
  621. arrayEach(list, isFunction(field) ? function (item, key) {
  622. item[index] = field.call(context, item.data, key, arr)
  623. } : function (item) {
  624. item[index] = field ? get(item.data, field) : item.data
  625. })
  626. }
  627. })
  628. return sortConfs
  629. }
  630. /**
  631. * 将数组进行排序
  632. *
  633. * @param {Array} arr 数组
  634. * @param {Function/String/Array} fieldConfs 方法或属性
  635. * @param {Object} context 上下文
  636. * @return {Array}
  637. */
  638. function orderBy (arr, fieldConfs, context) {
  639. if (arr) {
  640. if (eqNull(fieldConfs)) {
  641. return toArray(arr).sort(handleSort)
  642. }
  643. var compares
  644. var list = map(arr, function (item) {
  645. return { data: item }
  646. })
  647. var sortConfs = getSortConfs(arr, list, fieldConfs, context)
  648. var len = sortConfs.length - 1
  649. while (len >= 0) {
  650. compares = buildMultiOrders(len, sortConfs[len], compares)
  651. len--
  652. }
  653. if (compares) {
  654. list = list.sort(compares)
  655. }
  656. return map(list, property('data'))
  657. }
  658. return []
  659. }
  660. /**
  661. * 将一个数组随机打乱,返回一个新的数组
  662. *
  663. * @param {Array} array 数组
  664. * @return {Array}
  665. */
  666. function shuffle (array) {
  667. var index
  668. var result = []
  669. var list = values(array)
  670. var len = list.length - 1
  671. for (; len >= 0; len--) {
  672. index = len > 0 ? random(0, len) : 0
  673. result.push(list[index])
  674. list.splice(index, 1)
  675. }
  676. return result
  677. }
  678. /**
  679. * 从一个数组中随机返回几个元素
  680. *
  681. * @param {Array} array 数组
  682. * @param {Number} number 个数
  683. * @return {Array}
  684. */
  685. function sample (array, number) {
  686. var result = shuffle(array)
  687. if (arguments.length <= 1) {
  688. return result[0]
  689. }
  690. if (number < result.length) {
  691. result.length = number || 0
  692. }
  693. return result
  694. }
  695. /**
  696. * 对象中的值中的每一项运行给定函数,如果函数对任一项返回true,则返回true,否则返回false
  697. *
  698. * @param {Object} obj 对象/数组
  699. * @param {Function} iterate(item, index, obj) 回调
  700. * @param {Object} context 上下文
  701. * @return {Boolean}
  702. */
  703. var some = helperCreateIterateHandle('some', 1, 0, true, false)
  704. /**
  705. * 对象中的值中的每一项运行给定函数,如果该函数对每一项都返回true,则返回true,否则返回false
  706. *
  707. * @param {Object} obj 对象/数组
  708. * @param {Function} iterate(item, index, obj) 回调
  709. * @param {Object} context 上下文
  710. * @return {Boolean}
  711. */
  712. var every = helperCreateIterateHandle('every', 1, 1, false, true)
  713. /**
  714. * 裁剪 Arguments 或数组 array,从 start 位置开始到 end 结束,但不包括 end 本身的位置
  715. * @param {Array/Arguments} array 数组或Arguments
  716. * @param {Number} startIndex 开始索引
  717. * @param {Number} endIndex 结束索引
  718. */
  719. function slice (array, startIndex, endIndex) {
  720. var result = []
  721. var argsSize = arguments.length
  722. if (array) {
  723. startIndex = argsSize >= 2 ? toNumber(startIndex) : 0
  724. endIndex = argsSize >= 3 ? toNumber(endIndex) : array.length
  725. if (array.slice) {
  726. return array.slice(startIndex, endIndex)
  727. }
  728. for (; startIndex < endIndex; startIndex++) {
  729. result.push(array[startIndex])
  730. }
  731. }
  732. return result
  733. }
  734. /**
  735. * 根据回调过滤数据
  736. *
  737. * @param {Object} obj 对象/数组
  738. * @param {Function} iterate(item, index, obj) 回调
  739. * @param {Object} context 上下文
  740. * @return {Object}
  741. */
  742. function filter (obj, iterate, context) {
  743. var result = []
  744. if (obj && iterate) {
  745. if (obj.filter) {
  746. return obj.filter(iterate, context)
  747. }
  748. each(obj, function (val, key) {
  749. if (iterate.call(context, val, key, obj)) {
  750. result.push(val)
  751. }
  752. })
  753. }
  754. return result
  755. }
  756. /**
  757. * 从左至右遍历,匹配最近的一条数据
  758. *
  759. * @param {Object} obj 对象/数组
  760. * @param {Function} iterate(item, index, obj) 回调
  761. * @param {Object} context 上下文
  762. * @return {Object}
  763. */
  764. var find = helperCreateIterateHandle('find', 1, 3, true)
  765. /**
  766. * 从右至左遍历,匹配最近的一条数据
  767. *
  768. * @param {Object} obj 对象/数组
  769. * @param {Function} iterate(item, index, obj) 回调
  770. * @param {Object} context 上下文
  771. * @return {Object}
  772. */
  773. function findLast (obj, iterate, context) {
  774. if (obj) {
  775. if (!isArray(obj)) {
  776. obj = values(obj)
  777. }
  778. for (var len = obj.length - 1; len >= 0; len--) {
  779. if (iterate.call(context, obj[len], len, obj)) {
  780. return obj[len]
  781. }
  782. }
  783. }
  784. }
  785. /**
  786. * 查找匹配第一条数据的键
  787. *
  788. * @param {Object} obj 对象/数组
  789. * @param {Function} iterate(item, index, obj) 回调
  790. * @param {Object} context 上下文
  791. * @return {Object}
  792. */
  793. var findKey = helperCreateIterateHandle('', 0, 2, true)
  794. /**
  795. * 判断对象是否包含该值,成功返回true否则false
  796. *
  797. * @param {Object} obj 对象
  798. * @param {Object} val 值
  799. * @return {Boolean}
  800. */
  801. function includes (obj, val) {
  802. if (obj) {
  803. if (obj.includes) {
  804. return obj.includes(val)
  805. }
  806. for (var key in obj) {
  807. if (hasOwnProp(obj, key)) {
  808. if (val === obj[key]) {
  809. return true
  810. }
  811. }
  812. }
  813. }
  814. return false
  815. }
  816. function arrayIndexOf (list, val) {
  817. if (list.indexOf) {
  818. return list.indexOf(val)
  819. }
  820. for (var index = 0, len = list.length; index < len; index++) {
  821. if (val === list[index]) {
  822. return index
  823. }
  824. }
  825. }
  826. function arrayLastIndexOf (list, val) {
  827. if (list.lastIndexOf) {
  828. return list.lastIndexOf(val)
  829. }
  830. for (var len = list.length - 1; len >= 0; len--) {
  831. if (val === list[len]) {
  832. return len
  833. }
  834. }
  835. return -1
  836. }
  837. /**
  838. * 指定方法后的返回值组成的新数组
  839. *
  840. * @param {Object} obj 对象/数组
  841. * @param {Function} iterate(item, index, obj) 回调
  842. * @param {Object} context 上下文
  843. * @return {Array}
  844. */
  845. function map (obj, iterate, context) {
  846. var result = []
  847. if (obj && arguments.length > 1) {
  848. if (obj.map) {
  849. return obj.map(iterate, context)
  850. } else {
  851. each(obj, function () {
  852. result.push(iterate.apply(context, arguments))
  853. })
  854. }
  855. }
  856. return result
  857. }
  858. /**
  859. * 接收一个函数作为累加器,数组中的每个值(从左到右)开始合并,最终为一个值。
  860. *
  861. * @param {Array} array 数组
  862. * @param {Function} callback 方法
  863. * @param {Object} initialValue 初始值
  864. * @return {Number}
  865. */
  866. function reduce (array, callback, initialValue) {
  867. if (array) {
  868. var len, reduceMethod
  869. var index = 0
  870. var context = null
  871. var previous = initialValue
  872. var isInitialVal = arguments.length > 2
  873. var keyList = keys(array)
  874. if (array.length && array.reduce) {
  875. reduceMethod = function () {
  876. return callback.apply(context, arguments)
  877. }
  878. if (isInitialVal) {
  879. return array.reduce(reduceMethod, previous)
  880. }
  881. return array.reduce(reduceMethod)
  882. }
  883. if (isInitialVal) {
  884. index = 1
  885. previous = array[keyList[0]]
  886. }
  887. for (len = keyList.length; index < len; index++) {
  888. previous = callback.call(context, previous, array[keyList[index]], index, array)
  889. }
  890. return previous
  891. }
  892. }
  893. /**
  894. * 浅复制数组的一部分到同一数组中的另一个位置,数组大小不变
  895. *
  896. * @param {Array} array 数组
  897. * @param {Number} target 从该位置开始替换数据
  898. * @param {Number} start 从该位置开始读取数据,默认为 0 。如果为负值,表示倒数
  899. * @param {Number} end 到该位置前停止读取数据,默认等于数组长度。如果为负值,表示倒数
  900. * @return {Array}
  901. */
  902. function copyWithin (array, target, start, end) {
  903. if (isArray(array) && array.copyWithin) {
  904. return array.copyWithin(target, start, end)
  905. }
  906. var replaceIndex, replaceArray
  907. var targetIndex = target >> 0
  908. var startIndex = start >> 0
  909. var len = array.length
  910. var endIndex = arguments.length > 3 ? end >> 0 : len
  911. if (targetIndex < len) {
  912. targetIndex = targetIndex >= 0 ? targetIndex : len + targetIndex
  913. if (targetIndex >= 0) {
  914. startIndex = startIndex >= 0 ? startIndex : len + startIndex
  915. endIndex = endIndex >= 0 ? endIndex : len + endIndex
  916. if (startIndex < endIndex) {
  917. for (replaceIndex = 0, replaceArray = array.slice(startIndex, endIndex); targetIndex < len; targetIndex++) {
  918. if (replaceArray.length <= replaceIndex) {
  919. break
  920. }
  921. array[targetIndex] = replaceArray[replaceIndex++]
  922. }
  923. }
  924. }
  925. }
  926. return array
  927. }
  928. /**
  929. * 将一个数组分割成大小的组。如果数组不能被平均分配,那么最后一块将是剩下的元素
  930. *
  931. * @param {Array} array 数组
  932. * @param {Number} size 每组大小
  933. * @return {Array}
  934. */
  935. function chunk (array, size) {
  936. var index
  937. var result = []
  938. var arrLen = size >> 0 || 1
  939. if (isArray(array)) {
  940. if (arrLen >= 0 && array.length > arrLen) {
  941. index = 0
  942. while (index < array.length) {
  943. result.push(array.slice(index, index + arrLen))
  944. index += arrLen
  945. }
  946. } else {
  947. result = array.length ? [array] : array
  948. }
  949. }
  950. return result
  951. }
  952. /**
  953. * 将每个数组中相应位置的值合并在一起
  954. *
  955. * @param {Array*} array 数组
  956. */
  957. function zip () {
  958. return unzip(arguments)
  959. }
  960. /**
  961. * 与 zip 相反
  962. *
  963. * @param {Array} arrays 数组集合
  964. */
  965. function unzip (arrays) {
  966. var index, maxItem, len
  967. var result = []
  968. if (arrays && arrays.length) {
  969. index = 0
  970. maxItem = max(arrays, function (item) {
  971. return item ? item.length : 0
  972. })
  973. for (len = maxItem ? maxItem.length : 0; index < len; index++) {
  974. result.push(pluck(arrays, index))
  975. }
  976. }
  977. return result
  978. }
  979. /**
  980. * 根据键数组、值数组对转换为对象
  981. *
  982. * @param {Array} props 键数组
  983. * @param {Number} arr 值数组
  984. * @return {Object}
  985. */
  986. function zipObject (props, arr) {
  987. var result = {}
  988. arr = arr || []
  989. each(values(props), function (val, key) {
  990. result[val] = arr[key]
  991. })
  992. return result
  993. }
  994. function flattenDeep (array, deep) {
  995. var result = []
  996. arrayEach(array, function (vals) {
  997. result = result.concat(isArray(vals) ? (deep ? flattenDeep(vals, deep) : vals) : [vals])
  998. })
  999. return result
  1000. }
  1001. /**
  1002. * 将一个多维数组铺平
  1003. * @param {Array} array 数组
  1004. * @param {Boolean} deep 是否深层
  1005. * @return {Array}
  1006. */
  1007. function flatten (array, deep) {
  1008. if (isArray(array)) {
  1009. return flattenDeep(array, deep)
  1010. }
  1011. return []
  1012. }
  1013. /**
  1014. * 将对象或者伪数组转为新数组
  1015. *
  1016. * @param {Array} list 数组
  1017. * @return {Array}
  1018. */
  1019. function toArray (list) {
  1020. return map(list, function (item) {
  1021. return item
  1022. })
  1023. }
  1024. /**
  1025. * 判断数组是否包含另一数组
  1026. *
  1027. * @param {Array} array1 数组
  1028. * @param {Array} array2 被包含数组
  1029. * @return {Boolean}
  1030. */
  1031. function includeArrays (array1, array2) {
  1032. var len
  1033. var index = 0
  1034. if (isArray(array1) && isArray(array2)) {
  1035. for (len = array2.length; index < len; index++) {
  1036. if (!includes(array1, array2[index])) {
  1037. return false
  1038. }
  1039. }
  1040. return true
  1041. }
  1042. return includes(array1, array2)
  1043. }
  1044. /**
  1045. * 获取数组对象中某属性值,返回一个数组
  1046. *
  1047. * @param {Array} array 数组
  1048. * @param {String} key 属性值
  1049. * @return {Array}
  1050. */
  1051. function pluck (obj, key) {
  1052. return map(obj, property(key))
  1053. }
  1054. function deepGetObj (obj, path) {
  1055. var index = 0
  1056. var len = path.length
  1057. while (obj && index < len) {
  1058. obj = obj[path[index++]]
  1059. }
  1060. return len && obj ? obj : 0
  1061. }
  1062. /**
  1063. * 在list的每个元素上执行方法,任何传递的额外参数都会在调用方法的时候传递给它
  1064. *
  1065. * @param {Array} list
  1066. * @param {Array/String/Function} path
  1067. * @param {...Object} arguments
  1068. * @return {Array}
  1069. */
  1070. function invoke (list, path) {
  1071. var func
  1072. var args = arguments
  1073. var params = []
  1074. var paths = []
  1075. var index = 2
  1076. var len = args.length
  1077. for (; index < len; index++) {
  1078. params.push(args[index])
  1079. }
  1080. if (isArray(path)) {
  1081. len = path.length - 1
  1082. for (index = 0; index < len; index++) {
  1083. paths.push(path[index])
  1084. }
  1085. path = path[len]
  1086. }
  1087. return map(list, function (context) {
  1088. if (paths.length) {
  1089. context = deepGetObj(context, paths)
  1090. }
  1091. func = context[path] || path
  1092. if (func && func.apply) {
  1093. return func.apply(context, params)
  1094. }
  1095. })
  1096. }
  1097. function arrayEach (list, iterate, context) {
  1098. if (list) {
  1099. if (list.forEach) {
  1100. list.forEach(iterate, context)
  1101. } else {
  1102. for (var index = 0, len = list.length; index < len; index++) {
  1103. iterate.call(context, list[index], index, list)
  1104. }
  1105. }
  1106. }
  1107. }
  1108. function lastArrayEach (obj, iterate, context) {
  1109. for (var len = obj.length - 1; len >= 0; len--) {
  1110. iterate.call(context, obj[len], len, obj)
  1111. }
  1112. }
  1113. function strictTree (array, optChildren) {
  1114. each(array, function (item) {
  1115. if (item[optChildren] && !item[optChildren].length) {
  1116. remove(item, optChildren)
  1117. }
  1118. })
  1119. }
  1120. /**
  1121. * 将一个带层级的数据列表转成树结构
  1122. *
  1123. * @param {Array} array 数组
  1124. * @param {Object} options {strict: false, parentKey: 'parentId', key: 'id', children: 'children', mapChildren: 'children', data: 'data'}
  1125. * @return {Array}
  1126. */
  1127. function toArrayTree (array, options) {
  1128. var opts = assign({}, setupDefaults.treeOptions, options)
  1129. var optStrict = opts.strict
  1130. var optKey = opts.key
  1131. var optParentKey = opts.parentKey
  1132. var optChildren = opts.children
  1133. var optMapChildren = opts.mapChildren
  1134. var optSortKey = opts.sortKey
  1135. var optReverse = opts.reverse
  1136. var optData = opts.data
  1137. var result = []
  1138. var treeMaps = {}
  1139. var idsMap = {}
  1140. var id, treeData, parentId
  1141. if (optSortKey) {
  1142. array = orderBy(clone(array), optSortKey)
  1143. if (optReverse) {
  1144. array = array.reverse()
  1145. }
  1146. }
  1147. each(array, function (item) {
  1148. id = item[optKey]
  1149. if (idsMap[id]) {
  1150. helperLog('warn', 'Duplicate primary key=' + id)
  1151. }
  1152. idsMap[id] = true
  1153. })
  1154. each(array, function (item) {
  1155. id = item[optKey]
  1156. if (optData) {
  1157. treeData = {}
  1158. treeData[optData] = item
  1159. } else {
  1160. treeData = item
  1161. }
  1162. parentId = item[optParentKey]
  1163. treeMaps[id] = treeMaps[id] || []
  1164. treeData[optKey] = id
  1165. treeData[optParentKey] = parentId
  1166. if (id === parentId) {
  1167. parentId = null
  1168. helperLog('warn', 'Error infinite Loop. key=' + id + ' parentKey=' + id)
  1169. }
  1170. treeMaps[parentId] = treeMaps[parentId] || []
  1171. treeMaps[parentId].push(treeData)
  1172. treeData[optChildren] = treeMaps[id]
  1173. if (optMapChildren) {
  1174. treeData[optMapChildren] = treeMaps[id]
  1175. }
  1176. if (!optStrict || (optStrict && eqNull(parentId))) {
  1177. if (!idsMap[parentId]) {
  1178. result.push(treeData)
  1179. }
  1180. }
  1181. })
  1182. if (optStrict) {
  1183. strictTree(array, optChildren)
  1184. }
  1185. return result
  1186. }
  1187. function unTreeList (result, parentItem, array, opts) {
  1188. var optKey = opts.key
  1189. var optParentKey = opts.parentKey
  1190. var optChildren = opts.children
  1191. var optData = opts.data
  1192. var optUpdated = opts.updated
  1193. var optClear = opts.clear
  1194. arrayEach(array, function (item) {
  1195. var childList = item[optChildren]
  1196. if (optData) {
  1197. item = item[optData]
  1198. }
  1199. if (optUpdated !== false) {
  1200. item[optParentKey] = parentItem ? parentItem[optKey] : null
  1201. }
  1202. result.push(item)
  1203. if (childList && childList.length) {
  1204. unTreeList(result, item, childList, opts)
  1205. }
  1206. if (optClear) {
  1207. delete item[optChildren]
  1208. }
  1209. })
  1210. return result
  1211. }
  1212. /**
  1213. * 将一个树结构转成数组列表
  1214. *
  1215. * @param {Array} array 数组
  1216. * @param {Object} options { children: 'children', data: 'data', clear: false }
  1217. * @return {Array}
  1218. */
  1219. function toTreeArray (array, options) {
  1220. return unTreeList([], null, array, assign({}, setupDefaults.treeOptions, options))
  1221. }
  1222. function findTreeItem (parent, obj, iterate, context, path, node, parseChildren, opts) {
  1223. if (obj) {
  1224. var item, index, len, paths, nodes, match
  1225. for (index = 0, len = obj.length; index < len; index++) {
  1226. item = obj[index]
  1227. paths = path.concat(['' + index])
  1228. nodes = node.concat([item])
  1229. if (iterate.call(context, item, index, obj, paths, parent, nodes)) {
  1230. return { index: index, item: item, path: paths, items: obj, parent: parent, nodes: nodes }
  1231. }
  1232. if (parseChildren && item) {
  1233. match = findTreeItem(item, item[parseChildren], iterate, context, paths.concat([parseChildren]), nodes, parseChildren, opts)
  1234. if (match) {
  1235. return match
  1236. }
  1237. }
  1238. }
  1239. }
  1240. }
  1241. /**
  1242. * 从树结构中查找匹配第一条数据的键、值、路径
  1243. *
  1244. * @param {Object} obj 对象/数组
  1245. * @param {Function} iterate(item, index, items, path, parent, nodes) 回调
  1246. * @param {Object} options {children: 'children'}
  1247. * @param {Object} context 上下文
  1248. * @return {Object} { item, index, items, path, parent, nodes }
  1249. */
  1250. var findTree = helperCreateTreeFunc(findTreeItem)
  1251. function eachTreeItem (parent, obj, iterate, context, path, node, parseChildren, opts) {
  1252. var paths, nodes
  1253. each(obj, function (item, index) {
  1254. paths = path.concat(['' + index])
  1255. nodes = node.concat([item])
  1256. iterate.call(context, item, index, obj, paths, parent, nodes)
  1257. if (item && parseChildren) {
  1258. paths.push(parseChildren)
  1259. eachTreeItem(item, item[parseChildren], iterate, context, paths, nodes, parseChildren, opts)
  1260. }
  1261. })
  1262. }
  1263. /**
  1264. * 从树结构中遍历数据的键、值、路径
  1265. *
  1266. * @param {Object} obj 对象/数组
  1267. * @param {Function} iterate(item, index, items, path, parent, nodes) 回调
  1268. * @param {Object} options {children: 'children', mapChildren: 'children}
  1269. * @param {Object} context 上下文
  1270. */
  1271. var eachTree = helperCreateTreeFunc(eachTreeItem)
  1272. function mapTreeItem (parent, obj, iterate, context, path, node, parseChildren, opts) {
  1273. var paths, nodes, rest
  1274. var mapChildren = opts.mapChildren || parseChildren
  1275. return map(obj, function (item, index) {
  1276. paths = path.concat(['' + index])
  1277. nodes = node.concat([item])
  1278. rest = iterate.call(context, item, index, obj, paths, parent, nodes)
  1279. if (rest && item && parseChildren && item[parseChildren]) {
  1280. rest[mapChildren] = mapTreeItem(item, item[parseChildren], iterate, context, paths, nodes, parseChildren, opts)
  1281. }
  1282. return rest
  1283. })
  1284. }
  1285. /**
  1286. * 从树结构中指定方法后的返回值组成的新数组
  1287. *
  1288. * @param {Object} obj 对象/数组
  1289. * @param {Function} iterate(item, index, items, path, parent, nodes) 回调
  1290. * @param {Object} options {children: 'children'}
  1291. * @param {Object} context 上下文
  1292. * @return {Object/Array}
  1293. */
  1294. var mapTree = helperCreateTreeFunc(mapTreeItem)
  1295. /**
  1296. * 从树结构中根据回调过滤数据
  1297. *
  1298. * @param {Object} obj 对象/数组
  1299. * @param {Function} iterate(item, index, items, path, parent) 回调
  1300. * @param {Object} options {children: 'children'}
  1301. * @param {Object} context 上下文
  1302. * @return {Array}
  1303. */
  1304. function filterTree (obj, iterate, options, context) {
  1305. var result = []
  1306. if (obj && iterate) {
  1307. eachTree(obj, function (item, index, items, path, parent, nodes) {
  1308. if (iterate.call(context, item, index, items, path, parent, nodes)) {
  1309. result.push(item)
  1310. }
  1311. }, options)
  1312. }
  1313. return result
  1314. }
  1315. function searchTreeItem (matchParent, parent, obj, iterate, context, path, node, parseChildren, opts) {
  1316. var paths, nodes, rest, isMatch, hasChild
  1317. var rests = []
  1318. var hasOriginal = opts.original
  1319. var sourceData = opts.data
  1320. var mapChildren = opts.mapChildren || parseChildren
  1321. var isEvery = opts.isEvery
  1322. arrayEach(obj, function (item, index) {
  1323. paths = path.concat(['' + index])
  1324. nodes = node.concat([item])
  1325. isMatch = (matchParent && !isEvery) || iterate.call(context, item, index, obj, paths, parent, nodes)
  1326. hasChild = parseChildren && item[parseChildren]
  1327. if (isMatch || hasChild) {
  1328. if (hasOriginal) {
  1329. rest = item
  1330. } else {
  1331. rest = assign({}, item)
  1332. if (sourceData) {
  1333. rest[sourceData] = item
  1334. }
  1335. }
  1336. rest[mapChildren] = searchTreeItem(isMatch, item, item[parseChildren], iterate, context, paths, nodes, parseChildren, opts)
  1337. if (isMatch || rest[mapChildren].length) {
  1338. rests.push(rest)
  1339. }
  1340. } else if (isMatch) {
  1341. rests.push(rest)
  1342. }
  1343. })
  1344. return rests
  1345. }
  1346. /**
  1347. * 从树结构中根据回调查找数据
  1348. *
  1349. * @param {Object} obj 对象/数组
  1350. * @param {Function} iterate(item, index, items, path, parent, nodes) 回调
  1351. * @param {Object} options {children: 'children'}
  1352. * @param {Object} context 上下文
  1353. * @return {Array}
  1354. */
  1355. var searchTree = helperCreateTreeFunc(function (parent, obj, iterate, context, path, nodes, parseChildren, opts) {
  1356. return searchTreeItem(0, parent, obj, iterate, context, path, nodes, parseChildren, opts)
  1357. })
  1358. /**
  1359. * 判断对象自身属性中是否具有指定的属性
  1360. *
  1361. * @param {Object} obj 对象
  1362. * @param {String/Number} key 键值
  1363. * @return {Boolean}
  1364. */
  1365. function hasOwnProp (obj, key) {
  1366. return obj && obj.hasOwnProperty ? obj.hasOwnProperty(key) : false
  1367. }
  1368. /**
  1369. * 判断是否 undefined 和 null
  1370. * @param {Object} obj 对象
  1371. * @return {Boolean}
  1372. */
  1373. function eqNull (obj) {
  1374. return isNull(obj) || isUndefined(obj)
  1375. }
  1376. /* eslint-disable eqeqeq */
  1377. function isNumberNaN (obj) {
  1378. return isNumber(obj) && isNaN(obj)
  1379. }
  1380. function isNumberFinite (obj) {
  1381. return isNumber(obj) && isFinite(obj)
  1382. }
  1383. /**
  1384. * 判断是否Undefined
  1385. *
  1386. * @param {Object} obj 对象
  1387. * @return {Boolean}
  1388. */
  1389. var isUndefined = helperCreateInTypeof(staticStrUndefined)
  1390. /**
  1391. * 判断是否数组
  1392. *
  1393. * @param {Object} obj 对象
  1394. * @return {Boolean}
  1395. */
  1396. var isArray = Array.isArray || helperCreateInInObjectString('Array')
  1397. /**
  1398. * 判断是否小数
  1399. *
  1400. * @param {Number} obj 数值
  1401. * @return {Boolean}
  1402. */
  1403. function isFloat (obj) {
  1404. return !isNull(obj) && !isNaN(obj) && !isArray(obj) && !isInteger(obj)
  1405. }
  1406. /**
  1407. * 判断是否整数
  1408. *
  1409. * @param {Number, String} number 数值
  1410. * @return {Boolean}
  1411. */
  1412. var isInteger = function (obj) {
  1413. return !isNull(obj) && !isNaN(obj) && !isArray(obj) && obj % 1 === 0
  1414. }
  1415. /**
  1416. * 判断是否方法
  1417. *
  1418. * @param {Object} obj 对象
  1419. * @return {Boolean}
  1420. */
  1421. var isFunction = helperCreateInTypeof('function')
  1422. /**
  1423. * 判断是否Boolean对象
  1424. *
  1425. * @param {Object} obj 对象
  1426. * @return {Boolean}
  1427. */
  1428. var isBoolean = helperCreateInTypeof('boolean')
  1429. /**
  1430. * 判断是否String对象
  1431. *
  1432. * @param {Object} obj 对象
  1433. * @return {Boolean}
  1434. */
  1435. var isString = helperCreateInTypeof('string')
  1436. /**
  1437. * 判断是否Number对象
  1438. *
  1439. * @param {Object} obj 对象
  1440. * @return {Boolean}
  1441. */
  1442. var isNumber = helperCreateInTypeof('number')
  1443. /**
  1444. * 判断是否RegExp对象
  1445. *
  1446. * @param {Object} obj 对象
  1447. * @return {Boolean}
  1448. */
  1449. var isRegExp = helperCreateInInObjectString('RegExp')
  1450. /**
  1451. * 判断是否Object对象
  1452. *
  1453. * @param {Object} obj 对象
  1454. * @return {Boolean}
  1455. */
  1456. var isObject = helperCreateInTypeof('object')
  1457. /**
  1458. * 判断是否对象
  1459. *
  1460. * @param {Object} obj 对象
  1461. * @return {Boolean}
  1462. */
  1463. function isPlainObject (obj) {
  1464. return obj ? obj.constructor === Object : false
  1465. }
  1466. /**
  1467. * 判断是否Date对象
  1468. *
  1469. * @param {Object} obj 对象
  1470. * @return {Boolean}
  1471. */
  1472. var isDate = helperCreateInInObjectString('Date')
  1473. /**
  1474. * 判断是否Error对象
  1475. *
  1476. * @param {Object} obj 对象
  1477. * @return {Boolean}
  1478. */
  1479. var isError = helperCreateInInObjectString('Error')
  1480. /**
  1481. * 判断是否TypeError对象
  1482. *
  1483. * @param {Object} obj 对象
  1484. * @return {Boolean}
  1485. */
  1486. function isTypeError (obj) {
  1487. return obj ? obj.constructor === TypeError : false
  1488. }
  1489. /**
  1490. * 判断是否为空对象
  1491. *
  1492. * @param {Object} obj 对象
  1493. * @return {Boolean}
  1494. */
  1495. function isEmpty (obj) {
  1496. for (var key in obj) {
  1497. return false
  1498. }
  1499. return true
  1500. }
  1501. /**
  1502. * 判断是否为Null
  1503. *
  1504. * @param {Object} obj 对象
  1505. * @return {Boolean}
  1506. */
  1507. function isNull (obj) {
  1508. return obj === null
  1509. }
  1510. /* eslint-disable valid-typeof */
  1511. /**
  1512. * 判断是否Symbol对象
  1513. *
  1514. * @param {Object} obj 对象
  1515. * @return {Boolean}
  1516. */
  1517. var supportSymbol = typeof Symbol !== staticStrUndefined
  1518. function isSymbol (obj) {
  1519. return supportSymbol && Symbol.isSymbol ? Symbol.isSymbol(obj) : (typeof obj === 'symbol')
  1520. }
  1521. /**
  1522. * 判断是否Arguments对象
  1523. *
  1524. * @param {Object} obj 对象
  1525. * @return {Boolean}
  1526. */
  1527. var isArguments = helperCreateInInObjectString('Arguments')
  1528. /**
  1529. * 判断是否Element对象
  1530. *
  1531. * @param {Object} obj 对象
  1532. * @return {Boolean}
  1533. */
  1534. function isElement (obj) {
  1535. return !!(obj && isString(obj.nodeName) && isNumber(obj.nodeType))
  1536. }
  1537. /**
  1538. * 判断是否Document对象
  1539. *
  1540. * @param {Object} obj 对象
  1541. * @return {Boolean}
  1542. */
  1543. function isDocument (obj) {
  1544. return !!(obj && staticDocument && obj.nodeType === 9)
  1545. }
  1546. /**
  1547. * 判断是否Window对象
  1548. *
  1549. * @param {Object} obj 对象
  1550. * @return {Boolean}
  1551. */
  1552. function isWindow (obj) {
  1553. return !!(staticWindow && !!(obj && obj === obj.window))
  1554. }
  1555. /* eslint-disable valid-typeof */
  1556. /**
  1557. * 判断是否FormData对象
  1558. *
  1559. * @param {Object} obj 对象
  1560. * @return {Boolean}
  1561. */
  1562. var supportFormData = typeof FormData !== staticStrUndefined
  1563. function isFormData (obj) {
  1564. return supportFormData && obj instanceof FormData
  1565. }
  1566. /* eslint-disable valid-typeof */
  1567. /**
  1568. * 判断是否Map对象
  1569. *
  1570. * @param {Object} obj 对象
  1571. * @return {Boolean}
  1572. */
  1573. var supportMap = typeof Map !== staticStrUndefined
  1574. function isMap (obj) {
  1575. return supportMap && obj instanceof Map
  1576. }
  1577. /* eslint-disable valid-typeof */
  1578. /**
  1579. * 判断是否WeakMap对象
  1580. *
  1581. * @param {Object} obj 对象
  1582. * @return {Boolean}
  1583. */
  1584. var supportWeakMap = typeof WeakMap !== staticStrUndefined
  1585. function isWeakMap (obj) {
  1586. return supportWeakMap && obj instanceof WeakMap
  1587. }
  1588. /* eslint-disable valid-typeof */
  1589. /**
  1590. * 判断是否Set对象
  1591. *
  1592. * @param {Object} obj 对象
  1593. * @return {Boolean}
  1594. */
  1595. var supportSet = typeof Set !== staticStrUndefined
  1596. function isSet (obj) {
  1597. return supportSet && obj instanceof Set
  1598. }
  1599. /* eslint-disable valid-typeof */
  1600. /**
  1601. * 判断是否WeakSet对象
  1602. *
  1603. * @param {Object} obj 对象
  1604. * @return {Boolean}
  1605. */
  1606. var supportWeakSet = typeof WeakSet !== staticStrUndefined
  1607. function isWeakSet (obj) {
  1608. return supportWeakSet && obj instanceof WeakSet
  1609. }
  1610. /**
  1611. * 判断是否闰年
  1612. *
  1613. * @param {Date} date 日期或数字
  1614. * @return {Boolean}
  1615. */
  1616. function isLeapYear (date) {
  1617. var year
  1618. var currentDate = date ? toStringDate(date) : helperNewDate()
  1619. if (isDate(currentDate)) {
  1620. year = currentDate.getFullYear()
  1621. return (year % 4 === 0) && (year % 100 !== 0 || year % 400 === 0)
  1622. }
  1623. return false
  1624. }
  1625. /**
  1626. * 判断属性中的键和值是否包含在对象中
  1627. *
  1628. * @param {Object/Array} obj 对象
  1629. * @param {Object} source 值
  1630. * @return {Boolean}
  1631. */
  1632. function isMatch (obj, source) {
  1633. var objKeys = keys(obj)
  1634. var sourceKeys = keys(source)
  1635. if (sourceKeys.length) {
  1636. if (includeArrays(objKeys, sourceKeys)) {
  1637. return some(sourceKeys, function (key2) {
  1638. return findIndexOf(objKeys, function (key1) {
  1639. return key1 === key2 && isEqual(obj[key1], source[key2])
  1640. }) > -1
  1641. })
  1642. }
  1643. } else {
  1644. return true
  1645. }
  1646. return isEqual(obj, source)
  1647. }
  1648. /**
  1649. * 深度比较两个对象之间的值是否相等
  1650. *
  1651. * @param {Object} obj1 值1
  1652. * @param {Object} obj2 值2
  1653. * @return {Boolean}
  1654. */
  1655. function isEqual (obj1, obj2) {
  1656. return helperEqualCompare(obj1, obj2, helperDefaultCompare)
  1657. }
  1658. /**
  1659. * 深度比较两个对象之间的值是否相等,使用自定义比较函数
  1660. *
  1661. * @param {Object} obj1 值1
  1662. * @param {Object} obj2 值2
  1663. * @param {Function} func 自定义函数
  1664. * @return {Boolean}
  1665. */
  1666. function isEqualWith (obj1, obj2, func) {
  1667. if (isFunction(func)) {
  1668. return helperEqualCompare(obj1, obj2, function (v1, v2, key, obj1, obj2) {
  1669. var result = func(v1, v2, key, obj1, obj2)
  1670. return isUndefined(result) ? helperDefaultCompare(v1, v2) : !!result
  1671. }, func)
  1672. }
  1673. return helperEqualCompare(obj1, obj2, helperDefaultCompare)
  1674. }
  1675. /**
  1676. * 获取对象类型
  1677. *
  1678. * @param {Object} obj 对象
  1679. * @return {String}
  1680. */
  1681. function getType (obj) {
  1682. if (isNull(obj)) {
  1683. return 'null'
  1684. }
  1685. if (isSymbol(obj)) {
  1686. return 'symbol'
  1687. }
  1688. if (isDate(obj)) {
  1689. return 'date'
  1690. }
  1691. if (isArray(obj)) {
  1692. return 'array'
  1693. }
  1694. if (isRegExp(obj)) {
  1695. return 'regexp'
  1696. }
  1697. if (isError(obj)) {
  1698. return 'error'
  1699. }
  1700. return typeof obj
  1701. }
  1702. /**
  1703. * 获取一个全局唯一标识
  1704. *
  1705. * @param {String} prefix 前缀
  1706. * @return {Number}
  1707. */
  1708. function uniqueId (prefix) {
  1709. return '' + (eqNull(prefix) ? '' : prefix) + (setupDefaults.keyId++)
  1710. }
  1711. /**
  1712. * 返回对象的长度
  1713. *
  1714. * @param {Object} obj 对象
  1715. * @return {Number}
  1716. */
  1717. function getSize (obj) {
  1718. var len = 0
  1719. if (isString(obj) || isArray(obj)) {
  1720. return obj.length
  1721. }
  1722. each(obj, function () {
  1723. len++
  1724. })
  1725. return len
  1726. }
  1727. /**
  1728. * 返回对象第一个索引值
  1729. *
  1730. * @param {Object} obj 对象
  1731. * @param {Object} val 值
  1732. * @return {Number}
  1733. */
  1734. var indexOf = helperCreateIndexOf('indexOf', arrayIndexOf)
  1735. /**
  1736. * 从最后开始的索引值,返回对象第一个索引值
  1737. *
  1738. * @param {Object} array 对象
  1739. * @param {Object} val 值
  1740. * @return {Number}
  1741. */
  1742. var lastIndexOf = helperCreateIndexOf('lastIndexOf', arrayLastIndexOf)
  1743. /**
  1744. * 返回对象第一个索引值
  1745. *
  1746. * @param {Object} obj 对象/数组
  1747. * @param {Function} iterate(item, index, obj) 回调
  1748. * @param {Object} context 上下文
  1749. * @return {Object}
  1750. */
  1751. var findIndexOf = helperCreateiterateIndexOf(function (obj, iterate, context) {
  1752. for (var index = 0, len = obj.length; index < len; index++) {
  1753. if (iterate.call(context, obj[index], index, obj)) {
  1754. return index
  1755. }
  1756. }
  1757. return -1
  1758. })
  1759. /**
  1760. * 从最后开始的索引值,返回对象第一个索引值
  1761. *
  1762. * @param {Object} obj 对象/数组
  1763. * @param {Function} iterate(item, index, obj) 回调
  1764. * @param {Object} context 上下文
  1765. * @return {Object}
  1766. */
  1767. var findLastIndexOf = helperCreateiterateIndexOf(function (obj, iterate, context) {
  1768. for (var len = obj.length - 1; len >= 0; len--) {
  1769. if (iterate.call(context, obj[len], len, obj)) {
  1770. return len
  1771. }
  1772. }
  1773. return -1
  1774. })
  1775. /**
  1776. * 字符串转JSON
  1777. *
  1778. * @param {String} str 字符串
  1779. * @return {Object} 返回转换后对象
  1780. */
  1781. function toStringJSON (str) {
  1782. if (isPlainObject(str)) {
  1783. return str
  1784. } else if (isString(str)) {
  1785. try {
  1786. return JSON.parse(str)
  1787. } catch (e) {}
  1788. }
  1789. return {}
  1790. }
  1791. /**
  1792. * JSON转字符串
  1793. *
  1794. * @param {Object} obj 对象
  1795. * @return {String} 返回字符串
  1796. */
  1797. function toJSONString (obj) {
  1798. return eqNull(obj) ? '' : JSON.stringify(obj)
  1799. }
  1800. /**
  1801. * 获取对象所有属性
  1802. *
  1803. * @param {Object} obj 对象/数组
  1804. * @return {Array}
  1805. */
  1806. var keys = helperCreateGetObjects('keys', 1)
  1807. /**
  1808. * 获取对象所有值
  1809. *
  1810. * @param {Object} obj 对象/数组
  1811. * @return {Array}
  1812. */
  1813. var values = helperCreateGetObjects('values', 0)
  1814. /**
  1815. * 获取对象所有属性、值
  1816. *
  1817. * @param {Object} obj 对象/数组
  1818. * @return {Array}
  1819. */
  1820. var entries = helperCreateGetObjects('entries', 2)
  1821. /**
  1822. * 根据 key 过滤指定的属性值,返回一个新的对象
  1823. *
  1824. * @param {Object} obj 对象
  1825. * @param {String/Array} key 键数组
  1826. * @return {Object}
  1827. */
  1828. var pick = helperCreatePickOmit(1, 0)
  1829. /**
  1830. * 根据 key 排除指定的属性值,返回一个新的对象
  1831. *
  1832. * @param {Object} obj 对象
  1833. * @param {String/Array} key 键数组
  1834. * @return {Object}
  1835. */
  1836. var omit = helperCreatePickOmit(0, 1)
  1837. /**
  1838. * 获取对象第一个值
  1839. *
  1840. * @param {Object} obj 对象/数组
  1841. * @return {Object}
  1842. */
  1843. function first (obj) {
  1844. return values(obj)[0]
  1845. }
  1846. /**
  1847. * 获取对象最后一个值
  1848. *
  1849. * @param {Object} obj 对象/数组
  1850. * @return {Object}
  1851. */
  1852. function last (obj) {
  1853. var list = values(obj)
  1854. return list[list.length - 1]
  1855. }
  1856. /**
  1857. * 迭代器
  1858. *
  1859. * @param {Object} obj 对象/数组
  1860. * @param {Function} iterate(item, index, obj) 回调
  1861. * @param {Object} context 上下文
  1862. * @return {Object}
  1863. */
  1864. function each (obj, iterate, context) {
  1865. if (obj) {
  1866. return (isArray(obj) ? arrayEach : objectEach)(obj, iterate, context)
  1867. }
  1868. return obj
  1869. }
  1870. /**
  1871. * 已废弃,被 some, every 替换
  1872. * @deprecated
  1873. */
  1874. function forOf (obj, iterate, context) {
  1875. if (obj) {
  1876. if (isArray(obj)) {
  1877. for (var index = 0, len = obj.length; index < len; index++) {
  1878. if (iterate.call(context, obj[index], index, obj) === false) {
  1879. break
  1880. }
  1881. }
  1882. } else {
  1883. for (var key in obj) {
  1884. if (hasOwnProp(obj, key)) {
  1885. if (iterate.call(context, obj[key], key, obj) === false) {
  1886. break
  1887. }
  1888. }
  1889. }
  1890. }
  1891. }
  1892. }
  1893. /**
  1894. * 已废弃
  1895. * @deprecated
  1896. */
  1897. function lastForOf (obj, iterate, context) {
  1898. if (obj) {
  1899. var len, list
  1900. if (isArray(obj)) {
  1901. for (len = obj.length - 1; len >= 0; len--) {
  1902. if (iterate.call(context, obj[len], len, obj) === false) {
  1903. break
  1904. }
  1905. }
  1906. } else {
  1907. list = keys(obj)
  1908. for (len = list.length - 1; len >= 0; len--) {
  1909. if (iterate.call(context, obj[list[len]], list[len], obj) === false) {
  1910. break
  1911. }
  1912. }
  1913. }
  1914. }
  1915. }
  1916. /**
  1917. * 迭代器,从最后开始迭代
  1918. *
  1919. * @param {Object} obj 对象/数组
  1920. * @param {Function} iterate(item, index, obj) 回调
  1921. * @param {Object} context 上下文
  1922. * @return {Object}
  1923. */
  1924. function lastEach (obj, iterate, context) {
  1925. if (obj) {
  1926. return (isArray(obj) ? lastArrayEach : lastObjectEach)(obj, iterate, context)
  1927. }
  1928. return obj
  1929. }
  1930. /**
  1931. * 检查键、路径是否是该对象的属性
  1932. *
  1933. * @param {Object/Array} data 对象
  1934. * @param {String/Function} property 键、路径
  1935. * @return {Boolean}
  1936. */
  1937. function has (obj, property) {
  1938. if (obj) {
  1939. if (hasOwnProp(obj, property)) {
  1940. return true
  1941. } else {
  1942. var prop, arrIndex, objProp, matchs, rest, isHas
  1943. var props = helperGetHGSKeys(property)
  1944. var index = 0
  1945. var len = props.length
  1946. for (rest = obj; index < len; index++) {
  1947. isHas = false
  1948. prop = props[index]
  1949. matchs = prop ? prop.match(staticHGKeyRE) : ''
  1950. if (matchs) {
  1951. arrIndex = matchs[1]
  1952. objProp = matchs[2]
  1953. if (arrIndex) {
  1954. if (rest[arrIndex]) {
  1955. if (hasOwnProp(rest[arrIndex], objProp)) {
  1956. isHas = true
  1957. rest = rest[arrIndex][objProp]
  1958. }
  1959. }
  1960. } else {
  1961. if (hasOwnProp(rest, objProp)) {
  1962. isHas = true
  1963. rest = rest[objProp]
  1964. }
  1965. }
  1966. } else {
  1967. if (hasOwnProp(rest, prop)) {
  1968. isHas = true
  1969. rest = rest[prop]
  1970. }
  1971. }
  1972. if (isHas) {
  1973. if (index === len - 1) {
  1974. return true
  1975. }
  1976. } else {
  1977. break
  1978. }
  1979. }
  1980. }
  1981. }
  1982. return false
  1983. }
  1984. /**
  1985. * 获取对象的属性的值,如果值为 undefined,则返回默认值
  1986. * @param {Object/Array} obj 对象
  1987. * @param {String/Function} property 键、路径
  1988. * @param {Object} defaultValue 默认值
  1989. * @return {Object}
  1990. */
  1991. function get (obj, property, defaultValue) {
  1992. if (eqNull(obj)) {
  1993. return defaultValue
  1994. }
  1995. var result = getValueByPath(obj, property)
  1996. return isUndefined(result) ? defaultValue : result
  1997. }
  1998. function getDeepProps (obj, key) {
  1999. var matchs = key ? key.match(staticHGKeyRE) : ''
  2000. return matchs ? (matchs[1] ? (obj[matchs[1]] ? obj[matchs[1]][matchs[2]] : undefined) : obj[matchs[2]]) : obj[key]
  2001. }
  2002. function getValueByPath (obj, property) {
  2003. if (obj) {
  2004. var rest, props, len
  2005. var index = 0
  2006. if (obj[property] || hasOwnProp(obj, property)) {
  2007. return obj[property]
  2008. } else {
  2009. props = helperGetHGSKeys(property)
  2010. len = props.length
  2011. if (len) {
  2012. for (rest = obj; index < len; index++) {
  2013. rest = getDeepProps(rest, props[index])
  2014. if (eqNull(rest)) {
  2015. if (index === len - 1) {
  2016. return rest
  2017. }
  2018. return
  2019. }
  2020. }
  2021. }
  2022. return rest
  2023. }
  2024. }
  2025. }
  2026. var sKeyRE = /(.+)?\[(\d+)\]$/
  2027. function setDeepProps (obj, key, isEnd, nextKey, value) {
  2028. if (obj[key]) {
  2029. if (isEnd) {
  2030. obj[key] = value
  2031. }
  2032. } else {
  2033. var index
  2034. var rest
  2035. var currMatchs = key ? key.match(sKeyRE) : null
  2036. if (isEnd) {
  2037. rest = value
  2038. } else {
  2039. var nextMatchs = nextKey ? nextKey.match(sKeyRE) : null
  2040. if (nextMatchs && !nextMatchs[1]) {
  2041. // 如果下一个属性为数组类型
  2042. rest = new Array(staticParseInt(nextMatchs[2]) + 1)
  2043. } else {
  2044. rest = {}
  2045. }
  2046. }
  2047. if (currMatchs) {
  2048. if (currMatchs[1]) {
  2049. // 如果为对象中数组
  2050. index = staticParseInt(currMatchs[2])
  2051. if (obj[currMatchs[1]]) {
  2052. if (isEnd) {
  2053. obj[currMatchs[1]][index] = rest
  2054. } else {
  2055. if (obj[currMatchs[1]][index]) {
  2056. rest = obj[currMatchs[1]][index]
  2057. } else {
  2058. obj[currMatchs[1]][index] = rest
  2059. }
  2060. }
  2061. } else {
  2062. obj[currMatchs[1]] = new Array(index + 1)
  2063. obj[currMatchs[1]][index] = rest
  2064. }
  2065. } else {
  2066. // 如果为数组
  2067. obj[currMatchs[2]] = rest
  2068. }
  2069. } else {
  2070. // 如果为对象
  2071. obj[key] = rest
  2072. }
  2073. return rest
  2074. }
  2075. return obj[key]
  2076. }
  2077. /**
  2078. * 设置对象属性上的值。如果属性不存在则创建它
  2079. * @param {Object/Array} obj 对象
  2080. * @param {String/Function} property 键、路径
  2081. * @param {Object} value 值
  2082. */
  2083. function set (obj, property, value) {
  2084. if (obj && helperCheckCopyKey(property)) {
  2085. if ((obj[property] || hasOwnProp(obj, property)) && !isPrototypePolluted(property)) {
  2086. obj[property] = value
  2087. } else {
  2088. var rest = obj
  2089. var props = helperGetHGSKeys(property)
  2090. var len = props.length
  2091. for (var index = 0; index < len; index++) {
  2092. if (isPrototypePolluted(props[index])) {
  2093. continue
  2094. }
  2095. var isEnd = index === len - 1
  2096. rest = setDeepProps(rest, props[index], isEnd, isEnd ? null : props[index + 1], value)
  2097. }
  2098. }
  2099. }
  2100. return obj
  2101. }
  2102. /**
  2103. * Blacklist certain keys to prevent Prototype Pollution
  2104. * @param {string} key
  2105. */
  2106. function isPrototypePolluted(key) {
  2107. return key === '__proto__' || key === 'constructor' || key === 'prototype'
  2108. }
  2109. function createiterateEmpty (iterate) {
  2110. return function () {
  2111. return isEmpty(iterate)
  2112. }
  2113. }
  2114. /**
  2115. * 集合分组,默认使用键值分组,如果有iterate则使用结果进行分组
  2116. *
  2117. * @param {Array} obj 对象
  2118. * @param {Function} iterate 回调/对象属性
  2119. * @param {Object} context 上下文
  2120. * @return {Object}
  2121. */
  2122. function groupBy (obj, iterate, context) {
  2123. var groupKey
  2124. var result = {}
  2125. if (obj) {
  2126. if (iterate && isObject(iterate)) {
  2127. iterate = createiterateEmpty(iterate)
  2128. } else if (!isFunction(iterate)) {
  2129. iterate = property(iterate)
  2130. }
  2131. each(obj, function (val, key) {
  2132. groupKey = iterate ? iterate.call(context, val, key, obj) : val
  2133. if (result[groupKey]) {
  2134. result[groupKey].push(val)
  2135. } else {
  2136. result[groupKey] = [val]
  2137. }
  2138. })
  2139. }
  2140. return result
  2141. }
  2142. /**
  2143. * 集合分组统计,返回各组中对象的数量统计
  2144. *
  2145. * @param {Array} obj 对象
  2146. * @param {Function} iterate 回调/对象属性
  2147. * @param {Object} context 上下文
  2148. * @return {Object}
  2149. */
  2150. function countBy (obj, iterate, context) {
  2151. var result = groupBy(obj, iterate, context || this)
  2152. objectEach(result, function (item, key) {
  2153. result[key] = item.length
  2154. })
  2155. return result
  2156. }
  2157. function getCativeCtor (val, args) {
  2158. var Ctor = val.__proto__.constructor
  2159. return args ? new Ctor(args) : new Ctor()
  2160. }
  2161. function handleValueClone (item, isDeep) {
  2162. return isDeep ? copyValue(item, isDeep) : item
  2163. }
  2164. function copyValue (val, isDeep) {
  2165. if (val) {
  2166. switch(objectToString.call(val)) {
  2167. case "[object Object]": {
  2168. var restObj = Object.create(Object.getPrototypeOf(val))
  2169. objectEach(val, function (item, key) {
  2170. restObj[key] = handleValueClone(item, isDeep)
  2171. })
  2172. return restObj
  2173. }
  2174. case "[object Date]":
  2175. case "[object RegExp]": {
  2176. return getCativeCtor(val, val.valueOf())
  2177. }
  2178. case "[object Array]":
  2179. case "[object Arguments]": {
  2180. var restArr = []
  2181. arrayEach(val, function (item) {
  2182. restArr.push(handleValueClone(item, isDeep))
  2183. })
  2184. return restArr
  2185. }
  2186. case "[object Set]": {
  2187. var restSet = getCativeCtor(val)
  2188. restSet.forEach(function (item) {
  2189. restSet.add(handleValueClone(item, isDeep))
  2190. })
  2191. return restSet
  2192. }
  2193. case "[object Map]": {
  2194. var restMap = getCativeCtor(val)
  2195. restMap.forEach(function (item, key) {
  2196. restMap.set(key, handleValueClone(item, isDeep))
  2197. })
  2198. return restMap
  2199. }
  2200. }
  2201. }
  2202. return val
  2203. }
  2204. /**
  2205. * 浅拷贝/深拷贝
  2206. *
  2207. * @param {Object} obj 对象/数组
  2208. * @param {Boolean} deep 是否深拷贝
  2209. * @return {Object}
  2210. */
  2211. function clone (obj, deep) {
  2212. if (obj) {
  2213. return copyValue(obj, deep)
  2214. }
  2215. return obj
  2216. }
  2217. /**
  2218. * 清空对象
  2219. *
  2220. * @param {Object} obj 对象
  2221. * @param {*} defs 默认值,如果不传(清空所有属性)、如果传对象(清空并继承)、如果传值(给所有赋值)
  2222. * @param {Object/Array} assigns 默认值
  2223. * @return {Object}
  2224. */
  2225. function clear (obj, defs, assigns) {
  2226. if (obj) {
  2227. var len
  2228. var isDefs = arguments.length > 1 && (isNull(defs) || !isObject(defs))
  2229. var extds = isDefs ? assigns : defs
  2230. if (isPlainObject(obj)) {
  2231. objectEach(obj, isDefs ? function (val, key) {
  2232. obj[key] = defs
  2233. } : function (val, key) {
  2234. helperDeleteProperty(obj, key)
  2235. })
  2236. if (extds) {
  2237. assign(obj, extds)
  2238. }
  2239. } else if (isArray(obj)) {
  2240. if (isDefs) {
  2241. len = obj.length
  2242. while (len > 0) {
  2243. len--
  2244. obj[len] = defs
  2245. }
  2246. } else {
  2247. obj.length = 0
  2248. }
  2249. if (extds) {
  2250. obj.push.apply(obj, extds)
  2251. }
  2252. }
  2253. }
  2254. return obj
  2255. }
  2256. function pluckProperty (name) {
  2257. return function (obj, key) {
  2258. return key === name
  2259. }
  2260. }
  2261. /**
  2262. * 移除对象属性
  2263. *
  2264. * @param {Object/Array} obj 对象/数组
  2265. * @param {Function/String} iterate 方法或属性
  2266. * @param {Object} context 上下文
  2267. * @return {Object/Array}
  2268. */
  2269. function remove (obj, iterate, context) {
  2270. if (obj) {
  2271. if (!eqNull(iterate)) {
  2272. var removeKeys = []
  2273. var rest = []
  2274. if (!isFunction(iterate)) {
  2275. iterate = pluckProperty(iterate)
  2276. }
  2277. each(obj, function (item, index, rest) {
  2278. if (iterate.call(context, item, index, rest)) {
  2279. removeKeys.push(index)
  2280. }
  2281. })
  2282. if (isArray(obj)) {
  2283. lastEach(removeKeys, function (item, key) {
  2284. rest.push(obj[item])
  2285. obj.splice(item, 1)
  2286. })
  2287. } else {
  2288. rest = {}
  2289. arrayEach(removeKeys, function (key) {
  2290. rest[key] = obj[key]
  2291. helperDeleteProperty(obj, key)
  2292. })
  2293. }
  2294. return rest
  2295. }
  2296. return clear(obj)
  2297. }
  2298. return obj
  2299. }
  2300. /**
  2301. * 序号列表生成函数
  2302. *
  2303. * @param {Number} start 起始值
  2304. * @param {Number} stop 结束值
  2305. * @param {Number} step 自增值
  2306. * @return {Array}
  2307. */
  2308. function range (start, stop, step) {
  2309. var index, len
  2310. var result = []
  2311. var args = arguments
  2312. if (args.length < 2) {
  2313. stop = args[0]
  2314. start = 0
  2315. }
  2316. index = start >> 0
  2317. len = stop >> 0
  2318. if (index < stop) {
  2319. step = step >> 0 || 1
  2320. for (; index < len; index += step) {
  2321. result.push(index)
  2322. }
  2323. }
  2324. return result
  2325. }
  2326. /**
  2327. * 将一个或者多个对象值解构到目标对象
  2328. *
  2329. * @param {Object} destination 目标对象
  2330. * @param {...Object}
  2331. * @return {Boolean}
  2332. */
  2333. function destructuring (destination, sources) {
  2334. if (destination && sources) {
  2335. var rest = assign.apply(this, [{}].concat(slice(arguments, 1)))
  2336. var restKeys = keys(rest)
  2337. arrayEach(keys(destination), function (key) {
  2338. if (includes(restKeys, key)) {
  2339. destination[key] = rest[key]
  2340. }
  2341. })
  2342. }
  2343. return destination
  2344. }
  2345. /**
  2346. * 获取一个指定范围内随机数
  2347. *
  2348. * @param {Number} minVal 最小值
  2349. * @param {Number} maxVal 最大值
  2350. * @return {Number}
  2351. */
  2352. function random (minVal, maxVal) {
  2353. return minVal >= maxVal ? minVal : ((minVal = minVal >> 0) + Math.round(Math.random() * ((maxVal || 9) - minVal)))
  2354. }
  2355. /**
  2356. * 获取最小值
  2357. *
  2358. * @param {Array} arr 数组
  2359. * @param {Function} iterate(item, index, obj) 回调
  2360. * @return {Number}
  2361. */
  2362. var min = helperCreateMinMax(function (rest, itemVal) {
  2363. return rest > itemVal
  2364. })
  2365. /**
  2366. * 获取最大值
  2367. *
  2368. * @param {Array} arr 数组
  2369. * @param {Function} iterate(item, index, obj) 回调
  2370. * @return {Number}
  2371. */
  2372. var max = helperCreateMinMax(function (rest, itemVal) {
  2373. return rest < itemVal
  2374. })
  2375. /**
  2376. * 千分位分隔符、小数点
  2377. *
  2378. * @param {String/Number} num 数值
  2379. * @param {CommafyOptions} options 参数
  2380. * @return {String}
  2381. */
  2382. function commafy(num, options) {
  2383. var opts = assign({}, setupDefaults.commafyOptions, options)
  2384. var optDigits = opts.digits
  2385. var isNum = isNumber(num)
  2386. var rest, result, isNegative, intStr, floatStr
  2387. if (isNum) {
  2388. rest = (opts.ceil ? ceil : (opts.floor ? floor : round))(num, optDigits)
  2389. result = toNumberString(optDigits ? toFixed(rest, optDigits) : rest).split('.')
  2390. intStr = result[0]
  2391. floatStr = result[1]
  2392. isNegative = intStr && rest < 0
  2393. if (isNegative) {
  2394. intStr = intStr.substring(1, intStr.length)
  2395. }
  2396. } else {
  2397. rest = toValueString(num).replace(/,/g, '')
  2398. result = rest ? [rest] : []
  2399. intStr = result[0]
  2400. }
  2401. if (result.length) {
  2402. return (isNegative ? '-' : '') + intStr.replace(new RegExp('(?=(?!(\\b))(.{' + (opts.spaceNumber || 3) + '})+$)', 'g'), (opts.separator || ',')) + (floatStr ? ('.' + floatStr) : '')
  2403. }
  2404. return rest
  2405. }
  2406. /**
  2407. * 将数值四舍五入
  2408. *
  2409. * @param {string|number} num 数值
  2410. * @param {number} digits 小数保留位数
  2411. * @return {number}
  2412. */
  2413. var round = helperCreateMathNumber('round')
  2414. /**
  2415. * 将数值向上舍入
  2416. *
  2417. * @param {string|number} num 数值
  2418. * @param {number} digits 小数保留位数
  2419. * @return {number}
  2420. */
  2421. var ceil = helperCreateMathNumber('ceil')
  2422. /**
  2423. * 将数值向下舍入
  2424. *
  2425. * @param {string|number} num 数值
  2426. * @param {number} digits 小数保留位数
  2427. * @return {number}
  2428. */
  2429. var floor = helperCreateMathNumber('floor')
  2430. /**
  2431. * 将数值四舍五入并格式化为固定小数位的字符串
  2432. *
  2433. * @param {string|number} num 数值
  2434. * @param {number} digits 小数保留位数
  2435. * @return {String}
  2436. */
  2437. function toFixed (num, digits) {
  2438. digits = digits >> 0
  2439. var str = toValueString(round(num, digits))
  2440. var nums = str.split('.')
  2441. var intStr = nums[0]
  2442. var floatStr = nums[1] || ''
  2443. var digitOffsetIndex = digits - floatStr.length
  2444. if (digits) {
  2445. if (digitOffsetIndex > 0) {
  2446. return intStr + '.' + floatStr + helperStringRepeat('0', digitOffsetIndex)
  2447. }
  2448. return intStr + helperNumberOffsetPoint(floatStr, Math.abs(digitOffsetIndex))
  2449. }
  2450. return intStr
  2451. }
  2452. /**
  2453. * 转数值
  2454. * @param { String/Number } str 数值
  2455. *
  2456. * @return {Number}
  2457. */
  2458. var toNumber = helperCreateToNumber(parseFloat)
  2459. /**
  2460. * 数值转字符串,科学计数转字符串
  2461. * @param { Number } num 数值
  2462. *
  2463. * @return {Number}
  2464. */
  2465. function toNumberString(num) {
  2466. var rest = '' + num
  2467. var scienceMatchs = rest.match(/^([-+]?)((\d+)|((\d+)?[.](\d+)?))e([-+]{1})([0-9]+)$/)
  2468. if (scienceMatchs) {
  2469. var isNegative = num < 0
  2470. var absFlag = isNegative ? '-' : ''
  2471. var intNumStr = scienceMatchs[3] || ''
  2472. var dIntNumStr = scienceMatchs[5] || ''
  2473. var dFloatNumStr = scienceMatchs[6] || ''
  2474. var sciencFlag = scienceMatchs[7]
  2475. var scienceNumStr = scienceMatchs[8]
  2476. var floatOffsetIndex = scienceNumStr - dFloatNumStr.length
  2477. var intOffsetIndex = scienceNumStr - intNumStr.length
  2478. var dIntOffsetIndex = scienceNumStr - dIntNumStr.length
  2479. if (sciencFlag === '+') {
  2480. if (intNumStr) {
  2481. return absFlag + intNumStr + helperStringRepeat('0', scienceNumStr)
  2482. }
  2483. if (floatOffsetIndex > 0) {
  2484. return absFlag + dIntNumStr + dFloatNumStr + helperStringRepeat('0', floatOffsetIndex)
  2485. }
  2486. return absFlag + dIntNumStr + helperNumberOffsetPoint(dFloatNumStr, scienceNumStr)
  2487. }
  2488. if (intNumStr) {
  2489. if (intOffsetIndex > 0) {
  2490. return absFlag + '0.' + helperStringRepeat('0', Math.abs(intOffsetIndex)) + intNumStr
  2491. }
  2492. return absFlag + helperNumberOffsetPoint(intNumStr, intOffsetIndex)
  2493. }
  2494. if (dIntOffsetIndex > 0) {
  2495. return absFlag + '0.' + helperStringRepeat('0', Math.abs(dIntOffsetIndex)) + dIntNumStr + dFloatNumStr
  2496. }
  2497. return absFlag + helperNumberOffsetPoint(dIntNumStr, dIntOffsetIndex) + dFloatNumStr
  2498. }
  2499. return rest
  2500. }
  2501. /**
  2502. * 转整数
  2503. * @param { String/Number } str 数值
  2504. *
  2505. * @return {Number}
  2506. */
  2507. var toInteger = helperCreateToNumber(staticParseInt)
  2508. /**
  2509. * 加法运算
  2510. *
  2511. * @param { Number } num1 被加数
  2512. * @param { Number } num2 加数
  2513. * @return {Number}
  2514. */
  2515. function add (num1, num2) {
  2516. return helperNumberAdd(toNumber(num1), toNumber(num2))
  2517. }
  2518. /**
  2519. * 减法运算
  2520. *
  2521. * @param { Number } num1 被减数
  2522. * @param { Number } num2 减数
  2523. * @return {Number}
  2524. */
  2525. function subtract (num1, num2) {
  2526. var subtrahend = toNumber(num1)
  2527. var minuend = toNumber(num2)
  2528. var str1 = toNumberString(subtrahend)
  2529. var str2 = toNumberString(minuend)
  2530. var digit1 = helperNumberDecimal(str1)
  2531. var digit2 = helperNumberDecimal(str2)
  2532. var ratio = Math.pow(10, Math.max(digit1, digit2))
  2533. var precision = (digit1 >= digit2) ? digit1 : digit2
  2534. return parseFloat(toFixed((subtrahend * ratio - minuend * ratio) / ratio, precision))
  2535. }
  2536. /**
  2537. * 乘法运算
  2538. *
  2539. * @param { Number } num1 数值1
  2540. * @param { Number } num2 数值2
  2541. * @return {Number}
  2542. */
  2543. function multiply (num1, num2) {
  2544. var multiplier = toNumber(num1)
  2545. var multiplicand = toNumber(num2)
  2546. return helperMultiply(multiplier, multiplicand)
  2547. }
  2548. /**
  2549. * 除法运算
  2550. *
  2551. * @param { Number } num1 数值1
  2552. * @param { Number } num2 数值2
  2553. * @return {Number}
  2554. */
  2555. function divide (num1, num2) {
  2556. return helperNumberDivide(toNumber(num1), toNumber(num2))
  2557. }
  2558. /**
  2559. * 求和函数,将数值相加
  2560. *
  2561. * @param {Array} array 数组
  2562. * @param {Function/String} iterate 方法或属性
  2563. * @param {Object} context 上下文
  2564. * @return {Number}
  2565. */
  2566. function sum (array, iterate, context) {
  2567. var result = 0
  2568. each(array && array.length > 2 && isArray(array) ? array.sort() : array, iterate ? isFunction(iterate) ? function () {
  2569. result = helperNumberAdd(result, iterate.apply(context, arguments))
  2570. } : function (val) {
  2571. result = helperNumberAdd(result, get(val, iterate))
  2572. } : function (val) {
  2573. result = helperNumberAdd(result, val)
  2574. })
  2575. return result
  2576. }
  2577. /**
  2578. * 求平均值函数
  2579. *
  2580. * @param {Array} array 数组
  2581. * @param {Function/String} iterate 方法或属性
  2582. * @param {Object} context 上下文
  2583. * @return {Number}
  2584. */
  2585. function mean (array, iterate, context) {
  2586. return helperNumberDivide(sum(array, iterate, context), getSize(array))
  2587. }
  2588. /**
  2589. * 返回当前时间戳
  2590. *
  2591. * @returns Number
  2592. */
  2593. var now = Date.now || function () {
  2594. return helperGetDateTime(helperNewDate())
  2595. }
  2596. /**
  2597. * 将日期格式化为时间戳
  2598. *
  2599. * @param {String/Number/Date} str 日期或数字
  2600. * @param {String} format 解析日期格式
  2601. * @returns Number
  2602. */
  2603. var timestamp = function (str, format) {
  2604. if (str) {
  2605. var date = toStringDate(str, format)
  2606. return isDate(date) ? helperGetDateTime(date) : date
  2607. }
  2608. return now()
  2609. }
  2610. /**
  2611. * 判断是否有效的Date对象
  2612. *
  2613. * @param {any} val 对象
  2614. * @return {boolean}
  2615. */
  2616. function isValidDate (val) {
  2617. return isDate(val) && !isNaN(helperGetDateTime(val))
  2618. }
  2619. /**
  2620. * 比较两个日期
  2621. *
  2622. * @param {Number/String/Date} date1 日期
  2623. * @param {Number/String/Date} date2 日期
  2624. * @param {String} format 对比格式
  2625. */
  2626. function isDateSame (date1, date2, format) {
  2627. if (date1 && date2) {
  2628. date1 = toDateString(date1, format)
  2629. return date1 !== 'Invalid Date' && date1 === toDateString(date2, format)
  2630. }
  2631. return false
  2632. }
  2633. function getParseRule (txt) {
  2634. return '(\\d{' + txt + '})'
  2635. }
  2636. function toParseMs (num) {
  2637. if (num < 10) {
  2638. return num * 100
  2639. } else if (num < 100) {
  2640. return num * 10
  2641. }
  2642. return num
  2643. }
  2644. function toParseNum (num) {
  2645. return isNaN(num) ? num : staticParseInt(num)
  2646. }
  2647. var d2 = getParseRule(2)
  2648. var d1or2 = getParseRule('1,2')
  2649. var d1or7 = getParseRule('1,7')
  2650. var d3or4 = getParseRule('3,4')
  2651. var place = '.{1}'
  2652. var d1Or2RE = place + d1or2
  2653. var dzZ = '(([zZ])|([-+]\\d{2}:?\\d{2}))'
  2654. var defaulParseStrs = [d3or4, d1Or2RE, d1Or2RE, d1Or2RE, d1Or2RE, d1Or2RE, place + d1or7, dzZ]
  2655. var defaulParseREs = []
  2656. for (var len = defaulParseStrs.length - 1; len >= 0; len--) {
  2657. var rule = ''
  2658. for (var i = 0; i < len + 1; i++) {
  2659. rule += defaulParseStrs[i]
  2660. }
  2661. defaulParseREs.push(new RegExp('^' + rule + '$'))
  2662. }
  2663. /**
  2664. * 解析默认格式
  2665. */
  2666. function parseDefaultRules (str) {
  2667. var matchRest, resMaps = {}
  2668. for (var i = 0, dfrLen = defaulParseREs.length; i < dfrLen; i++) {
  2669. matchRest = str.match(defaulParseREs[i])
  2670. if (matchRest) {
  2671. resMaps.y = matchRest[1]
  2672. resMaps.M = matchRest[2]
  2673. resMaps.d = matchRest[3]
  2674. resMaps.H = matchRest[4]
  2675. resMaps.m = matchRest[5]
  2676. resMaps.s = matchRest[6]
  2677. resMaps.S = matchRest[7]
  2678. resMaps.Z = matchRest[8]
  2679. break
  2680. }
  2681. }
  2682. return resMaps
  2683. }
  2684. var customParseStrs = [
  2685. ['yyyy', d3or4],
  2686. ['yy', d2],
  2687. ['MM', d2],
  2688. ['M', d1or2],
  2689. ['dd', d2],
  2690. ['d', d1or2],
  2691. ['HH', d2],
  2692. ['H', d1or2],
  2693. ['mm', d2],
  2694. ['m', d1or2],
  2695. ['ss', d2],
  2696. ['s', d1or2],
  2697. ['SSS', getParseRule(3)],
  2698. ['S', d1or7],
  2699. ['Z', dzZ]
  2700. ]
  2701. var parseRuleMaps = {}
  2702. var parseRuleKeys = ['\\[([^\\]]+)\\]']
  2703. for (var i = 0; i < customParseStrs.length; i++) {
  2704. var itemRule = customParseStrs[i]
  2705. parseRuleMaps[itemRule[0]] = itemRule[1] + '?'
  2706. parseRuleKeys.push(itemRule[0])
  2707. }
  2708. var customParseRes = new RegExp(parseRuleKeys.join('|'), 'g')
  2709. var cacheFormatMaps = {}
  2710. /**
  2711. * 解析自定义格式
  2712. */
  2713. function parseCustomRules (str, format) {
  2714. var cacheItem = cacheFormatMaps[format]
  2715. if (!cacheItem) {
  2716. var posIndexs = []
  2717. var re = format.replace(/([$(){}*+.?\\^|])/g, "\\$1").replace(customParseRes, function (text, val) {
  2718. var firstChar = text.charAt(0)
  2719. // 如果为转义符号:[关键字]
  2720. if (firstChar === '[') {
  2721. return val
  2722. }
  2723. posIndexs.push(firstChar)
  2724. return parseRuleMaps[text]
  2725. })
  2726. cacheItem = cacheFormatMaps[format] = {
  2727. _i: posIndexs,
  2728. _r: new RegExp(re)
  2729. }
  2730. }
  2731. var resMaps = {}
  2732. var matchRest = str.match(cacheItem._r)
  2733. if (matchRest) {
  2734. var _i = cacheItem._i
  2735. for (var i = 1, len = matchRest.length; i < len; i++) {
  2736. resMaps[_i[i - 1]] = matchRest[i]
  2737. }
  2738. return resMaps
  2739. }
  2740. return resMaps
  2741. }
  2742. /**
  2743. * 解析时区
  2744. */
  2745. function parseTimeZone (resMaps) {
  2746. // 如果为UTC 时间
  2747. if (/^[zZ]/.test(resMaps.Z)) {
  2748. return new Date(helperGetUTCDateTime(resMaps))
  2749. } else {
  2750. // 如果指定时区,时区转换
  2751. var matchRest = resMaps.Z.match(/([-+])(\d{2}):?(\d{2})/)
  2752. if (matchRest) {
  2753. return new Date(helperGetUTCDateTime(resMaps) - (matchRest[1] === '-' ? -1 : 1) * staticParseInt(matchRest[2]) * 3600000 + staticParseInt(matchRest[3]) * 60000)
  2754. }
  2755. }
  2756. return new Date('')
  2757. }
  2758. /**
  2759. * 字符串转为日期
  2760. *
  2761. * @param {String/Number/Date} str 日期或数字
  2762. * @param {String} format 解析日期格式(yyyy年份、MM月份、dd天、hh(12)HH(24)小时、mm分钟、ss秒、SSS毫秒、Z时区)
  2763. * @return {Date}
  2764. */
  2765. function toStringDate (str, format) {
  2766. if (str) {
  2767. var isDType = isDate(str)
  2768. if (isDType || (!format && /^[0-9]{11,15}$/.test(str))) {
  2769. return new Date(isDType ? helperGetDateTime(str) : staticParseInt(str))
  2770. }
  2771. if (isString(str)) {
  2772. var resMaps = format ? parseCustomRules(str, format) : parseDefaultRules(str)
  2773. if (resMaps.y) {
  2774. if (resMaps.M) {
  2775. resMaps.M = toParseNum(resMaps.M) - 1
  2776. }
  2777. if (resMaps.S) {
  2778. // 如果7位则是微秒,只精确到3位毫秒
  2779. resMaps.S = toParseMs(toParseNum(resMaps.S.substring(0, 3)))
  2780. }
  2781. if (resMaps.Z) {
  2782. return parseTimeZone(resMaps)
  2783. } else {
  2784. return new Date(resMaps.y, resMaps.M || 0, resMaps.d || 1, resMaps.H || 0, resMaps.m || 0, resMaps.s || 0, resMaps.S || 0)
  2785. }
  2786. }
  2787. }
  2788. }
  2789. return new Date('')
  2790. }
  2791. function handleCustomTemplate (date, formats, match, value) {
  2792. var format = formats[match]
  2793. if (format) {
  2794. if (isFunction(format)) {
  2795. return format(value, match, date)
  2796. } else {
  2797. return format[value]
  2798. }
  2799. }
  2800. return value
  2801. }
  2802. var dateFormatRE = /\[([^\]]+)]|y{2,4}|M{1,2}|d{1,2}|H{1,2}|h{1,2}|m{1,2}|s{1,2}|S{1,3}|Z{1,2}|W{1,2}|D{1,3}|[aAeEq]/g
  2803. /**
  2804. * 日期格式化为字符串,转义符号 []
  2805. *
  2806. * @param {Date} date 日期或数字
  2807. * @param {String} format 输出日期格式(年份(yy|yyyy)、月份(M|MM自动补0)、天(d|dd自动补0)、12小时制(h|hh自动补0)、24小时制(H|HH自动补0)、分钟(m|mm自动补0)、秒(s|ss自动补0)、毫秒(S|SSS自动补0)、D当年的第几天、a/A上午下午、e/E星期几、w当年的第几周、W当月的第几周、q当年第几个季度、Z时区)
  2808. * @param {Object} options {formats: {q: ['日', '一', '二', '三', '四', '五', '六'], E: function (value, match, date) {return '三'}, }} 自定义格式化模板
  2809. * @return {String}
  2810. */
  2811. function toDateString (date, format, options) {
  2812. if (date) {
  2813. date = toStringDate(date)
  2814. if (isValidDate(date)) {
  2815. var result = format || setupDefaults.parseDateFormat || setupDefaults.formatString
  2816. var hours = date.getHours()
  2817. var apm = hours < 12 ? 'am' : 'pm'
  2818. var formats = assign({}, setupDefaults.parseDateRules || setupDefaults.formatStringMatchs, options ? options.formats : null)
  2819. var fy = function (match, length) {
  2820. return ('' + helperGetDateFullYear(date)).substr(4 - length)
  2821. }
  2822. var fM = function (match, length) {
  2823. return padStart(helperGetDateMonth(date) + 1, length, '0')
  2824. }
  2825. var fd = function (match, length) {
  2826. return padStart(date.getDate(), length, '0')
  2827. }
  2828. var fH = function (match, length) {
  2829. return padStart(hours, length, '0')
  2830. }
  2831. var fh = function (match, length) {
  2832. return padStart(hours <= 12 ? hours : hours - 12, length, '0')
  2833. }
  2834. var fm = function (match, length) {
  2835. return padStart(date.getMinutes(), length, '0')
  2836. }
  2837. var fs = function (match, length) {
  2838. return padStart(date.getSeconds(), length, '0')
  2839. }
  2840. var fS = function (match, length) {
  2841. return padStart(date.getMilliseconds(), length, '0')
  2842. }
  2843. var fZ = function (match, length) {
  2844. var zoneHours = date.getTimezoneOffset() / 60 * -1
  2845. return handleCustomTemplate(date, formats, match, (zoneHours >= 0 ? '+' : '-') + padStart(zoneHours, 2, '0') + (length === 1 ? ':' : '') + '00')
  2846. }
  2847. var fW = function (match, length) {
  2848. return padStart(handleCustomTemplate(date, formats, match, getYearWeek(date, (options ? options.firstDay : null) || setupDefaults.firstDayOfWeek)), length, '0')
  2849. }
  2850. var fD = function (match, length) {
  2851. return padStart(handleCustomTemplate(date, formats, match, getYearDay(date)), length, '0')
  2852. }
  2853. var parseDates = {
  2854. yyyy: fy,
  2855. yy: fy,
  2856. MM: fM,
  2857. M: fM,
  2858. dd: fd,
  2859. d: fd,
  2860. HH: fH,
  2861. H: fH,
  2862. hh: fh,
  2863. h: fh,
  2864. mm: fm,
  2865. m: fm,
  2866. ss: fs,
  2867. s: fs,
  2868. SSS: fS,
  2869. S: fS,
  2870. ZZ: fZ,
  2871. Z: fZ,
  2872. WW: fW,
  2873. W: fW,
  2874. DDD: fD,
  2875. D: fD,
  2876. a: function (match) {
  2877. return handleCustomTemplate(date, formats, match, apm)
  2878. },
  2879. A: function (match) {
  2880. return handleCustomTemplate(date, formats, match, helperStringUpperCase(apm))
  2881. },
  2882. e: function (match) {
  2883. return handleCustomTemplate(date, formats, match, date.getDay())
  2884. },
  2885. E: function (match) {
  2886. return handleCustomTemplate(date, formats, match, date.getDay())
  2887. },
  2888. q: function (match) {
  2889. return handleCustomTemplate(date, formats, match, Math.floor((helperGetDateMonth(date) + 3) / 3))
  2890. }
  2891. }
  2892. return result.replace(dateFormatRE, function (match, skip) {
  2893. return skip || (parseDates[match] ? parseDates[match](match, match.length) : match)
  2894. })
  2895. }
  2896. return 'Invalid Date'
  2897. }
  2898. return ''
  2899. }
  2900. /**
  2901. * 返回前几年或后几年的日期
  2902. *
  2903. * @param {Date} date 日期或数字
  2904. * @param {Number} offset 年(默认当前年)、前几个年(数值)、后几个年(数值)
  2905. * @param {Number/String} month 获取哪月(null默认当前年)、年初(first)、年末(last)、指定月份(0-11)
  2906. * @return {Date}
  2907. */
  2908. function getWhatYear (date, offset, month) {
  2909. var number
  2910. date = toStringDate(date)
  2911. if (isValidDate(date)) {
  2912. if (offset) {
  2913. number = offset && !isNaN(offset) ? offset : 0
  2914. date.setFullYear(helperGetDateFullYear(date) + number)
  2915. }
  2916. if (month || !isNaN(month)) {
  2917. if (month === staticStrFirst) {
  2918. return new Date(helperGetDateFullYear(date), 0, 1)
  2919. } else if (month === staticStrLast) {
  2920. date.setMonth(11)
  2921. return getWhatMonth(date, 0, staticStrLast)
  2922. } else {
  2923. date.setMonth(month)
  2924. }
  2925. }
  2926. }
  2927. return date
  2928. }
  2929. function getQuarterNumber (date) {
  2930. var month = date.getMonth()
  2931. if (month < 3) {
  2932. return 1
  2933. } else if (month < 6) {
  2934. return 2
  2935. } else if (month < 9) {
  2936. return 3
  2937. }
  2938. return 4
  2939. }
  2940. /**
  2941. * 返回前几季度或后几季度的日期
  2942. *
  2943. * @param {Date} date 日期
  2944. * @param {Number} offset 季度(默认当前季度)、前几季度、后几季度
  2945. * @param {Number} day 获取哪天:月初(first)、月末(last)、指定天数(数值),如果为空,但超过指定月份的天数时,则默认单月最后一天
  2946. * @return {Date}
  2947. */
  2948. function getWhatQuarter (date, offset, day) {
  2949. var currMonth, monthOffset = offset && !isNaN(offset) ? offset * 3 : 0
  2950. date = toStringDate(date)
  2951. if (isValidDate(date)) {
  2952. currMonth = (getQuarterNumber(date) - 1) * 3
  2953. date.setMonth(currMonth)
  2954. return getWhatMonth(date, monthOffset, day)
  2955. }
  2956. return date
  2957. }
  2958. /**
  2959. * 返回前几月或后几月的日期
  2960. *
  2961. * @param {Date} date 日期或数字
  2962. * @param {Number} offsetMonth 月(默认当前月)、前几个月、后几个月
  2963. * @param {Number/String} offsetDay 获取哪天:月初(first)、月末(last)、指定天数(数值),如果为空,但超过指定月份的天数时,则默认单月最后一天
  2964. * @return {Date}
  2965. */
  2966. function getWhatMonth (date, offsetMonth, offsetDay) {
  2967. var monthNum = offsetMonth && !isNaN(offsetMonth) ? offsetMonth : 0
  2968. date = toStringDate(date)
  2969. if (isValidDate(date)) {
  2970. if (offsetDay === staticStrFirst) {
  2971. return new Date(helperGetDateFullYear(date), helperGetDateMonth(date) + monthNum, 1)
  2972. } else if (offsetDay === staticStrLast) {
  2973. return new Date(helperGetDateTime(getWhatMonth(date, monthNum + 1, staticStrFirst)) - 1)
  2974. } else if (isNumber(offsetDay)) {
  2975. date.setDate(offsetDay)
  2976. }
  2977. if (monthNum) {
  2978. var currDate = date.getDate()
  2979. date.setMonth(helperGetDateMonth(date) + monthNum)
  2980. if (currDate !== date.getDate()) {
  2981. // 当为指定天数,且被跨月了,则默认单月最后一天
  2982. date.setDate(1)
  2983. return new Date(helperGetDateTime(date) - staticDayTime)
  2984. }
  2985. }
  2986. }
  2987. return date
  2988. }
  2989. /**
  2990. * 返回前几周或后几周的星期几
  2991. *
  2992. * @param {Date} date 日期
  2993. * @param {Number} offsetWeek 周(默认当前周)、前几周、后几周
  2994. * @param {Number} offsetDay 星期天(默认0)、星期一(1)、星期二(2)、星期三(3)、星期四(4)、星期五(5)、星期六(6)
  2995. * @param {Number} firstDay 周视图的起始天,默认星期一
  2996. * @return {Date}
  2997. */
  2998. function getWhatWeek (date, offsetWeek, offsetDay, firstDay) {
  2999. date = toStringDate(date)
  3000. if (isValidDate(date)) {
  3001. var hasCustomDay = isNumber(offsetDay)
  3002. var hasStartDay = isNumber(firstDay)
  3003. var whatDayTime = helperGetDateTime(date)
  3004. // 如果指定了天或周视图起始天
  3005. if (hasCustomDay || hasStartDay) {
  3006. var viewStartDay = hasStartDay ? firstDay : setupDefaults.firstDayOfWeek
  3007. var currentDay = date.getDay()
  3008. var customDay = hasCustomDay ? offsetDay : currentDay
  3009. if (currentDay !== customDay) {
  3010. var offsetNum = 0
  3011. if (viewStartDay > currentDay) {
  3012. offsetNum = -(7 - viewStartDay + currentDay)
  3013. } else if (viewStartDay < currentDay) {
  3014. offsetNum = viewStartDay - currentDay
  3015. }
  3016. if (customDay > viewStartDay) {
  3017. whatDayTime += ((customDay === 0 ? 7 : customDay) - viewStartDay + offsetNum) * staticDayTime
  3018. } else if (customDay < viewStartDay) {
  3019. whatDayTime += (7 - viewStartDay + customDay + offsetNum) * staticDayTime
  3020. } else {
  3021. whatDayTime += offsetNum * staticDayTime
  3022. }
  3023. }
  3024. }
  3025. if (offsetWeek && !isNaN(offsetWeek)) {
  3026. whatDayTime += offsetWeek * staticWeekTime
  3027. }
  3028. return new Date(whatDayTime)
  3029. }
  3030. return date
  3031. }
  3032. /**
  3033. * 返回前几天或后几天的日期
  3034. *
  3035. * @param {Date} date 日期或数字
  3036. * @param {Number} offset 天(默认当天)、前几天、后几天
  3037. * @param {String} mode 获取时分秒(null默认当前时分秒)、日初(first)、日末(last)
  3038. * @return {Date}
  3039. */
  3040. function getWhatDay (date, offset, mode) {
  3041. date = toStringDate(date)
  3042. if (isValidDate(date) && !isNaN(offset)) {
  3043. date.setDate(date.getDate() + staticParseInt(offset))
  3044. if (mode === staticStrFirst) {
  3045. return new Date(helperGetDateFullYear(date), helperGetDateMonth(date), date.getDate())
  3046. } else if (mode === staticStrLast) {
  3047. return new Date(helperGetDateTime(getWhatDay(date, 1, staticStrFirst)) - 1)
  3048. }
  3049. }
  3050. return date
  3051. }
  3052. /**
  3053. * 返回某个年份的第几天
  3054. *
  3055. * @param {Date} date 日期或数字
  3056. * @return {Number}
  3057. */
  3058. function getYearDay (date) {
  3059. date = toStringDate(date)
  3060. if (isValidDate(date)) {
  3061. return Math.floor((helperGetYMDTime(date) - helperGetYMDTime(getWhatYear(date, 0, staticStrFirst))) / staticDayTime) + 1
  3062. }
  3063. return NaN
  3064. }
  3065. /**
  3066. * 返回某个年份的第几周
  3067. *
  3068. * @param {Date} date 日期或数字
  3069. * @param {Number} firstDay 从年初的星期几为起始开始周开始算,默认星期一
  3070. * @return {Number}
  3071. */
  3072. var getYearWeek = helperCreateGetDateWeek(function (targetDate) {
  3073. return new Date(targetDate.getFullYear(), 0, 1)
  3074. }, function (date1, date2) {
  3075. return date1.getFullYear() !== date2.getFullYear()
  3076. })
  3077. /**
  3078. * 返回某个月的第几周
  3079. *
  3080. * @param {Date} date 日期或数字
  3081. * @param {Number} firstDay 周视图的起始天,默认星期一
  3082. * @return {Number}
  3083. */
  3084. var getMonthWeek = helperCreateGetDateWeek(function (targetDate) {
  3085. return new Date(targetDate.getFullYear(), targetDate.getMonth(), 1)
  3086. }, function (date1, date2) {
  3087. return date1.getMonth() !== date2.getMonth()
  3088. })
  3089. /**
  3090. * 返回某个年份的天数
  3091. *
  3092. * @param {Date} date 日期或数字
  3093. * @param {Number} offset 年(默认当年)、前几个年、后几个年
  3094. * @return {Number}
  3095. */
  3096. function getDayOfYear (date, year) {
  3097. date = toStringDate(date)
  3098. if (isValidDate(date)) {
  3099. return isLeapYear(getWhatYear(date, year)) ? 366 : 365
  3100. }
  3101. return NaN
  3102. }
  3103. /**
  3104. * 返回某个月份的天数
  3105. *
  3106. * @param {Date} date 日期或数字
  3107. * @param {Number} offset 月(默认当月)、前几个月、后几个月
  3108. * @return {Number}
  3109. */
  3110. function getDayOfMonth (date, month) {
  3111. date = toStringDate(date)
  3112. if (isValidDate(date)) {
  3113. return Math.floor((helperGetDateTime(getWhatMonth(date, month, staticStrLast)) - helperGetDateTime(getWhatMonth(date, month, staticStrFirst))) / staticDayTime) + 1
  3114. }
  3115. return NaN
  3116. }
  3117. var dateDiffRules = [
  3118. ['yyyy', 31536000000],
  3119. ['MM', 2592000000],
  3120. ['dd', 86400000],
  3121. ['HH', 3600000],
  3122. ['mm', 60000],
  3123. ['ss', 1000],
  3124. ['S', 0]
  3125. ]
  3126. /**
  3127. * 返回两个日期之间差距,如果结束日期小于开始日期done为fasle
  3128. *
  3129. * @param {Date} startDate 开始日期
  3130. * @param {Date} endDate 结束日期或当期日期
  3131. * @return {Object}
  3132. */
  3133. function getDateDiff (startDate, endDate) {
  3134. var startTime, endTime, item, diffTime, len, index
  3135. var result = { done: false, status: false, time: 0 }
  3136. startDate = toStringDate(startDate)
  3137. endDate = endDate ? toStringDate(endDate) : helperNewDate()
  3138. if (isValidDate(startDate) && isValidDate(endDate)) {
  3139. startTime = helperGetDateTime(startDate)
  3140. endTime = helperGetDateTime(endDate)
  3141. if (startTime < endTime) {
  3142. diffTime = result.time = endTime - startTime
  3143. result.done = true
  3144. result.status = true
  3145. for (index = 0, len = dateDiffRules.length; index < len; index++) {
  3146. item = dateDiffRules[index]
  3147. if (diffTime >= item[1]) {
  3148. if (index === len - 1) {
  3149. result[item[0]] = diffTime || 0
  3150. } else {
  3151. result[item[0]] = Math.floor(diffTime / item[1])
  3152. diffTime -= result[item[0]] * item[1]
  3153. }
  3154. } else {
  3155. result[item[0]] = 0
  3156. }
  3157. }
  3158. }
  3159. }
  3160. return result
  3161. }
  3162. /**
  3163. * 去除字符串左右两边的空格
  3164. *
  3165. * @param {String} str 字符串
  3166. * @return {String}
  3167. */
  3168. function trim (str) {
  3169. return str && str.trim ? str.trim() : trimRight(trimLeft(str))
  3170. }
  3171. /**
  3172. * 去除字符串左边的空格
  3173. *
  3174. * @param {String} str 字符串
  3175. * @return {String}
  3176. */
  3177. function trimLeft (str) {
  3178. return str && str.trimLeft ? str.trimLeft() : toValueString(str).replace(/^[\s\uFEFF\xA0]+/g, '')
  3179. }
  3180. /**
  3181. * 去除字符串右边的空格
  3182. *
  3183. * @param {String} str 字符串
  3184. * @return {String}
  3185. */
  3186. function trimRight (str) {
  3187. return str && str.trimRight ? str.trimRight() : toValueString(str).replace(/[\s\uFEFF\xA0]+$/g, '')
  3188. }
  3189. /**
  3190. * 转义HTML字符串,替换&, <, >, ", ', `字符
  3191. *
  3192. * @param {String} str 字符串
  3193. * @return {String}
  3194. */
  3195. var escape = helperFormatEscaper(staticEscapeMap)
  3196. var unescapeMap = {}
  3197. each(staticEscapeMap, function (item, key) {
  3198. unescapeMap[staticEscapeMap[key]] = key
  3199. })
  3200. /**
  3201. * 反转escape
  3202. *
  3203. * @param {String} str 字符串
  3204. * @return {String}
  3205. */
  3206. var unescape = helperFormatEscaper(unescapeMap)
  3207. var camelCacheMaps = {}
  3208. /**
  3209. * 将带字符串转成驼峰字符串,例如: project-name 转为 projectName
  3210. *
  3211. * @param {String} str 字符串
  3212. * @return {String}
  3213. */
  3214. function camelCase (str) {
  3215. str = toValueString(str)
  3216. if (camelCacheMaps[str]) {
  3217. return camelCacheMaps[str]
  3218. }
  3219. var strLen = str.length
  3220. var rest = str.replace(/([-]+)/g, function (text, flag, index) {
  3221. return index && index + flag.length < strLen ? '-' : ''
  3222. })
  3223. strLen = rest.length
  3224. rest = rest.replace(/([A-Z]+)/g, function (text, upper, index) {
  3225. var upperLen = upper.length
  3226. upper = helperStringLowerCase(upper)
  3227. if (index) {
  3228. if (upperLen > 2 && index + upperLen < strLen) {
  3229. return helperStringUpperCase(helperStringSubstring(upper, 0, 1)) + helperStringSubstring(upper, 1, upperLen - 1) + helperStringUpperCase(helperStringSubstring(upper, upperLen - 1, upperLen))
  3230. }
  3231. return helperStringUpperCase(helperStringSubstring(upper, 0, 1)) + helperStringSubstring(upper, 1, upperLen)
  3232. } else {
  3233. if (upperLen > 1 && index + upperLen < strLen) {
  3234. return helperStringSubstring(upper, 0, upperLen - 1) + helperStringUpperCase(helperStringSubstring(upper, upperLen - 1, upperLen))
  3235. }
  3236. }
  3237. return upper
  3238. }).replace(/(-[a-zA-Z])/g, function (text, upper) {
  3239. return helperStringUpperCase(helperStringSubstring(upper, 1, upper.length))
  3240. })
  3241. camelCacheMaps[str] = rest
  3242. return rest
  3243. }
  3244. var kebabCacheMaps = {}
  3245. /**
  3246. * 将带驼峰字符串转成字符串,例如: projectName 转为 project-name
  3247. *
  3248. * @param {String} str 字符串
  3249. * @return {String}
  3250. */
  3251. function kebabCase (str) {
  3252. str = toValueString(str)
  3253. if (kebabCacheMaps[str]) {
  3254. return kebabCacheMaps[str]
  3255. }
  3256. if (/^[A-Z]+$/.test(str)) {
  3257. return helperStringLowerCase(str)
  3258. }
  3259. var rest = str.replace(/^([a-z])([A-Z]+)([a-z]+)$/, function (text, prevLower, upper, nextLower) {
  3260. var upperLen = upper.length
  3261. if (upperLen > 1) {
  3262. return prevLower + '-' + helperStringLowerCase(helperStringSubstring(upper, 0, upperLen - 1)) + '-' + helperStringLowerCase(helperStringSubstring(upper, upperLen - 1, upperLen)) + nextLower
  3263. }
  3264. return helperStringLowerCase(prevLower + '-' + upper + nextLower)
  3265. }).replace(/^([A-Z]+)([a-z]+)?$/, function (text, upper, nextLower) {
  3266. var upperLen = upper.length
  3267. return helperStringLowerCase(helperStringSubstring(upper, 0, upperLen - 1) + '-' + helperStringSubstring(upper, upperLen - 1, upperLen) + (nextLower || ''))
  3268. }).replace(/([a-z]?)([A-Z]+)([a-z]?)/g, function (text, prevLower, upper, nextLower, index) {
  3269. var upperLen = upper.length
  3270. if (upperLen > 1) {
  3271. if (prevLower) {
  3272. prevLower += '-'
  3273. }
  3274. if (nextLower) {
  3275. return (prevLower || '') + helperStringLowerCase(helperStringSubstring(upper, 0, upperLen - 1)) + '-' + helperStringLowerCase(helperStringSubstring(upper, upperLen - 1, upperLen)) + nextLower
  3276. }
  3277. }
  3278. return (prevLower || '') + (index ? '-' : '') + helperStringLowerCase(upper) + (nextLower || '')
  3279. })
  3280. rest = rest.replace(/([-]+)/g, function (text, flag, index) {
  3281. return index && index + flag.length < rest.length ? '-' : ''
  3282. })
  3283. kebabCacheMaps[str] = rest
  3284. return rest
  3285. }
  3286. /**
  3287. * 将字符串重复 n 次
  3288. *
  3289. * @param {String} str 字符串
  3290. * @param {Number} count 次数
  3291. * @return {String}
  3292. */
  3293. function repeat (str, count) {
  3294. return helperStringRepeat(toValueString(str), count)
  3295. }
  3296. /**
  3297. * 用指定字符从前面开始补全字符串
  3298. *
  3299. * @param {String} str 字符串
  3300. * @param {Number} targetLength 结果长度
  3301. * @param {Number} padString 补全字符
  3302. * @return {String}
  3303. */
  3304. function padStart (str, targetLength, padString) {
  3305. var rest = toValueString(str)
  3306. targetLength = targetLength >> 0
  3307. padString = isUndefined(padString) ? ' ' : '' + padString
  3308. if (rest.padStart) {
  3309. return rest.padStart(targetLength, padString)
  3310. }
  3311. if (targetLength > rest.length) {
  3312. targetLength -= rest.length
  3313. if (targetLength > padString.length) {
  3314. padString += helperStringRepeat(padString, targetLength / padString.length)
  3315. }
  3316. return padString.slice(0, targetLength) + rest
  3317. }
  3318. return rest
  3319. }
  3320. /**
  3321. * 用指定字符从后面开始补全字符串
  3322. *
  3323. * @param {String} str 字符串
  3324. * @param {Number} targetLength 结果长度
  3325. * @param {Number} padString 补全字符
  3326. * @return {String}
  3327. */
  3328. function padEnd (str, targetLength, padString) {
  3329. var rest = toValueString(str)
  3330. targetLength = targetLength >> 0
  3331. padString = isUndefined(padString) ? ' ' : '' + padString
  3332. if (rest.padEnd) {
  3333. return rest.padEnd(targetLength, padString)
  3334. }
  3335. if (targetLength > rest.length) {
  3336. targetLength -= rest.length
  3337. if (targetLength > padString.length) {
  3338. padString += helperStringRepeat(padString, targetLength / padString.length)
  3339. }
  3340. return rest + padString.slice(0, targetLength)
  3341. }
  3342. return rest
  3343. }
  3344. /**
  3345. * 判断字符串是否在源字符串的头部
  3346. *
  3347. * @param {String} str 字符串
  3348. * @param {String/Number} val 值
  3349. * @param {Number} startIndex 开始索引
  3350. * @return {String}
  3351. */
  3352. function startsWith (str, val, startIndex) {
  3353. var rest = toValueString(str)
  3354. return (arguments.length === 1 ? rest : rest.substring(startIndex)).indexOf(val) === 0
  3355. }
  3356. /**
  3357. * 判断字符串是否在源字符串的尾部
  3358. *
  3359. * @param {String} str 字符串
  3360. * @param {String/Number} val 值
  3361. * @param {Number} startIndex 开始索引
  3362. * @return {String}
  3363. */
  3364. function endsWith (str, val, startIndex) {
  3365. var rest = toValueString(str)
  3366. var argsLen = arguments.length
  3367. return argsLen > 1 && (argsLen > 2 ? rest.substring(0, startIndex).indexOf(val) === startIndex - 1 : rest.indexOf(val) === rest.length - 1)
  3368. }
  3369. /**
  3370. * 解析动态字符串模板
  3371. * @param {atring} str 字符串模板
  3372. * @param {any | any[]} args 对象
  3373. * @param {any} options
  3374. */
  3375. function template (str, args, options) {
  3376. return toValueString(str).replace((options || setupDefaults).tmplRE || /\{{2}([.\w[\]\s]+)\}{2}/g, function (match, key) {
  3377. return get(args, trim(key))
  3378. })
  3379. }
  3380. /**
  3381. * 字符串格式化占位符
  3382. * @param { string } str
  3383. * @param { object | any[] } obj
  3384. */
  3385. function toFormatString (str, obj) {
  3386. return template(str, obj,{ tmplRE: /\{([.\w[\]\s]+)\}/g })
  3387. }
  3388. function toValueString (obj) {
  3389. if (isNumber(obj)) {
  3390. return toNumberString(obj)
  3391. }
  3392. return '' + (eqNull(obj) ? '' : obj)
  3393. }
  3394. /**
  3395. * 一个空的方法,始终返回 undefined,可用于初始化值
  3396. */
  3397. function noop () {}
  3398. /**
  3399. * 返回一个获取对象属性的函数
  3400. *
  3401. * @param {String} name 属性名
  3402. * @param {Object} defs 空值
  3403. */
  3404. function property (name, defs) {
  3405. return function (obj) {
  3406. return isNull(obj) ? defs : obj[name]
  3407. }
  3408. }
  3409. /**
  3410. * 创建一个绑定上下文的函数
  3411. *
  3412. * @param {Function} callback 函数
  3413. * @param {Object} context 上下文
  3414. * @param {*} args 额外的参数
  3415. * @return {Object}
  3416. */
  3417. function bind (callback, context) {
  3418. var args = slice(arguments, 2)
  3419. return function () {
  3420. return callback.apply(context, slice(arguments).concat(args))
  3421. }
  3422. }
  3423. /**
  3424. * 创建一个只能调用一次的函数,只会返回第一次执行后的结果
  3425. *
  3426. * @param {Function} callback 函数
  3427. * @param {Object} context 上下文
  3428. * @param {*} args 额外的参数
  3429. * @return {Object}
  3430. */
  3431. function once (callback, context) {
  3432. var done = false
  3433. var rest = null
  3434. var args = slice(arguments, 2)
  3435. return function () {
  3436. if (done) {
  3437. return rest
  3438. }
  3439. rest = callback.apply(context, slice(arguments).concat(args))
  3440. done = true
  3441. return rest
  3442. }
  3443. }
  3444. /**
  3445. * 创建一个函数, 调用次数超过 count 次之后执行回调并将所有结果记住后返回
  3446. *
  3447. * @param {Number} count 调用次数
  3448. * @param {Function} callback 完成回调
  3449. * @return {Object}
  3450. */
  3451. function after (count, callback, context) {
  3452. var runCount = 0
  3453. var rests = []
  3454. return function () {
  3455. var args = arguments
  3456. runCount++
  3457. if (runCount <= count) {
  3458. rests.push(args[0])
  3459. }
  3460. if (runCount >= count) {
  3461. callback.apply(context, [rests].concat(slice(args)))
  3462. }
  3463. }
  3464. }
  3465. /**
  3466. * 创建一个函数, 调用次数不超过 count 次之前执行回调并将所有结果记住后返回
  3467. *
  3468. * @param {Number} count 调用次数
  3469. * @param {Function} callback 完成回调
  3470. * @return {Object}
  3471. */
  3472. function before (count, callback, context) {
  3473. var runCount = 0
  3474. var rests = []
  3475. context = context || this
  3476. return function () {
  3477. var args = arguments
  3478. runCount++
  3479. if (runCount < count) {
  3480. rests.push(args[0])
  3481. callback.apply(context, [rests].concat(slice(args)))
  3482. }
  3483. }
  3484. }
  3485. /**
  3486. * 节流函数;当被调用 n 毫秒后才会执行,如果在这时间内又被调用则至少每隔 n 秒毫秒调用一次该函数
  3487. *
  3488. * @param {Function} callback 回调
  3489. * @param {Number} wait 多少秒毫
  3490. * @param {Object} options 参数{leading: 是否在之前执行, trailing: 是否在之后执行}
  3491. * @return {Function}
  3492. */
  3493. function throttle (callback, wait, options) {
  3494. var args = null
  3495. var context = null
  3496. var runFlag = false
  3497. var timeout = null
  3498. var opts = assign({ leading: true, trailing: true }, options)
  3499. var optLeading = opts.leading
  3500. var optTrailing = opts.trailing
  3501. var gcFn = function () {
  3502. args = null
  3503. context = null
  3504. }
  3505. var runFn = function () {
  3506. runFlag = true
  3507. callback.apply(context, args)
  3508. timeout = setTimeout(endFn, wait)
  3509. gcFn()
  3510. }
  3511. var endFn = function () {
  3512. timeout = null
  3513. if (runFlag) {
  3514. gcFn()
  3515. return
  3516. }
  3517. if (optTrailing === true) {
  3518. runFn()
  3519. return
  3520. }
  3521. gcFn()
  3522. }
  3523. var cancelFn = function () {
  3524. var rest = timeout !== null
  3525. if (rest) {
  3526. clearTimeout(timeout)
  3527. }
  3528. gcFn()
  3529. timeout = null
  3530. runFlag = false
  3531. return rest
  3532. }
  3533. var throttled = function () {
  3534. args = arguments
  3535. context = this
  3536. runFlag = false
  3537. if (timeout === null && optLeading === true) {
  3538. runFn()
  3539. return
  3540. }
  3541. if (optTrailing === true) {
  3542. timeout = setTimeout(endFn, wait)
  3543. }
  3544. }
  3545. throttled.cancel = cancelFn
  3546. return throttled
  3547. }
  3548. /**
  3549. * 函数去抖;当被调用 n 毫秒后才会执行,如果在这时间内又被调用则将重新计算执行时间
  3550. *
  3551. * @param {Function} callback 回调
  3552. * @param {Number} wait 多少秒毫
  3553. * @param {Object} options 参数{leading: 是否在之前执行, trailing: 是否在之后执行}
  3554. * @return {Function}
  3555. */
  3556. function debounce (callback, wait, options) {
  3557. var args = null
  3558. var context = null
  3559. var opts = typeof options === 'boolean' ? { leading: options, trailing: !options } : assign({ leading: false, trailing: true }, options)
  3560. var runFlag = false
  3561. var timeout = null
  3562. var optLeading = opts.leading
  3563. var optTrailing = opts.trailing
  3564. var gcFn = function () {
  3565. args = null
  3566. context = null
  3567. }
  3568. var runFn = function () {
  3569. runFlag = true
  3570. callback.apply(context, args)
  3571. gcFn()
  3572. }
  3573. var endFn = function () {
  3574. if (optLeading === true) {
  3575. timeout = null
  3576. }
  3577. if (runFlag) {
  3578. gcFn()
  3579. return
  3580. }
  3581. if (optTrailing === true) {
  3582. runFn()
  3583. return
  3584. }
  3585. gcFn()
  3586. }
  3587. var cancelFn = function () {
  3588. var rest = timeout !== null
  3589. if (rest) {
  3590. clearTimeout(timeout)
  3591. }
  3592. gcFn()
  3593. timeout = null
  3594. runFlag = false
  3595. return rest
  3596. }
  3597. var debounced = function () {
  3598. runFlag = false
  3599. args = arguments
  3600. context = this
  3601. if (timeout === null) {
  3602. if (optLeading === true) {
  3603. runFn()
  3604. }
  3605. } else {
  3606. clearTimeout(timeout)
  3607. }
  3608. timeout = setTimeout(endFn, wait)
  3609. }
  3610. debounced.cancel = cancelFn
  3611. return debounced
  3612. }
  3613. /**
  3614. * 该方法和 setTimeout 一样的效果,区别就是支持上下文和额外参数
  3615. *
  3616. * @param {Function} callback 函数
  3617. * @param {Number} wait 延迟毫秒
  3618. * @param {*} args 额外的参数
  3619. * @return {Number}
  3620. */
  3621. function delay (callback, wait) {
  3622. var args = slice(arguments, 2)
  3623. var context = this
  3624. return setTimeout(function () {
  3625. callback.apply(context, args)
  3626. }, wait)
  3627. }
  3628. function parseURLQuery (uri) {
  3629. return unserialize(uri.split('?')[1] || '')
  3630. }
  3631. function parseUrl (url) {
  3632. var hashs, portText, searchs, parsed
  3633. var href = '' + url
  3634. if (href.indexOf('//') === 0) {
  3635. href = (staticLocation ? staticLocation.protocol : '') + href
  3636. } else if (href.indexOf('/') === 0) {
  3637. href = helperGetLocatOrigin() + href
  3638. }
  3639. searchs = href.replace(/#.*/, '').match(/(\?.*)/)
  3640. parsed = {
  3641. href: href,
  3642. hash: '',
  3643. host: '',
  3644. hostname: '',
  3645. protocol: '',
  3646. port: '',
  3647. search: searchs && searchs[1] && searchs[1].length > 1 ? searchs[1] : ''
  3648. }
  3649. parsed.path = href.replace(/^([a-z0-9.+-]*:)\/\//, function (text, protocol) {
  3650. parsed.protocol = protocol
  3651. return ''
  3652. }).replace(/^([a-z0-9.+-]*)(:\d+)?\/?/, function (text, hostname, port) {
  3653. portText = port || ''
  3654. parsed.port = portText.replace(':', '')
  3655. parsed.hostname = hostname
  3656. parsed.host = hostname + portText
  3657. return '/'
  3658. }).replace(/(#.*)/, function (text, hash) {
  3659. parsed.hash = hash.length > 1 ? hash : ''
  3660. return ''
  3661. })
  3662. hashs = parsed.hash.match(/#((.*)\?|(.*))/)
  3663. parsed.pathname = parsed.path.replace(/(\?|#.*).*/, '')
  3664. parsed.origin = parsed.protocol + '//' + parsed.host
  3665. parsed.hashKey = hashs ? (hashs[2] || hashs[1] || '') : ''
  3666. parsed.hashQuery = parseURLQuery(parsed.hash)
  3667. parsed.searchQuery = parseURLQuery(parsed.search)
  3668. return parsed
  3669. }
  3670. function stringifyParams (resultVal, resultKey, isArr) {
  3671. var _arr
  3672. var result = []
  3673. each(resultVal, function (item, key) {
  3674. _arr = isArray(item)
  3675. if (isPlainObject(item) || _arr) {
  3676. result = result.concat(stringifyParams(item, resultKey + '[' + key + ']', _arr))
  3677. } else {
  3678. result.push(staticEncodeURIComponent(resultKey + '[' + (isArr ? '' : key) + ']') + '=' + staticEncodeURIComponent(isNull(item) ? '' : item))
  3679. }
  3680. })
  3681. return result
  3682. }
  3683. /**
  3684. * 序列化查询参数
  3685. *
  3686. * @param {Object} query 查询参数
  3687. */
  3688. function serialize (query) {
  3689. var _arr
  3690. var params = []
  3691. each(query, function (item, key) {
  3692. if (!isUndefined(item)) {
  3693. _arr = isArray(item)
  3694. if (isPlainObject(item) || _arr) {
  3695. params = params.concat(stringifyParams(item, key, _arr))
  3696. } else {
  3697. params.push(staticEncodeURIComponent(key) + '=' + staticEncodeURIComponent(isNull(item) ? '' : item))
  3698. }
  3699. }
  3700. })
  3701. return params.join('&').replace(/%20/g, '+')
  3702. }
  3703. /**
  3704. * 反序列化查询参数
  3705. * @param {String} query 字符串
  3706. */
  3707. function unserialize (str) {
  3708. var items
  3709. var result = {}
  3710. if (str && isString(str)) {
  3711. arrayEach(str.split('&'), function (param) {
  3712. items = param.split('=')
  3713. result[staticDecodeURIComponent(items[0])] = staticDecodeURIComponent(items[1] || '')
  3714. })
  3715. }
  3716. return result
  3717. }
  3718. function getBaseURL () {
  3719. if (staticLocation) {
  3720. var pathname = staticLocation.pathname
  3721. var lastIndex = lastIndexOf(pathname, '/') + 1
  3722. return helperGetLocatOrigin() + (lastIndex === pathname.length ? pathname : pathname.substring(0, lastIndex))
  3723. }
  3724. return ''
  3725. }
  3726. /**
  3727. * 获取地址栏信息
  3728. *
  3729. * @return Object
  3730. */
  3731. function locat () {
  3732. return staticLocation ? parseUrl(staticLocation.href) : {}
  3733. }
  3734. /* eslint-disable valid-typeof */
  3735. function isBrowseStorage (storage) {
  3736. try {
  3737. var testKey = '__xe_t'
  3738. storage.setItem(testKey, 1)
  3739. storage.removeItem(testKey)
  3740. return true
  3741. } catch (e) {
  3742. return false
  3743. }
  3744. }
  3745. function isBrowseType (type) {
  3746. return navigator.userAgent.indexOf(type) > -1
  3747. }
  3748. /**
  3749. * 获取浏览器内核
  3750. * @return Object
  3751. */
  3752. function browse () {
  3753. var $body, isChrome, isEdge
  3754. var isMobile = false
  3755. var isLocalStorage = false
  3756. var isSessionStorage = false
  3757. var result = {
  3758. isNode: false,
  3759. isMobile: isMobile,
  3760. isPC: false,
  3761. isDoc: !!staticDocument
  3762. }
  3763. if (!staticWindow && typeof process !== staticStrUndefined) {
  3764. result.isNode = true
  3765. } else {
  3766. isEdge = isBrowseType('Edge')
  3767. isChrome = isBrowseType('Chrome')
  3768. isMobile = /(Android|webOS|iPhone|iPad|iPod|SymbianOS|BlackBerry|Windows Phone)/.test(navigator.userAgent)
  3769. if (result.isDoc) {
  3770. $body = staticDocument.body || staticDocument.documentElement
  3771. arrayEach(['webkit', 'khtml', 'moz', 'ms', 'o'], function (core) {
  3772. result['-' + core] = !!$body[core + 'MatchesSelector']
  3773. })
  3774. }
  3775. try {
  3776. isLocalStorage = isBrowseStorage(staticWindow.localStorage)
  3777. } catch(e) {}
  3778. try {
  3779. isSessionStorage = isBrowseStorage(staticWindow.sessionStorage)
  3780. } catch(e) {}
  3781. assign(result, {
  3782. edge: isEdge,
  3783. firefox: isBrowseType('Firefox'),
  3784. msie: !isEdge && result['-ms'],
  3785. safari: !isChrome && !isEdge && isBrowseType('Safari'),
  3786. isMobile: isMobile,
  3787. isPC: !isMobile,
  3788. isLocalStorage: isLocalStorage,
  3789. isSessionStorage: isSessionStorage
  3790. })
  3791. }
  3792. return result
  3793. }
  3794. function toCookieUnitTime (unit, expires) {
  3795. var num = parseFloat(expires)
  3796. var nowdate = helperNewDate()
  3797. var time = helperGetDateTime(nowdate)
  3798. switch (unit) {
  3799. case 'y': return helperGetDateTime(getWhatYear(nowdate, num))
  3800. case 'M': return helperGetDateTime(getWhatMonth(nowdate, num))
  3801. case 'd': return helperGetDateTime(getWhatDay(nowdate, num))
  3802. case 'h':
  3803. case 'H': return time + num * 60 * 60 * 1000
  3804. case 'm': return time + num * 60 * 1000
  3805. case 's': return time + num * 1000
  3806. }
  3807. return time
  3808. }
  3809. function toCookieUTCString (date) {
  3810. return (isDate(date) ? date : new Date(date)).toUTCString()
  3811. }
  3812. /**
  3813. * cookie操作函数
  3814. * @param {String/Array/Object} name 键/数组/对象
  3815. * @param {String} value 值
  3816. * @param {Object} options 参数
  3817. * @param {String} name: 键
  3818. * @param {Object} value: 值
  3819. * @param {String} path: 路径
  3820. * @param {String} domain: 作用域
  3821. * @param {Boolean} secure: 设置为安全的,只能用https协议
  3822. * @param {Number} expires: 过期时间,可以指定日期或者字符串,默认天
  3823. */
  3824. function cookie (name, value, options) {
  3825. if (staticDocument) {
  3826. var opts, expires, values, result, cookies, keyIndex
  3827. var inserts = []
  3828. var args = arguments
  3829. if (isArray(name)) {
  3830. inserts = name
  3831. } else if (args.length > 1) {
  3832. inserts = [assign({ name: name, value: value }, options)]
  3833. } else if (isObject(name)) {
  3834. inserts = [name]
  3835. }
  3836. if (inserts.length > 0) {
  3837. arrayEach(inserts, function (obj) {
  3838. opts = assign({}, setupDefaults.cookies, obj)
  3839. values = []
  3840. if (opts.name) {
  3841. expires = opts.expires
  3842. values.push(staticEncodeURIComponent(opts.name) + '=' + staticEncodeURIComponent(isObject(opts.value) ? JSON.stringify(opts.value) : opts.value))
  3843. if (expires) {
  3844. if (isNaN(expires)) {
  3845. // UTCString || Unit
  3846. expires = expires.replace(/^([0-9]+)(y|M|d|H|h|m|s)$/, function (text, num, unit) {
  3847. return toCookieUTCString(toCookieUnitTime(unit, num))
  3848. })
  3849. } else if (/^[0-9]{11,13}$/.test(expires) || isDate(expires)) {
  3850. // Date || now
  3851. expires = toCookieUTCString(expires)
  3852. } else {
  3853. // day
  3854. expires = toCookieUTCString(toCookieUnitTime('d', expires))
  3855. }
  3856. opts.expires = expires
  3857. }
  3858. arrayEach(['expires', 'path', 'domain', 'secure'], function (key) {
  3859. if (!isUndefined(opts[key])) {
  3860. values.push(opts[key] && key === 'secure' ? key : (key + '=' + opts[key]))
  3861. }
  3862. })
  3863. }
  3864. staticDocument.cookie = values.join('; ')
  3865. })
  3866. return true
  3867. } else {
  3868. result = {}
  3869. cookies = staticDocument.cookie
  3870. if (cookies) {
  3871. arrayEach(cookies.split('; '), function (val) {
  3872. keyIndex = val.indexOf('=')
  3873. result[staticDecodeURIComponent(val.substring(0, keyIndex))] = staticDecodeURIComponent(val.substring(keyIndex + 1) || '')
  3874. })
  3875. }
  3876. return args.length === 1 ? result[name] : result
  3877. }
  3878. }
  3879. return false
  3880. }
  3881. function hasCookieItem (value) {
  3882. return includes(cookieKeys(), value)
  3883. }
  3884. function getCookieItem (name) {
  3885. return cookie(name)
  3886. }
  3887. function setCookieItem (name, value, options) {
  3888. cookie(name, value, options)
  3889. return cookie
  3890. }
  3891. function removeCookieItem (name, options) {
  3892. cookie(name, '', assign({ expires: -1 }, setupDefaults.cookies, options))
  3893. }
  3894. function cookieKeys () {
  3895. return keys(cookie())
  3896. }
  3897. function cookieJson () {
  3898. return cookie()
  3899. }
  3900. assign(cookie, {
  3901. has: hasCookieItem,
  3902. set: setCookieItem,
  3903. setItem: setCookieItem,
  3904. get: getCookieItem,
  3905. getItem: getCookieItem,
  3906. remove: removeCookieItem,
  3907. removeItem: removeCookieItem,
  3908. keys: cookieKeys,
  3909. getJSON: cookieJson
  3910. })
  3911. // 核心
  3912. // 对象相关的方法
  3913. // 数组相关的方法
  3914. // 基础方法
  3915. // 数值相关方法
  3916. // 日期相关的方法
  3917. // 字符串相关的方法
  3918. // 函数相关的方法
  3919. // 地址相关的方法
  3920. // 浏览器相关的方法
  3921. assign(XEUtils, {
  3922. // object
  3923. assign: assign,
  3924. objectEach: objectEach,
  3925. lastObjectEach: lastObjectEach,
  3926. objectMap: objectMap,
  3927. merge: merge,
  3928. // array
  3929. uniq: uniq,
  3930. union: union,
  3931. sortBy: sortBy,
  3932. orderBy: orderBy,
  3933. shuffle: shuffle,
  3934. sample: sample,
  3935. some: some,
  3936. every: every,
  3937. slice: slice,
  3938. filter: filter,
  3939. find: find,
  3940. findLast: findLast,
  3941. findKey: findKey,
  3942. includes: includes,
  3943. arrayIndexOf: arrayIndexOf,
  3944. arrayLastIndexOf: arrayLastIndexOf,
  3945. map: map,
  3946. reduce: reduce,
  3947. copyWithin: copyWithin,
  3948. chunk: chunk,
  3949. zip: zip,
  3950. unzip: unzip,
  3951. zipObject: zipObject,
  3952. flatten: flatten,
  3953. toArray: toArray,
  3954. includeArrays: includeArrays,
  3955. pluck: pluck,
  3956. invoke: invoke,
  3957. arrayEach: arrayEach,
  3958. lastArrayEach: lastArrayEach,
  3959. toArrayTree: toArrayTree,
  3960. toTreeArray: toTreeArray,
  3961. findTree: findTree,
  3962. eachTree: eachTree,
  3963. mapTree: mapTree,
  3964. filterTree: filterTree,
  3965. searchTree: searchTree,
  3966. // base
  3967. hasOwnProp: hasOwnProp,
  3968. eqNull: eqNull,
  3969. isNaN: isNumberNaN,
  3970. isFinite: isNumberFinite,
  3971. isUndefined: isUndefined,
  3972. isArray: isArray,
  3973. isFloat: isFloat,
  3974. isInteger: isInteger,
  3975. isFunction: isFunction,
  3976. isBoolean: isBoolean,
  3977. isString: isString,
  3978. isNumber: isNumber,
  3979. isRegExp: isRegExp,
  3980. isObject: isObject,
  3981. isPlainObject: isPlainObject,
  3982. isDate: isDate,
  3983. isError: isError,
  3984. isTypeError: isTypeError,
  3985. isEmpty: isEmpty,
  3986. isNull: isNull,
  3987. isSymbol: isSymbol,
  3988. isArguments: isArguments,
  3989. isElement: isElement,
  3990. isDocument: isDocument,
  3991. isWindow: isWindow,
  3992. isFormData: isFormData,
  3993. isMap: isMap,
  3994. isWeakMap: isWeakMap,
  3995. isSet: isSet,
  3996. isWeakSet: isWeakSet,
  3997. isLeapYear: isLeapYear,
  3998. isMatch: isMatch,
  3999. isEqual: isEqual,
  4000. isEqualWith: isEqualWith,
  4001. getType: getType,
  4002. uniqueId: uniqueId,
  4003. getSize: getSize,
  4004. indexOf: indexOf,
  4005. lastIndexOf: lastIndexOf,
  4006. findIndexOf: findIndexOf,
  4007. findLastIndexOf: findLastIndexOf,
  4008. toStringJSON: toStringJSON,
  4009. toJSONString: toJSONString,
  4010. keys: keys,
  4011. values: values,
  4012. entries: entries,
  4013. pick: pick,
  4014. omit: omit,
  4015. first: first,
  4016. last: last,
  4017. each: each,
  4018. forOf: forOf,
  4019. lastForOf: lastForOf,
  4020. lastEach: lastEach,
  4021. has: has,
  4022. get: get,
  4023. set: set,
  4024. groupBy: groupBy,
  4025. countBy: countBy,
  4026. clone: clone,
  4027. clear: clear,
  4028. remove: remove,
  4029. range: range,
  4030. destructuring: destructuring,
  4031. // number
  4032. random: random,
  4033. min: min,
  4034. max: max,
  4035. commafy: commafy,
  4036. round: round,
  4037. ceil: ceil,
  4038. floor: floor,
  4039. toFixed: toFixed,
  4040. toNumber: toNumber,
  4041. toNumberString: toNumberString,
  4042. toInteger: toInteger,
  4043. add: add,
  4044. subtract: subtract,
  4045. multiply: multiply,
  4046. divide: divide,
  4047. sum: sum,
  4048. mean: mean,
  4049. // date
  4050. now: now,
  4051. timestamp: timestamp,
  4052. isValidDate: isValidDate,
  4053. isDateSame: isDateSame,
  4054. toStringDate: toStringDate,
  4055. toDateString: toDateString,
  4056. getWhatYear: getWhatYear,
  4057. getWhatQuarter: getWhatQuarter,
  4058. getWhatMonth: getWhatMonth,
  4059. getWhatWeek: getWhatWeek,
  4060. getWhatDay: getWhatDay,
  4061. getYearDay: getYearDay,
  4062. getYearWeek: getYearWeek,
  4063. getMonthWeek: getMonthWeek,
  4064. getDayOfYear: getDayOfYear,
  4065. getDayOfMonth: getDayOfMonth,
  4066. getDateDiff: getDateDiff,
  4067. // string
  4068. trim: trim,
  4069. trimLeft: trimLeft,
  4070. trimRight: trimRight,
  4071. escape: escape,
  4072. unescape: unescape,
  4073. camelCase: camelCase,
  4074. kebabCase: kebabCase,
  4075. repeat: repeat,
  4076. padStart: padStart,
  4077. padEnd: padEnd,
  4078. startsWith: startsWith,
  4079. endsWith: endsWith,
  4080. template: template,
  4081. toFormatString: toFormatString,
  4082. toString: toValueString,
  4083. toValueString: toValueString,
  4084. // function
  4085. noop: noop,
  4086. property: property,
  4087. bind: bind,
  4088. once: once,
  4089. after: after,
  4090. before: before,
  4091. throttle: throttle,
  4092. debounce: debounce,
  4093. delay: delay,
  4094. // url
  4095. unserialize: unserialize,
  4096. serialize: serialize,
  4097. parseUrl: parseUrl,
  4098. // web
  4099. getBaseURL: getBaseURL,
  4100. locat: locat,
  4101. browse: browse,
  4102. cookie: cookie
  4103. })
  4104. return XEUtils
  4105. }))