Home.vue 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425
  1. <template>
  2. <div :class="['home', { 'home-page-main': IS_HOME_PAGE }]">
  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
  16. :class="[
  17. 'icon',
  18. MENU_ICONS[menu.url]
  19. ? `icon-${MENU_ICONS[menu.url]}`
  20. : 'icon-workspace'
  21. ]"
  22. ></i> -->
  23. <span>{{ menu.name }}</span>
  24. </li>
  25. </ul>
  26. </div>
  27. <div class="head-user menu-list">
  28. <ul>
  29. <li v-if="schoolName" @click="toSelectSchool" title="切换学校">
  30. <i class="el-icon-s-home"></i>
  31. <span>{{ schoolName }}</span>
  32. </li>
  33. <li class="menu-item menu-item-account" @click="toResetPwd">
  34. <i class="icon icon-account"></i>
  35. <span :title="username">{{ username }}</span>
  36. </li>
  37. <li class="menu-item" @click="toLogout">
  38. <i class="icon icon-logout" title="退出登录"></i>
  39. </li>
  40. </ul>
  41. </div>
  42. </div>
  43. <div class="home-navs">
  44. <div class="head-logo">
  45. <div class="head-logo-content" @click="toHomePage">
  46. <img v-if="schoolLogo" :src="schoolLogo" alt="知学知考" />
  47. <h1 v-else>知学知考</h1>
  48. </div>
  49. </div>
  50. <el-menu
  51. v-if="curMenu.children && curMenu.children.length"
  52. class="el-menu-home"
  53. active-text-color="#3a5ae5"
  54. text-color="#434656"
  55. router
  56. :default-active="curRouteName"
  57. :default-openeds="curSubMenuNames"
  58. >
  59. <template v-for="submenu in curMenu.children">
  60. <el-submenu
  61. v-if="submenu.children && submenu.children.length"
  62. :key="submenu.id"
  63. :index="submenu.url"
  64. >
  65. <span slot="title">{{ submenu.name }}</span>
  66. <el-menu-item
  67. v-for="nav in submenu.children"
  68. :key="nav.id"
  69. :index="nav.url"
  70. :route="{ name: nav.url }"
  71. >
  72. <span>{{ nav.name }}</span>
  73. <span
  74. class="nav-item-info"
  75. v-if="nav.url === 'WaitTask' && waitTaskCount"
  76. >{{ waitTaskCount }}</span
  77. >
  78. </el-menu-item>
  79. </el-submenu>
  80. <el-menu-item
  81. v-else
  82. :key="submenu.id"
  83. :index="submenu.url"
  84. :route="{ name: submenu.url }"
  85. >
  86. <span>{{ submenu.name }}</span>
  87. </el-menu-item>
  88. </template>
  89. </el-menu>
  90. </div>
  91. <div class="home-body">
  92. <div class="home-body-content">
  93. <div class="home-breadcrumb" v-if="breadcrumbs.length">
  94. <span class="breadcrumb-tips">
  95. <i class="icon icon-location"></i>
  96. <span>当前所在位置:</span>
  97. </span>
  98. <el-breadcrumb separator="/">
  99. <el-breadcrumb-item v-for="bread in breadcrumbs" :key="bread.url">{{
  100. bread.name
  101. }}</el-breadcrumb-item>
  102. </el-breadcrumb>
  103. </div>
  104. <!-- home-view: page detail -->
  105. <div class="home-view">
  106. <router-view />
  107. </div>
  108. </div>
  109. </div>
  110. <!-- 修改密码 -->
  111. <reset-pwd
  112. :user-info="userInfo"
  113. ref="ResetPwd"
  114. @modified="resetPwdModified"
  115. ></reset-pwd>
  116. </div>
  117. </template>
  118. <script>
  119. import { mapState, mapActions } from "vuex";
  120. import localMenus from "@/constants/menus-data";
  121. import { sysMenu, logout } from "../modules/login/api";
  122. import ResetPwd from "../modules/base/components/ResetPwd";
  123. import { SYS_ADMIN_NAME } from "@/constants/enumerate";
  124. const MENU_ICONS = {
  125. base: "base",
  126. exam: "exam",
  127. customer: "customer",
  128. stmms: "book"
  129. };
  130. export default {
  131. name: "home",
  132. components: { ResetPwd },
  133. data() {
  134. const user = this.$ls.get("user", { id: "", realName: "", roleList: [] });
  135. const IS_SUPER_ADMIN = user.loginName === SYS_ADMIN_NAME;
  136. return {
  137. MENU_ICONS,
  138. privileges: [],
  139. menus: [],
  140. curMenu: { url: "", children: [] },
  141. curRouteName: "",
  142. curSubMenuNames: [],
  143. breadcrumbs: [],
  144. validRoutes: [],
  145. username: user.realName,
  146. userRoles: user.roleList,
  147. schoolLogo: this.$ls.get("schoolLogo"),
  148. schoolName: this.$ls.get("schoolName"),
  149. userInfo: {
  150. pwdCount: 0,
  151. mobileNumber: 1,
  152. userId: user.id
  153. },
  154. IS_SUPER_ADMIN
  155. };
  156. },
  157. watch: {
  158. $route(val) {
  159. if (val.name === "Home") return;
  160. if (this.$route.name === "HomePage") {
  161. this.curMenu = { url: "", children: [] };
  162. return;
  163. }
  164. this.routerChange();
  165. }
  166. },
  167. computed: {
  168. ...mapState("exam", ["waitTaskCount"]),
  169. IS_HOME_PAGE() {
  170. return this.$route.name === "HomePage";
  171. }
  172. },
  173. created() {
  174. // this.initData1();
  175. this.initData();
  176. },
  177. methods: {
  178. ...mapActions("exam", ["updateWaitTaskCount"]),
  179. initData1() {
  180. // 开发阶段专用
  181. this.initPrivilegeMap(localMenus);
  182. this.privileges = this.transformMenu(localMenus);
  183. this.menus = this.getMenu();
  184. if (this.IS_HOME_PAGE) return;
  185. if (this.$route.name === "Home") {
  186. this.$router.replace({
  187. name: "HomePage"
  188. });
  189. return;
  190. }
  191. if (!this.validRoutes.includes(this.$route.name)) {
  192. this.$router.replace({
  193. name: "404"
  194. });
  195. return;
  196. }
  197. this.updateBreadcrumbs();
  198. const curMenu = this.menus.find(
  199. menu => menu.url === this.breadcrumbs[0].url
  200. );
  201. this.menuChange(curMenu);
  202. if (
  203. this.validRoutes.includes("WaitTask") &&
  204. this.curMenu.url === "exam"
  205. ) {
  206. this.updateWaitTaskCount();
  207. }
  208. },
  209. async initData() {
  210. const data = await sysMenu();
  211. this.initPrivilegeMap(data.privileges);
  212. this.privileges = this.transformMenu(data.privileges);
  213. this.menus = this.getMenu();
  214. if (this.IS_HOME_PAGE) return;
  215. if (this.$route.name === "Home") {
  216. this.$router.replace({
  217. name: "HomePage"
  218. });
  219. return;
  220. }
  221. if (!this.validRoutes.includes(this.$route.name)) {
  222. this.$router.replace({
  223. name: "404"
  224. });
  225. return;
  226. }
  227. this.updateBreadcrumbs();
  228. const curMenu = this.menus.find(
  229. menu => menu.url === this.breadcrumbs[0].url
  230. );
  231. this.menuChange(curMenu);
  232. if (
  233. this.validRoutes.includes("WaitTask") &&
  234. this.curMenu.url === "exam"
  235. ) {
  236. this.updateWaitTaskCount();
  237. }
  238. },
  239. transformMenu(list) {
  240. return list.map(item => {
  241. return {
  242. id: item.id,
  243. parentId: item.parentId,
  244. name: item.name,
  245. type: item.type,
  246. url: item.url
  247. };
  248. });
  249. },
  250. getMenu() {
  251. const getChildren = id => {
  252. return this.privileges
  253. .filter(item => item.parentId === id)
  254. .map(item => {
  255. return { ...item };
  256. });
  257. };
  258. let menus = getChildren("-1");
  259. let validRoutes = [];
  260. const toTree = menus => {
  261. menus.forEach(menu => {
  262. const children = getChildren(menu.id);
  263. if (children.length) {
  264. menu.children = children;
  265. toTree(menu.children);
  266. } else {
  267. validRoutes.push(menu.url);
  268. }
  269. });
  270. };
  271. toTree(menus);
  272. this.validRoutes = validRoutes;
  273. // console.log(JSON.stringify(menus));
  274. return menus;
  275. },
  276. getCurMenuFirstRouter() {
  277. let firstRouteName = "";
  278. let menu = this.curMenu;
  279. while (menu) {
  280. firstRouteName = menu.url;
  281. menu = menu.children && menu.children[0];
  282. }
  283. return firstRouteName;
  284. },
  285. initPrivilegeMap(data) {
  286. let privilegeMap = {};
  287. const pageSetTypes = ["conditions", "buttons", "lists", "links"];
  288. data.forEach(item => {
  289. // const isPage = [...pageSetTypes, "urls"].some(
  290. // type => item[type] && item[type].length
  291. // );
  292. // if (!isPage) return;
  293. privilegeMap[item.url] = [];
  294. pageSetTypes.forEach((type, index) => {
  295. if (item[type] && item[type].length) {
  296. item[type].forEach(elem => {
  297. privilegeMap[item.url].push(
  298. `${elem.type}_${elem.url}`.toLowerCase()
  299. );
  300. });
  301. }
  302. });
  303. });
  304. this.$store.commit("setPrivilegeMap", privilegeMap);
  305. this.$ls.set("privilegeMap", privilegeMap);
  306. },
  307. menuChange(menu) {
  308. this.curMenu = menu;
  309. this.curSubMenuNames = this.privileges
  310. .filter(item => item.parentId === menu.id)
  311. .map(item => item.url);
  312. },
  313. toMenu(menu) {
  314. if (this.curMenu.url === menu.url) return;
  315. this.menuChange(menu);
  316. const firstRouteName = this.getCurMenuFirstRouter();
  317. this.$router.replace({
  318. name: firstRouteName
  319. });
  320. },
  321. updateBreadcrumbs() {
  322. this.curRouteName = this.$route.name;
  323. let breadcrumbs = [];
  324. let curBreadcrumb = this.privileges.find(
  325. item => item.url === this.curRouteName
  326. );
  327. breadcrumbs.push({ ...curBreadcrumb });
  328. while (curBreadcrumb && curBreadcrumb.parentId !== "-1") {
  329. curBreadcrumb = this.privileges.find(
  330. item => item.id === curBreadcrumb.parentId
  331. );
  332. if (curBreadcrumb) breadcrumbs.unshift({ ...curBreadcrumb });
  333. }
  334. this.breadcrumbs = breadcrumbs;
  335. },
  336. routerChange() {
  337. this.updateBreadcrumbs();
  338. if (!this.curMenu.url) {
  339. // 从HomePage快捷菜单跳转过来的
  340. const curMenu = this.menus.find(
  341. menu => menu.url === this.breadcrumbs[0].url
  342. );
  343. this.menuChange(curMenu);
  344. }
  345. if (
  346. this.validRoutes.includes("WaitTask") &&
  347. this.curMenu.url === "exam"
  348. ) {
  349. this.updateWaitTaskCount();
  350. }
  351. },
  352. toLogout() {
  353. this.$confirm("确定要退出登录吗?", "提示", {
  354. type: "warning"
  355. })
  356. .then(() => {
  357. this.logoutAction();
  358. })
  359. .catch(() => {});
  360. },
  361. async logoutAction() {
  362. await logout();
  363. this.$ls.clear();
  364. this.$router.push({ name: "Login" });
  365. },
  366. toHomePage() {
  367. this.$router.push({ name: "HomePage" });
  368. },
  369. toSelectSchool() {
  370. if (this.IS_SUPER_ADMIN) this.$router.push({ name: "SelectSchool" });
  371. },
  372. toResetPwd() {
  373. if (this.IS_SUPER_ADMIN) return;
  374. this.$refs.ResetPwd.open();
  375. },
  376. resetPwdModified() {
  377. this.logoutAction();
  378. },
  379. // other
  380. getSubMenus(menu) {
  381. return this.privileges.filter(
  382. m => m.parentId === menu.id && m.type === "MENU"
  383. );
  384. },
  385. getFirstRouter() {
  386. let childNavs = this.privileges;
  387. let firstRouteName = "";
  388. while (childNavs.length) {
  389. firstRouteName = childNavs[0].url;
  390. childNavs = this.privileges.filter(
  391. item => item.parentId === childNavs[0].id
  392. );
  393. }
  394. return firstRouteName;
  395. }
  396. }
  397. };
  398. </script>