HomeView.vue 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341
  1. <!-- 主容器页面,通过顶部导航栏(TopNav)切换各子视图页面 -->
  2. <template>
  3. <div class="dashboard">
  4. <div class="background-image" v-if="activeTab !== '工作台'"></div>
  5. <div class="bottom-bg" v-if="!showMap && activeTab !== '工作台'"></div>
  6. <div class="top-title" v-if="activeTab !== '工作台'"></div>
  7. <TopNav v-if="activeTab !== '工作台'" :activeButton="navButtonMap[activeTab]" @navigate="handleNav" @toggle-mode="handleToggleMode" />
  8. <!-- 全局地图 -->
  9. <div class="map-container" v-if="showMap">
  10. <CesiumMap
  11. @toggleMap="toggleMap"
  12. :simulationTime="simulationTime"
  13. :simulationData="simulationData"
  14. :loadEmbankmentWarning="loadEmbankmentWarning"
  15. :poiVisible="activeTab === '水文四预'"
  16. :cameraTarget="cameraTarget"
  17. />
  18. </div>
  19. <!-- 渐变装饰层(四周暗角) -->
  20. <GradientOverlay v-if="activeTab !== '工作台'" />
  21. <!-- 流域总览视图 -->
  22. <OverviewView v-if="activeTab === '流域总览'" @selectTab="selectTab" />
  23. <!-- 水文四预视图 -->
  24. <HydrologyForecastView
  25. v-if="activeTab === '水文四预'"
  26. :activeSecondaryTab="activeSecondaryTab"
  27. :simulationTime="simulationTime"
  28. :simulationData="simulationData"
  29. :loadEmbankmentWarning="loadEmbankmentWarning"
  30. @selectSecondaryTab="selectSecondaryTab"
  31. @updateSimulationTime="updateSimulationTime"
  32. @updateSimulationData="updateSimulationData"
  33. @loadEmbankmentWarning="handleLoadEmbankmentWarning"
  34. @updateForecastData="handleUpdateForecastData"
  35. />
  36. <!-- 全生命周期管理视图 -->
  37. <LifecycleView v-if="activeTab === '全生命周期管理'" />
  38. <!-- 工程安全运维视图 -->
  39. <div v-if="activeTab === '工程安全运维'" class="tab-wrapper">
  40. <EngineeringSafetyView />
  41. </div>
  42. <!-- 闸门控制视图(内嵌模式,不重新加载地图) -->
  43. <GateControlView v-if="activeTab === '闸门控制'" :embedded="true" />
  44. <!-- 视频监控视图 -->
  45. <VideoMonitorView v-if="activeTab === '视频监控'" />
  46. <!-- 工作台视图 -->
  47. <WorkspaceView v-if="activeTab === '工作台'" @backToDashboard="selectTab('流域总览')" />
  48. <!-- 水资源调度视图 -->
  49. <div v-if="activeTab === '水资源调度'" class="tab-wrapper">
  50. <WaterResourceAllocationView style="width:100%;height:100%;padding:70px 16px 16px 16px;" />
  51. </div>
  52. </div>
  53. </template>
  54. <script>
  55. import OverviewView from './mainPages/OverviewView.vue'
  56. import HydrologyForecastView from './mainPages/HydrologyForecastView.vue'
  57. import CesiumMap from '../components/CesiumMap.vue'
  58. import GradientOverlay from '../components/gradient-overlay.vue'
  59. import EngineeringSafetyView from './mainPages/EngineeringSafetyView.vue'
  60. import GateControlView from './mainPages/GateControlView.vue'
  61. import LifecycleView from './mainPages/LifecycleView.vue'
  62. import VideoMonitorView from './mainPages/VideoMonitorView.vue'
  63. import WorkspaceView from './mainPages/WorkspaceView.vue'
  64. import WaterResourceAllocationView from './admin/WaterResourceAllocationView.vue'
  65. import TopNav from '../components/TopNav.vue'
  66. export default {
  67. name: 'HomeView',
  68. components: {
  69. OverviewView,
  70. HydrologyForecastView,
  71. EngineeringSafetyView,
  72. GateControlView,
  73. LifecycleView,
  74. VideoMonitorView,
  75. WorkspaceView,
  76. WaterResourceAllocationView,
  77. CesiumMap,
  78. GradientOverlay,
  79. TopNav
  80. },
  81. data() {
  82. return {
  83. activeTab: '流域总览',
  84. activeSecondaryTab: '水文监控',
  85. showMap: true,
  86. loadEmbankmentWarning: false,
  87. navButtonMap: {
  88. '流域总览': '综合首页',
  89. '水文四预': '水情测报',
  90. '全生命周期管理': '生命周期',
  91. '工程安全运维': '工程安全',
  92. '水资源调度': '水资源调度',
  93. '视频监控': '视频监控',
  94. '工作台': '工作台'
  95. },
  96. tabButtonMap: {
  97. '综合首页': '流域总览',
  98. '水情测报': '水文四预',
  99. '生命周期': '全生命周期管理',
  100. '工程安全': '工程安全运维',
  101. '水资源调度': '水资源调度',
  102. '闸门控制': '闸门控制',
  103. '视频监控': '视频监控',
  104. '工作台': '工作台'
  105. },
  106. simulationTime: 0,
  107. simulationData: {
  108. heilinStation: {
  109. waterLevel: '3.25',
  110. flow: '12.5',
  111. rainfall: '0.5'
  112. },
  113. reservoir: {
  114. waterLevel: '18.5',
  115. storage: '2350.8'
  116. }
  117. },
  118. cameraTarget: 'default'
  119. }
  120. },
  121. created() {
  122. this.applyTabFromRoute()
  123. },
  124. watch: {
  125. '$route.query.tab'(newTab) {
  126. if (newTab && this.tabButtonMap[newTab]) {
  127. this.selectTab(this.tabButtonMap[newTab])
  128. }
  129. }
  130. },
  131. methods: {
  132. applyTabFromRoute() {
  133. const tab = this.$route.query.tab
  134. if (tab && this.tabButtonMap[tab]) {
  135. this.selectTab(this.tabButtonMap[tab])
  136. }
  137. },
  138. selectTab(tab) {
  139. this.activeTab = tab
  140. const btn = this.navButtonMap[tab]
  141. if (btn && this.$route.query.tab !== btn) {
  142. this.$router.replace({ query: { tab: btn } })
  143. }
  144. if (tab === '水文四预' || tab === '水资源调配') {
  145. this.activeSecondaryTab = '水文监控'
  146. }
  147. if (tab !== '水文四预') {
  148. this.loadEmbankmentWarning = false
  149. }
  150. // 镜头切换
  151. if (tab === '水文四预') {
  152. this.cameraTarget = 'hydrology'
  153. } else {
  154. this.cameraTarget = 'default'
  155. }
  156. // 工作台和水资源调度页面隐藏地图(水资源调度有独立地图),其他页面显示地图
  157. if (tab === '工作台' || tab === '水资源调度') {
  158. this.showMap = false
  159. } else {
  160. this.showMap = true
  161. }
  162. },
  163. handleNav(button) {
  164. if (button === '综合首页') this.selectTab('流域总览')
  165. else if (button === '水情测报') this.selectTab('水文四预')
  166. else if (button === '工程安全') this.selectTab('工程安全运维')
  167. else if (button === '水资源调度') this.selectTab('水资源调度')
  168. else if (button === '生命周期') this.selectTab('全生命周期管理')
  169. else if (button === '闸门控制') this.selectTab('闸门控制')
  170. else if (button === '视频监控') this.selectTab('视频监控')
  171. else if (button === '工作台') this.selectTab('工作台')
  172. },
  173. selectSecondaryTab(tab) {
  174. this.activeSecondaryTab = tab
  175. // 在水文预警和水文预演页面时显示堤防图层
  176. if (this.activeTab === '水文四预' && (tab === '水文预警' || tab === '水文预演')) {
  177. // 先设为false,再设为true,触发重新加载
  178. this.loadEmbankmentWarning = false
  179. this.$nextTick(() => {
  180. this.loadEmbankmentWarning = true
  181. })
  182. } else if (this.activeTab === '水文四预' && tab !== '水文预警') {
  183. this.loadEmbankmentWarning = false
  184. }
  185. },
  186. toggleMap(show) {
  187. this.showMap = show
  188. },
  189. updateSimulationTime(time) {
  190. this.simulationTime = time
  191. },
  192. updateSimulationData(data) {
  193. this.simulationData = { ...this.simulationData, ...data }
  194. },
  195. handleLoadEmbankmentWarning() {
  196. // 在水文预警和水文预演页面时显示堤防图层
  197. if (this.activeTab === '水文四预' && (this.activeSecondaryTab === '水文预警' || this.activeSecondaryTab === '水文预演')) {
  198. this.loadEmbankmentWarning = true
  199. }
  200. },
  201. handleUpdateForecastData(data) {
  202. this.simulationData = { ...this.simulationData, ...data }
  203. },
  204. handleToggleMode(isFrontend) {
  205. console.log('切换模式:', isFrontend ? '前台模式' : '后台模式')
  206. // 可以在这里添加前后台切换的具体逻辑
  207. }
  208. }
  209. }</script>
  210. <style scoped>
  211. .dashboard {
  212. width: 100%;
  213. height: 100%;
  214. overflow: hidden;
  215. position: relative;
  216. }
  217. .background-image {
  218. position: absolute;
  219. top: 0;
  220. left: 0;
  221. width: 100%;
  222. height: 100%;
  223. background-image: url('/src/assets/images/背景.png');
  224. background-size: 100% 100%;
  225. background-position: center;
  226. background-repeat: no-repeat;
  227. pointer-events: none;
  228. z-index: 3;
  229. }
  230. .bottom-bg {
  231. position: absolute;
  232. bottom: 0;
  233. left: 0;
  234. width: 100%;
  235. height: 100%;
  236. background-image: url('/src/assets/images/Heilin/WPS图片(1).jpeg');
  237. background-size: 100% 100%;
  238. background-position: center;
  239. background-repeat: no-repeat;
  240. pointer-events: none;
  241. z-index: 3;
  242. }
  243. .top-title {
  244. position: absolute;
  245. top: 0;
  246. left: 0;
  247. width: 100%;
  248. height: 100%;
  249. background-image: url('/src/assets/images/顶部大标题.png');
  250. background-size: 100% 100%;
  251. background-position: center;
  252. background-repeat: no-repeat;
  253. pointer-events: none;
  254. z-index: 4;
  255. }
  256. /* 地图容器样式 */
  257. .map-container {
  258. position: absolute;
  259. width: 100%;
  260. height: 100%;
  261. bottom: 0;
  262. z-index: 1;
  263. overflow: hidden;
  264. pointer-events: auto;
  265. }
  266. .bottom-sub-title {
  267. position: absolute;
  268. bottom: 46px;
  269. width: 159px;
  270. height: 31px;
  271. background-image: url('/src/assets/images/未选中底部标题.png');
  272. background-size: 100% 100%;
  273. background-position: center;
  274. background-repeat: no-repeat;
  275. display: flex;
  276. align-items: center;
  277. justify-content: center;
  278. z-index: 2;
  279. cursor: pointer;
  280. transition: all 0.3s ease;
  281. }
  282. .bottom-sub-title:hover,
  283. .bottom-sub-title.active {
  284. background-image: url('/src/assets/images/选中底部标题.png');
  285. }
  286. .bottom-sub-title.bottom-left {
  287. left: 50%;
  288. transform: translateX(-169px);
  289. }
  290. .bottom-sub-title.bottom-right {
  291. right: 50%;
  292. transform: translateX(169px);
  293. }
  294. .bottom-text {
  295. font-size: 14px;
  296. font-weight: bold;
  297. background: linear-gradient(to bottom, #e2e8ff, #7bbef6);
  298. -webkit-background-clip: text;
  299. background-clip: text;
  300. color: transparent;
  301. text-shadow: 0 0 5px rgba(0, 212, 255, 0.3);
  302. }
  303. .bottom-sub-title.active .bottom-text {
  304. background: linear-gradient(to bottom, #e2e8ff, #62f6fb);
  305. -webkit-background-clip: text;
  306. background-clip: text;
  307. color: transparent;
  308. }
  309. /* tab 视图容器必须相对定位并填满,子视图用绝对定位 */
  310. .tab-wrapper {
  311. position: relative;
  312. width: 100%;
  313. height: 100%;
  314. }
  315. </style>