Head.vue 5.9 KB

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