header-bar.vue 9.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455
  1. <template>
  2. <div id="main" class="header-bar">
  3. <header>
  4. <ul class="nav">
  5. <div class="logo">ByteSailing</div>
  6. <li class="header-bar-hover-warp nav-li">
  7. <div
  8. @click="isChildMenu = !isChildMenu"
  9. class="menu-modal"
  10. >
  11. 功能导览
  12. </div>
  13. </li>
  14. <li class="nav-li active" v-for="i in barData" :key="i.id">
  15. <span>{{ i.name }}</span>
  16. </li>
  17. <div
  18. class="header-bar-warp"
  19. v-if="isChildMenu"
  20. @click.stop="isChildMenu = false"
  21. >
  22. <div class="header-bar-hover" @click.stop>
  23. <div class="header-bar-hover-content">
  24. <div class="left-banner">
  25. <div class="first-order">
  26. <el-icon size="16" color="#0084FF">
  27. <edit />
  28. </el-icon>
  29. 常用功能
  30. </div>
  31. <div class="first-order">
  32. <el-icon size="16" color="#0084FF">
  33. <edit />
  34. </el-icon>
  35. 功能菜单
  36. </div>
  37. <ul>
  38. <li>外贸ERP</li>
  39. <li>云仓</li>
  40. <li>办公OA</li>
  41. <li>供应链</li>
  42. <li>产品库</li>
  43. </ul>
  44. <!-- <div class="first-order">
  45. <el-icon size="16" color="#0084FF">
  46. <edit />
  47. </el-icon>
  48. 推荐服务
  49. </div> -->
  50. </div>
  51. <div class="menu-warp">
  52. <div class="first-order-title">外贸ERP</div>
  53. <ul class="second-level">
  54. <div
  55. v-for="(i, index) in sidebarRouters"
  56. :key="index"
  57. >
  58. <li
  59. v-if="i.isNone"
  60. class="menu-ul"
  61. style="cursor: auto"
  62. ></li>
  63. <li
  64. class="menu-title"
  65. v-else-if="i.isTitle"
  66. >
  67. <i :class="'iconfont icon-' + i.meta.icon" style="position: relative;top: -1px;"></i>
  68. {{ i.meta.title }}
  69. </li>
  70. <li
  71. v-else
  72. class="menu-ul"
  73. @click="routerPush(i)"
  74. style="cursor: pointer"
  75. >
  76. {{ i.meta.title }}
  77. </li>
  78. </div>
  79. </ul>
  80. </div>
  81. </div>
  82. </div>
  83. </div>
  84. </ul>
  85. <div class="fr">
  86. <!-- <el-input
  87. class="input-search"
  88. placeholder="请输入关键词"
  89. suffix-icon="el-icon-search"
  90. size="mini"
  91. v-model="input1">
  92. </el-input>
  93. <el-dropdown class="dropdown-box">
  94. <span class="el-dropdown-link">
  95. 中文<i class="el-icon-arrow-down el-icon--right"></i>
  96. </span>
  97. <el-dropdown-menu slot="dropdown">
  98. <el-dropdown-item>English</el-dropdown-item>
  99. <el-dropdown-item>中文</el-dropdown-item>
  100. </el-dropdown-menu>
  101. </el-dropdown> -->
  102. <el-badge :value="12" class="badge">
  103. <el-icon :size="20">
  104. <BellFilled />
  105. </el-icon>
  106. </el-badge>
  107. <el-dropdown
  108. @command="handleCommand"
  109. class="right-menu-item hover-effect"
  110. trigger="click"
  111. >
  112. <div class="dropdown-box">
  113. {{ userData }}
  114. </div>
  115. <template #dropdown>
  116. <el-dropdown-menu>
  117. <router-link to="/user/profile">
  118. <el-dropdown-item>个人中心</el-dropdown-item>
  119. </router-link>
  120. <el-dropdown-item command="setLayout">
  121. <span>布局设置</span>
  122. </el-dropdown-item>
  123. <el-dropdown-item divided command="logout">
  124. <span>退出登录</span>
  125. </el-dropdown-item>
  126. </el-dropdown-menu>
  127. </template>
  128. </el-dropdown>
  129. </div>
  130. </header>
  131. </div>
  132. </template>
  133. <script setup>
  134. import Cookies from 'js-cookie'
  135. import { ElMessageBox, ElNotification } from 'element-plus'
  136. import useUserStore from '@/store/modules/user'
  137. import usePermissionStore from '@/store/modules/permission'
  138. const router = useRouter()
  139. const userStore = useUserStore()
  140. const permissionStore = usePermissionStore()
  141. const { proxy } = getCurrentInstance()
  142. const sidebarRouters = ref([])
  143. const input1 = ref('')
  144. const isChildMenu = ref(false)
  145. const menuData = ref([])
  146. const barData = ref([
  147. {name:'首页1',id:1},
  148. {name:'首页2',id:2},
  149. {name:'首页3',id:3},
  150. {name:'首页4',id:4},
  151. ])
  152. const userData = ref(Cookies.get('username') || '')
  153. const routerInit = () => {
  154. //二维转一维
  155. const arr = []
  156. for (let i = 0; i < permissionStore.addRoutes.length; i++) {
  157. const element = permissionStore.addRoutes[i]
  158. if (element.type === 1) {
  159. element.isTitle = true
  160. arr.push(element)
  161. }
  162. if (element.children && element.children.length > 0) {
  163. for (let j = 0; j < element.children.length; j++) {
  164. const jelement = element.children[j]
  165. jelement.isTitle = false
  166. if (jelement.type === 1) {
  167. arr.push({ ...jelement, fatherPath: element.path })
  168. }
  169. }
  170. }
  171. }
  172. //添加剩余子元素,补齐一列
  173. for (let i = 0; i < arr.length; i++) {
  174. const element = arr[i]
  175. if (element.isTitle) {
  176. //判断余数加上子项列会不会爆掉
  177. if (
  178. element.children &&
  179. element.children.length > 0 &&
  180. ((i) % 11) + element.children.length + 1 > 11 &&
  181. element.children.length < 11
  182. ) {
  183. let num = 11 - ((i) % 11)
  184. for (let j = 0; j < num; j++) {
  185. arr.splice(i, 0, { ...element, isNone: true })
  186. i++
  187. }
  188. }
  189. }
  190. }
  191. sidebarRouters.value = arr
  192. }
  193. function handleCommand(command) {
  194. switch (command) {
  195. case 'setLayout':
  196. setLayout()
  197. break
  198. case 'logout':
  199. logout()
  200. break
  201. default:
  202. break
  203. }
  204. }
  205. function logout() {
  206. ElMessageBox.confirm('确定注销并退出系统吗?', '提示', {
  207. confirmButtonText: '确定',
  208. cancelButtonText: '取消',
  209. type: 'warning',
  210. })
  211. .then(() => {
  212. userStore.logOut().then(() => {
  213. location.href = '/index'
  214. })
  215. })
  216. .catch(() => {})
  217. }
  218. //拼接url跳转
  219. function routerPush(i) {
  220. router.push(i.fatherPath + '/' + i.path)
  221. isChildMenu.value = false
  222. }
  223. onMounted(() => {
  224. routerInit()
  225. proxy.get('/getInfo').then(res=>{
  226. userData.value = res.user.userName
  227. })
  228. })
  229. </script>
  230. <style lang="scss">
  231. .header-bar-warp {
  232. position: fixed;
  233. top: 50px;
  234. left: 0;
  235. right: 0;
  236. bottom: 0;
  237. background: rgba(0, 0, 0, 0.5);
  238. z-index: 1100;
  239. }
  240. .header-bar {
  241. background: #20222a;
  242. position: fixed;
  243. top: 0;
  244. left: 0;
  245. right: 0;
  246. z-index: 1100;
  247. ul,
  248. li {
  249. list-style: none;
  250. padding: 0;
  251. }
  252. .avatar-wrapper {
  253. margin-top: 10px;
  254. }
  255. .menu-modal {
  256. cursor: pointer;
  257. font-weight: 400;
  258. }
  259. .header-bar-hover {
  260. position: fixed;
  261. z-index: 205;
  262. top: 50px;
  263. left: 0px;
  264. right: 0;
  265. background: #fff;
  266. box-shadow: 0px 3px 10px 1px rgba(0, 0, 0, 0.1);
  267. height: 500px;
  268. .header-bar-hover-content {
  269. display: flex;
  270. text-align: left;
  271. .left-banner {
  272. width: 230px;
  273. ul {
  274. background: #f1f1f1;
  275. li {
  276. height: 50px;
  277. line-height: 50px;
  278. padding: 0 50px;
  279. font-size: 12px;
  280. cursor: pointer;
  281. }
  282. }
  283. .first-order {
  284. height: 50px;
  285. padding: 0 20px;
  286. line-height: 50px;
  287. font-size: 14px;
  288. font-weight: bold;
  289. background: #f9f9f9;
  290. cursor: pointer;
  291. i {
  292. position: relative;
  293. top: 3px;
  294. margin-right: 5px;
  295. }
  296. }
  297. }
  298. .el-alert {
  299. line-height: 20px;
  300. text-align: center;
  301. background: #dfecff;
  302. color: #666666;
  303. font-weight: 400;
  304. margin-bottom: 20px;
  305. i {
  306. color: #46a6ff;
  307. }
  308. }
  309. }
  310. .menu-warp {
  311. width: calc(100vw - 230px);
  312. background: #fff;
  313. overflow: hidden;
  314. box-sizing: border-box;
  315. padding: 0 40px;
  316. height: 500px;
  317. overflow-y: auto;
  318. .first-order-title {
  319. height: 70px;
  320. line-height: 70px;
  321. color: #333333;
  322. font-size: 15px;
  323. font-weight: bold;
  324. }
  325. .second-level {
  326. overflow: hidden;
  327. height: 420px;
  328. display: flex;
  329. flex-wrap: wrap;
  330. flex-direction: column;
  331. flex-grow: 0;
  332. flex-basis: auto;
  333. }
  334. .menu-title {
  335. font-weight: 600;
  336. color: #0084ff;
  337. height: 40px;
  338. line-height: 40px;
  339. border-bottom: 1px solid #ddd;
  340. font-size: 14px;
  341. width: 140px;
  342. margin: 0 100px 0 0;
  343. i {
  344. position: relative;
  345. top: 3px;
  346. margin-right: 5px;
  347. }
  348. }
  349. .menu-ul {
  350. float: left;
  351. width: 140px;
  352. list-style: none;
  353. margin: 0 100px 0 0;
  354. padding: 0;
  355. height: 36px;
  356. line-height: 36px;
  357. font-size: 12px;
  358. font-weight: 400;
  359. cursor: pointer;
  360. }
  361. .menu-ul:hover {
  362. color: #0084ff;
  363. }
  364. }
  365. }
  366. .nav {
  367. display: flex;
  368. padding: 0;
  369. margin: 0;
  370. height: 50px;
  371. overflow: hidden;
  372. .logo {
  373. color: #fff;
  374. font-size: 20px;
  375. font-weight: bold;
  376. line-height: 50px;
  377. margin: 0 20px;
  378. }
  379. .nav-li {
  380. width: 130px;
  381. height: 50px;
  382. font-size: 14px;
  383. font-weight: 400;
  384. text-align: center;
  385. line-height: 50px;
  386. list-style: none;
  387. color: #fff;
  388. cursor: pointer;
  389. a {
  390. color: #fff;
  391. }
  392. }
  393. .nav-li.active {
  394. background: #0084ff;
  395. color: #fff;
  396. a {
  397. color: #fff;
  398. }
  399. }
  400. }
  401. header {
  402. z-index: 11205;
  403. left: 0;
  404. right: 0;
  405. top: 0;
  406. height: 50px;
  407. display: flex;
  408. justify-content: space-between;
  409. .fr {
  410. display: flex;
  411. .input-search {
  412. margin: 12px 40px 12px 0;
  413. width: 240px;
  414. input {
  415. height: 30px;
  416. }
  417. }
  418. .dropdown-box {
  419. margin: 0 24px 0 0px;
  420. line-height: 50px;
  421. cursor: pointer;
  422. }
  423. .badge {
  424. margin: 15px 24px 15px 0;
  425. height: 20px;
  426. width: 20px;
  427. i {
  428. color: #bbbbbb;
  429. }
  430. }
  431. .user-img {
  432. margin: 12px 12px 12px 0;
  433. }
  434. }
  435. }
  436. }
  437. header > a {
  438. margin: 0 20px;
  439. }
  440. </style>