index.vue 5.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204
  1. <template>
  2. <div class="app-page" v-loading="fullLoading" element-loading-text="服务连接中...">
  3. <div class="app-page__header">
  4. <app-header>
  5. <!-- <template #left>
  6. <i class="icon-fold-expand" title="折叠/展开" @click="isCollapse = !isCollapse">
  7. <span :class="isCollapse ? 'g-icon-expand' : 'g-icon-fold'"></span>
  8. </i>
  9. </template> -->
  10. </app-header>
  11. </div>
  12. <div class="app-page__wrapper" :style="bodyStyles">
  13. <div class="app-page__sidebar">
  14. <app-sidebar v-model:collapse="isCollapse" />
  15. </div>
  16. <div class="app-page__main">
  17. <div class="app-page__navbar" v-if="false">
  18. <app-navbar />
  19. </div>
  20. <div id="appPageTeleport" class="app-page__container app-page__teleport"></div>
  21. <div class="app-page__container">
  22. <!-- 二级路由 -->
  23. <router-view v-slot="{ Component, route }">
  24. <component :is="handleComponent(Component, route)" :key="route.fullPath" />
  25. </router-view>
  26. </div>
  27. </div>
  28. </div>
  29. <!-- <HQChart /> -->
  30. <app-footer class="app-page__footer" :style="footerStyles" @tab-change="onTabChange">
  31. <div class="iconbar">
  32. <span @click="minimize">
  33. <AppIcon icon="ArrowUp" v-if="footerWinType === -1" />
  34. <AppIcon icon="ArrowDown" v-else />
  35. </span>
  36. <span @click="maximize">
  37. <AppIcon icon="g-icon-minimize2" v-if="footerWinType === 1" />
  38. <AppIcon icon="g-icon-maximize2" v-else />
  39. </span>
  40. </div>
  41. </app-footer>
  42. <div class="app-page__statusbar">
  43. <div class="statusbar-left">
  44. <span style="font-size: 12px;color: #444f57;padding: 0 5px;">v1.0.{{ version }}</span>
  45. </div>
  46. <div class="statusbar-right">
  47. <ul>
  48. <li>
  49. <span>用户ID:</span>
  50. <span>{{ loginStore.userId }}</span>
  51. </li>
  52. <li>
  53. <span>登录ID:</span>
  54. <span>{{ loginStore.loginId }}</span>
  55. </li>
  56. <li>
  57. <!-- <span>{{ serverTime?.format('MM/DD') }}</span> -->
  58. <span>{{ serverTime?.format('HH:mm:ss') }}</span>
  59. </li>
  60. </ul>
  61. </div>
  62. </div>
  63. </div>
  64. </template>
  65. <script lang="ts" setup>
  66. import { ref, onMounted, onUnmounted, computed } from 'vue'
  67. import { RouteRecordNormalized, RouteRecordName } from 'vue-router'
  68. import { timerTask } from '@/utils/timer'
  69. import { getServerTime } from '@/services/api/common'
  70. import { useGlobalStore, useLoginStore } from '@/stores'
  71. import eventBus from '@/services/bus'
  72. import moment, { Moment } from 'moment'
  73. import AppIcon from '@pc/components/base/icon/index.vue'
  74. import AppHeader from '../header/index.vue'
  75. import AppFooter from '../footer/index.vue'
  76. import AppNavbar from '../navbar/index.vue'
  77. import AppSidebar from '../sidebar/index.vue'
  78. //import HQChart from '@mobile/components/modules/chart/index.vue'
  79. const globalStore = useGlobalStore()
  80. const loginStore = useLoginStore()
  81. const fullLoading = ref(false)
  82. const isCollapse = ref(globalStore.isMobile)
  83. const footerWinType = ref(0) // -1最小化,0默认,1最大化
  84. const serverTime = ref<Moment>()
  85. const meta = document.getElementsByTagName('meta')
  86. const version = meta.namedItem('revised')?.content ?? '0'
  87. // 手动给组件添加 name 属性,处理缓存 exclude 无效的问题
  88. const handleComponent = (component: Record<'type', { name: RouteRecordName | undefined }>, route: RouteRecordNormalized) => {
  89. if (component) {
  90. component.type.name = route.name
  91. }
  92. return component
  93. }
  94. const bodyStyles = computed(() => {
  95. if (footerWinType.value === 1) {
  96. return {
  97. flex: 0,
  98. overflow: 'hidden'
  99. }
  100. }
  101. return {
  102. flex: 1,
  103. }
  104. })
  105. const footerStyles = computed(() => {
  106. switch (footerWinType.value) {
  107. case 1: {
  108. return {
  109. flex: 1,
  110. height: 'auto'
  111. }
  112. }
  113. case -1: {
  114. return {
  115. height: '36px',
  116. overflow: 'hidden'
  117. }
  118. }
  119. default: {
  120. return {
  121. height: '360px'
  122. }
  123. }
  124. }
  125. })
  126. // 最小化
  127. const minimize = () => {
  128. if (footerWinType.value === -1) {
  129. footerWinType.value = 0
  130. } else {
  131. footerWinType.value = -1
  132. }
  133. }
  134. // 最大化
  135. const maximize = () => {
  136. if (footerWinType.value === 1) {
  137. footerWinType.value = 0
  138. } else {
  139. footerWinType.value = 1
  140. }
  141. }
  142. const onTabChange = () => {
  143. if (footerWinType.value === -1) {
  144. footerWinType.value = 0
  145. }
  146. }
  147. // 校验服务器时间
  148. const checkServerTime = () => {
  149. getServerTime().then((res) => {
  150. serverTime.value = moment.parseZone(res.data)
  151. // 每1分钟同步一次服务器时间
  152. timerTask.setTimeout(() => {
  153. checkServerTime()
  154. }, 60 * 1000, 'getServerTime')
  155. })
  156. }
  157. // 接收窗口页面状态通知
  158. const documentVisibilityStateNotify = eventBus.$on('DocumentVisibilityStateNotify', (state) => {
  159. if (state === 'visible') {
  160. checkServerTime()
  161. }
  162. })
  163. // 接收交易服务重连通知
  164. const tradeServerReconnectNotify = eventBus.$on('TradeServerReconnectNotify', () => {
  165. fullLoading.value = true
  166. })
  167. // 接收交易服务重连成功通知
  168. const tradeServerReconnectSuccessNotify = eventBus.$on('TradeServerReconnectSuccessNotify', () => {
  169. fullLoading.value = false
  170. })
  171. onMounted(() => {
  172. serverTime.value = moment(new Date())
  173. timerTask.setInterval(() => {
  174. serverTime.value = moment(serverTime.value).add(1000, 'ms')
  175. }, 1000, 'refreshTime')
  176. checkServerTime()
  177. })
  178. onUnmounted(() => {
  179. timerTask.clearInterval('refreshTime')
  180. timerTask.clearTimeout('getServerTime')
  181. documentVisibilityStateNotify.cancel()
  182. tradeServerReconnectNotify.cancel()
  183. tradeServerReconnectSuccessNotify.cancel()
  184. })
  185. </script>
  186. <style lang="less">
  187. @import './index.less';
  188. </style>