TheMenu.vue 5.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205
  1. <script setup lang="jsx">
  2. import { h, watch, ref } from 'vue'
  3. import { useRoute, useRouter } from 'vue-router';
  4. import { NMenu, NScrollbar } from 'naive-ui'
  5. import SvgIcon from '@/components/SvgIcon/index.vue'
  6. import { useUserStore } from '@/stores/modules/userStore';
  7. let menuOptions = []
  8. const route = useRoute();
  9. const router = useRouter();
  10. const userStore = useUserStore();
  11. const activeMenuKey = ref(route.path);
  12. watch(() => route.path, currentPath => {
  13. activeMenuKey.value = currentPath;
  14. })
  15. function renderIcon(props) {
  16. return () => h(SvgIcon, { ...props })
  17. }
  18. function renderChildrenIcon({ name, size = '20' }) {
  19. return () => (
  20. <div class="flex items-center justify-center">
  21. {renderIcon({ name, size, class: ['icon-default'] })()}
  22. {renderIcon({ name: name + '-active', size, class: ['icon-active', 'hidden'] })()}
  23. </div>
  24. )
  25. }
  26. function renderLabel(val, url) {
  27. return url ? (<a href={url} target="_blank" class="pl-1">{val}</a>) : (<span class="">{val}</span>);
  28. }
  29. const updateMenOptions = () => {
  30. if (userStore.isCheckUser) {
  31. menuOptions = [
  32. {
  33. label: () => renderLabel('专家问答'),
  34. icon: renderIcon({ name: 'menu-answers' }),
  35. key: '/answer'
  36. },
  37. {
  38. label: () => renderLabel('智慧办公'),
  39. icon: renderIcon({ name: 'menu-work' }),
  40. key: '/work'
  41. },
  42. {
  43. label: () => renderLabel('用户中心'),
  44. icon: renderIcon({ name: 'menu-user' }),
  45. key: '/user',
  46. }
  47. ]
  48. } else {
  49. menuOptions = [
  50. {
  51. label: () => renderLabel('智慧总控'),
  52. icon: renderIcon({ name: 'menu-control' }),
  53. key: '/'
  54. },
  55. {
  56. label: () => renderLabel('专家问答'),
  57. icon: renderIcon({ name: 'menu-answers' }),
  58. key: '/answer'
  59. },
  60. {
  61. label: () => renderLabel('工艺管控'),
  62. icon: renderIcon({ name: 'menu-analyse' }),
  63. key: '/analyse',
  64. children: [
  65. {
  66. label: '水质报警',
  67. icon: renderChildrenIcon({ name: 'menu-analyse-water' }),
  68. key: '/water-warn',
  69. },
  70. {
  71. label: '生化报警',
  72. icon: renderChildrenIcon({ name: 'menu-analyse-pymol' }),
  73. key: '/pymol-warn',
  74. },
  75. {
  76. label: '预测预警',
  77. icon: renderChildrenIcon({ name: 'menu-analyse-notice' }),
  78. key: '/forecast-warn',
  79. },
  80. {
  81. label: '智能工单',
  82. icon: renderChildrenIcon({ name: 'menu-analyse-order' }),
  83. key: '/work-order',
  84. }
  85. ]
  86. },
  87. {
  88. label: () => renderLabel('成本管控'),
  89. icon: renderIcon({ name: 'menu-cost-control' }),
  90. key: '/control',
  91. children: [
  92. {
  93. label: '智适应碳源投加',
  94. icon: renderChildrenIcon({ name: 'menu-cost-drug' }),
  95. key: 'medicinal',
  96. },
  97. // {
  98. // label: '精准曝气',
  99. // icon: renderChildrenIcon({ name: 'menu-cost-accurate' }),
  100. // key: 'normal-2',
  101. // },
  102. // {
  103. // label: '微生物镜检',
  104. // icon: renderChildrenIcon({ name: 'menu-cost-microorganism' }),
  105. // key: 'normal-3',
  106. // },
  107. {
  108. label: '碳排放管理',
  109. icon: renderChildrenIcon({ name: 'menu-carbon-emission' }),
  110. key: '/carbon',
  111. },
  112. ]
  113. },
  114. {
  115. label: () => renderLabel('智慧办公'),
  116. icon: renderIcon({ name: 'menu-work' }),
  117. key: '/work'
  118. },
  119. {
  120. label: () => renderLabel('用户中心'),
  121. icon: renderIcon({ name: 'menu-user' }),
  122. key: '/user',
  123. }
  124. ]
  125. }
  126. }
  127. updateMenOptions();
  128. const handleUpdateValue = (key, { url }) => {
  129. if (url) return window.open(url);
  130. if (key.includes('normal')) return;
  131. router.push(key);
  132. }
  133. </script>
  134. <template>
  135. <n-scrollbar style="height: 100%">
  136. <n-menu :options="menuOptions" :icon-size="30" v-model:value="activeMenuKey" @update:value="handleUpdateValue">
  137. </n-menu>
  138. </n-scrollbar>
  139. </template>
  140. <style scoped lang="scss"></style>
  141. <style lang="scss">
  142. @mixin sub-menu-active {
  143. .n-menu-item-content__icon {
  144. .icon-default {
  145. display: none;
  146. }
  147. .icon-active {
  148. display: block;
  149. }
  150. }
  151. .n-menu-item-content-header {
  152. font-weight: bold;
  153. }
  154. }
  155. .n-menu .n-menu-item-content:not(.n-menu-item-content--disabled):hover::before {
  156. border: 1px solid #fff;
  157. background: #FCFDFE;
  158. }
  159. // 子菜单hover
  160. .n-submenu-children {
  161. .n-menu-item-content:hover {
  162. @include sub-menu-active();
  163. }
  164. }
  165. // reset - 选中状态
  166. .n-menu-item-content--selected {
  167. @include sub-menu-active();
  168. &:not(.n-menu-item-content--disabled)::before {
  169. border: 1px solid #fff;
  170. background: #FCFDFE;
  171. }
  172. }
  173. // reset - 选中状态
  174. // .n-menu-item-content--selected {
  175. // font-weight: bold;
  176. // }
  177. // .n-base-icon {
  178. // background: url('@/assets/svgs/menu/arrow.svg') center center no-repeat;
  179. // svg {
  180. // display: none;
  181. // }
  182. // }</style>