Navbar.vue 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706
  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
  10. id="breadcrumb-container"
  11. class="breadcrumb-container"
  12. v-if="!topNav"
  13. />
  14. <top-nav id="topmenu-container" class="topmenu-container" v-if="topNav" />
  15. <div class="right-menu">
  16. <template v-if="device !== 'mobile'">
  17. <search id="header-search" class="right-menu-item" />
  18. <!-- <el-tooltip content="源码地址" effect="dark" placement="bottom">
  19. <ruo-yi-git id="ruoyi-git" class="right-menu-item hover-effect" />
  20. </el-tooltip>
  21. <el-tooltip content="文档地址" effect="dark" placement="bottom">
  22. <ruo-yi-doc id="ruoyi-doc" class="right-menu-item hover-effect" />
  23. </el-tooltip> -->
  24. <el-tooltip content="版本说明" effect="dark" placement="bottom">
  25. <version
  26. id="version"
  27. class="right-menu-item hover-effect"
  28. @openMsg="openMsg"
  29. />
  30. </el-tooltip>
  31. <el-dialog
  32. append-to-body
  33. :visible.sync="dialogVisible"
  34. width="560px"
  35. :show-close="false"
  36. :close-on-click-modal="false"
  37. >
  38. <div slot="title" class="hearders">
  39. <div class="leftTitle">版本说明</div>
  40. <div class="rightBoxs">
  41. <img
  42. src="@/assets/images/Close@2x.png"
  43. alt=""
  44. @click="dialogVisible = false"
  45. />
  46. </div>
  47. </div>
  48. <div class="dialogSty">
  49. <h2>v6.0.0</h2>
  50. <p>1.第六阶段完整版</p>
  51. </div>
  52. <span slot="footer" class="dialog-footer">
  53. <el-button @click="dialogVisible = false">关 闭</el-button>
  54. </span>
  55. </el-dialog>
  56. <screenfull id="screenfull" class="right-menu-item hover-effect" />
  57. <el-tooltip content="布局大小" effect="dark" placement="bottom">
  58. <size-select id="size-select" class="right-menu-item hover-effect" />
  59. </el-tooltip>
  60. </template>
  61. <el-dropdown
  62. v-if="!spotDataStatus"
  63. class="avatar-container right-menu-item hover-effect"
  64. trigger="click"
  65. >
  66. <div class="avatar-wrapper">
  67. <img :src="avatar" class="user-avatar" />
  68. <i class="el-icon-caret-bottom" />
  69. </div>
  70. <el-dropdown-menu slot="dropdown">
  71. <router-link to="/user/profile">
  72. <el-dropdown-item>个人中心</el-dropdown-item>
  73. </router-link>
  74. <el-dropdown-item @click.native="setting = true">
  75. <span>布局设置</span>
  76. </el-dropdown-item>
  77. <el-dropdown-item divided @click.native="logout">
  78. <span>退出登录</span>
  79. </el-dropdown-item>
  80. </el-dropdown-menu>
  81. </el-dropdown>
  82. </div>
  83. <el-dialog
  84. append-to-body
  85. :visible.sync="dialog_haveRead"
  86. width="440px"
  87. :show-close="false"
  88. :close-on-click-modal="false"
  89. >
  90. <div slot="title" class="hearders">
  91. <div class="leftTitle">{{ total }}条未读消息</div>
  92. <div class="rightBoxs">
  93. <img
  94. src="@/assets/images/Close@2x.png"
  95. alt=""
  96. @click="dialog_haveRead = false"
  97. />
  98. </div>
  99. </div>
  100. <div class="haveRead_style">
  101. <div
  102. v-for="(item, index) in tableData"
  103. :key="index"
  104. class="haveRead_list"
  105. >
  106. <strong>{{ item.remind }}</strong>
  107. <p>
  108. {{ item.text }}
  109. </p>
  110. <p style="time_style">{{ $methodsTools.onlyForma(item.sendTime) }}</p>
  111. <div>
  112. <el-button type="primary" size="small" @click="newSee(item.id)"
  113. >立即查看</el-button
  114. >
  115. <el-button size="small" @click="changeReadStatus(item.id)"
  116. >标记为已读</el-button
  117. >
  118. </div>
  119. </div>
  120. </div>
  121. <span slot="footer" class="dialog-footer">
  122. <el-button @click="seeAllRead">查看所有</el-button>
  123. </span>
  124. </el-dialog>
  125. </div>
  126. </template>
  127. <script>
  128. import { mapGetters } from "vuex";
  129. import Breadcrumb from "@/components/Breadcrumb";
  130. import TopNav from "@/components/TopNav";
  131. import Hamburger from "@/components/Hamburger";
  132. import Screenfull from "@/components/Screenfull";
  133. import SizeSelect from "@/components/SizeSelect";
  134. import version from "@/components/version";
  135. import Search from "@/components/HeaderSearch";
  136. import RuoYiGit from "@/components/RuoYi/Git";
  137. import RuoYiDoc from "@/components/RuoYi/Doc";
  138. export default {
  139. components: {
  140. Breadcrumb,
  141. TopNav,
  142. Hamburger,
  143. Screenfull,
  144. SizeSelect,
  145. Search,
  146. RuoYiGit,
  147. RuoYiDoc,
  148. version,
  149. },
  150. data() {
  151. return {
  152. dialogVisible: false,
  153. dialog_haveRead: false,
  154. tableData: [], //未读列表
  155. total: 0, //未读数量
  156. spotDataStatus: false,
  157. };
  158. },
  159. computed: {
  160. ...mapGetters(["sidebar", "avatar", "device"]),
  161. setting: {
  162. get() {
  163. return this.$store.state.settings.showSettings;
  164. },
  165. set(val) {
  166. this.$store.dispatch("settings/changeSetting", {
  167. key: "showSettings",
  168. value: val,
  169. });
  170. },
  171. },
  172. topNav: {
  173. get() {
  174. return this.$store.state.settings.topNav;
  175. },
  176. },
  177. },
  178. mounted() {
  179. this.spotDataStatus = sessionStorage.getItem("spotData") ? true : false;
  180. if (
  181. this.$route.name !== "StationLetter" &&
  182. !sessionStorage.getItem("spotData")
  183. ) {
  184. this.$api.inquireinformsys_userinformUnReadSum().then((res) => {
  185. if (res.data > 0) {
  186. this.getDontReadList();
  187. }
  188. });
  189. }
  190. },
  191. methods: {
  192. /**
  193. * 立即查看
  194. */
  195. newSee(id) {
  196. this.$router.push({
  197. name: "StationLetter",
  198. params: {
  199. id: id,
  200. },
  201. });
  202. // this.dialog_haveRead = false;
  203. },
  204. /**
  205. * 获取未读数据列表
  206. */
  207. getDontReadList() {
  208. var self = this;
  209. let val = {
  210. receiptStatus: 0,
  211. systemStatus: 1,
  212. };
  213. this.$api.inquireinformsys_userlist(val).then((result) => {
  214. this.tableData = result.rows;
  215. this.total = result.total;
  216. if (this.total > 0) {
  217. const h = this.$createElement;
  218. let arrays = result.rows.map((item, index) => {
  219. return h(
  220. "div",
  221. {
  222. style: {
  223. borderBottom:
  224. result.total === index + 1 ? "none" : "1px solid #D9D9D9",
  225. marginTop: "26px",
  226. paddingBottom: "26px",
  227. },
  228. },
  229. [
  230. h(
  231. "strong",
  232. {
  233. style: {
  234. fontSize: "16px",
  235. fontWeight: "bold",
  236. color: "#222222",
  237. marginBottom: "12px",
  238. },
  239. },
  240. item.remind
  241. ),
  242. h(
  243. "p",
  244. {
  245. style: {
  246. fontSize: "14px",
  247. color: "#606266",
  248. marginBottom: "12px",
  249. },
  250. },
  251. item.text
  252. ),
  253. h(
  254. "p",
  255. {
  256. style: {
  257. fontSize: "12px",
  258. color: "#999999",
  259. marginBottom: "12px",
  260. },
  261. },
  262. this.$methodsTools.onlyForma(item.sendTime)
  263. ),
  264. h(
  265. "el-button",
  266. {
  267. attrs: {
  268. size: "small",
  269. type: "primary",
  270. },
  271. on: {
  272. click: function () {
  273. self.newSee(item.id);
  274. self.$notify.closeAll();
  275. },
  276. },
  277. },
  278. "立即查看"
  279. ),
  280. h(
  281. "el-button",
  282. {
  283. attrs: {
  284. size: "small",
  285. },
  286. on: {
  287. click: async function () {
  288. await self.changeReadStatus(item.id);
  289. self.$notify.closeAll();
  290. self.$nextTick(() => {
  291. self.getDontReadList();
  292. });
  293. },
  294. },
  295. },
  296. "标记为已读"
  297. ),
  298. ]
  299. );
  300. });
  301. this.$notify({
  302. title: `${result.total}条未读信息`,
  303. position: "bottom-right",
  304. dangerouslyUseHTMLString: true,
  305. duration: 0,
  306. customClass: "notiSty",
  307. message: h("div", [
  308. h(
  309. "div",
  310. {
  311. class: "znxStyle",
  312. },
  313. arrays
  314. ),
  315. h(
  316. "div",
  317. {
  318. class: "btn_bottom_style",
  319. on: {
  320. click: function () {
  321. self.seeAllRead();
  322. self.$notify.closeAll();
  323. },
  324. },
  325. },
  326. "查看所有"
  327. ),
  328. ]),
  329. });
  330. // this.dialog_haveRead = true;
  331. } else {
  332. // this.dialog_haveRead = false;
  333. }
  334. });
  335. },
  336. /**
  337. * 更新已读状态
  338. */
  339. changeReadStatus(id) {
  340. return new Promise((resolve, reject) => {
  341. this.$api
  342. .editupdateReadStatusBatch({ ids: [id], receiptStatus: 1 })
  343. .then((res) => {
  344. this.$message.success("已读成功");
  345. resolve();
  346. // this.getDontReadList();
  347. });
  348. });
  349. },
  350. /**
  351. * 查看所有消息
  352. */
  353. seeAllRead() {
  354. this.$router.push({
  355. name: "StationLetter",
  356. });
  357. // this.dialog_haveRead = false;
  358. },
  359. openMsg() {
  360. this.dialogVisible = true;
  361. },
  362. toggleSideBar() {
  363. this.$store.dispatch("app/toggleSideBar");
  364. },
  365. async logout() {
  366. this.$confirm("确定注销并退出系统吗?", "提示", {
  367. confirmButtonText: "确定",
  368. cancelButtonText: "取消",
  369. type: "warning",
  370. })
  371. .then(() => {
  372. const tid = sessionStorage.TenantId;
  373. this.$store.dispatch("LogOut").then(() => {
  374. location.href = "/index?TenantId=" + tid;
  375. });
  376. })
  377. .catch(() => {
  378. // var message: h("div", [
  379. // h("strong", null, item.text),
  380. // h("p", null, this.$methodsTools.onlyForma(item.sendTime)),
  381. // h(
  382. // "el-button",
  383. // {
  384. // attrs: {
  385. // size: "small",
  386. // type: "primary",
  387. // },
  388. // on: {
  389. // click: function () {
  390. // self.newSee(item.id);
  391. // self.$notify.closeAll();
  392. // },
  393. // },
  394. // },
  395. // "立即查看"
  396. // ),
  397. // h(
  398. // "el-button",
  399. // {
  400. // attrs: {
  401. // size: "small",
  402. // },
  403. // on: {
  404. // click: function () {
  405. // self.changeReadStatus(item.id);
  406. // instance[index].close();
  407. // },
  408. // },
  409. // },
  410. // "标记已读"
  411. // ),
  412. // h(
  413. // "el-button",
  414. // {
  415. // attrs: {
  416. // size: "small",
  417. // type: "success",
  418. // },
  419. // on: {
  420. // click: function () {
  421. // self.seeAllRead()
  422. // self.$notify.closeAll();
  423. // },
  424. // },
  425. // },
  426. // "查看全部"
  427. // ),
  428. // ]),
  429. });
  430. },
  431. },
  432. };
  433. </script>
  434. <style lang="scss" scoped>
  435. .haveRead_list {
  436. margin-top: 24px;
  437. padding-bottom: 28px;
  438. border-bottom: 1px solid #d9d9d9;
  439. & > strong {
  440. color: #000;
  441. }
  442. & > .time_style {
  443. color: #999999;
  444. }
  445. &:last-child {
  446. border-bottom: none;
  447. }
  448. }
  449. /deep/.el-button {
  450. border-radius: 8px;
  451. }
  452. /deep/.el-dialog {
  453. z-index: 9999;
  454. border-radius: 8px;
  455. .el-dialog__header {
  456. padding: 0;
  457. .hearders {
  458. height: 40px;
  459. display: flex;
  460. align-items: center;
  461. justify-content: space-between;
  462. padding: 0px 18px 0px 20px;
  463. border-bottom: 1px solid #e2e2e2;
  464. .leftTitle {
  465. font-size: 14px;
  466. font-weight: bold;
  467. color: #2f4378;
  468. }
  469. .rightBoxs {
  470. display: flex;
  471. align-items: center;
  472. img {
  473. width: 14px;
  474. height: 14px;
  475. margin-left: 13px;
  476. cursor: pointer;
  477. }
  478. }
  479. }
  480. }
  481. .el-dialog__body {
  482. padding: 0px 20px;
  483. max-height: 450px;
  484. overflow: auto;
  485. h2 {
  486. font-weight: bold;
  487. color: #333;
  488. border-bottom: 2px dashed #000;
  489. padding-bottom: 10px;
  490. }
  491. }
  492. .el-dialog__footer {
  493. padding: 0;
  494. .dialog-footer {
  495. padding: 0px 40px;
  496. height: 70px;
  497. border-top: 1px solid #e2e2e2;
  498. display: flex;
  499. align-items: center;
  500. justify-content: flex-end;
  501. }
  502. }
  503. }
  504. .imgBox {
  505. width: 100%;
  506. // height: 210px;
  507. border: 1px solid #e2e2e2;
  508. border-radius: 8px;
  509. padding: 8px 8px 3px;
  510. display: flex;
  511. flex-direction: column;
  512. align-items: center;
  513. .imgLabel {
  514. flex: 1;
  515. width: 100%;
  516. border: 1px dotted #e2e2e2;
  517. color: #999;
  518. font-size: 14px;
  519. cursor: pointer;
  520. border-radius: 8px;
  521. .msPhoto {
  522. display: flex;
  523. justify-content: center;
  524. align-items: center;
  525. max-width: 100%;
  526. max-height: 270px;
  527. img {
  528. max-width: 100%;
  529. max-height: 270px;
  530. }
  531. }
  532. .imgbbx {
  533. display: flex;
  534. flex-direction: column;
  535. align-items: center;
  536. justify-content: center;
  537. width: 100%;
  538. height: 100%;
  539. i {
  540. font-weight: bold;
  541. margin: 14px 0;
  542. font-size: 24px;
  543. }
  544. }
  545. }
  546. p {
  547. margin: 5px 0px;
  548. }
  549. }
  550. .navbar {
  551. height: 50px;
  552. overflow: hidden;
  553. position: relative;
  554. background: #fff;
  555. box-shadow: 0 1px 4px rgba(0, 21, 41, 0.08);
  556. .hamburger-container {
  557. line-height: 46px;
  558. height: 100%;
  559. float: left;
  560. cursor: pointer;
  561. transition: background 0.3s;
  562. -webkit-tap-highlight-color: transparent;
  563. &:hover {
  564. background: rgba(0, 0, 0, 0.025);
  565. }
  566. }
  567. .breadcrumb-container {
  568. float: left;
  569. }
  570. .topmenu-container {
  571. position: absolute;
  572. left: 50px;
  573. }
  574. .errLog-container {
  575. display: inline-block;
  576. vertical-align: top;
  577. }
  578. .right-menu {
  579. float: right;
  580. height: 100%;
  581. line-height: 50px;
  582. &:focus {
  583. outline: none;
  584. }
  585. .right-menu-item {
  586. display: inline-block;
  587. padding: 0 8px;
  588. height: 100%;
  589. font-size: 18px;
  590. color: #5a5e66;
  591. vertical-align: text-bottom;
  592. &.hover-effect {
  593. cursor: pointer;
  594. transition: background 0.3s;
  595. &:hover {
  596. background: rgba(0, 0, 0, 0.025);
  597. }
  598. }
  599. }
  600. .avatar-container {
  601. margin-right: 30px;
  602. .avatar-wrapper {
  603. margin-top: 5px;
  604. position: relative;
  605. .user-avatar {
  606. cursor: pointer;
  607. width: 40px;
  608. height: 40px;
  609. border-radius: 10px;
  610. }
  611. .el-icon-caret-bottom {
  612. cursor: pointer;
  613. position: absolute;
  614. right: -20px;
  615. top: 25px;
  616. font-size: 12px;
  617. }
  618. }
  619. }
  620. }
  621. }
  622. .znxStyle {
  623. max-height: 460px;
  624. overflow-y: auto;
  625. padding: 0px 28px;
  626. &::-webkit-scrollbar {
  627. width: 4px;
  628. }
  629. &::-webkit-scrollbar-thumb {
  630. border-radius: 10px;
  631. -webkit-box-shadow: inset 0 0 5px rgba(165, 165, 165, 0.2);
  632. background: rgba(165, 165, 165, 0.2);
  633. }
  634. &::-webkit-scrollbar-track {
  635. -webkit-box-shadow: inset 0 0 5px rgba(165, 165, 165, 0.2);
  636. border-radius: 0;
  637. background: rgba(226, 225, 225, 0.2);
  638. }
  639. }
  640. .btn_bottom_style {
  641. height: 50px;
  642. border-top: 1px solid #d9d9d9;
  643. line-height: 50px;
  644. text-align: center;
  645. color: #222;
  646. font-size: 16px;
  647. cursor: pointer;
  648. transition: all 0.2s;
  649. &:hover {
  650. background-color: #eee;
  651. }
  652. }
  653. .btnStyle_s {
  654. margin-top: 6px;
  655. background-color: skyblue;
  656. color: #fff;
  657. }
  658. </style>
  659. <style lang="less">
  660. .notiSty {
  661. width: 400px !important;
  662. padding: 0px !important;
  663. & > .el-notification__group {
  664. width: 100%;
  665. margin: 0px;
  666. & > .el-notification__title {
  667. text-align: center;
  668. height: 60px;
  669. line-height: 60px;
  670. color: #fff;
  671. font-size: 18px;
  672. font-weight: bold;
  673. background-color: #409eff;
  674. font-family: OPPOSans-Bold, OPPOSans;
  675. }
  676. & > .el-notification__closeBtn {
  677. color: #fff;
  678. font-size: 18px;
  679. top: 24px;
  680. }
  681. }
  682. }
  683. </style>