Navbar.vue 9.7 KB

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