Home.vue 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385
  1. <template>
  2. <div class="home">
  3. <div class="home-header">
  4. <div class="head-menu menu-list">
  5. <ul>
  6. <li
  7. v-for="(menu, index) in menus"
  8. :key="index"
  9. :class="[
  10. 'menu-item',
  11. { 'menu-item-act': curMenu.url === menu.url }
  12. ]"
  13. @click="toMenu(menu)"
  14. >
  15. <i :class="menu.icon"></i>
  16. <span>{{ menu.name }}</span>
  17. </li>
  18. </ul>
  19. </div>
  20. <div class="head-user menu-list">
  21. <ul>
  22. <li v-if="schoolName" @click="toSelectSchool" title="切换学校">
  23. <i class="el-icon-s-home"></i>
  24. <span>{{ schoolName }}</span>
  25. </li>
  26. <li
  27. class="menu-item menu-item-account"
  28. @click="$refs.ResetPwd.open()"
  29. >
  30. <i class="icon icon-account"></i>
  31. <span :title="username">{{ username }}</span>
  32. </li>
  33. <li class="menu-item" @click="toLogout">
  34. <i class="icon icon-logout" title="退出登录"></i>
  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="curMenu.children">
  43. <div class="head-logo">
  44. <img v-if="schoolLogo" :src="schoolLogo" alt="分布式印刷" />
  45. <h1 v-else>分布式印刷</h1>
  46. </div>
  47. <div
  48. v-for="(submenu, sindex) in curMenu.children"
  49. :key="sindex"
  50. class="nav-part"
  51. >
  52. <div class="nav-head">
  53. <span>{{ submenu.name }}</span>
  54. <i class="nav-head-right-icon el-icon-caret-bottom"></i>
  55. </div>
  56. <ul class="nav-list">
  57. <li
  58. class="nav-item"
  59. v-for="(nav, navNo) in submenu.children"
  60. :key="navNo"
  61. >
  62. <div
  63. :class="[
  64. 'nav-item-main',
  65. { 'nav-item-main-act': curActNav === nav.url }
  66. ]"
  67. @click="toNav(nav)"
  68. >
  69. <p class="nav-item-cont">{{ nav.name }}</p>
  70. <span
  71. class="nav-item-info"
  72. v-if="nav.url === 'WaitTask' && waitTaskCount"
  73. >{{ waitTaskCount }}</span
  74. >
  75. </div>
  76. </li>
  77. </ul>
  78. </div>
  79. </div>
  80. <div class="home-body">
  81. <div class="home-main">
  82. <div class="home-breadcrumb" v-if="breadcrumbs.length">
  83. <span class="breadcrumb-tips">
  84. <i class="icon icon-location"></i>
  85. <span>当前所在位置:</span>
  86. </span>
  87. <el-breadcrumb separator="/">
  88. <el-breadcrumb-item
  89. v-for="(bread, index) in breadcrumbs"
  90. :key="index"
  91. >{{ bread.title }}</el-breadcrumb-item
  92. >
  93. </el-breadcrumb>
  94. </div>
  95. <!-- home-view: page detail -->
  96. <div class="home-view">
  97. <router-view />
  98. </div>
  99. </div>
  100. </div>
  101. <!-- popover menu-->
  102. <el-dialog
  103. class="menu-dialog"
  104. :visible.sync="menuDailogIsShow"
  105. title="导航菜单"
  106. top="60px"
  107. fullscreen
  108. :close-on-click-modal="false"
  109. :close-on-press-escape="false"
  110. append-to-body
  111. >
  112. <div
  113. class="home-navs home-navs-full"
  114. v-for="(curMenu, mainNo) in menus"
  115. :key="mainNo"
  116. >
  117. <div
  118. v-for="(submenu, sindex) in curMenu.children"
  119. :key="sindex"
  120. class="nav-part"
  121. >
  122. <div class="nav-head">
  123. <i :class="submenu.icon"></i>
  124. <span>{{ curMenu.name }} - {{ submenu.name }}</span>
  125. </div>
  126. <ul class="nav-list">
  127. <li
  128. class="nav-item"
  129. v-for="(nav, navNo) in submenu.children"
  130. :key="navNo"
  131. >
  132. <div
  133. :class="[
  134. 'nav-item-main',
  135. { 'nav-item-main-act': curActNav === nav.url }
  136. ]"
  137. @click="toNav(nav)"
  138. >
  139. <p class="nav-item-cont">{{ nav.name }}</p>
  140. <span class="nav-item-icon nav-item-icon-right">
  141. <i
  142. :class="[
  143. 'icon',
  144. curActNav === nav.url
  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.url === 'WaitTask' && waitTaskCount"
  153. >{{ waitTaskCount }}</span
  154. >
  155. </div>
  156. </li>
  157. </ul>
  158. </div>
  159. </div>
  160. <div class="menu-logout" @click="toLogout">
  161. <i class="el-icon-switch-button"></i>
  162. </div>
  163. </el-dialog>
  164. <!-- 修改密码 -->
  165. <reset-pwd ref="ResetPwd"></reset-pwd>
  166. </div>
  167. </template>
  168. <script>
  169. import { mapState, mapActions } from "vuex";
  170. import localNavs from "@/constants/navs";
  171. import { deepCopy } from "@/plugins/utils";
  172. import { sysMenu, logout } from "../modules/login/api";
  173. import ResetPwd from "../modules/base/components/ResetPwd";
  174. import { SYS_ADMIN_NAME } from "@/constants/enumerate";
  175. export default {
  176. name: "home",
  177. components: { ResetPwd },
  178. data() {
  179. const IS_SUPER_ADMIN =
  180. this.$ls.get("user", { loginName: "" }).loginName === SYS_ADMIN_NAME;
  181. return {
  182. menus: [],
  183. curMenu: { url: "", children: [] },
  184. curActNav: "",
  185. breadcrumbs: [],
  186. validRoutes: [],
  187. username: this.$ls.get("user", { realName: "" }).realName,
  188. userRoles: this.$ls.get("user", { roleList: [] }).roleList,
  189. schoolLogo: this.$ls.get("schoolLogo"),
  190. schoolName: this.$ls.get("schoolName"),
  191. menuDailogIsShow: false,
  192. IS_SUPER_ADMIN
  193. };
  194. },
  195. watch: {
  196. $route(val) {
  197. if (val.name === "Home") return;
  198. this.actCurNav();
  199. }
  200. },
  201. computed: {
  202. ...mapState("exam", ["waitTaskCount"])
  203. },
  204. created() {
  205. this.getMenus();
  206. },
  207. methods: {
  208. ...mapActions("exam", ["updateWaitTaskCount"]),
  209. getMenus1() {
  210. this.menus = localNavs;
  211. if (this.$route.name === "Home") {
  212. this.$router.replace({
  213. name: "CampusManage"
  214. });
  215. } else {
  216. this.actCurNav();
  217. }
  218. },
  219. async getMenus() {
  220. const data = await sysMenu();
  221. this.initPrivilegeMap(data.privileges);
  222. const { menus, firstRouter } = this.menusToTree(data.privileges);
  223. this.menus = menus;
  224. if (this.$route.name === "Home") {
  225. this.$router.replace({
  226. name: firstRouter
  227. });
  228. return;
  229. } else {
  230. if (!this.validRoutes.includes(this.$route.name)) {
  231. this.$router.replace({
  232. name: "404"
  233. });
  234. return;
  235. }
  236. this.actCurNav();
  237. }
  238. },
  239. initPrivilegeMap(data) {
  240. let privilegeMap = {};
  241. const pageSetTypes = ["conditions", "buttons", "lists", "links"];
  242. data.forEach(item => {
  243. const isPage = pageSetTypes.some(
  244. type => item[type] && item[type].length
  245. );
  246. if (!isPage) return;
  247. privilegeMap[item.url] = [];
  248. pageSetTypes.forEach((type, index) => {
  249. if (item[type] && item[type].length) {
  250. item[type].forEach(elem => {
  251. privilegeMap[item.url].push(
  252. `${elem.type}_${elem.url}`.toLowerCase()
  253. );
  254. });
  255. }
  256. });
  257. });
  258. this.$store.commit("setPrivilegeMap", privilegeMap);
  259. this.$ls.set("privilegeMap", privilegeMap);
  260. },
  261. menusToTree(menus) {
  262. let navTree = deepCopy(localNavs);
  263. let validRoutes = [];
  264. let validMenuDict = {};
  265. let firstRouter = "";
  266. menus.forEach(item => (validMenuDict[item.url] = item.name));
  267. const anchorNav = menus => {
  268. let list = [];
  269. menus.forEach(item => {
  270. const routerOrName = item.url;
  271. if (!validMenuDict[routerOrName]) return;
  272. if (!firstRouter && item.isRouter) firstRouter = item.url;
  273. item.name = validMenuDict[routerOrName];
  274. validRoutes.push(routerOrName);
  275. let navItem = { ...item };
  276. if (item["children"]) {
  277. navItem.children = anchorNav(item.children);
  278. }
  279. list.push(navItem);
  280. });
  281. return list;
  282. };
  283. this.validRoutes = validRoutes;
  284. return { menus: anchorNav(navTree), firstRouter };
  285. },
  286. toMenu(menu) {
  287. if (this.curMenu.url === menu.url) return;
  288. this.curMenu = menu;
  289. const firstRouter = menu.children[0].children[0];
  290. this.toNav(firstRouter);
  291. },
  292. toNav(nav) {
  293. if (nav.url === this.$route.name) return;
  294. this.curActNav = nav.url;
  295. this.$router.push({ name: nav.url });
  296. this.menuDailogIsShow = false;
  297. },
  298. actCurNav() {
  299. const routerName = this.$route.name;
  300. let breadcrumbs = [];
  301. const getRouterPath = (navs, pathList) => {
  302. navs.forEach(nav => {
  303. let navPathList = [...pathList];
  304. if (breadcrumbs.length) return;
  305. if (nav.url === routerName) {
  306. breadcrumbs = [
  307. ...navPathList,
  308. { title: nav.name, router: nav.url, isRouter: true }
  309. ];
  310. return;
  311. } else {
  312. navPathList = [
  313. ...navPathList,
  314. {
  315. title: nav.name,
  316. router: nav.url,
  317. isRouter: !!nav.isRouter
  318. }
  319. ];
  320. if (nav["children"]) {
  321. getRouterPath(nav.children, navPathList);
  322. }
  323. }
  324. });
  325. };
  326. getRouterPath(this.menus, []);
  327. const curRouter = breadcrumbs.find(item => item.isRouter);
  328. this.curActNav = curRouter.router;
  329. this.curMenu = this.menus.find(
  330. menu => menu.url === breadcrumbs[0].router
  331. );
  332. this.breadcrumbs = breadcrumbs;
  333. if (
  334. this.validRoutes.includes("WaitTask") &&
  335. this.curMenu.url === "exam"
  336. ) {
  337. this.updateWaitTaskCount();
  338. }
  339. },
  340. toLogout() {
  341. this.$confirm("确定要退出登录吗?", "提示", {
  342. type: "warning"
  343. })
  344. .then(() => {
  345. this.logoutAction();
  346. })
  347. .catch(() => {});
  348. },
  349. async logoutAction() {
  350. await logout();
  351. this.$ls.clear();
  352. this.$router.push({ name: "Login" });
  353. },
  354. toSelectSchool() {
  355. if (this.IS_SUPER_ADMIN) this.$router.push({ name: "SelectSchool" });
  356. },
  357. // popover menu
  358. showMenu() {
  359. this.menuDailogIsShow = !this.menuDailogIsShow;
  360. },
  361. toNavDetail(mainNo, subNo) {
  362. this.toNav(subNo);
  363. this.showMenu();
  364. }
  365. }
  366. };
  367. </script>