Navbar.vue 7.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306
  1. <template>
  2. <div class="navbar">
  3. <hamburger id="hamburger-container" :is-active="sidebar.opened" class="hamburger-container" @toggleClick="toggleSideBar" />
  4. <breadcrumb id="breadcrumb-container" class="breadcrumb-container" v-if="!topNav"/>
  5. <top-nav id="topmenu-container" class="breadcrumb-container" v-if="topNav"/>
  6. <div class="right-menu">
  7. <template v-if="device!=='mobile'">
  8. <div class="right-menu-item hover-effect">
  9. <el-badge v-if="msgCount>0" :value="msgCount" :max="99" class="dot">
  10. </el-badge>
  11. <div class="msg" @click="openMsg()"><i class="el-icon-message-solid"></i> </div>
  12. </div>
  13. <!-- <search id="header-search" class="right-menu-item" />
  14. -->
  15. <screenfull id="screenfull" class="right-menu-item hover-effect" />
  16. <el-tooltip content="布局大小" effect="dark" placement="bottom">
  17. <size-select id="size-select" class="right-menu-item hover-effect" />
  18. </el-tooltip>
  19. </template>
  20. <el-dropdown class="avatar-container right-menu-item hover-effect" trigger="click">
  21. <div class="avatar-wrapper">
  22. <img :src="logImg" class="user-avatar">
  23. <i class="el-icon-caret-bottom" />
  24. </div>
  25. <el-dropdown-menu slot="dropdown">
  26. <router-link to="/user/profile">
  27. <el-dropdown-item>个人中心</el-dropdown-item>
  28. </router-link>
  29. <el-dropdown-item @click.native="setting = true">
  30. <span>布局设置</span>
  31. </el-dropdown-item>
  32. <el-dropdown-item divided @click.native="logout">
  33. <span>退出登录</span>
  34. </el-dropdown-item>
  35. </el-dropdown-menu>
  36. </el-dropdown>
  37. </div>
  38. <el-drawer
  39. :append-to-body="true"
  40. size="35%"
  41. title="消息中心"
  42. :with-header="false"
  43. :title="msg.title" :visible.sync="msg.open"
  44. >
  45. <msg ref="msg" @update-count="getMsgCount" />
  46. </el-drawer>
  47. <red-packet-balance-msg-dialog ref="redPacketBalanceMsgDialog" @msg-read="getMsgCount" />
  48. <order-audit-msg-dialog ref="orderAuditMsgDialog" @msg-read="getMsgCount" />
  49. <proxy-order-msg-dialog ref="proxyOrderMsgDialog" @msg-read="getMsgCount" />
  50. </div>
  51. </template>
  52. <script>
  53. import { mapGetters } from 'vuex'
  54. import Breadcrumb from '@/components/Breadcrumb'
  55. import TopNav from '@/components/TopNav'
  56. import Hamburger from '@/components/Hamburger'
  57. import Screenfull from '@/components/Screenfull'
  58. import SizeSelect from '@/components/SizeSelect'
  59. import Search from '@/components/HeaderSearch'
  60. import msg from "@/views/crm/components/msg";
  61. import { getMsg,getMsgList,getMsgCount,setRead } from "@/api/crm/msg";
  62. import RedPacketBalanceMsgDialog from '@/components/RedPacketBalanceMsgDialog'
  63. import OrderAuditMsgDialog from '@/components/OrderAuditMsgDialog'
  64. import ProxyOrderMsgDialog from '@/components/ProxyOrderMsgDialog'
  65. export default {
  66. components: {
  67. Breadcrumb,
  68. TopNav,
  69. Hamburger,
  70. Screenfull,
  71. SizeSelect,
  72. Search,
  73. msg,
  74. RedPacketBalanceMsgDialog,
  75. OrderAuditMsgDialog,
  76. ProxyOrderMsgDialog
  77. },
  78. computed: {
  79. ...mapGetters([
  80. 'sidebar',
  81. 'avatar',
  82. 'device'
  83. ]),
  84. setting: {
  85. get() {
  86. return this.$store.state.settings.showSettings
  87. },
  88. set(val) {
  89. this.$store.dispatch('settings/changeSetting', {
  90. key: 'showSettings',
  91. value: val
  92. })
  93. }
  94. },
  95. topNav: {
  96. get() {
  97. return this.$store.state.settings.topNav
  98. }
  99. }
  100. },
  101. data() {
  102. return {
  103. msgCount:0,
  104. previousMsgCount: 0,
  105. msg:{
  106. open:false,
  107. title:'通知消息'
  108. },
  109. msgPollingTimer: null,
  110. isFirstCheck: true,
  111. }
  112. },
  113. created() {
  114. this.getMsgCount();
  115. this.startMsgPolling();
  116. },
  117. beforeDestroy() {
  118. this.stopMsgPolling();
  119. },
  120. methods: {
  121. startMsgPolling() {
  122. if (this.msgPollingTimer) {
  123. clearInterval(this.msgPollingTimer);
  124. }
  125. this.msgPollingTimer = setInterval(() => {
  126. this.getMsgCount();
  127. }, 30000);
  128. },
  129. stopMsgPolling() {
  130. if (this.msgPollingTimer) {
  131. clearInterval(this.msgPollingTimer);
  132. this.msgPollingTimer = null;
  133. }
  134. },
  135. checkSpecialMsgs() {
  136. if (this.$refs.redPacketBalanceMsgDialog) {
  137. this.$refs.redPacketBalanceMsgDialog.show();
  138. }
  139. if (this.$refs.orderAuditMsgDialog) {
  140. this.$refs.orderAuditMsgDialog.show();
  141. }
  142. if (this.$refs.proxyOrderMsgDialog) {
  143. this.$refs.proxyOrderMsgDialog.show();
  144. }
  145. },
  146. getMsgCount(){
  147. getMsg().then(response => {
  148. let totalCount = 0;
  149. response.counts.forEach(item => {
  150. totalCount += item.total;
  151. });
  152. this.previousMsgCount = this.msgCount;
  153. this.msgCount = totalCount;
  154. if (this.isFirstCheck) {
  155. this.isFirstCheck = false;
  156. this.$nextTick(() => {
  157. this.checkSpecialMsgs();
  158. });
  159. }
  160. }).catch(error => {
  161. console.error("获取消息计数失败:", error);
  162. });
  163. },
  164. openMsg(){
  165. console.log(11);
  166. this.msg.open=true;
  167. if (this.$refs.msg) {
  168. this.$refs.msg.getMsg();
  169. }
  170. this.getMsgCount();
  171. },
  172. toggleSideBar() {
  173. this.$store.dispatch('app/toggleSideBar')
  174. },
  175. async logout() {
  176. this.$confirm('确定注销并退出系统吗?', '提示', {
  177. confirmButtonText: '确定',
  178. cancelButtonText: '取消',
  179. type: 'warning'
  180. }).then(() => {
  181. this.$store.dispatch('LogOut').then(() => {
  182. location.href = '/index';
  183. })
  184. })
  185. }
  186. }
  187. }
  188. </script>
  189. <style lang="scss" scoped>
  190. .navbar {
  191. height: 50px;
  192. overflow: hidden;
  193. position: relative;
  194. background: #fff;
  195. box-shadow: 0 1px 4px rgba(0,21,41,.08);
  196. .hamburger-container {
  197. line-height: 46px;
  198. height: 100%;
  199. float: left;
  200. cursor: pointer;
  201. transition: background .3s;
  202. -webkit-tap-highlight-color:transparent;
  203. &:hover {
  204. background: rgba(0, 0, 0, .025)
  205. }
  206. }
  207. .breadcrumb-container {
  208. float: left;
  209. }
  210. .errLog-container {
  211. display: inline-block;
  212. vertical-align: top;
  213. }
  214. .right-menu {
  215. float: right;
  216. height: 100%;
  217. line-height: 50px;
  218. &:focus {
  219. outline: none;
  220. }
  221. .right-menu-item {
  222. position: relative;
  223. display: inline-block;
  224. padding: 0 8px;
  225. height: 100%;
  226. font-size: 18px;
  227. color: #5a5e66;
  228. vertical-align: text-bottom;
  229. .msg{
  230. text-align: center;
  231. width:40px;
  232. }
  233. .dot{
  234. position: absolute;
  235. right:0px;
  236. top:0px;
  237. }
  238. &.hover-effect {
  239. cursor: pointer;
  240. transition: background .3s;
  241. &:hover {
  242. background: rgba(0, 0, 0, .025)
  243. }
  244. }
  245. }
  246. .avatar-container {
  247. margin-right: 30px;
  248. .avatar-wrapper {
  249. margin-top: 5px;
  250. position: relative;
  251. .user-avatar {
  252. cursor: pointer;
  253. width: 40px;
  254. height: 40px;
  255. border-radius: 10px;
  256. }
  257. .el-icon-caret-bottom {
  258. cursor: pointer;
  259. position: absolute;
  260. right: -20px;
  261. top: 25px;
  262. font-size: 12px;
  263. }
  264. }
  265. }
  266. }
  267. }
  268. </style>