main.vue 53 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843
  1. <template>
  2. <view class="devTools">
  3. <!-- #ifndef APP-PLUS -->
  4. <view class="navbar">
  5. <view
  6. class="navbarBody"
  7. :style="{
  8. marginTop: navbarStyle.statusBarHeightPx,
  9. height: navbarStyle.navbarHeightPx,
  10. }"
  11. >
  12. <view
  13. class="left"
  14. @click="back"
  15. >
  16. <image
  17. class="foldIcon"
  18. src="@/devTools/page/static/fold.png"
  19. />
  20. <text class="margin-left-sm">返回</text>
  21. </view>
  22. <view
  23. class="right"
  24. :style="{ 'margin-right': windowInfo.navbar.capsuleRightPx + 'px' }"
  25. v-if="tabList[tabIndex].canRefreshing"
  26. @click="getPage(true)"
  27. >
  28. <text :class="tabList[tabIndex].isRefreshing ? 'refreshing' : ''">
  29. {{ tabList[tabIndex].isRefreshing ? "刷新中" : "刷新" }}
  30. </text>
  31. <image
  32. class="refreshIcon"
  33. src="@/devTools/page/static/refresh.png"
  34. />
  35. </view>
  36. </view>
  37. </view>
  38. <!-- #endif -->
  39. <view
  40. ref="mask"
  41. class="mask"
  42. @click="$devTools.hide()"
  43. ></view>
  44. <view
  45. @click.stop
  46. ref="panel"
  47. class="panel"
  48. :style="{
  49. height: panelHeight + 'px',
  50. }"
  51. >
  52. <view class="head">
  53. <scroll-view
  54. :scroll-x="true"
  55. class="tabList showScrollbars"
  56. :class="isDialog ? '' : 'tab-h5'"
  57. :show-scrollbar="false"
  58. >
  59. <view style="display: flex; flex-direction: row">
  60. <view
  61. v-for="(item, index) in tabList"
  62. :key="index"
  63. class="tabItem"
  64. @click="tabIndex = index"
  65. >
  66. <text
  67. class="tabText"
  68. :class="index == tabIndex ? 'active' : ''"
  69. >
  70. {{ item.title }}
  71. </text>
  72. <view
  73. class="tabLine"
  74. v-if="index == tabIndex"
  75. ></view>
  76. </view>
  77. </view>
  78. </scroll-view>
  79. <view
  80. v-if="isDialog"
  81. class="close"
  82. @click="$devTools.hide()"
  83. >
  84. <view class="line"></view>
  85. <text class="icon">×</text>
  86. </view>
  87. </view>
  88. <mobileSwiperScroll
  89. :scrollHeight="listHeight"
  90. :tabIndex="tabIndex"
  91. :tabList="tabList"
  92. @refresh="onrefresh"
  93. @pullingdown="onpullingdown"
  94. @tabIndexChange="tabIndex = $event"
  95. ref="mobileSwiperScroll"
  96. >
  97. <template #default="{ item, index }">
  98. <template v-if="item.title == 'Tools'">
  99. <cell>
  100. <tools
  101. ref="tools"
  102. @goOpenRequest="$refs.sendRequest.show()"
  103. />
  104. </cell>
  105. </template>
  106. <template v-if="item.title == 'Error'">
  107. <cell
  108. v-for="(_item, _index) in item.data"
  109. :key="_index"
  110. >
  111. <errorItem
  112. :item="_item"
  113. :key="_index"
  114. />
  115. </cell>
  116. </template>
  117. <template v-if="item.title == 'Console'">
  118. <cell
  119. v-for="(_item, _index) in item.data"
  120. :key="_index"
  121. >
  122. <consoleItem
  123. :item="_item"
  124. :key="_index"
  125. />
  126. </cell>
  127. </template>
  128. <template v-if="item.title == 'Network'">
  129. <cell
  130. v-for="(_item, _index) in item.data"
  131. :key="_index"
  132. >
  133. <networkItem
  134. :item="_item"
  135. :key="_index"
  136. @goSendRequest="$refs.sendRequest.show($event, true)"
  137. @goOpenRequest="$refs.sendRequest.show($event)"
  138. />
  139. </cell>
  140. </template>
  141. <template v-if="item.title == 'Storage'">
  142. <cell>
  143. <storageList ref="storageList" />
  144. </cell>
  145. </template>
  146. <template v-if="item.title == 'Pages'">
  147. <cell>
  148. <subTitleBar
  149. :isOpen="item.isShowPages"
  150. title="当前页面栈"
  151. @click="pagesShowChange('isShowPages')"
  152. />
  153. </cell>
  154. <cell>
  155. <pages
  156. ref="pages"
  157. :isShow="item.isShowPages"
  158. />
  159. </cell>
  160. <cell>
  161. <view class="cellDivisionLine"></view>
  162. </cell>
  163. <cell>
  164. <subTitleBar
  165. :isOpen="item.isShowRouteList"
  166. title="全部路由"
  167. @click="pagesShowChange('isShowRouteList')"
  168. />
  169. </cell>
  170. <template v-if="item.isShowRouteList">
  171. <cell
  172. v-for="_item in item.routeList"
  173. :key="_item.path"
  174. >
  175. <routeItem :item="_item" />
  176. </cell>
  177. </template>
  178. <cell>
  179. <view class="cellDivisionLine"></view>
  180. </cell>
  181. <cell>
  182. <subTitleBar
  183. :isOpen="item.isShowData"
  184. title="页面停留统计"
  185. @click="pagesShowChange('isShowData')"
  186. />
  187. </cell>
  188. <template v-if="item.isShowData">
  189. <cell
  190. v-for="(_item, _index) in item.data"
  191. :key="_item.route"
  192. >
  193. <pageItem
  194. :item="_item"
  195. :key="_index"
  196. />
  197. </cell>
  198. </template>
  199. <cell>
  200. <view class="cellDivisionLine"></view>
  201. </cell>
  202. <cell>
  203. <subTitleBar
  204. :isOpen="item.dayOnlineShow"
  205. title="日活跃时间统计"
  206. @click="pagesShowChange('dayOnlineShow')"
  207. />
  208. </cell>
  209. <template v-if="item.dayOnlineShow">
  210. <cell
  211. v-for="(_item, _index) in item.dayOnlineList"
  212. :key="_index"
  213. >
  214. <dayOnlineItem
  215. @click="showOnlineDetailsDialog(_item)"
  216. :item="_item"
  217. :key="_index"
  218. />
  219. </cell>
  220. </template>
  221. <cell>
  222. <view class="cellDivisionLine"></view>
  223. </cell>
  224. </template>
  225. <template v-if="item.title == 'Vuex'">
  226. <cell>
  227. <vuexList
  228. ref="vuexList"
  229. :stateType="tabList[tabList.findIndex((x) => x.title == 'Vuex')].stateType"
  230. />
  231. </cell>
  232. </template>
  233. <template v-if="item.title == 'Logs'">
  234. <cell
  235. v-for="(_item, _index) in item.data"
  236. :key="_index"
  237. >
  238. <logItem
  239. :item="_item"
  240. :key="_index"
  241. />
  242. </cell>
  243. </template>
  244. <template v-if="item.title == 'Info'">
  245. <cell>
  246. <infoList ref="infoList" />
  247. </cell>
  248. </template>
  249. <template v-if="item.title == 'UniBus'">
  250. <cell>
  251. <subTitleBar
  252. :isOpen="item.isShowCount"
  253. title="事件统计"
  254. @click="pagesShowChange('isShowCount')"
  255. />
  256. </cell>
  257. <template v-if="item.isShowCount">
  258. <cell
  259. v-for="_item in item.countList"
  260. :key="_item.e"
  261. >
  262. <view
  263. class="eventItem"
  264. @longpress.stop="busCountMenu(_item)"
  265. >
  266. <text class="eventName">name: {{ _item.e }}</text>
  267. <view class="eventCount">
  268. <text
  269. v-if="item.filterType == '' || item.filterType == 'on'"
  270. class="eventCountItem"
  271. >
  272. on: {{ _item.on }}
  273. </text>
  274. <text
  275. v-if="item.filterType == '' || item.filterType == 'emit'"
  276. class="eventCountItem"
  277. >
  278. emit: {{ _item.emit }}
  279. </text>
  280. <text
  281. v-if="item.filterType == '' || item.filterType == 'once'"
  282. class="eventCountItem"
  283. >
  284. once: {{ _item.once }}
  285. </text>
  286. <text
  287. v-if="item.filterType == '' || item.filterType == 'off'"
  288. class="eventCountItem"
  289. >
  290. off: {{ _item.off }}
  291. </text>
  292. </view>
  293. </view>
  294. </cell>
  295. </template>
  296. <cell>
  297. <view class="cellDivisionLine"></view>
  298. </cell>
  299. <cell>
  300. <subTitleBar
  301. :isOpen="item.isShowLog"
  302. title="执行记录"
  303. @click="pagesShowChange('isShowLog')"
  304. />
  305. </cell>
  306. <template v-if="item.isShowLog">
  307. <cell
  308. v-for="(_item, _index) in item.logList"
  309. :key="_index"
  310. >
  311. <view
  312. class="eventLogItem"
  313. @longpress.stop="busLogMenu(_item)"
  314. >
  315. <text class="logText">{{ _item.e }}</text>
  316. <text class="logTime">{{ _item.date }}</text>
  317. </view>
  318. </cell>
  319. </template>
  320. <cell>
  321. <view class="cellDivisionLine"></view>
  322. </cell>
  323. </template>
  324. <template v-if="item.title == 'FileSys'">
  325. <!-- #ifdef APP-PLUS || MP-WEIXIN -->
  326. <cell
  327. v-for="(_item, _index) in item.data"
  328. :key="_index"
  329. >
  330. <fileSysItem
  331. :item="_item"
  332. :key="_index"
  333. :dirType="item.dirType"
  334. :dirList="item.dirList"
  335. @goChildDir="goChildDir"
  336. @getPage="getPage"
  337. @editDirName="editDirName"
  338. @openEditFileDialog="($event) => $refs.textFileEditDialog.show($event)"
  339. />
  340. </cell>
  341. <cell v-if="item.data.length == 0 || (item.data.length == 1 && item.data[0].type == 'back')">
  342. <view class="devEmpty">
  343. <text class="devEmptyText">空空如也</text>
  344. </view>
  345. </cell>
  346. <!-- #endif -->
  347. <!-- #ifndef APP-PLUS || MP-WEIXIN -->
  348. <cell>
  349. <view class="listCenterView">
  350. <text class="listCenterText">该平台无FileSys文件管理</text>
  351. </view>
  352. </cell>
  353. <!-- #endif -->
  354. </template>
  355. <template v-if="item.title == 'Setting'">
  356. <cell>
  357. <settingView ref="settingView" />
  358. </cell>
  359. </template>
  360. <template v-if="item.title == 'JsRunner'">
  361. <!-- #ifdef APP-PLUS || H5 -->
  362. <cell
  363. v-for="(_item, _index) in item.data"
  364. :key="_index"
  365. >
  366. <jsRunnerItem
  367. :item="_item"
  368. :key="_index"
  369. />
  370. </cell>
  371. <cell v-if="item.data.length == 0">
  372. <view class="devEmpty">
  373. <text class="devEmptyText">动态执行JS代码</text>
  374. </view>
  375. </cell>
  376. <!-- #endif -->
  377. <!-- #ifndef APP-PLUS || H5 -->
  378. <cell>
  379. <view class="listCenterView">
  380. <text class="listCenterText">该平台不支持该功能</text>
  381. </view>
  382. </cell>
  383. <!-- #endif -->
  384. </template>
  385. <template v-if="item.isLongList">
  386. <cell v-if="!item.isLoadAll && item.data.length == 30">
  387. <view
  388. class="loadAll"
  389. @click="showListAll"
  390. >
  391. <image
  392. class="loadAllFold"
  393. src="@/devTools/page/static/unfold.png"
  394. />
  395. <text class="loadAllText">展示全部数据</text>
  396. <image
  397. class="loadAllFold"
  398. src="@/devTools/page/static/unfold.png"
  399. />
  400. </view>
  401. </cell>
  402. <cell v-if="item.type == 'success' && item.data.length == 0">
  403. <view class="devEmpty">
  404. <text class="devEmptyText">空空如也</text>
  405. </view>
  406. </cell>
  407. <cell v-if="(item.type == 'loading' || item.type == 'loading') && item.data.length == 0">
  408. <view class="devEmpty">
  409. <text class="devEmptyText">加载中</text>
  410. </view>
  411. </cell>
  412. </template>
  413. <cell>
  414. <view style="height: 300rpx"></view>
  415. </cell>
  416. </template>
  417. </mobileSwiperScroll>
  418. </view>
  419. <bottomTools
  420. :tabIndex="tabIndex"
  421. :tabTitle="tabTitle"
  422. :options="bottomToolsOptions"
  423. :isShow="isShowBottomTools"
  424. :stateType="tabList[tabList.findIndex((x) => x.title == 'Vuex')].stateType"
  425. @filterTypeChange="onFilterTypeChange"
  426. @goChildDir="goChildDir"
  427. @changeFileDirType="changeFileDirType"
  428. @changeStorageType="changeStorageType"
  429. @editDirName="editDirName"
  430. @getPage="getPage"
  431. @runJs="runJs"
  432. @emptyCodeHis="emptyCodeHis"
  433. @changeStateType="changeStateType"
  434. />
  435. <editDialog ref="editDialog" />
  436. <dayOnlinePageList ref="dayOnlinePageList" />
  437. <sendRequest ref="sendRequest" />
  438. <textFileEditDialog
  439. ref="textFileEditDialog"
  440. @getPage="getPage"
  441. />
  442. <createDir
  443. ref="createDir"
  444. :dirList="tabList[11].dirList"
  445. :dirType="tabList[11].dirType"
  446. @getPage="getPage"
  447. />
  448. <addStorage
  449. :storageType="tabList[5].storageType"
  450. @getPage="getPage"
  451. />
  452. <routeDialog />
  453. </view>
  454. </template>
  455. <script>
  456. import init from "../../index";
  457. import consoleItem from "./listItem/consoleItem.vue";
  458. import infoList from "./listItem/infoList.vue";
  459. import storageList from "./listItem/storageList.vue";
  460. import tools from "./listItem/tools.vue";
  461. import vuexList from "./listItem/vuexList.vue";
  462. import animationControl from "./mixins/animationControl";
  463. import { timeFormat, timeFromNow } from "../../core/libs/timeFormat";
  464. import devCache from "../../core/libs/devCache";
  465. import networkItem from "./listItem/networkItem.vue";
  466. import pages from "./listItem/pages.vue";
  467. import logItem from "./listItem/logItem.vue";
  468. import pageItem from "./listItem/pageItem.vue";
  469. import errorItem from "./listItem/errorItem.vue";
  470. import mobileSwiperScroll from "./ui/mobileSwiperScroll.vue";
  471. import subTitleBar from "./ui/subTitleBar.vue";
  472. import dayOnlineItem from "./listItem/dayOnlineItem.vue";
  473. import dayOnlinePageList from "./dialog/dayOnlinePageList.vue";
  474. import sendRequest from "./dialog/sendRequest.vue";
  475. import bottomTools from "./bottomTools.vue";
  476. import dirReader from "./libs/dirReader";
  477. import fileSysItem from "./listItem/fileSysItem.vue";
  478. import fileSize from "./libs/fileSize";
  479. import textFileEditDialog from "./dialog/textFileEditDialog.vue";
  480. import createDir from "./dialog/createDir.vue";
  481. import editDialog from "./dialog/editDialog.vue";
  482. import addStorage from "./dialog/addStorage.vue";
  483. import settingView from "./listItem/setting.vue";
  484. import mp from "./mixins/mp";
  485. import jsRunnerItem from "./listItem/jsRunnerItem.vue";
  486. import routeItem from "./listItem/routeItem.vue";
  487. import routeDialog from "./dialog/routeDialog.vue";
  488. import pageLinkList from "../../core/libs/pageLinkList.js";
  489. // #ifndef APP-PLUS
  490. import h5Cell from "./ui/h5Cell.vue";
  491. // #endif
  492. /**
  493. * 时间戳转时间文字
  494. */
  495. function getTime(t) {
  496. let c = "0s";
  497. if (t < 60) {
  498. c = t + "秒";
  499. } else if (t < 60 * 60) {
  500. c = Math.ceil(t / 60) + "分钟";
  501. } else {
  502. c = Math.ceil(t / 60 / 60) + "小时" + Math.ceil((t % (60 * 60)) / 60) + "分钟";
  503. }
  504. return c;
  505. }
  506. export default {
  507. mixins: [animationControl, mp],
  508. components: {
  509. mobileSwiperScroll,
  510. consoleItem,
  511. storageList,
  512. vuexList,
  513. tools,
  514. infoList,
  515. networkItem,
  516. pages,
  517. logItem,
  518. pageItem,
  519. errorItem,
  520. subTitleBar,
  521. dayOnlinePageList,
  522. dayOnlineItem,
  523. sendRequest,
  524. bottomTools,
  525. fileSysItem,
  526. textFileEditDialog,
  527. createDir,
  528. editDialog,
  529. addStorage,
  530. settingView,
  531. jsRunnerItem,
  532. routeItem,
  533. routeDialog,
  534. // #ifndef APP-PLUS
  535. cell: h5Cell,
  536. // #endif
  537. },
  538. data() {
  539. return {
  540. /**
  541. * 是否处于弹窗状态
  542. */
  543. isDialog: true,
  544. tabLoading: true,
  545. tabIndex: 0,
  546. tabList: [
  547. {
  548. title: "Tools", //标题
  549. hasLoad: false,
  550. },
  551. {
  552. title: "Error", //标题
  553. canRefreshing: true, //是否允许下拉刷新
  554. isRefreshing: false, //下拉刷新状态
  555. refreshType: "waitPullUp", //刷新状态 'waitPullUp','waitRelease','refreshing'
  556. type: "init", //列表状态
  557. data: [], //数据条数
  558. hasLoad: false,
  559. isLongList: true, // 是否长列表
  560. isLoadAll: false, //是否加载全部
  561. filterType: "", //过滤类型
  562. isShowBottomTools: true, //显示底部工具栏
  563. },
  564. {
  565. title: "Console", //标题
  566. canRefreshing: true, //是否允许下拉刷新
  567. isRefreshing: false, //下拉刷新状态
  568. refreshType: "waitPullUp", //刷新状态 'waitPullUp','waitRelease','refreshing'
  569. type: "init", //列表状态
  570. data: [], //数据条数
  571. hasLoad: false,
  572. isLongList: true, // 是否长列表
  573. isLoadAll: false, //是否加载全部
  574. filterType: "", //过滤类型
  575. isShowBottomTools: true, //显示底部工具栏
  576. },
  577. {
  578. title: "Network", //标题
  579. canRefreshing: true, //是否允许下拉刷新
  580. isRefreshing: false, //下拉刷新状态
  581. refreshType: "waitPullUp", //刷新状态 'waitPullUp','waitRelease','refreshing'
  582. type: "init", //列表状态
  583. data: [], //数据条数
  584. hasLoad: false,
  585. isLongList: true, // 是否长列表
  586. isLoadAll: false, //是否加载全部
  587. filterType: "", //过滤类型
  588. isShowBottomTools: true, //显示底部工具栏
  589. },
  590. {
  591. title: "JsRunner", //标题
  592. canRefreshing: false, //是否允许下拉刷新
  593. isRefreshing: false, //下拉刷新状态
  594. refreshType: "waitPullUp", //刷新状态 'waitPullUp','waitRelease','refreshing'
  595. type: "init", //列表状态
  596. data: [], //数据条数
  597. hasLoad: false,
  598. // #ifdef APP-PLUS || H5
  599. isShowBottomTools: true, //显示底部工具栏
  600. // #endif
  601. },
  602. {
  603. title: "Storage", //标题
  604. canRefreshing: true, //是否允许下拉刷新
  605. isRefreshing: false, //下拉刷新状态
  606. refreshType: "waitPullUp", //刷新状态 'waitPullUp','waitRelease','refreshing'
  607. hasLoad: false,
  608. storageType: "localStorage", //缓存类型默认为localStorage
  609. isShowBottomTools: true, //显示底部工具栏
  610. },
  611. {
  612. title: "Pages", //标题
  613. canRefreshing: true, //是否允许下拉刷新
  614. isRefreshing: false, //下拉刷新状态
  615. refreshType: "waitPullUp", //刷新状态 'waitPullUp','waitRelease','refreshing'
  616. hasLoad: false,
  617. isShowPages: true, //是否展示页面堆栈列表
  618. data: [],
  619. isShowData: false, //是否展示页面全部统计数据
  620. dayOnlineList: [], //日浏览量日志
  621. dayOnlineShow: false,
  622. isShowBottomTools: true, //显示底部工具栏
  623. isShowRouteList: false, // 是否显示路由列表
  624. routeList: [], //全部路由列表
  625. },
  626. {
  627. title: "Vuex", //标题
  628. canRefreshing: true, //是否允许下拉刷新
  629. isRefreshing: false, //下拉刷新状态
  630. refreshType: "waitPullUp", //刷新状态 'waitPullUp','waitRelease','refreshing'
  631. hasLoad: false,
  632. stateType: "vuex", //全局变量类型 vuex pinia globalData
  633. isShowBottomTools: true, //显示底部工具栏
  634. },
  635. {
  636. title: "Logs", //标题
  637. canRefreshing: true, //是否允许下拉刷新
  638. isRefreshing: false, //下拉刷新状态
  639. refreshType: "waitPullUp", //刷新状态 'waitPullUp','waitRelease','refreshing'
  640. type: "init", //列表状态
  641. data: [], //数据条数
  642. page: 0, //当前页码
  643. hasLoad: false,
  644. isLoadAll: false, //是否加载全部
  645. isLongList: true, // 是否长列表
  646. isShowBottomTools: true, //显示底部工具栏
  647. },
  648. {
  649. title: "Info", //标题
  650. canRefreshing: true, //是否允许下拉刷新
  651. isRefreshing: false, //下拉刷新状态
  652. refreshType: "waitPullUp", //刷新状态 'waitPullUp','waitRelease','refreshing'
  653. hasLoad: false,
  654. },
  655. {
  656. title: "UniBus", //标题
  657. canRefreshing: true, //是否允许下拉刷新
  658. isRefreshing: false, //下拉刷新状态
  659. refreshType: "waitPullUp", //刷新状态 'waitPullUp','waitRelease','refreshing'
  660. type: "init", //列表状态
  661. isShowCount: true,
  662. countList: [],
  663. isShowLog: false,
  664. logList: [],
  665. filterType: "", //过滤类型
  666. hasLoad: false,
  667. isShowBottomTools: true, //显示底部工具栏
  668. },
  669. {
  670. title: "FileSys", //标题
  671. canRefreshing: true, //是否允许下拉刷新
  672. isRefreshing: false, //下拉刷新状态
  673. refreshType: "waitPullUp", //刷新状态 'waitPullUp','waitRelease','refreshing'
  674. type: "init", //列表状态
  675. // #ifdef APP-PLUS
  676. dirType: "PRIVATE_DOC", //文件类型 wx, PRIVATE_WWW, PRIVATE_DOC PUBLIC_DOCUMENTS PUBLIC_DOWNLOADS
  677. // #endif
  678. // #ifdef MP
  679. dirType: "wx", //文件类型 wx, PRIVATE_WWW, PRIVATE_DOC
  680. // #endif
  681. data: [], //文件列表
  682. dirList: [], //目录列表
  683. hasLoad: false,
  684. isShowBottomTools: true, //显示底部工具栏
  685. },
  686. {
  687. title: "Setting", //标题
  688. canRefreshing: true, //是否允许下拉刷新
  689. isRefreshing: false, //下拉刷新状态
  690. refreshType: "waitPullUp", //刷新状态 'waitPullUp','waitRelease','refreshing'
  691. type: "init", //列表状态
  692. data: [], //数据条数
  693. page: 0, //当前页码
  694. hasLoad: false,
  695. },
  696. ],
  697. };
  698. },
  699. watch: {
  700. /**
  701. * 监听tab改变事件
  702. */
  703. tabIndex(index) {
  704. if (!this.tabList[index].hasLoad) {
  705. this.getPage();
  706. }
  707. },
  708. },
  709. computed: {
  710. /**
  711. * 挂载dev对象
  712. */
  713. $devTools() {
  714. return init;
  715. },
  716. /**
  717. * 面板高度
  718. */
  719. panelHeight() {
  720. // #ifndef APP-PLUS
  721. if (1) return this.windowInfo.system.windowHeight - this.windowInfo.navbar.heightPx;
  722. // #endif
  723. return Math.ceil(this.windowInfo.system.windowHeight * 0.8);
  724. },
  725. /**
  726. * 滚动列表的高度
  727. */
  728. listHeight() {
  729. let sys = uni.getSystemInfoSync();
  730. // #ifdef H5
  731. if (1) return sys.windowHeight - 50 - uni.upx2px(80) - 1;
  732. // #endif
  733. // #ifdef MP-WEIXIN
  734. if (1) return sys.windowHeight - this.windowInfo.navbar.heightPx - uni.upx2px(80) - 1;
  735. // #endif
  736. return this.panelHeight - uni.upx2px(80) - 1;
  737. },
  738. /**
  739. * 当前tab栏的标题
  740. */
  741. tabTitle() {
  742. return this.tabList[this.tabIndex].title;
  743. },
  744. /**
  745. * 获取底部栏需要的参数
  746. */
  747. bottomToolsOptions() {
  748. let that = this;
  749. const getTabItemByTitle = (title) => {
  750. let i = that.tabList.findIndex((x) => x.title == title);
  751. return that.tabList[i];
  752. };
  753. return {
  754. errorFilterType: getTabItemByTitle("Error").filterType,
  755. consoleFilterType: getTabItemByTitle("Console").filterType,
  756. networkFilterType: getTabItemByTitle("Network").filterType,
  757. busFilterType: getTabItemByTitle("UniBus").filterType,
  758. fileSysDirList: getTabItemByTitle("FileSys").dirList,
  759. fileSysDirType: getTabItemByTitle("FileSys").dirType,
  760. storageType: getTabItemByTitle("Storage").storageType,
  761. codeHisLength: getTabItemByTitle("JsRunner").data.length,
  762. };
  763. },
  764. /**
  765. * 是否显示底部工具栏
  766. */
  767. isShowBottomTools() {
  768. // [1, 2, 3, 4, 5, 7, 9, 10].indexOf(tabIndex) != -1
  769. let item = this.tabList[this.tabIndex];
  770. return item.isShowBottomTools === true;
  771. },
  772. },
  773. mounted() {
  774. let that = this;
  775. this.getPage();
  776. // #ifndef APP-PLUS
  777. this.isDialog = false;
  778. // #endif
  779. // ! 刷新当前列表
  780. uni.$on("devTools_listGetPage", () => {
  781. that.getPage();
  782. });
  783. // ! 删除指定请求记录
  784. uni.$on("devTools_delNetworkItemById", (id) => {
  785. let tabIndex = that.tabList.findIndex((x) => x.title == "Network");
  786. let i = that.tabList[tabIndex].data.findIndex((x) => x.id == id);
  787. if (i != -1) {
  788. that.tabList[tabIndex].data.splice(i, 1);
  789. }
  790. });
  791. // ! 删除日志
  792. uni.$on("devTools_delLog", (item) => {
  793. let tabIndex = that.tabList.findIndex((x) => x.title == "Logs");
  794. let i = that.tabList[tabIndex].data.findIndex((x) => x.date == item.date && x.t == item.t);
  795. if (i != -1) {
  796. that.tabList[tabIndex].data.splice(i, 1);
  797. }
  798. });
  799. // ! 删除错误记录
  800. uni.$on("devTools_delError", (item) => {
  801. let tabIndex = that.tabList.findIndex((x) => x.title == "Error");
  802. let i = that.tabList[tabIndex].data.findIndex(
  803. (x) => x.type == item.type && x.t == item.t && x.m == item.m && x.tr == item.tr && x.p == item.p
  804. );
  805. if (i != -1) {
  806. that.tabList[tabIndex].data.splice(i, 1);
  807. }
  808. });
  809. // ! 删除打印日志
  810. uni.$on("devTools_delConsoleItem", (item) => {
  811. let tabIndex = that.tabList.findIndex((x) => x.title == "Console");
  812. let i = that.tabList[tabIndex].data.findIndex((x) => {
  813. let t = JSON.stringify(x.list);
  814. return t == JSON.stringify(item.list) && x.time == item.time && x.page == item.page && x.type == item.type;
  815. });
  816. if (i != -1) {
  817. that.tabList[tabIndex].data.splice(i, 1);
  818. }
  819. });
  820. // !初始化Vuex,自动推断全局变量类型
  821. let vIndex = that.tabList.findIndex((x) => x.title == "Vuex");
  822. let vType = "globalData";
  823. if (that.$store) {
  824. vType = "vuex";
  825. } else if (uni.Pinia || that.$pinia) {
  826. vType = "pinia";
  827. }
  828. // console.log("vType", vType);
  829. that.tabList[vIndex].stateType = vType;
  830. },
  831. methods: {
  832. /**
  833. * 页面加载事件
  834. */
  835. pageOnLoad(options) {
  836. let that = this;
  837. that.$nextTick(() => {
  838. // #ifdef APP-PLUS
  839. that.panelShow();
  840. // #endif
  841. });
  842. uni.$once("devTools_closeDevToolsPanel", () => {
  843. that.panelHide();
  844. });
  845. },
  846. /**
  847. * 加载列表
  848. */
  849. async getPage() {
  850. let that = this;
  851. const index = Number(that.tabIndex);
  852. let item = that.tabList[index];
  853. if (item.isRefreshing) return;
  854. await that.awaitNextTick();
  855. if (item.title == "Storage") {
  856. that.refreshStorage();
  857. } else if (item.title == "Vuex") {
  858. that.refreshVuex();
  859. } else if (item.title == "Info") {
  860. that.refreshInfo();
  861. } else if (item.title == "Pages") {
  862. that.getPages();
  863. } else if (item.title == "Console") {
  864. that.getConsole();
  865. } else if (item.title == "Network") {
  866. that.getNetwork();
  867. } else if (item.title == "Logs") {
  868. that.getLogs();
  869. } else if (item.title == "Error") {
  870. that.getError();
  871. } else if (item.title == "UniBus") {
  872. that.getUniBus();
  873. } else if (item.title == "FileSys") {
  874. that.getDirList();
  875. } else if (item.title == "Setting") {
  876. let tabIndex = that.tabList.findIndex((x) => x.title == "Setting");
  877. that.tabList[tabIndex].isRefreshing = true;
  878. that.tabList[tabIndex].type = "loading";
  879. that.$refs.settingView.getPage();
  880. setTimeout(() => {
  881. that.tabList[tabIndex].isRefreshing = false;
  882. that.tabList[tabIndex].refreshType = "success";
  883. that.tabList[tabIndex].type = "success";
  884. setTimeout(() => {
  885. that.tabList[tabIndex].refreshType = "waitRelease";
  886. }, 1000);
  887. }, 500);
  888. }
  889. that.tabList[index].hasLoad = true;
  890. },
  891. /**
  892. * 等待渲染完成
  893. */
  894. awaitNextTick() {
  895. let that = this;
  896. return new Promise((yes) => {
  897. // #ifdef APP-PLUS
  898. setTimeout(() => {
  899. yes();
  900. }, 200);
  901. // #endif
  902. // #ifndef APP-PLUS
  903. that.$nextTick(() => {
  904. setTimeout(() => {
  905. yes();
  906. }, 200);
  907. });
  908. // #endif
  909. });
  910. },
  911. /**
  912. * 隐藏弹窗
  913. */
  914. hide() {
  915. init.hide();
  916. },
  917. /**
  918. * 下拉刷新事件
  919. */
  920. onrefresh() {
  921. if (!this.tabList[this.tabIndex].canRefreshing || this.tabList[this.tabIndex].type == "loading") return false;
  922. this.getPage(true);
  923. },
  924. /**
  925. * 下拉过程触发
  926. */
  927. onpullingdown(args) {
  928. let e = args.event;
  929. if (this.tabList[this.tabIndex].refreshType == "refreshing") return false;
  930. if (e.pullingDistance > e.viewHeight) {
  931. this.tabList[this.tabIndex].refreshType = "waitRelease";
  932. } else {
  933. this.tabList[this.tabIndex].refreshType = "waitPullUp";
  934. }
  935. },
  936. /**
  937. * 刷新缓存数据
  938. */
  939. refreshStorage() {
  940. let that = this;
  941. let tabIndex = that.tabList.findIndex((x) => x.title == "Storage");
  942. that.tabList[tabIndex].isRefreshing = true;
  943. that.tabList[tabIndex].refreshType = "refreshing";
  944. that.$refs.storageList.getData(that.tabList[tabIndex].storageType);
  945. setTimeout(() => {
  946. that.tabList[tabIndex].isRefreshing = false;
  947. that.tabList[tabIndex].refreshType = "success";
  948. setTimeout(() => {
  949. that.tabList[tabIndex].refreshType = "waitRelease";
  950. }, 1000);
  951. }, 500);
  952. },
  953. /**
  954. * 刷新vuex数据
  955. */
  956. refreshVuex() {
  957. let that = this;
  958. let tabIndex = that.tabList.findIndex((x) => x.title == "Vuex");
  959. that.tabList[tabIndex].isRefreshing = true;
  960. that.tabList[tabIndex].refreshType = "refreshing";
  961. that.$refs.vuexList.getData();
  962. setTimeout(() => {
  963. that.tabList[tabIndex].isRefreshing = false;
  964. that.tabList[tabIndex].refreshType = "success";
  965. setTimeout(() => {
  966. that.tabList[tabIndex].refreshType = "waitRelease";
  967. }, 1000);
  968. }, 500);
  969. },
  970. /**
  971. * 刷新pages
  972. */
  973. getPages() {
  974. let that = this;
  975. let tabIndex = that.tabList.findIndex((x) => x.title == "Pages");
  976. that.tabList[tabIndex].isRefreshing = true;
  977. that.tabList[tabIndex].refreshType = "refreshing";
  978. that.tabList[tabIndex].data = [];
  979. that.$refs.pages.getData();
  980. let data = devCache.get("pageCount");
  981. if (!data) data = [];
  982. data = data.map((x) => {
  983. x.timeCount = getTime(x.activeTimeCount);
  984. return x;
  985. });
  986. let onlineList = devCache.get("dayOnline");
  987. if (!onlineList) onlineList = [];
  988. onlineList = onlineList.map((x) => {
  989. x.timeCount = getTime(x.activeTimeCount);
  990. x.page = x.page.map((v) => {
  991. v.timeCount = getTime(v.t);
  992. return v;
  993. });
  994. return x;
  995. });
  996. let pages = pageLinkList.getAllRoutes();
  997. setTimeout(() => {
  998. that.tabList[tabIndex].data = data;
  999. that.tabList[tabIndex].routeList = pages;
  1000. that.tabList[tabIndex].dayOnlineList = onlineList;
  1001. that.tabList[tabIndex].refreshType = "success";
  1002. that.tabList[tabIndex].isRefreshing = false;
  1003. setTimeout(() => {
  1004. that.tabList[tabIndex].refreshType = "waitRelease";
  1005. }, 1000);
  1006. }, 500);
  1007. },
  1008. /**
  1009. * 改变pages列表展示状态
  1010. */
  1011. pagesShowChange(key) {
  1012. this.tabList[this.tabIndex][key] = !this.tabList[this.tabIndex][key];
  1013. },
  1014. /**
  1015. * 打开在线统计详情弹窗
  1016. */
  1017. showOnlineDetailsDialog(item) {
  1018. this.$refs.dayOnlinePageList.show(item);
  1019. },
  1020. /**
  1021. * 刷新info
  1022. */
  1023. refreshInfo() {
  1024. let that = this;
  1025. let tabIndex = that.tabList.findIndex((x) => x.title == "Info");
  1026. that.tabList[tabIndex].isRefreshing = true;
  1027. that.tabList[tabIndex].isRefreshing = true;
  1028. that.tabList[tabIndex].refreshType = "refreshing";
  1029. that.$refs.infoList.getData();
  1030. setTimeout(() => {
  1031. that.tabList[tabIndex].isRefreshing = false;
  1032. that.tabList[tabIndex].refreshType = "success";
  1033. setTimeout(() => {
  1034. that.tabList[tabIndex].refreshType = "waitRelease";
  1035. }, 1000);
  1036. }, 500);
  1037. },
  1038. /**
  1039. * 加载数据
  1040. */
  1041. getConsole() {
  1042. let that = this;
  1043. let tabIndex = that.tabList.findIndex((x) => x.title == "Console");
  1044. that.tabList[tabIndex].isRefreshing = true;
  1045. that.tabList[tabIndex].type = "loading";
  1046. let data = devCache.get("console");
  1047. if (!data) data = [];
  1048. data = data.map((item) => {
  1049. // item.date = timeFormat(item.time);
  1050. item.date = timeFromNow(item.time);
  1051. return item;
  1052. });
  1053. let filterType = that.tabList[tabIndex].filterType;
  1054. if (filterType != "") {
  1055. data = data.filter((x) => x.type == filterType);
  1056. }
  1057. if (data.length > 30 && that.tabList[tabIndex].isLongList && !that.tabList[tabIndex].isLoadAll) {
  1058. data.splice(30, data.length - 1);
  1059. }
  1060. that.tabList[tabIndex].data = data;
  1061. setTimeout(() => {
  1062. that.tabList[tabIndex].refreshType = "success";
  1063. that.tabList[tabIndex].isRefreshing = false;
  1064. that.tabList[tabIndex].type = "success";
  1065. setTimeout(() => {
  1066. that.tabList[tabIndex].refreshType = "waitRelease";
  1067. }, 1000);
  1068. }, 500);
  1069. },
  1070. /**
  1071. * 加载请求数据
  1072. */
  1073. getNetwork() {
  1074. let that = this;
  1075. let tabIndex = that.tabList.findIndex((x) => x.title == "Network");
  1076. that.tabList[tabIndex].isRefreshing = true;
  1077. that.tabList[tabIndex].type = "loading";
  1078. let data = devCache.get("request");
  1079. if (!data) data = [];
  1080. data = data.map((item) => {
  1081. item.date = timeFromNow(item.sendTime);
  1082. return item;
  1083. });
  1084. let filterType = that.tabList[tabIndex].filterType;
  1085. if (filterType != "") {
  1086. if (filterType == "请求失败") {
  1087. data = data.filter((x) => x.type == 2 || (x.type == 1 && x.responseStatus != 200));
  1088. } else if (filterType == "其他") {
  1089. data = data.filter((x) => x.method != "get" && x.method != "post");
  1090. } else if (filterType == "1s+") {
  1091. data = data.filter((x) => x.type != 0 && x.useTime > 1);
  1092. } else if (filterType == "5s+") {
  1093. data = data.filter((x) => x.type != 0 && x.useTime > 5);
  1094. } else if (filterType == "10s+") {
  1095. data = data.filter((x) => x.type != 0 && x.useTime > 10);
  1096. } else if (filterType == "get") {
  1097. data = data.filter((x) => x.method.toLocaleLowerCase() == "get");
  1098. } else if (filterType == "post") {
  1099. data = data.filter((x) => x.method.toLocaleLowerCase() == "post");
  1100. } else if (filterType == "500KB+") {
  1101. data = data.filter((x) => x.type == 1 && x.responseBodySize > 1024 * 500);
  1102. } else if (filterType == "1MB+") {
  1103. data = data.filter((x) => x.type == 1 && x.responseBodySize > 1024 * 1024);
  1104. } else {
  1105. data = data.filter((x) => x.method == filterType);
  1106. }
  1107. }
  1108. console.log("data", data);
  1109. if (data.length > 30 && that.tabList[tabIndex].isLongList && !that.tabList[tabIndex].isLoadAll) {
  1110. data.splice(30, data.length - 1);
  1111. }
  1112. that.tabList[tabIndex].data = data;
  1113. setTimeout(() => {
  1114. that.tabList[tabIndex].isRefreshing = false;
  1115. that.tabList[tabIndex].refreshType = "success";
  1116. that.tabList[tabIndex].type = "success";
  1117. setTimeout(() => {
  1118. that.tabList[tabIndex].refreshType = "waitRelease";
  1119. }, 1000);
  1120. }, 500);
  1121. },
  1122. /**
  1123. * 获取日志
  1124. */
  1125. getLogs() {
  1126. let that = this;
  1127. let tabIndex = that.tabList.findIndex((x) => x.title == "Logs");
  1128. that.tabList[tabIndex].isRefreshing = true;
  1129. that.tabList[tabIndex].type = "loading";
  1130. let data = devCache.get("logReport");
  1131. if (!data) data = [];
  1132. data = data.map((x) => {
  1133. x.date = timeFromNow(x.t);
  1134. return x;
  1135. });
  1136. if (data.length > 30 && that.tabList[tabIndex].isLongList && !that.tabList[tabIndex].isLoadAll) {
  1137. data.splice(30, data.length - 1);
  1138. }
  1139. that.tabList[tabIndex].data = data;
  1140. setTimeout(() => {
  1141. that.tabList[tabIndex].isRefreshing = false;
  1142. that.tabList[tabIndex].refreshType = "success";
  1143. that.tabList[tabIndex].type = "success";
  1144. setTimeout(() => {
  1145. that.tabList[tabIndex].refreshType = "waitRelease";
  1146. }, 1000);
  1147. }, 500);
  1148. },
  1149. /**
  1150. * 获取错误列表
  1151. */
  1152. getError() {
  1153. let that = this;
  1154. let tabIndex = that.tabList.findIndex((x) => x.title == "Error");
  1155. that.tabList[tabIndex].isRefreshing = true;
  1156. that.tabList[tabIndex].type = "loading";
  1157. let data = devCache.get("errorReport");
  1158. if (!data) data = [];
  1159. data = data.map((x) => {
  1160. x.date = timeFromNow(x.t);
  1161. return x;
  1162. });
  1163. let filterType = that.tabList[tabIndex].filterType;
  1164. if (filterType != "") {
  1165. data = data.filter((x) => x.type == filterType);
  1166. }
  1167. if (data.length > 30 && that.tabList[tabIndex].isLongList && !that.tabList[tabIndex].isLoadAll) {
  1168. data.splice(30, data.length - 1);
  1169. }
  1170. that.tabList[tabIndex].data = data;
  1171. setTimeout(() => {
  1172. that.tabList[tabIndex].isRefreshing = false;
  1173. that.tabList[tabIndex].refreshType = "success";
  1174. that.tabList[tabIndex].type = "success";
  1175. setTimeout(() => {
  1176. that.tabList[tabIndex].refreshType = "waitRelease";
  1177. }, 1000);
  1178. }, 500);
  1179. },
  1180. /**
  1181. * 加载全部列表
  1182. */
  1183. showListAll() {
  1184. let that = this;
  1185. that.tabList[that.tabIndex].isLoadAll = true;
  1186. that.tabList[that.tabIndex].data = [];
  1187. that.tabList[that.tabIndex].type = "loading";
  1188. that.getPage();
  1189. },
  1190. /**
  1191. * 加载eventBus日志列表
  1192. */
  1193. getUniBus() {
  1194. let that = this;
  1195. let tabIndex = that.tabList.findIndex((x) => x.title == "UniBus");
  1196. that.tabList[tabIndex].isRefreshing = true;
  1197. that.tabList[tabIndex].refreshType = "refreshing";
  1198. let logList = devCache.get("uniBus");
  1199. if (!logList) logList = [];
  1200. let busCount = devCache.get("busCount");
  1201. if (!busCount) busCount = [];
  1202. logList = logList.map((x) => {
  1203. x.date = timeFormat(x.t);
  1204. return x;
  1205. });
  1206. let filterType = that.tabList[tabIndex].filterType;
  1207. if (filterType != "") {
  1208. logList = logList.filter((x) => x.e.indexOf(`${filterType}>`) == 0);
  1209. }
  1210. setTimeout(() => {
  1211. that.tabList[tabIndex].logList = logList;
  1212. that.tabList[tabIndex].countList = busCount;
  1213. that.tabList[tabIndex].refreshType = "success";
  1214. that.tabList[tabIndex].isRefreshing = false;
  1215. setTimeout(() => {
  1216. that.tabList[tabIndex].refreshType = "waitRelease";
  1217. }, 1000);
  1218. }, 500);
  1219. },
  1220. /**
  1221. * 长按BUS事件
  1222. */
  1223. busCountMenu(item) {
  1224. let that = this;
  1225. let menu = [
  1226. {
  1227. text: `复制名称`,
  1228. click() {
  1229. uni.setClipboardData({
  1230. data: item.e,
  1231. });
  1232. },
  1233. },
  1234. {
  1235. text: `复制完整日志`,
  1236. click() {
  1237. uni.setClipboardData({
  1238. data: JSON.stringify(item),
  1239. });
  1240. },
  1241. },
  1242. ];
  1243. uni.showActionSheet({
  1244. itemList: menu.map((x) => x.text),
  1245. success({ tapIndex }) {
  1246. menu[tapIndex].click();
  1247. },
  1248. });
  1249. },
  1250. /**
  1251. * 长按BUS log事件
  1252. */
  1253. busLogMenu(item) {
  1254. let that = this;
  1255. let menu = [
  1256. {
  1257. text: `复制名称`,
  1258. click() {
  1259. uni.setClipboardData({
  1260. data: item.e,
  1261. });
  1262. },
  1263. },
  1264. {
  1265. text: `复制完整日志`,
  1266. click() {
  1267. uni.setClipboardData({
  1268. data: JSON.stringify(item),
  1269. });
  1270. },
  1271. },
  1272. ];
  1273. uni.showActionSheet({
  1274. itemList: menu.map((x) => x.text),
  1275. success({ tapIndex }) {
  1276. menu[tapIndex].click();
  1277. },
  1278. });
  1279. },
  1280. /**
  1281. * 列表过滤类型改变事件
  1282. */
  1283. onFilterTypeChange(type) {
  1284. this.tabList[this.tabIndex].filterType = type;
  1285. this.getPage();
  1286. },
  1287. /**
  1288. * 加载文件列表
  1289. */
  1290. async getDirList() {
  1291. let that = this;
  1292. let tabIndex = that.tabList.findIndex((x) => x.title == "FileSys");
  1293. // #ifndef APP-PLUS || MP-WEIXIN
  1294. if (1) return;
  1295. // #endif
  1296. that.tabList[tabIndex].isRefreshing = true;
  1297. that.tabList[tabIndex].type = "loading";
  1298. let path = "";
  1299. let data = [];
  1300. // #ifdef APP-PLUS
  1301. if (that.tabList[tabIndex].dirType == "PRIVATE_DOC") {
  1302. path = "_doc";
  1303. } else if (that.tabList[tabIndex].dirType == "PRIVATE_WWW") {
  1304. path = "_www";
  1305. } else if (that.tabList[tabIndex].dirType == "PUBLIC_DOCUMENTS") {
  1306. path = "_documents";
  1307. } else if (that.tabList[tabIndex].dirType == "PUBLIC_DOWNLOADS") {
  1308. path = "_downloads";
  1309. }
  1310. if (that.tabList[tabIndex].dirList) {
  1311. that.tabList[tabIndex].dirList.forEach((item) => {
  1312. path = path + "/" + item;
  1313. });
  1314. }
  1315. data = await dirReader.getDirFileList(path);
  1316. // #endif
  1317. // #ifdef MP-WEIXIN
  1318. let fs = wx.getFileSystemManager();
  1319. path = wx.env.USER_DATA_PATH;
  1320. if (that.tabList[tabIndex].dirList) {
  1321. that.tabList[tabIndex].dirList.forEach((item) => {
  1322. path = path + "/" + item;
  1323. });
  1324. }
  1325. let fileList = [];
  1326. let dirList = [];
  1327. let list = fs.readdirSync(path + "/");
  1328. for (let i = 0; i < list.length; i++) {
  1329. let name = list[i];
  1330. let stats = fs.statSync(path + "/" + name);
  1331. let row = {
  1332. type: stats.isFile() ? "file" : "dir",
  1333. size: stats.size,
  1334. time: stats.lastModifiedTime,
  1335. name,
  1336. fileType: name.split(".").pop(),
  1337. };
  1338. if (stats.isFile()) {
  1339. fileList.push(row);
  1340. } else {
  1341. dirList.push(row);
  1342. }
  1343. }
  1344. data = [...dirList, ...fileList];
  1345. // #endif
  1346. data = data.map((x) => {
  1347. x.date = timeFormat(x.time, "yyyy-mm-dd hh:MM");
  1348. x.sizeText = fileSize.getByteSize(x.size);
  1349. x.icon = x.type == "dir" ? "/devTools/page/static/fileSys/wenjianjia.png" : dirReader.getFileIcon(x.fileType);
  1350. return x;
  1351. });
  1352. if (that.tabList[tabIndex].dirList.length > 0) {
  1353. data.unshift({
  1354. type: "back",
  1355. name: "返回上一级",
  1356. });
  1357. }
  1358. that.tabList[tabIndex].data = data;
  1359. setTimeout(() => {
  1360. that.tabList[tabIndex].isRefreshing = false;
  1361. that.tabList[tabIndex].refreshType = "success";
  1362. that.tabList[tabIndex].type = "success";
  1363. setTimeout(() => {
  1364. that.tabList[tabIndex].refreshType = "waitRelease";
  1365. }, 1000);
  1366. }, 500);
  1367. },
  1368. /**
  1369. * 打开文件夹
  1370. */
  1371. goChildDir(dirName) {
  1372. let that = this;
  1373. let tabIndex = that.tabList.findIndex((x) => x.title == "FileSys");
  1374. if (typeof dirName == "string" && dirName.indexOf("_goIndex_") == 0) {
  1375. let i = Number(dirName.replace("_goIndex_", ""));
  1376. that.tabList[tabIndex].dirList.splice(i, 99999);
  1377. } else if (dirName == "__back__") {
  1378. if (that.tabList[tabIndex].dirList.length > 0) {
  1379. that.tabList[tabIndex].dirList.splice(that.tabList[tabIndex].dirList.length - 1, 1);
  1380. }
  1381. } else {
  1382. that.tabList[tabIndex].dirList.push(dirName);
  1383. }
  1384. that.getPage();
  1385. },
  1386. /**
  1387. * 更改文件管理器地址
  1388. */
  1389. changeFileDirType(type) {
  1390. let that = this;
  1391. let tabIndex = that.tabList.findIndex((x) => x.title == "FileSys");
  1392. this.tabList[tabIndex].dirType = type;
  1393. this.tabList[tabIndex].dirList = [];
  1394. this.tabList[tabIndex].data = [];
  1395. this.getPage();
  1396. },
  1397. /**
  1398. * 编辑文件夹或创建文件夹
  1399. */
  1400. editDirName(options) {
  1401. this.$refs.createDir.show(options);
  1402. },
  1403. /**
  1404. * 更改缓存类型
  1405. */
  1406. changeStorageType(type) {
  1407. let that = this;
  1408. let tabIndex = that.tabList.findIndex((x) => x.title == "Storage");
  1409. this.tabList[tabIndex].storageType = type;
  1410. this.getPage();
  1411. },
  1412. /**
  1413. * 运行js代码
  1414. */
  1415. runJs({ code, type }) {
  1416. let that = this;
  1417. let tabIndex = that.tabList.findIndex((x) => x.title == "JsRunner");
  1418. let id = new Date().getTime() + "_" + Math.random();
  1419. this.tabList[tabIndex].data.push({
  1420. id,
  1421. code,
  1422. result: "",
  1423. isEnd: false,
  1424. });
  1425. let logIndex = this.tabList[tabIndex].data.findIndex((x) => x.id == id);
  1426. let context;
  1427. try {
  1428. // #ifdef H5
  1429. context = window;
  1430. // #endif
  1431. // #ifdef APP-PLUS
  1432. context = globalThis;
  1433. // #endif
  1434. } catch (error) {}
  1435. let result = undefined;
  1436. uni.hideKeyboard();
  1437. if (type == "h5" || type == "nvue") {
  1438. try {
  1439. let fun = ("ev" + "__混淆__" + "al").replace("__混淆__", "");
  1440. if (context && context[fun]) {
  1441. result = context[fun](code);
  1442. } else {
  1443. result = "当前环境不支持运行js!";
  1444. }
  1445. } catch (error) {
  1446. if (error && error.message) {
  1447. result = error.message;
  1448. }
  1449. }
  1450. } else {
  1451. setTimeout(() => {
  1452. try {
  1453. uni.$once("devTools_jsRunnerCallback", (result) => {
  1454. console.log("result", result);
  1455. this.$set(this.tabList[this.tabIndex].data[logIndex], "result", result);
  1456. this.$set(this.tabList[this.tabIndex].data[logIndex], "isEnd", true);
  1457. this.$refs.mobileSwiperScroll.scrollToBottom();
  1458. });
  1459. uni.$emit("devTools_jsRunner", code);
  1460. } catch (error) {}
  1461. }, 1);
  1462. }
  1463. let his = devCache.get("codeRunHis");
  1464. if (!his) his = [];
  1465. let i = his.indexOf(code);
  1466. if (i > -1) {
  1467. his.splice(i, 1);
  1468. }
  1469. his.unshift(code);
  1470. if (his.length > 100) {
  1471. his.splice(100, 9999999);
  1472. }
  1473. devCache.set("codeRunHis", his);
  1474. this.$set(this.tabList[this.tabIndex].data[logIndex], "result", result);
  1475. this.$set(this.tabList[this.tabIndex].data[logIndex], "isEnd", true);
  1476. this.$refs.mobileSwiperScroll.scrollToBottom();
  1477. },
  1478. /**
  1479. * 清空js运行记录
  1480. */
  1481. emptyCodeHis() {
  1482. let that = this;
  1483. let tabIndex = that.tabList.findIndex((x) => x.title == "JsRunner");
  1484. uni.showToast({
  1485. title: "清空成功!",
  1486. icon: "success",
  1487. });
  1488. that.tabList[tabIndex].data = [];
  1489. },
  1490. /**
  1491. * Vuex变量类型改变事件
  1492. */
  1493. changeStateType(type) {
  1494. let that = this;
  1495. let tabIndex = that.tabList.findIndex((x) => x.title == "Vuex");
  1496. this.tabList[tabIndex].stateType = type;
  1497. this.getPage();
  1498. },
  1499. },
  1500. };
  1501. </script>
  1502. <style lang="scss" scoped>
  1503. /* #ifndef APP-PLUS */
  1504. view,
  1505. text {
  1506. box-sizing: border-box;
  1507. }
  1508. /* #endif */
  1509. .devTools {
  1510. /* #ifdef APP-PLUS */
  1511. flex: 1;
  1512. /* #endif */
  1513. /* #ifndef APP-PLUS */
  1514. height: 100vh;
  1515. /* #endif */
  1516. width: 750rpx;
  1517. position: relative;
  1518. .mask {
  1519. position: fixed;
  1520. z-index: 1;
  1521. width: 750rpx;
  1522. flex: 1;
  1523. /* #ifndef APP-PLUS */
  1524. height: 100vh;
  1525. /* #endif */
  1526. background-color: rgba(0, 0, 0, 0.3);
  1527. opacity: 0;
  1528. }
  1529. .panel {
  1530. position: fixed;
  1531. z-index: 2;
  1532. bottom: 0px;
  1533. left: 0px;
  1534. background-color: #ffffff;
  1535. display: flex;
  1536. flex-direction: column;
  1537. width: 750rpx;
  1538. color: #333;
  1539. /* #ifdef APP-PLUS */
  1540. border-radius: 20rpx 20rpx 0 0;
  1541. /* #endif */
  1542. .head {
  1543. width: 750rpx;
  1544. display: flex;
  1545. flex-direction: row;
  1546. align-items: center;
  1547. justify-content: space-between;
  1548. height: 80rpx;
  1549. border-bottom: 1px solid rgba(0, 0, 0, 0.05);
  1550. .tabList {
  1551. height: 80rpx;
  1552. width: 670rpx;
  1553. display: flex;
  1554. flex-direction: row;
  1555. /* #ifndef APP-PLUS */
  1556. white-space: nowrap;
  1557. /* #endif */
  1558. &.tab-h5 {
  1559. width: 750rpx !important;
  1560. }
  1561. .uni-scroll-view-content {
  1562. display: flex !important;
  1563. flex-direction: row !important;
  1564. }
  1565. .tabItem {
  1566. display: flex;
  1567. flex-direction: row;
  1568. align-items: center;
  1569. justify-content: center;
  1570. height: 80rpx;
  1571. padding: 0 20rpx;
  1572. /* #ifndef APP-PLUS */
  1573. min-width: 90rpx;
  1574. /* #endif */
  1575. position: relative;
  1576. .tabText {
  1577. font-size: 28rpx;
  1578. color: #888;
  1579. line-height: 80rpx;
  1580. }
  1581. .tabText.active {
  1582. font-size: 28rpx;
  1583. color: #ff2d55;
  1584. font-weight: bold;
  1585. }
  1586. .tabLine {
  1587. position: absolute;
  1588. bottom: -1px;
  1589. height: 2px;
  1590. width: 100rpx;
  1591. background-color: #ff2d55;
  1592. }
  1593. }
  1594. }
  1595. .close {
  1596. height: 80rpx;
  1597. width: 80rpx;
  1598. display: flex;
  1599. flex-direction: row;
  1600. align-items: center;
  1601. justify-content: center;
  1602. position: relative;
  1603. .icon {
  1604. font-size: 40rpx;
  1605. line-height: 40rpx;
  1606. text-align: center;
  1607. color: #ff2d55;
  1608. }
  1609. .line {
  1610. position: absolute;
  1611. left: 0;
  1612. height: 40rpx;
  1613. width: 1px;
  1614. background-color: rgba(0, 0, 0, 0.05);
  1615. }
  1616. }
  1617. }
  1618. }
  1619. }
  1620. .cellDivisionLine {
  1621. height: 1px;
  1622. width: 750rpx;
  1623. background-color: rgba(0, 0, 0, 0.1);
  1624. }
  1625. .navbar {
  1626. position: fixed;
  1627. background-color: #fff;
  1628. width: 750rpx;
  1629. z-index: 2;
  1630. border-bottom: 1px solid rgba(0, 0, 0, 0.03);
  1631. .navbarBody {
  1632. display: flex;
  1633. flex-direction: row;
  1634. align-items: center;
  1635. justify-content: space-between;
  1636. color: #333;
  1637. width: 710rpx;
  1638. margin-left: 20rpx;
  1639. .left {
  1640. display: flex;
  1641. flex-direction: row;
  1642. align-items: center;
  1643. font-size: 26rpx;
  1644. line-height: 26rpx;
  1645. .foldIcon {
  1646. transform: rotate(-90deg);
  1647. width: 30rpx;
  1648. height: 30rpx;
  1649. }
  1650. }
  1651. .right {
  1652. display: flex;
  1653. flex-direction: row;
  1654. align-items: center;
  1655. font-size: 26rpx;
  1656. line-height: 26rpx;
  1657. color: #ff2d55;
  1658. .refreshIcon {
  1659. width: 30rpx;
  1660. height: 30rpx;
  1661. margin-left: 5rpx;
  1662. }
  1663. .refreshing {
  1664. color: #aaa !important;
  1665. }
  1666. }
  1667. }
  1668. }
  1669. .navbarEmpty {
  1670. position: fixed;
  1671. }
  1672. .loadAll:active {
  1673. background-color: rgba(0, 0, 0, 0.03);
  1674. }
  1675. .loadAll {
  1676. width: 750rpx;
  1677. height: 80rpx;
  1678. display: flex;
  1679. flex-direction: row;
  1680. align-items: center;
  1681. justify-content: center;
  1682. .loadAllFold {
  1683. width: 30rpx;
  1684. height: 30rpx;
  1685. }
  1686. .loadAllText {
  1687. font-size: 26rpx;
  1688. color: #333;
  1689. margin: 0 10rpx;
  1690. }
  1691. }
  1692. .cellDivisionLine {
  1693. height: 1px;
  1694. width: 750rpx;
  1695. background-color: rgba(0, 0, 0, 0.1);
  1696. }
  1697. .cellDivisionLine {
  1698. height: 1px;
  1699. width: 750rpx;
  1700. background-color: rgba(0, 0, 0, 0.1);
  1701. }
  1702. .devEmpty {
  1703. display: flex;
  1704. flex-direction: row;
  1705. align-items: center;
  1706. justify-content: center;
  1707. height: 200rpx;
  1708. width: 750rpx;
  1709. .devEmptyText {
  1710. font-size: 26rpx;
  1711. color: #888;
  1712. line-height: 26rpx;
  1713. }
  1714. }
  1715. .eventItem {
  1716. display: flex;
  1717. flex-direction: column;
  1718. width: 750rpx;
  1719. padding: 10rpx 20rpx;
  1720. border-bottom: 1px solid rgba(0, 0, 0, 0.05);
  1721. &:active {
  1722. background-color: rgba(0, 0, 0, 0.05);
  1723. }
  1724. .eventName {
  1725. font-size: 20rpx;
  1726. color: #333;
  1727. }
  1728. .eventCount {
  1729. margin-top: 4rpx;
  1730. display: flex;
  1731. flex-direction: row;
  1732. justify-content: space-between;
  1733. .eventCountItem {
  1734. width: 170rpx;
  1735. /* #ifndef APP-PLUS */
  1736. max-width: 170rpx;
  1737. /* #endif */
  1738. font-size: 20rpx;
  1739. color: #333;
  1740. }
  1741. }
  1742. }
  1743. .eventLogItem {
  1744. display: flex;
  1745. flex-direction: column;
  1746. width: 750rpx;
  1747. padding: 10rpx 20rpx;
  1748. border-bottom: 1px solid rgba(0, 0, 0, 0.05);
  1749. &:active {
  1750. background-color: rgba(0, 0, 0, 0.05);
  1751. }
  1752. .logText {
  1753. font-size: 20rpx;
  1754. color: #333;
  1755. }
  1756. .logTime {
  1757. font-size: 20rpx;
  1758. color: #999;
  1759. }
  1760. }
  1761. .listCenterView {
  1762. width: 750rpx;
  1763. /* #ifndef APP-PLUS */
  1764. min-height: 200rpx;
  1765. /* #endif */
  1766. display: flex;
  1767. flex-direction: row;
  1768. align-items: center;
  1769. justify-content: center;
  1770. .listCenterText {
  1771. font-size: 24rpx;
  1772. color: #999;
  1773. }
  1774. }
  1775. </style>