header-bar.vue 9.0 KB

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