Home.vue 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371
  1. <template>
  2. <div class="home">
  3. <div class="home-header">
  4. <div class="head-logo">
  5. <h1>逸教云</h1>
  6. </div>
  7. <div class="head-menu menu-list">
  8. <ul>
  9. <li
  10. v-for="(nav, index) in navs"
  11. :key="index"
  12. @click="toPage(index, 0)"
  13. :class="{ 'menu-item-act': curMainIndex === index }"
  14. >
  15. <div class="menu-item">
  16. <i :class="['icon', `icon-${nav.router}`]"></i>
  17. <span>{{ nav.title }}</span>
  18. </div>
  19. </li>
  20. </ul>
  21. </div>
  22. <div class="head-user menu-list">
  23. <ul>
  24. <li @click="$refs.ResetPwd.open()">
  25. <div class="menu-item menu-item-account">
  26. <i class="icon icon-account"></i>
  27. <span :title="username">{{ username }}</span>
  28. </div>
  29. </li>
  30. <li @click="toLogout">
  31. <div class="menu-item">
  32. <i class="icon icon-shut"></i>
  33. <span>退出登录</span>
  34. </div>
  35. </li>
  36. </ul>
  37. </div>
  38. <div class="head-menu-btn" @click="showMenu">
  39. <span><i class="el-icon-menu"></i></span>
  40. </div>
  41. </div>
  42. <div class="home-navs" v-if="curNav">
  43. <div class="nav-head">
  44. <i :class="['icon', `icon-${curNav.router}-gray`]"></i>
  45. <span>{{ curNav.title }}</span>
  46. </div>
  47. <ul class="nav-list">
  48. <li
  49. class="nav-item"
  50. v-for="(nav, subNo) in curNav.children"
  51. :key="subNo"
  52. >
  53. <div
  54. :class="[
  55. 'nav-item-main',
  56. { 'nav-item-main-act': curSubIndex === subNo }
  57. ]"
  58. @click="switchNav(subNo)"
  59. >
  60. <p class="nav-item-cont">{{ nav.title }}</p>
  61. <span class="nav-item-icon nav-item-icon-right">
  62. <i
  63. :class="[
  64. 'icon',
  65. curSubIndex === subNo
  66. ? 'icon-arrow-right-act'
  67. : 'icon-arrow-right'
  68. ]"
  69. ></i>
  70. </span>
  71. <span
  72. class="nav-item-info"
  73. v-if="nav.router === 'WaitTask' && waitTaskCount"
  74. >{{ waitTaskCount }}</span
  75. >
  76. </div>
  77. </li>
  78. </ul>
  79. </div>
  80. <div class="home-body">
  81. <div class="home-main">
  82. <div class="home-breadcrumb" v-if="breadcrumbs.length">
  83. <el-breadcrumb separator=">">
  84. <el-breadcrumb-item :to="{ name: 'Home' }">
  85. <i class="icon icon-home" style="margin-top: -2px;"></i>
  86. </el-breadcrumb-item>
  87. <el-breadcrumb-item
  88. v-for="(bread, index) in breadcrumbs"
  89. :key="index"
  90. >{{ bread.title }}</el-breadcrumb-item
  91. >
  92. </el-breadcrumb>
  93. </div>
  94. <!-- home-view: page detail -->
  95. <div class="home-view">
  96. <!-- <router-view /> -->
  97. <keep-alive :include="keepAliveRoutes">
  98. <router-view />
  99. </keep-alive>
  100. </div>
  101. </div>
  102. </div>
  103. <!-- popover menu-->
  104. <el-dialog
  105. class="menu-dialog"
  106. :visible.sync="menuDailogIsShow"
  107. title="导航菜单"
  108. top="60px"
  109. fullscreen
  110. :close-on-click-modal="false"
  111. :close-on-press-escape="false"
  112. append-to-body
  113. >
  114. <div
  115. class="home-navs home-navs-full"
  116. v-for="(mainNav, mainNo) in navs"
  117. :key="mainNo"
  118. >
  119. <div class="nav-head">
  120. <i :class="['icon', `icon-${mainNav.router}-gray`]"></i>
  121. <span>{{ mainNav.title }}</span>
  122. </div>
  123. <ul class="nav-list">
  124. <li
  125. class="nav-item"
  126. v-for="(nav, subNo) in mainNav.children"
  127. :key="subNo"
  128. >
  129. <div
  130. :class="[
  131. 'nav-item-main',
  132. {
  133. 'nav-item-main-act':
  134. curMainIndex === mainNo && curSubIndex === subNo
  135. }
  136. ]"
  137. @click="switchNavDetail(mainNo, subNo)"
  138. >
  139. <p class="nav-item-cont">{{ nav.title }}</p>
  140. <span class="nav-item-icon nav-item-icon-right">
  141. <i
  142. :class="[
  143. 'icon',
  144. curMainIndex === mainNo && curSubIndex === subNo
  145. ? 'icon-arrow-right-act'
  146. : 'icon-arrow-right'
  147. ]"
  148. ></i>
  149. </span>
  150. <span
  151. class="nav-item-info"
  152. v-if="nav.router === 'WaitTask' && waitTaskCount"
  153. >{{ waitTaskCount }}</span
  154. >
  155. </div>
  156. </li>
  157. </ul>
  158. </div>
  159. <div class="menu-logout" @click="toLogout">
  160. <i class="el-icon-switch-button"></i>
  161. </div>
  162. </el-dialog>
  163. <!-- 修改密码 -->
  164. <reset-pwd @modified="logoutAction" ref="ResetPwd"></reset-pwd>
  165. </div>
  166. </template>
  167. <script>
  168. import { mapState, mapActions } from "vuex";
  169. import localNavs from "@/constants/navs";
  170. import { deepCopy } from "@/plugins/utils";
  171. import { MENU_ROUTER_DICT } from "@/constants/enumerate";
  172. import { logout, sysMenu } from "../modules/login/api";
  173. import ResetPwd from "../modules/base/components/ResetPwd";
  174. export default {
  175. name: "home",
  176. components: { ResetPwd },
  177. data() {
  178. return {
  179. navs: [],
  180. validRoutes: [],
  181. curMainIndex: 0,
  182. curSubIndex: 0,
  183. breadcrumbs: [],
  184. username: this.$ls.get("user", { name: "" }).name,
  185. IS_SUPER_ADMIN: this.$ls
  186. .get("user", { roleCode: "" })
  187. .roleCode.includes("SUPER_ADMIN"),
  188. menuDailogIsShow: false
  189. };
  190. },
  191. watch: {
  192. $route(val) {
  193. this.actCurNav();
  194. }
  195. },
  196. computed: {
  197. ...mapState("examCenter", ["waitTaskCount"]),
  198. curNav() {
  199. return this.navs[this.curMainIndex];
  200. },
  201. keepAliveRoutes() {
  202. return this.$store.state.keepAliveRoutes;
  203. }
  204. },
  205. created() {
  206. this.getMenus();
  207. // this.navs = localNavs;
  208. // this.actCurNav();
  209. },
  210. methods: {
  211. ...mapActions("examCenter", ["updateWaitTaskCount"]),
  212. async getMenus() {
  213. const data = await sysMenu();
  214. this.navs = this.menusToTree(data.records);
  215. if (this.$route.name === "Home") {
  216. this.$router.replace({
  217. name: this.navs[0].children[0].router
  218. });
  219. } else {
  220. if (!this.validRoutes.includes(this.$route.name)) {
  221. this.$router.replace({
  222. name: "404"
  223. });
  224. return;
  225. }
  226. }
  227. this.actCurNav();
  228. if (
  229. this.validRoutes.includes("WaitTask") &&
  230. this.navs[this.curMainIndex].router === "exam-center"
  231. ) {
  232. this.updateWaitTaskCount();
  233. }
  234. },
  235. menusToTree(menus) {
  236. if (this.IS_SUPER_ADMIN) {
  237. const names = {
  238. todoExam: "待办任务(考务)",
  239. todoTaskManager: "待办任务(命题)",
  240. doneTaskManager: "已办任务(命题)"
  241. };
  242. menus.forEach(item => {
  243. item.name = names[item.url] || item.name;
  244. });
  245. }
  246. let navTree = deepCopy(localNavs);
  247. let validRoutes = [];
  248. const anchorNav = (menu, navs) => {
  249. const name = MENU_ROUTER_DICT[menu.url];
  250. navs.forEach(item => {
  251. if (item.router === name) {
  252. item.fixed = true;
  253. item.title = menu.name;
  254. validRoutes.push(item.router);
  255. if (menu.parentId !== null && item["children"]) {
  256. item.children.map(el => {
  257. el.fixed = true;
  258. validRoutes.push(el.router);
  259. });
  260. }
  261. return;
  262. } else {
  263. if (item["children"]) anchorNav(menu, item.children);
  264. }
  265. });
  266. };
  267. const clearNoFixed = navs => {
  268. let list = [];
  269. navs.forEach(nav => {
  270. if (nav["fixed"]) {
  271. let navItem = { title: nav.title, router: nav.router };
  272. if (nav["children"])
  273. navItem.children = clearNoFixed(nav["children"]);
  274. list.push(navItem);
  275. }
  276. });
  277. return list;
  278. };
  279. menus.forEach(menu => {
  280. anchorNav(menu, navTree);
  281. });
  282. this.validRoutes = validRoutes;
  283. return clearNoFixed(navTree);
  284. },
  285. switchNav(subNo) {
  286. const curSubItem = this.curNav.children[subNo];
  287. if (curSubItem.router === this.$route.name) return;
  288. this.$router.push({ name: curSubItem.router });
  289. },
  290. actCurNav() {
  291. const relate = this.$route.meta && this.$route.meta.relate;
  292. const routerName = relate ? relate.split("/")[0] : this.$route.name;
  293. this.navs.forEach((item, index) => {
  294. item.children.forEach((elem, pindex) => {
  295. if (elem.router === routerName) {
  296. this.curSubIndex = pindex;
  297. this.curMainIndex = index;
  298. this.breadcrumbs = [
  299. { title: item.title, router: item.router },
  300. { title: elem.title, router: elem.router }
  301. ];
  302. }
  303. });
  304. });
  305. if (relate) this.getMoreBreadcrumbs(relate);
  306. },
  307. getMoreBreadcrumbs(relate) {
  308. const curSubNav = this.navs[this.curMainIndex].children[this.curSubIndex];
  309. if (!curSubNav.children || !curSubNav.children.length) return;
  310. relate
  311. .split("/")
  312. .slice(1)
  313. .map(routerName => {
  314. const matchRouter = curSubNav.children.find(
  315. elem => elem.router === routerName
  316. );
  317. if (matchRouter)
  318. this.breadcrumbs.push({
  319. title: matchRouter.title,
  320. router: matchRouter.router
  321. });
  322. });
  323. },
  324. toPage(mainIndex, subIndex) {
  325. const elem = this.navs[mainIndex].children[subIndex];
  326. if (elem.router === this.$route.name) return;
  327. this.$router.push({
  328. name: elem.router
  329. });
  330. },
  331. toLogout() {
  332. this.$confirm("确定要退出登录吗?", "提示", {
  333. cancelButtonClass: "el-button--danger is-plain",
  334. confirmButtonClass: "el-button--primary",
  335. type: "warning"
  336. })
  337. .then(() => {
  338. this.logoutAction();
  339. })
  340. .catch(() => {});
  341. },
  342. async logoutAction() {
  343. await logout(this.$ls.get("user", { id: "" }).id);
  344. this.$ls.clear();
  345. this.$router.push({ name: "Login" });
  346. },
  347. // popover menu
  348. showMenu() {
  349. this.menuDailogIsShow = !this.menuDailogIsShow;
  350. },
  351. switchNavDetail(mainNo, subNo) {
  352. this.curMainIndex = mainNo;
  353. this.switchNav(subNo);
  354. this.showMenu();
  355. }
  356. }
  357. };
  358. </script>