track.vue 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727
  1. <!--
  2. 场控
  3. http://localhost:5173/actMgt/#/pages/actManage/track?compId=80
  4. https://oss-mbh5.colormaprun.com/actMgt/#/pages/actManage/track?compId=80
  5. -->
  6. <template>
  7. <view class="body">
  8. <view class="content uni-column">
  9. <view class="uni-column top" :style="getBannerStyle()">
  10. <my-topbar :title="actRs.config.matchInfo.compName" @btnBackClick="btnBack"></my-topbar>
  11. <view class="top-content uni-row">
  12. </view>
  13. </view>
  14. <view class="main uni-column">
  15. <view class="selectBox uni-row uni-jcse">
  16. <view class="select">
  17. <e-select v-model="mapId" maxHeight="300px" :props="selectMapProps" :options="mapList"
  18. :search="false" :inputClick="false" :clearable="false" @getText="getESelectText"
  19. @change="selectMapChange"></e-select>
  20. </view>
  21. <view class="select">
  22. <e-select v-model="actionId" maxHeight="300px" :props="selectActionProps" :options="actionList"
  23. :search="false" :inputClick="false" :clearable="false" @getText="getESelectText"
  24. @change="selectActionChange"></e-select>
  25. </view>
  26. </view>
  27. <view id="map" class="map"></view>
  28. <view v-show="popupShow" class="popup"
  29. :style="{ height: popupHeight + 'px', width: popupWidth + 'px' }">
  30. <!-- <uni-section class="section" title="活动路线列表" type="line">
  31. <uni-data-picker class="actionsTree" :style="{ width: popupWidth + 'px' }" placeholder="请选择活动" popup-title="请选择活动路线" :localdata="actionsTree"
  32. v-model="sltActRoute" @change="onActionChange" @popupopened="onActionsTreePopupOpened" @popupclosed="onActionsTreePopupClosed"></uni-data-picker>
  33. </uni-section> -->
  34. <uni-section class="section" title="玩家列表" type="line">
  35. <view class="norecord" v-if="players == null || players.length == 0">暂无记录</view>
  36. <scroll-view :scroll-top="0" scroll-y="true" :style="{ height: popupHeight - 43 + 'px'}">
  37. <uni-list v-for="(item, index) in players" :key="index" :border="true" class="list">
  38. <uni-list-item :clickable="true" @click="onPlayerListItemClick(item)" class="list-item"
  39. :class="{
  40. 'list-item-focus': focusPlayerId == item.id
  41. }">
  42. <template v-slot:header>
  43. <!-- <image class="slot-image" src="/static/logo.png" mode="widthFix"></image> -->
  44. <div class="slot-image" :style="'background-color:' + getPlayerColor(item.id)">
  45. </div>
  46. </template>
  47. <template v-slot:body>
  48. <view class="slot-box">
  49. <view class="slot-title">
  50. <!-- <span class="slot-sn" :style="'background-color:' + getPlayerColor(item.id)">{{index+1}}</span> -->
  51. [{{index+1}}]<span class="slot-phone" @click="onPhoneClick(item.phone)">
  52. {{item.name}}
  53. <uni-icons v-if="admin" type="phone" size="14"></uni-icons>
  54. </span>
  55. 打点 {{item.EffectiveNum}}/{{item.TotalControlNum}} &nbsp; 目标点
  56. {{item.nextControlPoint.orderNO}} &nbsp; 百味豆 {{item.sysPoint}}
  57. </view>
  58. <view class="slot-note">
  59. 距离 {{tools.fmtDistanctKm(item.distance)}}km &nbsp; 配速
  60. {{tools.convertSecondsToHMS(item.pace, 2)}}
  61. &nbsp; Cal {{Math.round(item.Calorie/1000)}} &nbsp; | &nbsp; 心率
  62. {{item.lastHr}} &nbsp; 平均 {{item.avgHr}} &nbsp; 最大 {{item.maxHr}}
  63. <!-- &nbsp; | &nbsp; Ck {{item.Ck}} Ei {{Math.round(item.Ei*100)/100}}-->
  64. </view>
  65. </view>
  66. </template>
  67. <!-- <template v-slot:footer>
  68. <image class="slot-image" src="/static/logo.png" mode="widthFix"></image>
  69. </template> -->
  70. </uni-list-item>
  71. </uni-list>
  72. </scroll-view>
  73. </uni-section>
  74. </view>
  75. </view>
  76. </view>
  77. </view>
  78. </template>
  79. <script>
  80. import {
  81. mapState,
  82. mapGetters
  83. } from 'vuex';
  84. import tools from '/utils/tools.js';
  85. import card from '/utils/card.js';
  86. import 'leaflet/dist/leaflet.css';
  87. import '/utils/map/leafletHelper.css'
  88. import leafletHelper from '/utils/map/leafletHelper';
  89. import mapHelper from '/utils/map/mapHelper';
  90. import {
  91. apiCompInfoDetail,
  92. apiMapList,
  93. apiMapDetail,
  94. apiActionList,
  95. apiActionDetail,
  96. apiUsersInGameDetail,
  97. apiUsersInGameGpsQuery,
  98. checkResCode
  99. } from '/utils/api.js';
  100. export default {
  101. data() {
  102. return {
  103. tools: tools,
  104. queryObj: {},
  105. queryString: "",
  106. interval: null,
  107. refreshTime: 300000, // 刷新时间 ms
  108. admin: true, // 是否场控管理员
  109. compId: 0, // 赛事ID
  110. actRs: card.actRs, // 赛事详情
  111. mapList: [], // 地图列表
  112. mapId: 0, // (当前选中的)地图ID
  113. mapDetail: {}, // (当前选中的)地图详情
  114. mapInfo: {}, // (当前选中的)地图信息 mapDetail.mapInfo
  115. mapUrl: null, // (当前选中的)地图图片URL
  116. mapConfig: "", // (当前选中的)地图图片的地理参考信息
  117. actionList: [], // 活动列表
  118. actionId: 0, // (当前选中的)活动ID
  119. actionDetail: {}, // (当前选中的)活动详情
  120. selectMapProps: {
  121. value: 'id',
  122. text: 'name',
  123. // disabled: 'noallowed'
  124. },
  125. selectActionProps: {
  126. value: 'id',
  127. text: 'name',
  128. // disabled: 'noallowed'
  129. },
  130. map: null,
  131. checkPoints: [],
  132. players: [],
  133. players_position: [],
  134. focusPlayerId: 0,
  135. trailTime: 0,
  136. popupHeight: 360,
  137. popupWidth: 0,
  138. popupType: 'bottom',
  139. popupShow: false,
  140. }
  141. },
  142. computed: {
  143. ...mapState([
  144. 'username', // 映射 this.username 为 store.state.username
  145. 'userlevel',
  146. 'token'
  147. ]),
  148. ...mapGetters([
  149. 'metadata'
  150. ]),
  151. },
  152. onLoad(query) {
  153. // console.log(query);
  154. this.queryObj = query;
  155. this.queryString = tools.objectToQueryString(this.queryObj);
  156. // console.log(queryString);
  157. this.compId = query["compId"] ?? 0;
  158. this.compInfoDetail();
  159. this.getMapList();
  160. },
  161. mounted() {
  162. console.log("mounted");
  163. this.$global.getWindowInfo();
  164. uni.$on('windowResize', this.reLoad);
  165. this.popupShow = this.$store.state.mapPopupShow;
  166. this.layoutInit()
  167. },
  168. beforeDestroy() {
  169. console.log("beforeDestroy")
  170. clearInterval(this.interval)
  171. leafletHelper.free()
  172. },
  173. methods: {
  174. getBannerStyle() {
  175. return card.getBannerStyle(this.actRs);
  176. },
  177. reLoad() {
  178. this.savePlayersData()
  179. var fullPath = this.$route.fullPath
  180. console.log("[windowResize] reLaunch: " + fullPath)
  181. uni.redirectTo({
  182. url: fullPath
  183. });
  184. },
  185. // 布局初始化 设置地图高度
  186. layoutInit() {
  187. this.popupWidth = this.$global.windowWidth
  188. /* this.windowHeight = this.$global.windowHeight
  189. this.windowWidth = this.$global.windowWidth
  190. if (this.$global.deviceOrientation == 'portrait') { // 竖屏
  191. this.flexDirection = 'column'
  192. this.mapWidth = this.$global.windowWidth
  193. this.mapHeight = this.$global.windowHeight
  194. this.popupHeight = this.popupHeightPortrait
  195. this.popupWidth = this.$global.windowWidth
  196. } else { // 横屏
  197. this.flexDirection = 'row'
  198. this.mapHeight = this.$global.windowHeight
  199. this.mapWidth = this.$global.windowWidth
  200. this.popupHeight = this.$global.windowHeight
  201. this.popupWidth = this.popupWidthlandscape
  202. // console.log("横屏 popupHeight", this.popupHeight)
  203. } */
  204. },
  205. popupToggle() {
  206. this.popupShow = !this.popupShow
  207. this.$store.commit('setMapPopupShow', this.popupShow)
  208. // this.layoutInit()
  209. },
  210. async loadMap() {
  211. await mapHelper.handleMapInfo(this, this.mapInfo);
  212. this.mapUrl = mapHelper.mapUrl;
  213. this.mapConfig = mapHelper.mapConfig;
  214. },
  215. async initMap() {
  216. const zoomNum = this.mapInfo.DefScale;
  217. const mapOptions = {
  218. zoom: zoomNum
  219. };
  220. if (this.mapUrl != undefined && this.mapUrl.length > 0) {
  221. // console.log("[initMap] mapUrl", this.mapUrl);
  222. await leafletHelper.init(this, 'map', this.mapUrl, this.mapConfig, mapOptions);
  223. }
  224. },
  225. async loadData() {
  226. await this.loadMap();
  227. await this.initMap();
  228. this.handleMapDrawRoute();
  229. if (this.interval != null) {
  230. clearInterval(this.interval);
  231. }
  232. let that = this;
  233. that.players = await that.getUsersInGameDetail();
  234. console.log('players', that.players)
  235. // leafletHelper.global.setPlayers(this.players)
  236. that.players_position = await that.usersInGameGpsQuery();
  237. // leafletHelper.global.setPlayersPosition(this.players_position)
  238. that.handleMapDrawPlayer();
  239. that.handleMapDrawTrail();
  240. this.interval = setInterval(async function() {
  241. that.players = await that.getUsersInGameDetail();
  242. that.players_position = await that.usersInGameGpsQuery();
  243. //// leaflet.leafletHelper.global.setPlayers(that.players);
  244. // leafletHelper.global.setPlayersPosition(that.players_position);
  245. that.handleMapDrawPlayer();
  246. that.handleMapDrawTrail();
  247. }, that.refreshTime);
  248. // await mapHelper.handleMapInfo(this, this.mapInfo)
  249. this.handleMapToggle();
  250. },
  251. handleWindowResize() {
  252. leafletHelper.onWindowResize()
  253. },
  254. handleMapDrawRoute() {
  255. // console.log("this.actionDetail.routes", this.actionDetail.routes);
  256. // leafletHelper.global.setCheckPoints(this.checkPoints)
  257. leafletHelper.global.setRoutes(this.actionDetail.routes)
  258. // leafletHelper.checkPoint.drawAllCheckPoints()
  259. // leafletHelper.checkPoint.drawPath()
  260. leafletHelper.route.drawAllRoutes()
  261. leafletHelper.route.drawAllPath()
  262. },
  263. handleMapDrawPlayer() {
  264. leafletHelper.global.setPlayers(this.players)
  265. leafletHelper.global.setPlayersPosition(this.players_position)
  266. leafletHelper.player.drawAllPlayers()
  267. leafletHelper.global.dealStaleData()
  268. },
  269. handleMapDrawTrail() {
  270. this.trailTime = leafletHelper.config.trailTime
  271. // leafletHelper.player.drawOneTrail(2, 10000)
  272. // leafletHelper.player.drawOneTrail(3, 10000)
  273. // leafletHelper.player.drawOneTrail(2, 0, false)
  274. leafletHelper.player.drawAllTrails(this.trailTime)
  275. },
  276. handleMapToggle() {
  277. // leafletHelper.checkPoint.toggle(true)
  278. // leafletHelper.route.toggle(true)
  279. // leafletHelper.player.togglePlayer(true)
  280. // leafletHelper.player.toggleTooltip(true)
  281. // leafletHelper.player.toggleTrail(true)
  282. leafletHelper.route.toggle(this.$store.state.mapControlRoute)
  283. leafletHelper.player.togglePlayer(this.$store.state.mapControlPlayer)
  284. leafletHelper.player.toggleTooltip(this.$store.state.mapControlTooltip)
  285. leafletHelper.player.toggleTrail(this.$store.state.mapControlTrail)
  286. },
  287. handlePlayerListItemClick(item) {
  288. this.focusPlayerId = item.id
  289. leafletHelper.player.handleFocusPlayer(this.focusPlayerId)
  290. },
  291. getPlayerColor(playerId) {
  292. if (playerId != this.focusPlayerId)
  293. return leafletHelper.player.getPlayerColor(playerId)
  294. else
  295. return leafletHelper.config.gStyle.marker.focus.fillColor
  296. },
  297. // 页面reLoad前调用本方法,将用户数据先保存,页面重载后再进行数据恢复
  298. savePlayersData() {
  299. leafletHelper.global.savePlayersData()
  300. },
  301. // 自助赛事详情查询
  302. compInfoDetail() {
  303. uni.request({
  304. url: apiCompInfoDetail,
  305. header: this.metadata,
  306. method: "POST",
  307. data: {
  308. compId: this.compId
  309. },
  310. success: (res) => {
  311. // console.log("[compInfoDetail] res", res);
  312. if (checkResCode(res)) {
  313. const data = res.data.data;
  314. this.actRs = data;
  315. }
  316. },
  317. fail: (err) => {
  318. console.log("[compInfoDetail] err", err);
  319. },
  320. });
  321. },
  322. // 自助赛事详情查询
  323. getMapList() {
  324. uni.request({
  325. url: apiMapList,
  326. header: this.metadata,
  327. method: "POST",
  328. data: {
  329. compId: this.compId
  330. },
  331. success: (res) => {
  332. console.log("[getMapList] res", res);
  333. if (checkResCode(res)) {
  334. const data = res.data.data;
  335. this.mapList = data.list;
  336. this.mapId = data.list[0].id;
  337. this.selectMapChange();
  338. }
  339. },
  340. fail: (err) => {
  341. console.log("[getMapList] err", err);
  342. },
  343. });
  344. },
  345. // 赛事监控地图详情
  346. getMapDetail() {
  347. uni.request({
  348. url: apiMapDetail,
  349. header: this.metadata,
  350. method: "POST",
  351. data: {
  352. compId: this.compId,
  353. mapId: this.mapId
  354. },
  355. success: (res) => {
  356. console.log("[getMapDetail] res", res);
  357. if (checkResCode(res)) {
  358. const data = res.data.data;
  359. this.mapDetail = data;
  360. this.mapInfo = data.mapInfo;
  361. // this.mapUrl = data.mapInfo.mapUrl;
  362. // console.log("[getMapDetail] mapInfo", this.mapInfo);
  363. }
  364. },
  365. fail: (err) => {
  366. console.log("[getMapDetail] err", err);
  367. },
  368. });
  369. },
  370. // 赛事监控地图下的活动列表
  371. getActionList() {
  372. uni.request({
  373. url: apiActionList,
  374. header: this.metadata,
  375. method: "POST",
  376. data: {
  377. compId: this.compId,
  378. mapId: this.mapId
  379. },
  380. success: (res) => {
  381. console.log("[getActionList] res", res);
  382. if (checkResCode(res)) {
  383. const data = res.data.data;
  384. this.actionList = data.list;
  385. this.actionId = data.list[0].id;
  386. this.selectActionChange();
  387. }
  388. },
  389. fail: (err) => {
  390. console.log("[getActionList] err", err);
  391. },
  392. });
  393. },
  394. // 赛事监控地图下的活动详情
  395. getActionDetail() {
  396. uni.request({
  397. url: apiActionDetail,
  398. header: this.metadata,
  399. method: "POST",
  400. data: {
  401. actId: this.actionId
  402. },
  403. success: (res) => {
  404. console.log("[getActionDetail] res", res);
  405. if (checkResCode(res)) {
  406. const data = res.data.data;
  407. this.actionDetail = data;
  408. this.loadData();
  409. }
  410. },
  411. fail: (err) => {
  412. console.log("[getActionDetail] err", err);
  413. },
  414. });
  415. },
  416. //场控端_活动详情
  417. /* async getActionDetail() {
  418. try {
  419. return new Promise((resolve, reject) => {
  420. uni.request({
  421. url: apiActionDetail,
  422. header: this.metadata,
  423. method: "POST",
  424. data: {
  425. actId: this.actionId
  426. },
  427. success: (res) => {
  428. console.log("getActionDetail", res);
  429. if (checkResCode(res)) {
  430. resolve(res);
  431. } else {
  432. reject(res);
  433. }
  434. },
  435. fail: (err) => {
  436. console.log("getActionDetail err", err);
  437. reject(err);
  438. },
  439. });
  440. });
  441. } catch (e) {
  442. console.log('[getActionDetail] err', e)
  443. reject(e)
  444. }
  445. }, */
  446. //场控端_正在进行中所有用户实时信息
  447. async getUsersInGameDetail() {
  448. try {
  449. return new Promise((resolve, reject) => {
  450. uni.request({
  451. url: apiUsersInGameDetail,
  452. header: this.metadata,
  453. method: "POST",
  454. data: {
  455. actId: this.actionId
  456. },
  457. success: (res) => {
  458. console.log("getUsersInGameDetail", res);
  459. if (checkResCode(res)) {
  460. resolve(res.data.data.users);
  461. } else {
  462. reject(res);
  463. }
  464. },
  465. fail: (err) => {
  466. console.log("getUsersInGameDetail err", err);
  467. reject(err);
  468. },
  469. });
  470. });
  471. } catch (e) {
  472. console.log('[getUsersInGameDetail] err', e)
  473. reject(e)
  474. }
  475. },
  476. //场控端_正在进行中所有用户实时gps查询
  477. async usersInGameGpsQuery() {
  478. try {
  479. return new Promise((resolve, reject) => {
  480. uni.request({
  481. url: apiUsersInGameGpsQuery,
  482. header: this.metadata,
  483. method: "POST",
  484. data: {
  485. actId: this.actionId
  486. },
  487. success: (res) => {
  488. console.log("usersInGameGpsQuery", res);
  489. if (checkResCode(res)) {
  490. resolve(res.data.data.gpsInfo);
  491. } else {
  492. reject(res);
  493. }
  494. },
  495. fail: (err) => {
  496. console.log("usersInGameGpsQuery err", err);
  497. reject(err);
  498. },
  499. });
  500. });
  501. } catch (e) {
  502. console.log('[usersInGameGpsQuery] err', e)
  503. reject(e)
  504. }
  505. },
  506. onActionChange(e) {
  507. const value = e.detail.value
  508. console.log("onActionChange", value)
  509. },
  510. onPlayerListItemClick(item) {
  511. // console.log("onListItemClick", item)
  512. this.handlePlayerListItemClick(item)
  513. },
  514. onPhoneClick(phoneNumber) {
  515. if (!this.admin) {
  516. return;
  517. }
  518. if (phoneNumber.length == 11) {
  519. uni.makePhoneCall({
  520. phoneNumber: phoneNumber
  521. })
  522. } else {
  523. uni.showToast({
  524. title: '手机号码不正确',
  525. icon: 'none'
  526. })
  527. }
  528. },
  529. fullScreenToggle() {
  530. this.$global.fullscreen();
  531. // this.layoutInit();
  532. },
  533. // 获取输入框中值
  534. getESelectText(data) {
  535. // console.log("getESelectText:", data);
  536. },
  537. selectMapChange(data) {
  538. // console.log("selectMapChange:", data);
  539. this.getMapDetail();
  540. this.getActionList();
  541. },
  542. selectActionChange(data) {
  543. // console.log("selectActionChange:", data);
  544. this.getActionDetail();
  545. },
  546. btnBack() {
  547. const url = "/pages/actManage/actDetail?" + this.queryString;
  548. tools.appAction(url, "uni.navigateTo");
  549. },
  550. }
  551. }
  552. </script>
  553. <style scoped>
  554. .content {
  555. height: 100vh;
  556. }
  557. .top {
  558. height: 36px;
  559. padding-top: 16px;
  560. flex-shrink: 0;
  561. background-repeat: no-repeat;
  562. background-size: cover;
  563. }
  564. .selectBox {
  565. width: 100%;
  566. margin-top: 5px;
  567. margin-bottom: 5px;
  568. }
  569. .select {
  570. width: 48%;
  571. }
  572. .map {
  573. width: 100%;
  574. flex: 1 1 auto;
  575. background-color: white;
  576. z-index: 0;
  577. }
  578. .popup {
  579. display: flex;
  580. flex-direction: column;
  581. align-items: center;
  582. background-color: #f5f5f5;
  583. /* border-left: #dedede solid 1px; */
  584. border-top: #dedede solid 1px;
  585. }
  586. .section {
  587. width: 100%;
  588. }
  589. .scroll {
  590. overflow: scroll;
  591. }
  592. .section-title {
  593. font-size: 14px;
  594. color: #424242;
  595. line-height: 20px;
  596. padding: 10px 0 10px 10px;
  597. }
  598. .section-content {
  599. width: 100%;
  600. height: 100%;
  601. }
  602. /* .section-content-item {
  603. display: flex;
  604. flex-direction: row;
  605. align-items: center;
  606. height: 46px;
  607. } */
  608. /* .actionsTree {
  609. /deep/ .input-value-border {
  610. border-top: 1px solid #e5e5e5;
  611. border-bottom: 1px solid #e5e5e5;
  612. border-radius: 0px;
  613. }
  614. /deep/ .uni-scroll-view {
  615. overflow: unset !important;
  616. }
  617. } */
  618. .list {
  619. margin-left: -6px;
  620. }
  621. .list-item {
  622. display: flex;
  623. flex-direction: row;
  624. align-items: center;
  625. height: 46px;
  626. }
  627. .slot-box {
  628. display: flex;
  629. flex-direction: column;
  630. align-items: flex-start;
  631. width: 330px;
  632. max-width: 350px;
  633. }
  634. .slot-image {
  635. display: block;
  636. margin-right: 6px;
  637. width: 3px;
  638. height: 33px;
  639. align-self: center;
  640. }
  641. .slot-title {
  642. flex: 1;
  643. font-size: 13px;
  644. color: #424242;
  645. line-height: 18px;
  646. white-space: nowrap;
  647. }
  648. .slot-sn {
  649. display: inline-flex;
  650. width: 15px;
  651. height: 15px;
  652. border-radius: 50%;
  653. }
  654. .slot-note {
  655. flex: 1;
  656. margin-left: 20px;
  657. font-size: 12px;
  658. color: #7d8da7;
  659. line-height: 18px;
  660. white-space: nowrap;
  661. }
  662. .slot-phone {
  663. padding: 0 5px;
  664. color: #000;
  665. font-weight: bold;
  666. }
  667. .norecord {
  668. font-weight: 500;
  669. color: #818181;
  670. font-size: 14px;
  671. text-align: center;
  672. line-height: 50px;
  673. }
  674. /* /deep/ .uni-data-tree-dialog {
  675. top: 39px;
  676. } */
  677. </style>