navbar.vue 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176
  1. <template>
  2. <div style="z-index: var(--zIndex-nav)">
  3. <v-banner
  4. single-line
  5. class="banner"
  6. :style="`padding-left: ${isLayout ? left : 0 }px;background-color:${systemInfo?.bgc || '#007cd6'}`"
  7. >
  8. <div class="left pa-4" :style="`width: ${left}px;`">
  9. <img v-if="systemInfo?.headImg" :src="systemInfo.headImg" alt="" class="mr-2 header-img">
  10. <span @click="$router.push('/')">{{ webTitle }}</span>
  11. </div>
  12. <template v-slot:actions>
  13. <slot name="tools" ></slot>
  14. <!-- 语言切换 -->
  15. <v-menu v-if="false" offset-y nudge-bottom="5" attach left>
  16. <template v-slot:activator="{ on, attrs }">
  17. <v-btn
  18. fab
  19. x-small
  20. v-bind="attrs"
  21. v-on="on"
  22. >
  23. <v-icon size="24">mdi-translate</v-icon>
  24. </v-btn>
  25. </template>
  26. <v-list nav dense>
  27. <v-list-item
  28. v-for="item in langList"
  29. :key="item.value"
  30. class="hover"
  31. @click="langChange(item.value)"
  32. >
  33. <v-list-item-content>
  34. <v-list-item-title>{{ item.text }}</v-list-item-title>
  35. </v-list-item-content>
  36. </v-list-item>
  37. </v-list>
  38. </v-menu>
  39. <v-menu v-if="person" offset-y nudge-bottom="5" attach left>
  40. <template v-slot:activator="{ on, attrs }">
  41. <v-btn class="mx-5 buttons" rounded v-bind="attrs" v-on="on">
  42. <v-icon left>mdi mdi-account</v-icon>
  43. <div style="flex: 1; width: 0" class="text-truncate">
  44. {{ userInfo?.name ? userInfo.name : userInfo?.username ?? '新用户' }}
  45. </div>
  46. </v-btn>
  47. </template>
  48. <v-list dense>
  49. <v-list-item
  50. v-for="item in list"
  51. :key="item.id"
  52. class="hover"
  53. @click="handleClick(item)"
  54. >
  55. <v-list-item-content>
  56. <v-list-item-title>{{ item.text }}</v-list-item-title>
  57. </v-list-item-content>
  58. </v-list-item>
  59. </v-list>
  60. </v-menu>
  61. </template>
  62. </v-banner>
  63. </div>
  64. </template>
  65. <script>
  66. import { mapGetters } from 'vuex'
  67. import { timestampToTime } from '@/utils/date'
  68. /**
  69. * props.title: []
  70. * @param { text, href, disabled }
  71. */
  72. export default {
  73. name: 'header-navbar',
  74. props: {
  75. person: {
  76. type: Boolean,
  77. default: true
  78. },
  79. title: {
  80. type: [String, Array],
  81. default: () => [] || ''
  82. },
  83. isLayout: {
  84. type: Boolean,
  85. default: false
  86. },
  87. left: {
  88. type: Number,
  89. default: 300
  90. }
  91. },
  92. data () {
  93. return {
  94. list: [
  95. // { text: '绑定手机', id: 1, icon: 'mdi-lock-check', path: '' },
  96. // { text: '系统管理', id: 2, icon: 'mdi-cog', path: '' },
  97. // { text: '系统更新', id: 2, icon: 'mdi-cog-sync', path: '/update' },
  98. // { text: '我的消息', id: 4, icon: 'mdi-email-outline', path: '/message' },
  99. { text: '刷新菜单', id: 5, icon: 'mdi-refresh', path: '' },
  100. { text: '版本信息', id: 1, icon: 'mdi-logout', path: '' },
  101. { text: '注销登录', id: 3, icon: 'mdi-logout', path: '' }
  102. ],
  103. langList: [
  104. { text: '中文', value: 'zh' },
  105. { text: 'English', value: 'en' }
  106. ]
  107. }
  108. },
  109. computed: {
  110. ...mapGetters(['userInfo', 'lang', 'systemInfo']),
  111. webTitle () {
  112. if (this.lang === 'zh') {
  113. return this.systemInfo?.title || this.$DEFAULT_TITLE
  114. }
  115. return this.systemInfo?.titleEn || 'Refined Management'
  116. }
  117. },
  118. methods: {
  119. langChange (value) {
  120. this.$i18n.locale = value
  121. this.$store.commit('system/SET_LANG', value)
  122. },
  123. handleClick ({ id, path }) {
  124. const version = localStorage.getItem('version') ?? 0
  125. switch (id) {
  126. case 1:
  127. this.$snackbar.info('版本更新时间: ' + timestampToTime(+version, true))
  128. break
  129. case 2:
  130. window.open(path)
  131. break
  132. case 3:
  133. this.$store.dispatch('user/userLogout')
  134. break
  135. case 5:
  136. this.$store.dispatch('menu/getMenu2').then(() => {
  137. // 刷新
  138. this.$router.go(0)
  139. })
  140. break
  141. default:
  142. this.$router.push(path)
  143. break
  144. }
  145. }
  146. }
  147. }
  148. </script>
  149. <style lang="scss" scoped>
  150. .header-img {
  151. width: 40px;
  152. height: 40px;
  153. border-radius: 50%;
  154. }
  155. .v-btn {
  156. text-transform: none;
  157. }
  158. .banner {
  159. z-index: var(--zIndex-nav) !important;
  160. color: #FFF;
  161. .left {
  162. height: 100%;
  163. display: flex;
  164. align-items: center;
  165. font-size: 20px;
  166. cursor: pointer;
  167. }
  168. }
  169. .hover:hover {
  170. cursor: pointer;
  171. background: rgba(0,0,0,.03);
  172. }
  173. </style>