Head.vue 6.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231
  1. <template>
  2. <div class="head-wrapper">
  3. <div class="head-logo">
  4. <svg-icon icon-class="zhihui-logo" @click="topHome()" />
  5. </div>
  6. <div v-for="item in headList" :key="item.path" class="nav-tag" :class="{'active-nav-tag':activeNavTag === item.name}" @click="changeNavTag(item)">
  7. <div v-if="item.icon" class="icon">
  8. <div v-show="notice && item.name.search(/个人工作台/)>=0" class="if-notice" />
  9. <svg-icon :icon-class="item.icon" />
  10. </div>
  11. <div class="name">{{ item.name }}</div>
  12. </div>
  13. <!-- <div v-show="navTagType === 2" class="nav-tag-type" @click="setNavTagType(1)">
  14. <i class="el-icon-notebook-2" style="transform: rotate(90deg);" />
  15. </div>
  16. <div v-show="navTagType === 1" class="nav-tag-type" @click="setNavTagType(2)">
  17. <i class="el-icon-notebook-2" />
  18. </div> -->
  19. <el-tooltip class="item" effect="dark" content="用户指导手册" placement="right">
  20. <el-link class="user-tip" href="https://base3.xiaojukeji.com/docs/zhihui/" target="_blank">
  21. <svg-icon style="width: 24px; height: 24px;" icon-class="question" />
  22. </el-link>
  23. </el-tooltip>
  24. <div v-if="userInfo" class="user-info">
  25. <a-popover placement="rightBottom" overlay-class-name="head-popover">
  26. <template #content>
  27. <div class="user-control">
  28. <div class="user-name">{{ userInfo.name }}</div>
  29. <div class="line" />
  30. <div class="user-logout">
  31. <el-button v-if="navTagType === 1" type="primary" plain size="small" @click="setNavTagType(2)">顶部导航</el-button>
  32. <el-button v-if="navTagType === 2" type="primary" plain size="small" @click="setNavTagType(1)">侧边导航</el-button>
  33. </div>
  34. <div class="line" />
  35. <div class="user-logout">
  36. <el-button type="primary" plain size="small" @click="layout()">退出登录</el-button>
  37. </div>
  38. </div>
  39. </template>
  40. <img :src="userInfo.phoneUrl">
  41. </a-popover>
  42. </div>
  43. </div>
  44. </template>
  45. <script>
  46. import { mapGetters } from 'vuex'
  47. import routes from '@/router/newRouter'
  48. import websocket from '@/views/workbench/mixins/websocket'
  49. import { memberGetLoginInMemberInfoByLdap } from '@/api/projectIndex'
  50. import { logoutUrl } from '@/apiConfig/requestIP.js'
  51. export default {
  52. mixins: [websocket],
  53. data() {
  54. return {
  55. headList: routes.filter(item => item.name !== '业务线'),
  56. userInfo: null
  57. }
  58. },
  59. computed: {
  60. ...mapGetters(['activeNavTag', 'navTagType', 'notice'])
  61. },
  62. watch: {
  63. $route: {
  64. handler(to) {
  65. this.findRoute(to.name)
  66. },
  67. immediate: true
  68. }
  69. },
  70. created() {
  71. this.getLoginUser()
  72. },
  73. methods: {
  74. findRoute(routeName) {
  75. for (const element of routes) {
  76. if (element.name === routeName) {
  77. // 先对父元素进行查找
  78. this.$store.dispatch('global/setActiveNavTag', element.name)
  79. } else if (element.children) {
  80. const child = element.children.find(item => item.name === routeName) // 对子元素进行查找
  81. child ? this.$store.dispatch('global/setActiveNavTag', element.name) : '' // 父元素的名字设为路径
  82. }
  83. }
  84. },
  85. // 切换二级导航
  86. changeNavTag(nav) {
  87. this.$store.dispatch('global/setActiveNavTag', nav.name) // 设置二级导航的类别
  88. this.$router.push({ name: nav.name }) // 跳转
  89. },
  90. // 设置二级导航类型
  91. setNavTagType(type) {
  92. this.$store.dispatch('global/setNavTagType', type)
  93. localStorage.setItem('navTagType', type)
  94. },
  95. // 获取登录人员信息
  96. async getLoginUser() {
  97. const res = await memberGetLoginInMemberInfoByLdap()
  98. if (res && res.data) this.userInfo = res.data || null
  99. },
  100. // 退出登录
  101. layout() {
  102. window.location.href = logoutUrl
  103. },
  104. topHome() {
  105. this.$router.push({ path: '/' })
  106. },
  107. // websocket数据接收
  108. websocketonmessage(e) {
  109. const { hasReminding } = JSON.parse(e.data)
  110. if (hasReminding) {
  111. this.$store.dispatch('data/setNotice', true)
  112. const link = document.querySelector('link')
  113. link.href = link.href.replace(/favicon.ico/, 'favicon-tips.ico')
  114. } else {
  115. this.$store.dispatch('data/setNotice', false)
  116. const link = document.querySelector('link')
  117. link.href = link.href.replace(/favicon-tips.ico/, 'favicon.ico')
  118. }
  119. }
  120. }
  121. }
  122. </script>
  123. <style lang="scss" scoped>
  124. .head-wrapper {
  125. display: flex;
  126. flex-direction: column;
  127. flex-shrink: 0;
  128. z-index: 99;
  129. width: 80px;
  130. align-items: center;
  131. background: #409eff;
  132. font-size: 20px;
  133. color: #333;
  134. padding-top: 17px;
  135. }
  136. .head-logo {
  137. height: 40px;
  138. width: 40px;
  139. margin-bottom: 42px;
  140. .svg-icon {
  141. cursor: pointer;
  142. width: 100%;
  143. height: 100%;
  144. }
  145. }
  146. .nav-tag {
  147. width: 100%;
  148. font-size: 14px;
  149. color: #ffffff;
  150. text-align: center;
  151. margin-bottom: 20px;
  152. padding: 5px 0 9px 0;
  153. cursor: pointer;
  154. .icon {
  155. position: relative;
  156. color: #ffffff;
  157. height: 27px;
  158. width: 33px;
  159. margin: 7px auto;
  160. font-size: 32px;
  161. }
  162. .svg-icon {
  163. position: absolute;
  164. top: 0;
  165. left: 0;
  166. width: 100%;
  167. height: 100%;
  168. }
  169. .if-notice {
  170. position: absolute;
  171. z-index: 1;
  172. height: 8px;
  173. width: 8px;
  174. background-color: #E02020;
  175. border-radius: 50%;
  176. top: 0;
  177. right: 0;
  178. transform: translateY(-50%);
  179. }
  180. }
  181. .active-nav-tag {
  182. background-color: #1E89F7;
  183. }
  184. .nav-tag-type {
  185. margin-top: auto;
  186. color: #ffffff;
  187. cursor: pointer;
  188. }
  189. .user-tip {
  190. margin-top: auto;
  191. margin-bottom: 30px;
  192. }
  193. .user-info {
  194. height: 30px;
  195. width: 30px;
  196. display: flex;
  197. justify-content: center;
  198. align-items: center;
  199. background-color: #fff;
  200. border-radius: 50%;
  201. overflow: hidden;
  202. // margin-top: auto;
  203. margin-bottom: 30px;
  204. img {
  205. height: 30px;
  206. }
  207. }
  208. .user-control {
  209. height: 143px;
  210. width: 95px;
  211. display: flex;
  212. flex-direction: column;
  213. display: grid;
  214. grid-template-rows: 47px 1px 47px 1px 47px;
  215. justify-items: center;
  216. align-items: center;
  217. .line {
  218. width: 100%;
  219. height: 1px;
  220. background-color: rgba(112, 112, 112, 0.2);
  221. }
  222. }
  223. </style>
  224. <style lang="scss">
  225. .head-popover {
  226. box-shadow: 10px 0px 11px #dedede;
  227. /deep/ .ant-popover-inner-content {
  228. padding: 0;
  229. }
  230. }
  231. </style>