index.vue 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565
  1. <template>
  2. <div class="right-menu">
  3. <div class="menu-container">
  4. <div style="position: relative; margin-top: 60px">
  5. <div ref="scrollListRef" :class="!menuState.showMenu ? 'menu-list' : 'menu-list menu-list-right'">
  6. <div
  7. v-for="(item, index) in menuState.menuData"
  8. :key="index"
  9. :class="menuState.activeIndex === index ? 'menu-item menu-active' : 'menu-item'"
  10. style="pointer-events: auto"
  11. @click="clickMenu(index)"
  12. >
  13. <div :class="item.meta?.icon + ' ' + item.meta?.icon + '_checked'"></div>
  14. <div class="gradient-text text">{{ item.name }}</div>
  15. </div>
  16. </div>
  17. <div
  18. v-show="menuState.menuData.length > 0"
  19. :class="menuState.showMenu ? 'right-btn' : 'left-btn'"
  20. style="pointer-events: auto"
  21. @click="clickContractMenu"
  22. ></div>
  23. <div v-show="menuState.menuData.length > 7" class="btn-box" style="pointer-events: auto">
  24. <div class="up-btn" @click="clickBtn('up')"></div>
  25. <div class="down-btn" @click="clickBtn('down')"></div>
  26. </div>
  27. </div>
  28. <div v-show="menuState.showMenu" style="pointer-events: auto; position: relative">
  29. <div class="fold-btn" @click="clickContractMenu">
  30. <i class="fold-icon" />
  31. 折叠菜单
  32. </div>
  33. <template v-if="menuState.showMenu">
  34. <!--图层分析-->
  35. <LayerAnalysis v-if="menuState.menuData[menuState.activeIndex]?.name === '图层分析'" :point-type="pointType" />
  36. <!--空间分析-->
  37. <SpatialAnalysis
  38. v-if="menuState.menuData[menuState.activeIndex]?.name === '空间分析'"
  39. :update-location="location"
  40. @handle-menu="handleMenu"
  41. />
  42. <!--江湖河库-->
  43. <Reservoir v-if="menuState.menuData[menuState.activeIndex]?.name === '江湖河库'" />
  44. <!--路网视频-->
  45. <RoadNetworkVideo v-if="menuState.menuData[menuState.activeIndex]?.name === '路网视频'" />
  46. <!--防溺水视频-->
  47. <PreventDrowning v-if="menuState.menuData[menuState.activeIndex]?.name === '防溺水'" />
  48. <!--水库监测-->
  49. <ReservoirMonitor v-if="menuState.menuData[menuState.activeIndex]?.name === '水库监测'" />
  50. <!--河道监测-->
  51. <RiverMonitor v-if="menuState.menuData[menuState.activeIndex]?.name === '河道监测'" />
  52. <!--无人机-->
  53. <UAV v-if="menuState.menuData[menuState.activeIndex]?.name === '无人机'" @handle-menu="handleMenu" />
  54. <!--实时标绘-->
  55. <OnlinePlotting v-if="menuState.menuData[menuState.activeIndex]?.name === '实时标绘'" />
  56. <!--定点分析-->
  57. <FixedPointAnalysis v-if="menuState.menuData[menuState.activeIndex]?.name === '定点分析'" :location="location2" />
  58. <!--雨情监测-->
  59. <RainMonitor v-if="menuState.menuData[menuState.activeIndex]?.name === '雨情监测'" />
  60. <!--铁塔运行监测-->
  61. <TowerStatus v-if="menuState.menuData[menuState.activeIndex]?.name === '铁塔运行监测'" />
  62. <!--预警信号-->
  63. <WarningInfo v-if="menuState.menuData[menuState.activeIndex]?.name === '预警信号'" @handle-menu="handleMenu" />
  64. <!--森林防火-->
  65. <Fireproofing v-if="menuState.menuData[menuState.activeIndex]?.name === '森林防火'" @handle-menu="handleMenu" />
  66. <!--森防视频-->
  67. <ForestDefenseVideo v-if="menuState.menuData[menuState.activeIndex]?.name === '森防视频'" :activeMap="activeMap" @handle-menu="handleMenu" />
  68. <!--防灾救援-->
  69. <Mitigation v-if="menuState.menuData[menuState.activeIndex]?.name === '防灾救援'" @handle-menu="handleMenu" />
  70. <!--交通视频-->
  71. <TrafficVideo v-if="menuState.menuData[menuState.activeIndex]?.name === '交通视频'" @handle-menu="handleMenu" />
  72. <!--易涝隐患点-->
  73. <PotentialFloodHazard v-if="menuState.menuData[menuState.activeIndex]?.name === '易涝隐患点'" @handle-menu="handleMenu" />
  74. <!--通讯保障-->
  75. <CommunicationSupport v-if="menuState.menuData[menuState.activeIndex]?.name === '通讯保障'" @handle-menu="handleMenu" />
  76. <!--手机工作平台-->
  77. <MobilePlatform v-if="menuState.menuData[menuState.activeIndex]?.name === '手机工作台'" @handle-menu="handleMenu" />
  78. <!--重点车辆-->
  79. <KeyVehicles v-if="menuState.menuData[menuState.activeIndex]?.name === '重点车辆'" @handle-menu="handleMenu" />
  80. <!--卫星电话-->
  81. <SatellitePhone v-if="menuState.menuData[menuState.activeIndex]?.name === '卫星电话'" @handle-menu="handleMenu" />
  82. <!--机动无人机-->
  83. <MobileUnmannedVehicle v-if="menuState.menuData[menuState.activeIndex]?.name === '机动无人机'" @handle-menu="handleMenu" />
  84. <!--移动指挥车-->
  85. <MobileCommandVehicle v-if="menuState.menuData[menuState.activeIndex]?.name === '移动指挥车'" @handle-menu="handleMenu" />
  86. <!--直升机-->
  87. <Helicopter v-if="menuState.menuData[menuState.activeIndex]?.name === '直升机'" @handle-menu="handleMenu" />
  88. <!--台风视频-->
  89. <TyphoonVideo v-if="menuState.menuData[menuState.activeIndex]?.name === '台风视频'" @handle-menu="handleMenu" />
  90. <RescueTeam v-if="menuState.menuData[menuState.activeIndex]?.name === '救援队伍'" />
  91. </template>
  92. </div>
  93. </div>
  94. </div>
  95. </template>
  96. <script lang="ts" setup name="rightMenu">
  97. import { PointType } from '@/api/globalMap/type';
  98. import RiverMonitor from './RiverMonitor.vue';
  99. import ReservoirMonitor from './ReservoirMonitor.vue';
  100. import RoadNetworkVideo from './RoadNetworkVideo.vue';
  101. import Reservoir from './Reservoir.vue';
  102. import SpatialAnalysis from './SpatialAnalysis.vue';
  103. import LayerAnalysis from './LayerAnalysis.vue';
  104. import OnlinePlotting from './OnlinePlotting/index.vue';
  105. import FixedPointAnalysis from './FixedPointAnalysis.vue';
  106. import UAV from './UAV.vue';
  107. import WarningInfo from './WarningInfo.vue';
  108. import RainMonitor from './RainMonitor/index.vue';
  109. import PreventDrowning from './PreventDrowning.vue';
  110. import Fireproofing from './Fireproofing.vue';
  111. import ForestDefenseVideo from './ForestDefenseVideo/index.vue';
  112. import Mitigation from './Mitigation.vue';
  113. import PotentialFloodHazard from './PotentialFloodHazard.vue';
  114. import TowerStatus from './TowerStatus.vue';
  115. import CommunicationSupport from './CommunicationSupport.vue';
  116. import MobilePlatform from './MobilePlatform.vue';
  117. import KeyVehicles from './KeyVehicles.vue';
  118. import SatellitePhone from './SatellitePhone.vue';
  119. import MobileUnmannedVehicle from './MobileUnmannedVehicle.vue';
  120. import MobileCommandVehicle from './MobileCommandVehicle.vue';
  121. import Helicopter from './Helicopter.vue';
  122. import TyphoonVideo from './TyphoonVideo.vue';
  123. import RescueTeam from './RescueTeam.vue';
  124. interface Props {
  125. pointType: PointType[];
  126. activeMap: string;
  127. }
  128. withDefaults(defineProps<Props>(), {});
  129. const emits = defineEmits(['update:drawing', '']);
  130. const scrollListRef = ref();
  131. const menuState = reactive({
  132. showMenu: false,
  133. activeIndex: 0,
  134. menuData: []
  135. });
  136. const activeName = computed(() => {
  137. let name = '';
  138. if (!!menuState.menuData && menuState.menuData.length > 0 && !!menuState.menuData[menuState.activeIndex]) {
  139. name = menuState.menuData[menuState.activeIndex].name;
  140. }
  141. return name;
  142. });
  143. // 点击收缩展开
  144. const clickContractMenu = () => {
  145. menuState.showMenu = !menuState.showMenu;
  146. };
  147. // 菜单上下移动
  148. const clickBtn = (direction: string) => {
  149. const len = menuState.menuData.length;
  150. if (direction === 'up' && scrollListRef.value.scrollTop - 168 >= 0) {
  151. scrollListRef.value.scrollTop -= 168;
  152. } else if (direction === 'down' && scrollListRef.value.scrollTop + 168 <= 168 * len) {
  153. scrollListRef.value.scrollTop += 168;
  154. }
  155. };
  156. const showIndexMenu = (name) => {
  157. let index = menuState.menuData.findIndex((item) => {
  158. return item.name === name;
  159. });
  160. if (index > -1) {
  161. clickMenu(index);
  162. }
  163. };
  164. // 点击菜单
  165. const clickMenu = (index) => {
  166. menuState.showMenu = true;
  167. menuState.activeIndex = index;
  168. };
  169. let location = ref([]);
  170. let location2 = ref([]);
  171. // 显示菜单
  172. const handleMenu = (name, data) => {
  173. let index = menuState.menuData.findIndex((item) => {
  174. return item.name === name;
  175. });
  176. if (name === '空间分析') {
  177. menuState.showMenu = true;
  178. menuState.activeIndex = index;
  179. nextTick(() => {
  180. location.value = data;
  181. });
  182. } else if (index > -1) {
  183. clickMenu(index);
  184. }
  185. };
  186. // 新增菜单 type 1 新增 2 删除
  187. const updateMenu = (type, menu, location?: any) => {
  188. if (type === '1') {
  189. if (menu.name === '图层分析') {
  190. let index = menuState.menuData.findIndex((item) => {
  191. return item.name === menu.name;
  192. });
  193. if (index === -1) {
  194. menuState.menuData.push(menu);
  195. }
  196. } else if (menu.name === '定点分析') {
  197. menuState.menuData.push(menu);
  198. location2.value = location;
  199. } else {
  200. menuState.menuData.push(menu);
  201. }
  202. clickMenu(menuState.menuData.length - 1);
  203. } else if (type === '2') {
  204. let index = menuState.menuData.findIndex((item) => item.name === menu.name);
  205. if (index > -1) {
  206. menuState.menuData.splice(index, 1);
  207. menuState.activeIndex = 0;
  208. }
  209. } else if (type === '4') {
  210. let index = menuState.menuData.findIndex((item) => item.name === menu.name);
  211. if (index > -1) {
  212. menuState.menuData.splice(index, 1);
  213. menuState.activeIndex = 0;
  214. }
  215. location2.value = location;
  216. }
  217. };
  218. const getMenuState = () => {
  219. return menuState;
  220. };
  221. defineExpose({ handleMenu, showIndexMenu, clickContractMenu, updateMenu, getMenuState });
  222. </script>
  223. <style lang="scss" scoped>
  224. .right-menu {
  225. position: absolute;
  226. top: 100px;
  227. right: 0;
  228. z-index: 20;
  229. pointer-events: none;
  230. }
  231. .expand-btn {
  232. width: 70px;
  233. height: 240px;
  234. font-size: 32px;
  235. background: #d7d7d7;
  236. padding: 10px 18px;
  237. cursor: pointer;
  238. display: flex;
  239. align-items: center;
  240. }
  241. .menu-container {
  242. display: flex;
  243. .menu-list-right {
  244. margin-right: -115px;
  245. }
  246. .menu-list {
  247. position: relative;
  248. max-height: 1176px;
  249. overflow: hidden;
  250. .menu-item {
  251. width: 470px;
  252. height: 168px;
  253. font-size: 32px;
  254. padding: 30px 18px 10px 40px;
  255. cursor: pointer;
  256. display: flex;
  257. align-items: center;
  258. background: url('@/assets/images/map/rightMenu/box.png') no-repeat;
  259. .text {
  260. font-size: 48px;
  261. }
  262. &:hover {
  263. background: url('@/assets/images/map/rightMenu/box_checked.png') no-repeat;
  264. }
  265. }
  266. .menu-active {
  267. background: url('@/assets/images/map/rightMenu/box_checked.png') no-repeat;
  268. }
  269. }
  270. .left-btn,
  271. .right-btn {
  272. position: absolute;
  273. top: 50%;
  274. right: -80px;
  275. transform: translateY(-50%);
  276. z-index: 2;
  277. }
  278. .right-btn {
  279. width: 177px;
  280. height: 151px;
  281. cursor: pointer;
  282. background: url('@/assets/images/map/rightMenu/right.png') no-repeat;
  283. cursor: pointer;
  284. }
  285. .left-btn {
  286. right: 20px;
  287. width: 125px;
  288. height: 151px;
  289. background: url('@/assets/images/map/rightMenu/left.png') no-repeat;
  290. cursor: pointer;
  291. }
  292. .btn-box {
  293. width: 100%;
  294. display: flex;
  295. margin-left: 45px;
  296. .up-btn {
  297. width: 151px;
  298. height: 178px;
  299. background: url('@/assets/images/map/rightMenu/up.png') no-repeat;
  300. cursor: pointer;
  301. }
  302. .down-btn {
  303. height: 177px;
  304. width: 151px;
  305. background: url('@/assets/images/map/rightMenu/down.png') no-repeat;
  306. cursor: pointer;
  307. }
  308. }
  309. }
  310. .fold-btn {
  311. position: absolute;
  312. right: 16px;
  313. top: 50px;
  314. z-index: 10;
  315. width: 268px;
  316. height: 72px;
  317. background: url('@/assets/images/map/rightMenu/btn3.png') no-repeat;
  318. background-size: 100% 100%;
  319. color: #ffffff;
  320. font-size: 38px;
  321. display: flex;
  322. align-items: center;
  323. padding-left: 12px;
  324. cursor: pointer;
  325. .fold-icon {
  326. display: inline-block;
  327. width: 33px;
  328. height: 31px;
  329. background: url('@/assets/images/map/rightMenu/fold.png') no-repeat;
  330. background-size: 100% 100%;
  331. margin-right: 24px;
  332. }
  333. }
  334. .icon1 {
  335. width: 99px;
  336. height: 92px;
  337. background: url('@/assets/images/map/rightMenu/icon2.png') no-repeat;
  338. cursor: pointer;
  339. }
  340. .icon1_checked {
  341. background: url('@/assets/images/map/rightMenu/icon2_checked.png') no-repeat;
  342. }
  343. .icon2 {
  344. width: 99px;
  345. height: 92px;
  346. background: url('@/assets/images/map/rightMenu/icon2.png') no-repeat;
  347. cursor: pointer;
  348. }
  349. .icon2_checked {
  350. background: url('@/assets/images/map/rightMenu/icon2_checked.png') no-repeat;
  351. }
  352. .icon3 {
  353. width: 92px;
  354. height: 92px;
  355. background: url('@/assets/images/map/rightMenu/icon3.png') no-repeat;
  356. cursor: pointer;
  357. }
  358. .icon3_checked {
  359. background: url('@/assets/images/map/rightMenu/icon3_checked.png') no-repeat;
  360. }
  361. .icon4 {
  362. width: 90px;
  363. height: 85px;
  364. background: url('@/assets/images/map/rightMenu/icon4.png') no-repeat;
  365. cursor: pointer;
  366. }
  367. .icon4_checked {
  368. background: url('@/assets/images/map/rightMenu/icon4_checked.png') no-repeat;
  369. }
  370. .icon5 {
  371. width: 91px;
  372. height: 82px;
  373. background: url('@/assets/images/map/rightMenu/icon5.png') no-repeat;
  374. cursor: pointer;
  375. }
  376. .icon5_checked {
  377. background: url('@/assets/images/map/rightMenu/icon5_checked.png') no-repeat;
  378. }
  379. .icon6 {
  380. width: 89px;
  381. height: 87px;
  382. background: url('@/assets/images/map/rightMenu/icon6.png') no-repeat;
  383. cursor: pointer;
  384. }
  385. .icon6_checked {
  386. background: url('@/assets/images/map/rightMenu/icon6_checked.png') no-repeat;
  387. }
  388. //
  389. .icon7 {
  390. width: 89px;
  391. height: 87px;
  392. background: url('@/assets/images/map/rightMenu/icon7.png') no-repeat;
  393. cursor: pointer;
  394. }
  395. .icon7_checked {
  396. background: url('@/assets/images/map/rightMenu/icon7_checked.png') no-repeat;
  397. }
  398. .icon8 {
  399. width: 89px;
  400. height: 87px;
  401. background: url('@/assets/images/map/rightMenu/icon8.png') no-repeat;
  402. cursor: pointer;
  403. }
  404. .icon8_checked {
  405. background: url('@/assets/images/map/rightMenu/icon8_checked.png') no-repeat;
  406. }
  407. .icon9 {
  408. width: 89px;
  409. height: 87px;
  410. background: url('@/assets/images/map/rightMenu/icon9.png') no-repeat;
  411. cursor: pointer;
  412. }
  413. .icon9_checked {
  414. background: url('@/assets/images/map/rightMenu/icon9_checked.png') no-repeat;
  415. }
  416. .icon10 {
  417. width: 89px;
  418. height: 87px;
  419. background: url('@/assets/images/map/rightMenu/icon10.png') no-repeat;
  420. cursor: pointer;
  421. }
  422. .icon10_checked {
  423. background: url('@/assets/images/map/rightMenu/icon10_checked.png') no-repeat;
  424. }
  425. .icon11 {
  426. width: 89px;
  427. height: 87px;
  428. background: url('@/assets/images/map/rightMenu/icon11.png') no-repeat;
  429. cursor: pointer;
  430. }
  431. .icon11_checked {
  432. background: url('@/assets/images/map/rightMenu/icon11_checked.png') no-repeat;
  433. }
  434. .icon12 {
  435. width: 89px;
  436. height: 87px;
  437. background: url('@/assets/images/map/rightMenu/icon12.png') no-repeat;
  438. cursor: pointer;
  439. }
  440. .icon12_checked {
  441. background: url('@/assets/images/map/rightMenu/icon12_checked.png') no-repeat;
  442. }
  443. .icon13 {
  444. width: 89px;
  445. height: 87px;
  446. background: url('@/assets/images/map/rightMenu/icon13.png') no-repeat;
  447. cursor: pointer;
  448. }
  449. .icon13_checked {
  450. background: url('@/assets/images/map/rightMenu/icon13_checked.png') no-repeat;
  451. }
  452. .icon14 {
  453. width: 89px;
  454. height: 87px;
  455. background: url('@/assets/images/map/rightMenu/icon14.png') no-repeat;
  456. cursor: pointer;
  457. }
  458. .icon14_checked {
  459. background: url('@/assets/images/map/rightMenu/icon14_checked.png') no-repeat;
  460. }
  461. .icon15 {
  462. width: 89px;
  463. height: 87px;
  464. background: url('@/assets/images/map/rightMenu/icon15.png') no-repeat;
  465. cursor: pointer;
  466. }
  467. .icon15_checked {
  468. background: url('@/assets/images/map/rightMenu/icon15_checked.png') no-repeat;
  469. }
  470. .icon16 {
  471. width: 89px;
  472. height: 87px;
  473. background: url('@/assets/images/map/rightMenu/icon16.png') no-repeat;
  474. cursor: pointer;
  475. }
  476. .icon16_checked {
  477. background: url('@/assets/images/map/rightMenu/icon16_checked.png') no-repeat;
  478. }
  479. .icon17 {
  480. width: 89px;
  481. height: 87px;
  482. background: url('@/assets/images/map/rightMenu/icon17.png') no-repeat;
  483. cursor: pointer;
  484. }
  485. .icon17_checked {
  486. background: url('@/assets/images/map/rightMenu/icon17_checked.png') no-repeat;
  487. }
  488. .icon18 {
  489. width: 89px;
  490. height: 87px;
  491. background: url('@/assets/images/map/rightMenu/icon18.png') no-repeat;
  492. cursor: pointer;
  493. }
  494. .icon18_checked {
  495. background: url('@/assets/images/map/rightMenu/icon18_checked.png') no-repeat;
  496. }
  497. .icon19 {
  498. width: 89px;
  499. height: 87px;
  500. background: url('@/assets/images/map/rightMenu/icon19.png') no-repeat;
  501. cursor: pointer;
  502. }
  503. .icon19_checked {
  504. background: url('@/assets/images/map/rightMenu/icon19_checked.png') no-repeat;
  505. }
  506. .icon20 {
  507. width: 89px;
  508. height: 87px;
  509. background: url('@/assets/images/map/rightMenu/icon20.png') no-repeat;
  510. cursor: pointer;
  511. }
  512. .icon20_checked {
  513. background: url('@/assets/images/map/rightMenu/icon20_checked.png') no-repeat;
  514. }
  515. .icon21 {
  516. width: 89px;
  517. height: 87px;
  518. background: url('@/assets/images/map/rightMenu/icon21.png') no-repeat;
  519. cursor: pointer;
  520. }
  521. .icon21_checked {
  522. background: url('@/assets/images/map/rightMenu/icon21_checked.png') no-repeat;
  523. }
  524. .icon22 {
  525. width: 89px;
  526. height: 87px;
  527. background: url('@/assets/images/map/rightMenu/icon22.png') no-repeat;
  528. cursor: pointer;
  529. }
  530. .icon22_checked {
  531. background: url('@/assets/images/map/rightMenu/icon22_checked.png') no-repeat;
  532. }
  533. .icon23 {
  534. width: 89px;
  535. height: 87px;
  536. background: url('@/assets/images/map/rightMenu/icon23.png') no-repeat;
  537. cursor: pointer;
  538. }
  539. .icon23_checked {
  540. background: url('@/assets/images/map/rightMenu/icon23_checked.png') no-repeat;
  541. }
  542. .icon24 {
  543. width: 89px;
  544. height: 87px;
  545. background: url('@/assets/images/map/rightMenu/icon24.png') no-repeat;
  546. cursor: pointer;
  547. }
  548. .icon24_checked {
  549. background: url('@/assets/images/map/rightMenu/icon24_checked.png') no-repeat;
  550. }
  551. .icon25 {
  552. width: 89px;
  553. height: 87px;
  554. background: url('@/assets/images/map/rightMenu/icon25.png') no-repeat;
  555. cursor: pointer;
  556. }
  557. .icon25_checked {
  558. background: url('@/assets/images/map/rightMenu/icon25_checked.png') no-repeat;
  559. }
  560. </style>