header-bar.vue 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506
  1. <template>
  2. <div id="main" class="header-bar" @click="isChildMenu = false">
  3. <header>
  4. <ul class="nav">
  5. <!-- <div class="logo">尔泓时代</div> -->
  6. <div
  7. class="logo"
  8. style="display: flex; align-items: center; justify-content: center"
  9. >
  10. <img v-if="!logoUrl" :src="'/img/logo2.png'" />
  11. <el-image
  12. v-else
  13. style="width: 120px; height: 30px"
  14. :src="logoUrl"
  15. fit="scale-down"
  16. />
  17. </div>
  18. <li
  19. class="header-bar-hover-warp nav-li"
  20. :class="isChildMenu ? 'active' : ''"
  21. >
  22. <div @click.stop="isChildMenu = !isChildMenu" class="menu-modal">
  23. <i
  24. class="iconfont icon-icomx_gongndh"
  25. style="margin: 0 5px 0 0"
  26. ></i>
  27. {{ $t("header.functionGuide") }}
  28. <i
  29. class="iconfont icon-iconm_xialan1"
  30. style="margin: 0 0 0 3px"
  31. ></i>
  32. </div>
  33. </li>
  34. <div class="auto-list">
  35. <li
  36. class="nav-li"
  37. @click="commonsBannerToRouter(i)"
  38. v-for="(i, index) in commonsRouterList"
  39. v-show="index < autoListChidrenNum - 1"
  40. :key="i.id"
  41. >
  42. <span>{{ i.menuName }}</span>
  43. </li>
  44. <li
  45. class="nav-li more-box"
  46. v-show="commonsRouterList.length > autoListChidrenNum - 1"
  47. >
  48. {{ $t("header.more") }}
  49. <i class="iconfont icon-iconm_xialan1"></i>
  50. <ul class="more-list">
  51. <li
  52. v-for="(i, index) in commonsRouterList"
  53. v-show="index >= autoListChidrenNum - 1"
  54. :key="i.id"
  55. >
  56. <span @click="commonsBannerToRouter(i)">{{ i.menuName }}</span>
  57. </li>
  58. </ul>
  59. </li>
  60. </div>
  61. <div
  62. class="header-bar-warp"
  63. v-if="isChildMenu"
  64. @click.stop="isChildMenu = false"
  65. >
  66. <div class="header-bar-hover" @click.stop>
  67. <div class="header-bar-hover-content">
  68. <div class="left-banner">
  69. <!-- :style="leftBanerType == 2 ? 'color:#0084ff' : ''" -->
  70. <div class="first-order" @click="leftBanerType = 2">
  71. <i
  72. class="iconfont icon-iconm_changycd"
  73. style="position: relative; top: -1px"
  74. ></i>
  75. {{ $t("header.commonFunctions") }}
  76. </div>
  77. <div class="first-order">
  78. <i
  79. class="iconfont icon-iconm_gongncd"
  80. style="position: relative; top: -1px"
  81. ></i>
  82. {{ $t("header.functionMenu") }}
  83. </div>
  84. <ul>
  85. <li
  86. :class="menuName == i.menuName ? 'active' : ''"
  87. @click="openLeftBaner(i, index)"
  88. v-for="(i, index) in sidebarRoutersCopy"
  89. :key="i.name"
  90. v-show="i.type == 1 && i.status == '0'"
  91. >
  92. <!-- <i
  93. :class="'iconfont icon-' + i.icon"
  94. style="position: relative; top: -1px"
  95. ></i> -->
  96. {{ i.menuName }}
  97. </li>
  98. </ul>
  99. <!-- <div class="first-order">
  100. <el-icon size="16" color="#0084FF">
  101. <edit />
  102. </el-icon>
  103. 推荐服务
  104. </div> -->
  105. </div>
  106. <div class="menu-warp" v-show="leftBanerType == 1">
  107. <div class="first-order-title">{{ menuName }}</div>
  108. <!-- <ul class="second-level" v-for="i in activeLeftData.children" :key="i.menuId">
  109. <li class="menu-title">
  110. {{ i.menuName }}
  111. </li>
  112. <div v-for="(j, index) in i.children" :key="index">
  113. <li v-if="i.isNone" class="menu-ul" style="cursor: auto"></li>
  114. <li class="menu-ul" @click="routerPush(i,j)" style="cursor: pointer">
  115. {{ j.menuName }}
  116. </li>
  117. </div>
  118. </ul> -->
  119. <ul class="second-level">
  120. <div v-for="(i, index) in activeLeftData" :key="index">
  121. <li
  122. v-if="i.isNone"
  123. class="menu-ul"
  124. style="cursor: auto"
  125. ></li>
  126. <li class="menu-title" v-else-if="i.isTitle">
  127. <a
  128. v-if="i.icon && i.icon !== '#'"
  129. :class="'iconfont icon-' + i.icon"
  130. style="margin-right: 4px"
  131. ></a
  132. ><span>{{ i.menuName }}</span>
  133. </li>
  134. <li
  135. v-else
  136. class="menu-ul"
  137. @click="commonsBannerToRouter(i)"
  138. style="cursor: pointer; display: flex"
  139. >
  140. <a
  141. :class="'iconfont icon-' + i.icon"
  142. style="
  143. margin-right: 4px;
  144. width: 20px;
  145. min-height: 20px;
  146. display: block;
  147. "
  148. ></a>
  149. <span>{{ i.menuName }}</span>
  150. </li>
  151. </div>
  152. </ul>
  153. </div>
  154. <div class="menu-warp" v-show="leftBanerType == 2">
  155. <div class="first-order-title">
  156. {{ $t("header.commonFunctions") }}
  157. </div>
  158. <div class="commons-warp">
  159. <div>
  160. <div
  161. class="header-button-box cp"
  162. v-for="(i, index) in commonsRouterList"
  163. :key="i.name"
  164. @click="commonsBannerToRouter(i)"
  165. >
  166. <span>{{ i.menuName }}</span>
  167. <div
  168. class="right-icon"
  169. @click.stop="deleteCommonsRouter(i, index)"
  170. >
  171. <!-- <el-icon color="#46A6FF"><CirclePlus /></el-icon> -->
  172. <el-icon color="#BBBBBB" v-show="isEidtType">
  173. <Close />
  174. </el-icon>
  175. </div>
  176. </div>
  177. <div
  178. class="header-add-button-box"
  179. v-if="!isEidtType"
  180. @click="isEidtType = true"
  181. >
  182. <el-icon color="#46A6FF">
  183. <CirclePlus />
  184. </el-icon>
  185. {{ $t("header.edit") }}
  186. </div>
  187. </div>
  188. </div>
  189. <div class="first-order-title" v-if="isEidtType">
  190. {{ $t("header.toAdd") }}
  191. </div>
  192. <div class="all-menu-warp" v-if="isEidtType">
  193. <div
  194. v-for="(i, index) in sidebarRoutersCopy"
  195. :key="i.name"
  196. v-show="i.type === 1"
  197. >
  198. <div
  199. class="all-menu-title"
  200. v-for="(j, jindex) in i.children"
  201. :key="j.name"
  202. >
  203. <div class="title">
  204. {{ j.menuName }}
  205. </div>
  206. <div class="all-menu-lists">
  207. <div
  208. class="header-button-box"
  209. v-for="(n, nindex) in j.children"
  210. v-show="n.visible == '0'"
  211. :key="n.name"
  212. >
  213. <span>{{ n.menuName }}</span>
  214. <div
  215. class="right-icon"
  216. @click="addCommonsRouter(index, jindex, nindex, n)"
  217. >
  218. <el-icon color="#46A6FF">
  219. <CirclePlus />
  220. </el-icon>
  221. </div>
  222. </div>
  223. </div>
  224. </div>
  225. </div>
  226. </div>
  227. <div class="btn-warp" v-if="isEidtType">
  228. <el-button type="" @click="isEidtType = false"
  229. >取消</el-button
  230. >
  231. <el-button type="primary" @click="userMenuEdit"
  232. >保存</el-button
  233. >
  234. </div>
  235. </div>
  236. </div>
  237. </div>
  238. </div>
  239. </ul>
  240. <div class="fr">
  241. <!-- :value="12" -->
  242. <el-badge
  243. :value="badgeNum"
  244. style="cursor: pointer"
  245. class="badge"
  246. @click="noticeTableModal = true"
  247. >
  248. <el-icon :size="20">
  249. <BellFilled />
  250. </el-icon>
  251. </el-badge>
  252. <notice
  253. v-model="noticeTableModal"
  254. @changeNum="(e) => (badgeNum = e)"
  255. ></notice>
  256. <el-dropdown
  257. @command="handleCommand"
  258. class="right-menu-item hover-effect"
  259. trigger="click"
  260. >
  261. <div class="dropdown-box">
  262. {{ userData }}
  263. </div>
  264. <template #dropdown>
  265. <el-dropdown-menu>
  266. <router-link to="/user/profile">
  267. <el-dropdown-item>{{
  268. $t("header.personalCenter")
  269. }}</el-dropdown-item>
  270. </router-link>
  271. <el-dropdown-item command="setLayout">
  272. <span>{{ $t("header.layoutSettings") }}</span>
  273. </el-dropdown-item>
  274. <el-dropdown-item divided command="logout">
  275. <span>{{ $t("header.logout") }}</span>
  276. </el-dropdown-item>
  277. </el-dropdown-menu>
  278. </template>
  279. </el-dropdown>
  280. </div>
  281. </header>
  282. </div>
  283. </template>
  284. <script setup>
  285. import Cookies from "js-cookie";
  286. import { ElMessageBox, ElNotification, ElMessage } from "element-plus";
  287. import useUserStore from "@/store/modules/user";
  288. import "@/components/headerBar/header.scss";
  289. import notice from "@/components/notice/index";
  290. const router = useRouter();
  291. const userStore = useUserStore();
  292. const { proxy } = getCurrentInstance();
  293. const sidebarRouters = ref([]);
  294. const sidebarRoutersCopy = ref([]);
  295. const isChildMenu = ref(false);
  296. const autoListChidrenNum = ref(0);
  297. const isEidtType = ref(false);
  298. const leftBanerType = ref(2);
  299. const noticeTableModal = ref(false);
  300. const userData = ref(Cookies.get("nickName") || "");
  301. const commonsRouterList = ref([]);
  302. const activeLeftData = ref({});
  303. const openLeftBaner = (i, index) => {
  304. leftBanerType.value = 1;
  305. activeLeftData.value = i;
  306. menuName.value = i.menuName;
  307. routerInit(i);
  308. };
  309. const badgeNum = ref(0);
  310. let menuName = ref("");
  311. const logoUrl = ref();
  312. const getLogo = () => {
  313. proxy.post("/tenantInfo/getLogo", {}).then((res) => {
  314. if (res && res.length > 0 && res[0].fileUrl) {
  315. logoUrl.value = res[0].fileUrl;
  316. }
  317. });
  318. };
  319. getLogo();
  320. const userMenuEdit = () => {
  321. proxy
  322. .post("/sysUserMenu/edit", {
  323. type: 1,
  324. menuIdList: commonsRouterList.value.map((item) => item.menuId),
  325. })
  326. .then((res) => {
  327. ElMessage({
  328. message: "保存成功",
  329. type: "success",
  330. });
  331. isEidtType.value = false;
  332. });
  333. };
  334. const deleteCommonsRouter = (i, index) => {
  335. commonsRouterList.value.splice(index, 1);
  336. };
  337. const addCommonsRouter = (index, jindex, nindex, n) => {
  338. for (let i = 0; i < commonsRouterList.value.length; i++) {
  339. const element = commonsRouterList.value[i];
  340. if (element.menuId === n.menuId) {
  341. ElMessage({
  342. message: proxy.t("header.thisDirectoryHasBeenAdded"),
  343. type: "error",
  344. });
  345. return;
  346. }
  347. }
  348. if (n.hidden) {
  349. ElMessage({
  350. message: proxy.t("header.thisDirectoryRequiresAdditionalParameters"),
  351. type: "error",
  352. });
  353. return;
  354. }
  355. commonsRouterList.value.push(n);
  356. sidebarRoutersCopy.value[index].children[jindex].children[
  357. nindex
  358. ].isCommonsBanner = true;
  359. };
  360. const routerInit = (item) => {
  361. //二维转一维
  362. const arr = [];
  363. for (let i = 0; i < item.children.length; i++) {
  364. const element = item.children[i];
  365. if (element.type === 1) {
  366. element.isTitle = true;
  367. arr.push(element);
  368. }
  369. if (element.children && element.children.length > 0) {
  370. for (let j = 0; j < element.children.length; j++) {
  371. const jelement = element.children[j];
  372. jelement.isTitle = false;
  373. if (jelement.type === 1) {
  374. arr.push({ ...jelement, fatherPath: element.path });
  375. }
  376. }
  377. }
  378. }
  379. //添加剩余子元素,补齐一列
  380. for (let i = 0; i < arr.length; i++) {
  381. const element = arr[i];
  382. if (element.isTitle) {
  383. //判断余数加上子项列会不会爆掉
  384. if (
  385. element.children &&
  386. element.children.length > 0 &&
  387. (i % 11) + element.children.length + 1 > 11 &&
  388. element.children.length < 11
  389. ) {
  390. let num = 11 - (i % 11);
  391. for (let j = 0; j < num; j++) {
  392. arr.splice(i, 0, { ...element, isNone: true });
  393. i++;
  394. }
  395. }
  396. }
  397. }
  398. activeLeftData.value = arr;
  399. };
  400. function handleCommand(command) {
  401. switch (command) {
  402. case "setLayout":
  403. setLayout();
  404. break;
  405. case "logout":
  406. logout();
  407. break;
  408. default:
  409. break;
  410. }
  411. }
  412. function logout() {
  413. ElMessageBox.confirm(
  414. proxy.t("header.areYouSureYouWantToLogOutAndExitTheSystem"),
  415. proxy.t("common.prompt"),
  416. {
  417. confirmButtonText: proxy.t("common.confirm"),
  418. cancelButtonText: proxy.t("common.cancel"),
  419. type: "warning",
  420. }
  421. )
  422. .then(() => {
  423. userStore.logOut().then(() => {
  424. location.href = "/index";
  425. });
  426. })
  427. .catch(() => {});
  428. }
  429. //使用id计算拼接url
  430. const commonsBannerToRouter = (i) => {
  431. sidebarRoutersCopy.value.map((item) => {
  432. if (item.children) {
  433. item.children.map((j) => {
  434. if (j.children) {
  435. j.children.map((n) => {
  436. if (n.menuId === i.menuId) {
  437. router.push("/" + item.path + "/" + j.path + "/" + n.path);
  438. isChildMenu.value = false;
  439. }
  440. });
  441. }
  442. });
  443. }
  444. });
  445. };
  446. //获取浏览器宽度
  447. function getBrowserWidth() {
  448. return document.documentElement.clientWidth;
  449. }
  450. //计算auto-list 能放下几个
  451. function calcAutoListChidren() {
  452. autoListChidrenNum.value = Math.floor((getBrowserWidth() - 616) / 120);
  453. }
  454. //一维数组转tree
  455. onMounted(() => {
  456. calcAutoListChidren();
  457. window.addEventListener("resize", calcAutoListChidren);
  458. proxy.get("/getInfo").then((res) => {
  459. userData.value = res.user.nickName;
  460. });
  461. proxy.get("/system/menu/list").then((res) => {
  462. res.data = res.data.map((item) => {
  463. return {
  464. ...item,
  465. isCommonsBanner: false,
  466. };
  467. });
  468. sidebarRoutersCopy.value = proxy.handleTree(res.data, "menuId");
  469. //循环删除 i.status != 0 || i.visible != 0 的元素
  470. sidebarRoutersCopy.value.map((item) => {
  471. if (item.children) {
  472. item.children.map((j) => {
  473. if (j.children) {
  474. j.children.map((n) => {
  475. if (n.status != 0 || n.visible != 0 || n.type != 1) {
  476. j.children.splice(j.children.indexOf(n), 1);
  477. }
  478. });
  479. }
  480. });
  481. }
  482. });
  483. });
  484. proxy.post("/sysUserMenu/list", { type: 1 }).then((res) => {
  485. commonsRouterList.value = res;
  486. });
  487. });
  488. </script>
  489. <style lang="scss"></style>