layout.vue 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329
  1. <template>
  2. <el-container>
  3. <el-aside :class="menuClass" width="">
  4. <el-menu :default-active="menuActiveIndex" :router="true" :collapse="isCollapse" :unique-opened="true">
  5. <div class="site-title">
  6. <h1>{{siteTitle}}</h1>
  7. </div>
  8. <div class="user-profile">
  9. <!--<img :src="userAvatar" alt="" class="profile-avatar img-circle">-->
  10. <img src="../../static/img/avatar/1.png" alt="" class="profile-avatar img-circle">
  11. <el-dropdown>
  12. <span class="el-dropdown-link">
  13. {{userName}} <i class="el-icon-caret-bottom el-icon--right"></i>
  14. </span>
  15. <el-dropdown-menu slot="dropdown">
  16. <el-dropdown-item icon="el-icon-user" @click.native="onGo('/user/index')">Personal Information</el-dropdown-item><!--个人资料-->
  17. <el-dropdown-item icon="el-icon-s-promotion">
  18. <a target="_blank" :href="visitWebsite">New Member Management System</a>
  19. </el-dropdown-item><!--新版-->
  20. <!--<el-dropdown-item icon="el-icon-message" @click.native="onGo('/message/list')">站内信</el-dropdown-item>-->
  21. <!-- <el-dropdown-item icon="el-icon-setting" @click.native="onGo('/config/base')">个人设置</el-dropdown-item>-->
  22. <el-dropdown-item icon="el-icon-switch-button" @click.native="onLogout">Log Out</el-dropdown-item><!--安全退出-->
  23. </el-dropdown-menu>
  24. </el-dropdown>
  25. </div>
  26. <template v-for="parent in menu">
  27. <el-submenu :index="'/'+parent.routePath" v-if="parent.child.length">
  28. <template slot="title">
  29. <i :class="parent.icon"></i>
  30. <span>{{parent.name}}</span>
  31. <span v-show="parent.routePath==='message'&&notifyShow" class="text-danger">new</span>
  32. </template>
  33. <el-menu-item-group title="">
  34. <el-menu-item :index="'/'+child.routePath" v-for="child in parent.child" :key="'/'+child.routePath">
  35. {{child.name}}
  36. </el-menu-item>
  37. </el-menu-item-group>
  38. </el-submenu>
  39. <el-menu-item :index="'/'+parent.routePath" v-else>
  40. <i :class="parent.icon"></i>
  41. <span>{{parent.name}}</span>
  42. </el-menu-item>
  43. </template>
  44. </el-menu>
  45. </el-aside>
  46. <el-container>
  47. <el-header>
  48. <ul class="al-left layout-menu-left">
  49. <li class="mobile-menu">
  50. <el-button type="text" @click="onMobileMenu"><i class="el-icon-s-fold"></i></el-button>
  51. </li>
  52. <li class="scale-menu">
  53. <el-button type="text" @click="onMenu"><i class="el-icon-s-fold"></i></el-button>
  54. </li>
  55. <!-- <li class="top-message button">-->
  56. <!-- <el-button type="text" @click="onMessage"><i class="el-icon-message"></i>-->
  57. <!-- <div class="notify" v-show="notifyShow"><span class="heartbit"></span><span class="point"></span></div>-->
  58. <!-- </el-button>-->
  59. <!-- <transition name="custom-classes-transition" enter-active-class="animated bounceInDown">-->
  60. <!-- <div class="top-message-card" v-if="messageShow" v-loading="messageLoading">-->
  61. <!-- <ul v-if="unreadMessage !== null">-->
  62. <!-- <li v-for="(item,index) in unreadMessage" :key="index" @click="toMessage(item.ID)">-->
  63. <!-- <h5>{{item.TITLE}}</h5>-->
  64. <!-- <span>{{tool.formatDate(item.CREATED_AT)}}</span>-->
  65. <!-- </li>-->
  66. <!-- </ul>-->
  67. <!-- </div>-->
  68. <!-- </transition>-->
  69. <!-- </li>-->
  70. </ul>
  71. <div style="text-align: right">
  72. <el-button type="text" @click.native="onLogout">Log Out</el-button><!--安全退出-->
  73. </div>
  74. </el-header>
  75. <div :class="'breadcrumb-box '+menuClass">
  76. <h4>{{contentTitle}}</h4>
  77. <div class="breadcrumb-content">
  78. <el-breadcrumb separator="/">
  79. <el-breadcrumb-item v-for="(item, index) in breadcrumb" :to="{ path: item.path }" :key="index">
  80. {{item.title}}
  81. </el-breadcrumb-item>
  82. </el-breadcrumb>
  83. </div>
  84. </div>
  85. <el-main>
  86. <router-view></router-view>
  87. </el-main>
  88. </el-container>
  89. </el-container>
  90. </template>
  91. <script>
  92. import {WEBSOCKET_HOST, CDN_IMG_URL} from '@/utils/config'
  93. import websocketHelper from '@/utils/websocketHelper';
  94. import userInfo from '@/utils/userInfo'
  95. import network from '@/utils/network'
  96. import tool from '@/utils/tool'
  97. import Waves from '../../static/plugins/waves/waves.js'
  98. import store from '@/utils/vuexStore'
  99. import baseInfo from '@/utils/baseInfo'
  100. import initRegion from '@/utils/region'
  101. export default {
  102. name: 'layout',
  103. beforeCreate () {
  104. let thisObj = this
  105. // 检测用户是否已经登录,如果已经登录则直接跳转到控制台页
  106. if (!userInfo.hasLogin()) {
  107. this.$router.push('/login')
  108. return
  109. }
  110. // 获取未读消息数量
  111. if (store.state.baseInfo.messageUnreadNum === null) {
  112. network.getUnreadMessage()
  113. }
  114. let baseInfo = userInfo.baseData()
  115. //链接websocket 服务器
  116. this.$webSocket.onOpen(thisObj, function(evt){
  117. thisObj.$webSocket.onSend(thisObj, JSON.stringify({
  118. cmd: websocketHelper.HAND_SHAKE,
  119. app: websocketHelper.WS_APP_BONUS,
  120. userId: baseInfo.ID
  121. }));
  122. });
  123. this.$webSocket.onMessage(thisObj, function(res){
  124. websocketHelper.onMessage(res,baseInfo);
  125. });
  126. // websocket连接
  127. /*let wsServer = WEBSOCKET_HOST
  128. let webSocket = new WebSocket(wsServer)
  129. store.state.socket.socketObj = webSocket
  130. webSocket.onopen = function (evt) {
  131. let userId = userInfo.userId()
  132. let sendData = {app: 'userPc', userId: userId}
  133. webSocket.send(JSON.stringify(sendData))
  134. }
  135. webSocket.onmessage = function (env) {
  136. let data = JSON.parse(env.data)
  137. if (data.handle === 'userPullMsg') {
  138. // vueObj.$message({
  139. // message: data.message,
  140. // type: data.success ? 'success' : 'error',
  141. // });
  142. // if(store.state.socket.onMessageCallback !== null){
  143. // store.state.socket.onMessageCallback();
  144. // }
  145. // 请求服务器拉取信息
  146. network.getData('message/pull').then(response => {
  147. // 请求服务器,获取未读站内信数量
  148. return network.getUnreadMessage()
  149. })
  150. }
  151. }*/
  152. // 获取地区信息
  153. initRegion(thisObj)
  154. },
  155. mounted () {
  156. let promise = network.getSiteInfo().then(response => {
  157. this.siteTitle = response.siteTitle
  158. })
  159. Waves.init()
  160. Waves.attach('.waves-btn')
  161. },
  162. data () {
  163. return {
  164. isCollapse: false,
  165. menuActiveIndex: this.$route.meta.highLight || this.$route.path,
  166. mainTitle: this.$route.meta.title,
  167. messageShow: false,
  168. profileShow: false,
  169. userNameShow: true,
  170. menuClass: '',
  171. userName: userInfo.userName(),
  172. userAvatar: userInfo.baseData().AVATAR,
  173. messageLoading: true,
  174. unreadMessage: null,
  175. tool: tool,
  176. siteTitle: '',
  177. whetherBA: baseInfo.whetherBA(),
  178. visitWebsite: 'http://16.163.228.151:8037',
  179. }
  180. },
  181. computed: {
  182. menu: function () {
  183. return baseInfo.menu()
  184. },
  185. contentTitle: function () {
  186. return this.$route.meta.title
  187. },
  188. breadcrumb: function () {
  189. let breadcrumbArr = []
  190. for (let i in this.$route.meta.breadcrumb) {
  191. breadcrumbArr.push(this.$route.meta.breadcrumb[i])
  192. }
  193. breadcrumbArr.push({title: this.$route.meta.title, path: ''})
  194. return breadcrumbArr
  195. },
  196. notifyShow: function () {
  197. if (store.state.baseInfo.messageUnreadNum > 0) {
  198. return true
  199. } else {
  200. return false
  201. }
  202. },
  203. },
  204. methods: {
  205. onMenu () {
  206. if (this.isCollapse) {
  207. this.isCollapse = false
  208. document.getElementsByTagName('body')[0].className = ''
  209. } else {
  210. this.isCollapse = true
  211. document.getElementsByTagName('body')[0].className = 'content-wrapper'
  212. }
  213. },
  214. onMobileMenu () {
  215. if (this.menuClass === 'show-menu') {
  216. this.menuClass = ''
  217. } else {
  218. this.menuClass = 'show-menu'
  219. }
  220. },
  221. onMessage () {
  222. if (store.state.baseInfo.messageUnreadNum > 0) {
  223. this.messageShow = !this.messageShow
  224. network.getData(`message/unread-text`).then(response => {
  225. this.unreadMessage = response
  226. this.messageLoading = false
  227. })
  228. } else {
  229. this.$message({
  230. message: 'No Unread Message',//暂无未读消息
  231. type: 'warning'
  232. })
  233. }
  234. },
  235. onProfile () {
  236. this.profileShow = !this.profileShow
  237. },
  238. onGo(url) {
  239. let _url = !this.whetherBA ? url : '/user/ba-info';
  240. this.$router.push(_url)
  241. },
  242. onLogout () {
  243. userInfo.clear()
  244. this.$router.push('/login')
  245. },
  246. onCloseProfile () {
  247. this.profileShow = false
  248. },
  249. toMessage (id) {
  250. this.$router.push(`/message/detail/${id}`)
  251. this.messageShow = !this.messageShow
  252. network.getData(`message/unread-text`).then(response => {
  253. this.unreadMessage = response
  254. this.messageLoading = false
  255. })
  256. }
  257. }
  258. }
  259. </script>
  260. <style>
  261. @import '../../static/css/animate.css';
  262. @import '../../static/plugins/waves/waves.css';
  263. @import '../../static/css/style.css';
  264. .el-menu-item-group__title{display: none;}
  265. .top-message {
  266. position: relative
  267. }
  268. .top-message .notify {
  269. position: relative;
  270. margin-top: -8px;
  271. }
  272. .top-message .notify .heartbit {
  273. position: absolute;
  274. top: -24px;
  275. right: -20px;
  276. height: 25px;
  277. width: 25px;
  278. z-index: 10;
  279. border: 5px solid #f75b36;
  280. border-radius: 70px;
  281. animation: heartbit 1s ease-out;
  282. animation-iteration-count: infinite;
  283. }
  284. .top-message .notify .point {
  285. width: 6px;
  286. height: 6px;
  287. -webkit-border-radius: 30px;
  288. -moz-border-radius: 30px;
  289. border-radius: 30px;
  290. background-color: #f75b36;
  291. position: absolute;
  292. right: -5px;
  293. top: -9px;
  294. }
  295. @keyframes heartbit {
  296. 0% {
  297. transform: scale(0);
  298. opacity: 0
  299. }
  300. 25% {
  301. transform: scale(.1);
  302. opacity: .1
  303. }
  304. 50% {
  305. transform: scale(.5);
  306. opacity: .3
  307. }
  308. 75% {
  309. transform: scale(.65);
  310. opacity: .5
  311. }
  312. 100% {
  313. transform: scale(.8);
  314. opacity: 0
  315. }
  316. }
  317. </style>