Navbar.vue 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450
  1. <template>
  2. <div class="navbar">
  3. <hamburger
  4. id="hamburger-container"
  5. :is-active="sidebar.opened"
  6. class="hamburger-container"
  7. @toggleClick="toggleSideBar"
  8. />
  9. <breadcrumb id="breadcrumb-container" class="breadcrumb-container" />
  10. <div class="right-menu">
  11. <div class="right-menu-item">
  12. <company-select select-all global placeholder="请选择供应商" />
  13. </div>
  14. <template v-if="device !== 'mobile'">
  15. <i
  16. v-if="isShow"
  17. class="el-icon-message-solid right-menu-item hover-effect shake"
  18. style="height: 50px; width: 40px; line-height: 52px; font-size: 22px"
  19. @click="openNotice()"
  20. />
  21. <screenfull id="screenfull" class="right-menu-item hover-effect" />
  22. <!-- <el-tooltip content="Global Size" effect="dark" placement="bottom">
  23. <size-select id="size-select" class="right-menu-item hover-effect" />
  24. </el-tooltip> -->
  25. </template>
  26. <el-dropdown class="avatar-container right-menu-item hover-effect" trigger="click">
  27. <div class="avatar-wrapper">
  28. <img :src="avatar + '?imageView2/1/w/80/h/80'" class="user-avatar">
  29. <div class="username">
  30. {{ $store.state.user.name }}
  31. <i class="el-icon-caret-bottom" />
  32. </div>
  33. </div>
  34. <el-dropdown-menu slot="dropdown">
  35. <!-- <router-link to="/person/my-message">
  36. <el-dropdown-item>我的信息</el-dropdown-item>
  37. </router-link>
  38. <router-link to="/person/change-phone">
  39. <el-dropdown-item>更换手机号</el-dropdown-item>
  40. </router-link>
  41. <router-link to="/person/change-password">
  42. <el-dropdown-item>修改密码</el-dropdown-item>
  43. </router-link> -->
  44. <el-dropdown-item @click.native="logout">
  45. <span style="display: block">退出登录</span>
  46. </el-dropdown-item>
  47. </el-dropdown-menu>
  48. </el-dropdown>
  49. </div>
  50. <!-- <el-select
  51. class="fr right-menu-item"
  52. v-model="companyNo"
  53. :size="'mini'"
  54. style="width: 350px; margin: 12px 16px 0 0"
  55. @change="business_companyNo_change"
  56. placeholder="请选择供应商"
  57. >
  58. <el-option
  59. v-for="(item, index) in companyList"
  60. :key="item.supplierNo + item.id + index"
  61. :label="item.supplierName"
  62. :disabled="item.status !== '1'"
  63. :value="item.supplierNo"
  64. >
  65. </el-option>
  66. </el-select> -->
  67. <el-dialog
  68. title="系统公告"
  69. :center="true"
  70. align="left"
  71. top="6vh"
  72. width="900px"
  73. :close-on-click-modal="false"
  74. :visible.sync="showModel"
  75. element-loading-text="拼命加载中"
  76. element-loading-spinner="el-icon-loading"
  77. element-loading-background="rgba(0, 0, 0, 0.8)"
  78. append-to-body
  79. @close="submit"
  80. >
  81. <el-card style="margin-top: -20px">
  82. <el-row v-if="activeMsg !== null" :gutter="10">
  83. <el-col :span="24">
  84. <div style="padding: 0 0 22px 0">
  85. <el-alert
  86. :closable="false"
  87. show-icon
  88. center
  89. class="my-el-alert"
  90. :title="activeMsg.module"
  91. :type="activeMsg.sys_type === 'VER' ? 'success' : 'warning'"
  92. />
  93. </div>
  94. <el-form
  95. :size="'mini'"
  96. label-position="left"
  97. label-width="82px"
  98. class="demo-table-expand"
  99. style="padding-left: 25px"
  100. >
  101. <el-row>
  102. <el-col v-if="activeMsg.sys_type === 'VER'" :span="12">
  103. <el-form-item label="版本编号:">
  104. <p style="margin: 0">{{ activeMsg.version }}</p>
  105. </el-form-item>
  106. </el-col>
  107. <el-col :span="activeMsg.sys_type === 'VER' ? 12 : 24">
  108. <el-form-item
  109. :label="activeMsg.sys_type === 'VER' ? '更新时间:' : '预计时间:'"
  110. >
  111. <p style="margin: 0">
  112. {{ activeMsg.addtime }}
  113. </p>
  114. </el-form-item>
  115. </el-col>
  116. <el-col :span="24">
  117. <el-form-item label="更新内容:">
  118. <p style="margin: 0" v-html="activeMsg.system" />
  119. </el-form-item>
  120. </el-col>
  121. <el-col :span="24" style="text-align: right">
  122. <el-checkbox
  123. v-model="checked"
  124. class="fl"
  125. style="padding-top: 5px"
  126. >我已知晓,后续不再提示!</el-checkbox>
  127. <el-button
  128. type="primary"
  129. plain
  130. :size="'mini'"
  131. @click="submit"
  132. >关闭
  133. </el-button>
  134. </el-col>
  135. </el-row>
  136. </el-form>
  137. </el-col>
  138. </el-row>
  139. </el-card>
  140. </el-dialog>
  141. </div>
  142. </template>
  143. <script>
  144. import { mapGetters } from 'vuex'
  145. import asyncRequest from '@/apis/service/system/updates'
  146. import resToken from '@/mixins/resToken'
  147. import CompanySelect from './company-select/index.vue'
  148. import {
  149. getNotice,
  150. setNotice,
  151. get_business_companyNo,
  152. get_business_company
  153. } from '@/utils/auth'
  154. export default {
  155. computed: {
  156. ...mapGetters(['sidebar', 'avatar', 'device'])
  157. },
  158. components: {
  159. CompanySelect
  160. },
  161. mixins: [resToken],
  162. data() {
  163. return {
  164. companyNo: '',
  165. companyNoName: '',
  166. showModel: false,
  167. loading: false,
  168. isShow: true,
  169. statsTime: 0,
  170. endTime: 0,
  171. checked: true,
  172. lastNotice: null, // 最后一次提示时间
  173. parmValue: {
  174. type: '',
  175. page: 1, // 页码
  176. size: 15 // 每页显示条数
  177. },
  178. activeMsg: null // 消息展示对象
  179. }
  180. },
  181. mounted() {
  182. this.companyNo = get_business_companyNo() || ''
  183. this.companyNoName = get_business_company() || ''
  184. this.openNotice(true)
  185. },
  186. methods: {
  187. async openNotice(is) {
  188. if (getNotice() && getNotice().length > 0) {
  189. this.lastNotice = JSON.parse(getNotice())
  190. } else {
  191. this.lastNotice = null
  192. }
  193. const { code, count, item, message } = await this.initData()
  194. if (code === 0) {
  195. if (count != 0) {
  196. this.activeMsg = item
  197. if (is) {
  198. this.typeShow()
  199. } else {
  200. this.showModel = true
  201. }
  202. } else {
  203. this.$message.warning('暂无系统消息!')
  204. }
  205. } else if (code >= 100 && code <= 104) {
  206. await this.logout()
  207. } else {
  208. this.$message.warning(message)
  209. }
  210. },
  211. business_companyNo_change(e) {
  212. // const index = this.companyList.findIndex((si) => si.supplierNo === e);
  213. // if (index !== -1) {
  214. // const { supplierNo, supplierName } = this.companyList[index];
  215. // this.companyNo = supplierNo;
  216. // this.companyNoName = supplierName;
  217. // this.$store
  218. // .dispatch("user/change_company", { supplierNo, supplierName })
  219. // .then((res) => {
  220. // console.log(res);
  221. // })
  222. // .catch(() => {});
  223. // }
  224. },
  225. async initData() {
  226. const res = {
  227. code: 0,
  228. count: 0,
  229. item: {},
  230. message: ''
  231. }
  232. this.loading = true
  233. const { code, data, message } = await asyncRequest.list(this.parmValue)
  234. this.loading = false
  235. res.code = code
  236. res.message = message
  237. if (code === 0) {
  238. const { list, count } = data
  239. res.count = count
  240. if (count !== 0) {
  241. res.item = JSON.parse(JSON.stringify(list[0]))
  242. }
  243. }
  244. return res
  245. },
  246. typeShow() {
  247. const is = this.is_Tips()
  248. if (!is) {
  249. return
  250. }
  251. if (this.lastNotice + '' === 'null' && is) {
  252. this.showModel = true
  253. } else {
  254. const { addtime: laddtime, type: ltype, sys_type: lsys_type } = this.lastNotice
  255. const { sys_type, addtime } = this.activeMsg
  256. if (laddtime === addtime && lsys_type === sys_type) {
  257. if (ltype + '' === '1') {
  258. this.showModel = false
  259. } else {
  260. this.showModel = true
  261. }
  262. } else {
  263. this.showModel = true
  264. }
  265. }
  266. },
  267. is_Tips() {
  268. const nowtime = new Date().valueOf()
  269. const { sys_type, addtime } = this.activeMsg
  270. const timeV = new Date(addtime).valueOf()
  271. if (sys_type === 'VER') {
  272. this.statsTime = timeV
  273. this.endTime = this.statsTime + 1000 * 60 * 60 * 24 * 7
  274. if (nowtime >= this.statsTime && nowtime <= this.endTime) {
  275. return true
  276. } else {
  277. return false
  278. }
  279. } else {
  280. this.statsTime = 0
  281. this.endTime = timeV
  282. if (nowtime <= this.endTime) {
  283. return true
  284. } else {
  285. return false
  286. }
  287. }
  288. },
  289. toggleSideBar() {
  290. this.$store.dispatch('app/toggleSideBar')
  291. },
  292. async logout() {
  293. await this.$store.dispatch('user/logout')
  294. this.$router.push(`/login?redirect=${this.$route.fullPath}`)
  295. },
  296. submit() {
  297. this.page_set_notice()
  298. this.showModel = false
  299. },
  300. // 保存提交结果
  301. page_set_notice() {
  302. const { sys_type, addtime } = this.activeMsg
  303. const model = {
  304. type: this.checked ? '1' : '0',
  305. sys_type: sys_type,
  306. addtime: addtime
  307. }
  308. setNotice(JSON.stringify(model))
  309. }
  310. }
  311. }
  312. </script>
  313. <style lang="scss" scoped>
  314. @keyframes shake {
  315. /* 水平抖动,核心代码 */
  316. 10%,
  317. 90% {
  318. transform: translate3d(-1px, 0, 0);
  319. }
  320. 20%,
  321. 80% {
  322. transform: translate3d(+2px, 0, 0);
  323. }
  324. 30%,
  325. 70% {
  326. transform: translate3d(-4px, 0, 0);
  327. }
  328. 40%,
  329. 60% {
  330. transform: translate3d(+4px, 0, 0);
  331. }
  332. 50% {
  333. transform: translate3d(-4px, 0, 0);
  334. }
  335. }
  336. .shake {
  337. animation: shake 800ms ease-in-out;
  338. }
  339. .navbar {
  340. height: 50px;
  341. overflow: hidden;
  342. position: relative;
  343. background: #fff;
  344. min-width: 1000px;
  345. box-shadow: 0 1px 4px rgba(0, 21, 41, 0.08);
  346. .hamburger-container {
  347. line-height: 46px;
  348. height: 100%;
  349. float: left;
  350. cursor: pointer;
  351. transition: background 0.3s;
  352. -webkit-tap-highlight-color: transparent;
  353. &:hover {
  354. background: rgba(0, 0, 0, 0.025);
  355. }
  356. }
  357. .breadcrumb-container {
  358. float: left;
  359. width: 500px;
  360. //min-width: calc(1200px - 200px - 150px);
  361. }
  362. .errLog-container {
  363. display: inline-block;
  364. vertical-align: top;
  365. }
  366. .right-menu {
  367. float: right;
  368. height: 100%;
  369. line-height: 50px;
  370. &:focus {
  371. outline: none;
  372. }
  373. .right-menu-item {
  374. display: inline-block;
  375. padding: 0 8px;
  376. height: 100%;
  377. font-size: 18px;
  378. color: #5a5e66;
  379. vertical-align: text-bottom;
  380. &.hover-effect {
  381. cursor: pointer;
  382. transition: background 0.3s;
  383. &:hover {
  384. background: rgba(0, 0, 0, 0.025);
  385. }
  386. }
  387. }
  388. .avatar-container {
  389. margin-right: 30px;
  390. .username {
  391. float: right;
  392. font-size: 14px;
  393. margin-left: 10px;
  394. margin-bottom: 10px;
  395. }
  396. .avatar-wrapper {
  397. margin-top: 5px;
  398. position: relative;
  399. .user-avatar {
  400. cursor: pointer;
  401. width: 40px;
  402. height: 40px;
  403. border-radius: 10px;
  404. }
  405. .el-icon-caret-bottom {
  406. cursor: pointer;
  407. position: absolute;
  408. right: -20px;
  409. top: 25px;
  410. font-size: 12px;
  411. }
  412. }
  413. }
  414. }
  415. }
  416. </style>