header-bar.vue 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405
  1. <template>
  2. <div id="main" class="header-bar">
  3. <header>
  4. <ul class="nav">
  5. <!-- <div class="logo">ByteSailing</div> -->
  6. <div class="logo" style="display: flex; align-items: center; justify-content: center">
  7. <img v-if="!logoUrl" :src="'/img/logo2.png'"/>
  8. <el-image v-else style="width: 120px; height: 30px" :src="logoUrl" fit="scale-down"/>
  9. </div>
  10. <li class="header-bar-hover-warp nav-li" :class="isChildMenu ? 'active' : ''">
  11. <div @click="isChildMenu = !isChildMenu" class="menu-modal">
  12. <i class="iconfont icon-icomx_gongndh" style="margin: 0 5px 0 0;"></i>
  13. 功能导览
  14. <i class="iconfont icon-iconm_xialan1" style="margin: 0 0 0 3px;"></i>
  15. </div>
  16. </li>
  17. <div class="auto-list">
  18. <li
  19. class="nav-li"
  20. @click="commonsBannerToRouter(i)"
  21. v-for="(i, index) in commonsRouterList"
  22. v-show="index < autoListChidrenNum - 1" :key="i.id">
  23. <span>{{ i.menuName }}</span>
  24. </li>
  25. <li class="nav-li more-box" v-show="commonsRouterList.length > autoListChidrenNum - 1">
  26. 更多
  27. <i class="iconfont icon-iconm_xialan1"></i>
  28. <ul class="more-list">
  29. <li v-for="(i, index) in commonsRouterList" v-show="index >= autoListChidrenNum - 1" :key="i.id">
  30. <span @click="commonsBannerToRouter(i)">{{ i.menuName }}</span>
  31. </li>
  32. </ul>
  33. </li>
  34. </div>
  35. <div class="header-bar-warp" v-if="isChildMenu" @click.stop="isChildMenu = false">
  36. <div class="header-bar-hover" @click.stop>
  37. <div class="header-bar-hover-content">
  38. <div class="left-banner">
  39. <div class="first-order" @click="leftBanerType = 2">
  40. <el-icon size="16" color="#0084FF">
  41. <edit />
  42. </el-icon>
  43. 常用功能
  44. </div>
  45. <div class="first-order">
  46. <el-icon size="16" color="#0084FF">
  47. <edit />
  48. </el-icon>
  49. 功能菜单
  50. </div>
  51. <ul>
  52. <li @click="openLeftBaner(i,index)" v-for="(i,index) in sidebarRoutersCopy" :key="i.name"
  53. v-show="i.type == 1 && i.status == '0'">{{ i.menuName
  54. }}</li>
  55. </ul>
  56. <!-- <div class="first-order">
  57. <el-icon size="16" color="#0084FF">
  58. <edit />
  59. </el-icon>
  60. 推荐服务
  61. </div> -->
  62. </div>
  63. <div class="menu-warp" v-show="leftBanerType == 1">
  64. <div class="first-order-title">{{ activeLeftData.menuName }}</div>
  65. <!-- <ul class="second-level" v-for="i in activeLeftData.children" :key="i.menuId">
  66. <li class="menu-title">
  67. {{ i.menuName }}
  68. </li>
  69. <div v-for="(j, index) in i.children" :key="index">
  70. <li v-if="i.isNone" class="menu-ul" style="cursor: auto"></li>
  71. <li class="menu-ul" @click="routerPush(i,j)" style="cursor: pointer">
  72. {{ j.menuName }}
  73. </li>
  74. </div>
  75. </ul> -->
  76. <ul class="second-level">
  77. <div v-for="(i, index) in activeLeftData" :key="index">
  78. <li v-if="i.isNone" class="menu-ul" style="cursor: auto"></li>
  79. <li class="menu-title" v-else-if="i.isTitle">
  80. {{ i.menuName }}
  81. </li>
  82. <li v-else class="menu-ul" @click="commonsBannerToRouter(i)" style="cursor: pointer">
  83. {{ i.menuName }}
  84. </li>
  85. </div>
  86. </ul>
  87. </div>
  88. <div class="menu-warp" v-show="leftBanerType == 2">
  89. <div class="first-order-title">常用功能</div>
  90. <div class="commons-warp">
  91. <div>
  92. <div class="header-button-box cp" v-for="(i,index) in commonsRouterList" :key="i.name" @click="commonsBannerToRouter(i)">
  93. <span>{{ i.menuName }}</span>
  94. <div class="right-icon" @click.stop="deleteCommonsRouter(i,index)">
  95. <!-- <el-icon color="#46A6FF"><CirclePlus /></el-icon> -->
  96. <el-icon color="#BBBBBB" v-show="isEidtType">
  97. <Close />
  98. </el-icon>
  99. </div>
  100. </div>
  101. <div class="header-add-button-box" v-if="!isEidtType" @click="isEidtType = true">
  102. <el-icon color="#46A6FF">
  103. <CirclePlus />
  104. </el-icon>
  105. 编辑功能
  106. </div>
  107. </div>
  108. </div>
  109. <div class="first-order-title" v-if="isEidtType">待添加功能</div>
  110. <div class="all-menu-warp" v-if="isEidtType">
  111. <div v-for="(i, index) in sidebarRoutersCopy" :key="i.name" v-show="i.type === 1">
  112. <div class="all-menu-title" v-for="(j, jindex) in i.children" :key="j.name">
  113. <div class="title">
  114. {{ j.menuName }}
  115. </div>
  116. <div class="all-menu-lists">
  117. <div class="header-button-box" v-for="(n, nindex) in j.children"
  118. v-show="n.visible == '0'"
  119. :key="n.name">
  120. <span>{{ n.menuName }}</span>
  121. <div class="right-icon"
  122. @click="addCommonsRouter(index, jindex, nindex, n)">
  123. <el-icon color="#46A6FF">
  124. <CirclePlus />
  125. </el-icon>
  126. </div>
  127. </div>
  128. </div>
  129. </div>
  130. </div>
  131. </div>
  132. <div class="btn-warp" v-if="isEidtType">
  133. <el-button type="" @click="isEidtType = false">取消</el-button>
  134. <el-button type="primary" @click="userMenuEdit">保存</el-button>
  135. </div>
  136. </div>
  137. </div>
  138. </div>
  139. </div>
  140. </ul>
  141. <div class="fr">
  142. <!-- <el-input
  143. class="input-search"
  144. placeholder="请输入关键词"
  145. suffix-icon="el-icon-search"
  146. size="mini"
  147. v-model="input1">
  148. </el-input>
  149. <el-dropdown class="dropdown-box">
  150. <span class="el-dropdown-link">
  151. 中文<i class="el-icon-arrow-down el-icon--right"></i>
  152. </span>
  153. <el-dropdown-menu slot="dropdown">
  154. <el-dropdown-item>English</el-dropdown-item>
  155. <el-dropdown-item>中文</el-dropdown-item>
  156. </el-dropdown-menu>
  157. </el-dropdown> -->
  158. <el-badge :value="12" class="badge">
  159. <el-icon :size="20">
  160. <BellFilled />
  161. </el-icon>
  162. </el-badge>
  163. <el-dropdown @command="handleCommand" class="right-menu-item hover-effect" trigger="click">
  164. <div class="dropdown-box">
  165. {{ userData }}
  166. </div>
  167. <template #dropdown>
  168. <el-dropdown-menu>
  169. <router-link to="/user/profile">
  170. <el-dropdown-item>个人中心</el-dropdown-item>
  171. </router-link>
  172. <el-dropdown-item command="setLayout">
  173. <span>布局设置</span>
  174. </el-dropdown-item>
  175. <el-dropdown-item divided command="logout">
  176. <span>退出登录</span>
  177. </el-dropdown-item>
  178. </el-dropdown-menu>
  179. </template>
  180. </el-dropdown>
  181. </div>
  182. </header>
  183. </div>
  184. </template>
  185. <script setup>
  186. import Cookies from 'js-cookie'
  187. import { ElMessageBox, ElNotification, ElMessage } from 'element-plus'
  188. import useUserStore from '@/store/modules/user'
  189. import '@/components/headerBar/header.scss'
  190. const router = useRouter()
  191. const userStore = useUserStore()
  192. const { proxy } = getCurrentInstance()
  193. const sidebarRouters = ref([])
  194. const sidebarRoutersCopy = ref([])
  195. const isChildMenu = ref(false)
  196. const autoListChidrenNum = ref(0)
  197. const isEidtType = ref(false)
  198. const leftBanerType = ref(2)
  199. const userData = ref(Cookies.get('nickName') || '')
  200. const commonsRouterList = ref([])
  201. const activeLeftData = ref({})
  202. const openLeftBaner = (i,index) => {
  203. leftBanerType.value = 1
  204. activeLeftData.value = i
  205. routerInit(i)
  206. }
  207. const logoUrl = ref()
  208. const getLogo = () => {
  209. proxy.post('/tenantInfo/getLogo',{}).then(
  210. res => {
  211. if (res && res.length > 0 && res[0].fileUrl) {
  212. logoUrl.value = res[0].fileUrl
  213. }
  214. }
  215. )
  216. }
  217. getLogo()
  218. const userMenuEdit = () => {
  219. proxy.post('/sysUserMenu/edit',{
  220. type:1,
  221. menuIdList:commonsRouterList.value.map(item=>item.menuId)
  222. }).then(res=>{
  223. ElMessage({
  224. message: '保存成功',
  225. type: 'success',
  226. })
  227. isEidtType.value = false
  228. })
  229. }
  230. const deleteCommonsRouter = (i,index) => {
  231. commonsRouterList.value.splice(index, 1)
  232. }
  233. const addCommonsRouter = (index, jindex, nindex, n) => {
  234. for (let i = 0; i < commonsRouterList.value.length; i++) {
  235. const element = commonsRouterList.value[i];
  236. if(element.menuId === n.menuId){
  237. ElMessage({
  238. message: '此目录已添加',
  239. type: 'error',
  240. })
  241. return
  242. }
  243. }
  244. if (n.hidden) {
  245. ElMessage({
  246. message: '此目录需要额外参数,暂不支持添加',
  247. type: 'error',
  248. })
  249. return
  250. }
  251. commonsRouterList.value.push(n)
  252. sidebarRoutersCopy.value[index].children[jindex].children[nindex].isCommonsBanner = true
  253. }
  254. const routerInit = (item) => {
  255. //二维转一维
  256. const arr = []
  257. for (let i = 0; i < item.children.length; i++) {
  258. const element = item.children[i]
  259. if (element.type === 1) {
  260. element.isTitle = true
  261. arr.push(element)
  262. }
  263. if (element.children && element.children.length > 0) {
  264. for (let j = 0; j < element.children.length; j++) {
  265. const jelement = element.children[j]
  266. jelement.isTitle = false
  267. if (jelement.type === 1) {
  268. arr.push({ ...jelement, fatherPath: element.path })
  269. }
  270. }
  271. }
  272. }
  273. //添加剩余子元素,补齐一列
  274. for (let i = 0; i < arr.length; i++) {
  275. const element = arr[i]
  276. if (element.isTitle) {
  277. //判断余数加上子项列会不会爆掉
  278. if (
  279. element.children &&
  280. element.children.length > 0 &&
  281. ((i) % 11) + element.children.length + 1 > 11 &&
  282. element.children.length < 11
  283. ) {
  284. let num = 11 - ((i) % 11)
  285. for (let j = 0; j < num; j++) {
  286. arr.splice(i, 0, { ...element, isNone: true })
  287. i++
  288. }
  289. }
  290. }
  291. }
  292. activeLeftData.value = arr
  293. }
  294. function handleCommand(command) {
  295. switch (command) {
  296. case 'setLayout':
  297. setLayout()
  298. break
  299. case 'logout':
  300. logout()
  301. break
  302. default:
  303. break
  304. }
  305. }
  306. function logout() {
  307. ElMessageBox.confirm('确定注销并退出系统吗?', '提示', {
  308. confirmButtonText: '确定',
  309. cancelButtonText: '取消',
  310. type: 'warning',
  311. })
  312. .then(() => {
  313. userStore.logOut().then(() => {
  314. location.href = '/index'
  315. })
  316. })
  317. .catch(() => { })
  318. }
  319. //使用id计算拼接url
  320. const commonsBannerToRouter = (i) => {
  321. sidebarRoutersCopy.value.map(item => {
  322. if(item.children) {
  323. item.children.map(j => {
  324. if(j.children){
  325. j.children.map(n => {
  326. if(n.menuId === i.menuId){
  327. router.push('/' + item.path + '/' + j.path + '/' + n.path)
  328. isChildMenu.value = false
  329. }
  330. })
  331. }
  332. })
  333. }
  334. })
  335. }
  336. //获取浏览器宽度
  337. function getBrowserWidth() {
  338. return document.documentElement.clientWidth
  339. }
  340. //计算auto-list 能放下几个
  341. function calcAutoListChidren() {
  342. autoListChidrenNum.value = Math.floor((getBrowserWidth() - 390) / 120)
  343. }
  344. //一维数组转tree
  345. onMounted(() => {
  346. calcAutoListChidren()
  347. window.addEventListener('resize', calcAutoListChidren);
  348. proxy.get('/getInfo').then(res => {
  349. userData.value = res.user.nickName
  350. })
  351. proxy.get('/system/menu/list').then(res => {
  352. res.data = res.data.map(item => {
  353. return {
  354. ...item,
  355. isCommonsBanner: false,
  356. }
  357. })
  358. sidebarRoutersCopy.value = proxy.handleTree(res.data, "menuId")
  359. //循环删除 i.status != 0 || i.visible != 0 的元素
  360. sidebarRoutersCopy.value.map(item => {
  361. if(item.children) {
  362. item.children.map(j => {
  363. if(j.children){
  364. j.children.map(n => {
  365. if(n.status != 0 || n.visible != 0 || n.type != 1){
  366. j.children.splice(j.children.indexOf(n),1)
  367. }
  368. })
  369. }
  370. })
  371. }
  372. })
  373. })
  374. proxy.post('/sysUserMenu/list',{type:1}).then(res => {
  375. commonsRouterList.value = res
  376. })
  377. })
  378. </script>
  379. <style lang="scss"></style>