From f50451fcb85ab7d67a51a725fed1b7b7360b01b0 Mon Sep 17 00:00:00 2001 From: panyuyi Date: Mon, 28 Oct 2024 11:36:31 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E6=B0=B4=E5=BA=93=E7=AC=AC=E4=B8=80?= =?UTF-8?q?=E7=89=88=E9=9C=80=E6=B1=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- package.json | 4 +- src/api/reservoir/index.js | 44 + src/assets/image/right.png | Bin 0 -> 866 bytes src/assets/image/warning.png | Bin 0 -> 789 bytes src/assets/styles/element-ui.scss | 7 + src/assets/styles/index.scss | 6 + src/layout/components/Navbar.vue | 2 +- src/permission.js | 2 - src/router/index.js | 2 +- src/store/modules/permission.js | 20 +- .../waterSetting/runScene/layerTree/index.js | 1 + src/views/components/SyMixMap.vue | 18 +- src/views/mobilePage/index.vue | 26 +- .../reservoir/safeMonitorSetting/index.vue | 359 +++++++++ .../safeOperation/components/BaseInfo.vue | 751 ++++++++++++++++++ .../components/ProjectDetail.vue | 38 + .../components/RealTimeMonitor.vue | 185 +++++ src/views/reservoir/safeOperation/index.vue | 381 +++++++++ .../reservoir/safeOperation/js/initEcharts.js | 124 +++ .../reservoir/safeOperation/js/mapUtils.js | 119 +++ 20 files changed, 2062 insertions(+), 27 deletions(-) create mode 100644 src/api/reservoir/index.js create mode 100644 src/assets/image/right.png create mode 100644 src/assets/image/warning.png create mode 100644 src/views/reservoir/safeMonitorSetting/index.vue create mode 100644 src/views/reservoir/safeOperation/components/BaseInfo.vue create mode 100644 src/views/reservoir/safeOperation/components/ProjectDetail.vue create mode 100644 src/views/reservoir/safeOperation/components/RealTimeMonitor.vue create mode 100644 src/views/reservoir/safeOperation/index.vue create mode 100644 src/views/reservoir/safeOperation/js/initEcharts.js create mode 100644 src/views/reservoir/safeOperation/js/mapUtils.js diff --git a/package.json b/package.json index 6f6571c..25d8e0d 100644 --- a/package.json +++ b/package.json @@ -63,6 +63,8 @@ "jspdf": "^2.5.1", "jsplumb": "^2.15.6", "jszip": "^3.0.0", + "lodash-es": "^4.17.21", + "mitt": "^3.0.1", "node-jsencrypt": "^1.0.0", "normalize.css": "7.0.0", "nprogress": "0.2.0", @@ -132,4 +134,4 @@ "> 1%", "last 2 versions" ] -} \ No newline at end of file +} diff --git a/src/api/reservoir/index.js b/src/api/reservoir/index.js new file mode 100644 index 0000000..ddfa8a0 --- /dev/null +++ b/src/api/reservoir/index.js @@ -0,0 +1,44 @@ +import request from '@/utils/request' + +// 获取场景列表 +export const getSceneListData = async (data) => { + return request({ + url: `/map/scene/sceneList`, + method: 'post', + data: { + pageNum: 1, + pageSize: 10, + data: { + id: '', + name: data.name + }, + params: { + order: 'asc', + orderBy: 'pub_date' + } + } + }); +}; + +// 根据id获取图层树 +export const getLayerData = async (sceneId) => { + return request({ + url: `/map/scene/getLayerTree/${sceneId}`, + method: 'get' + }); +}; + +// 水库基础信息详情 +export const getReservoirBaseDetailData = (id) =>{ + return request({ + url: `/sk/base/${id}`, + method: 'get' + }) +} +// 水库特征信息详情 +export const getReservoirRsppDetailData = (id) =>{ + return request({ + url: `/sk/rspp/${id}`, + method: 'get' + }) +} diff --git a/src/assets/image/right.png b/src/assets/image/right.png new file mode 100644 index 0000000000000000000000000000000000000000..b6bccc92870b509ff19b9c9790c37aad2dc0c181 GIT binary patch literal 866 zcmV-o1D*VdP)Px#1am@3R0s$N2z&@+hyVZs3`s;mR9J<*m$7RbXBdZ{_q&sIU^nL>r5Ze_kP<^v zsA(+%bp{QAb|{HyI&>`L53til3Us+8V4IM*b2Vhk;^1cMrX>aA(o(3C$Za4RG^lj( zsVY5L-|6iT#n`oCUF3^@>%HGS5BJ@@_q{^GMAWCvy8CLN2Z>w*O?Z!7mDhY=e~u)OuLhns>6f+F zyCEW8Lhym8Y9z)i)po+06a$-BAiuei^IUfwI6n$_KsF+4=j(-1bEv?XUvIzb^!Pzw zDkV4o3XRzC@zeLOJ$k7?esd+4b={xRhVPf?SUbD_Ntiu&HSj#wU4LD00D&pbb=Ro| z?jZqh(l3+Vo*$L-)06%;`=t7h-f^Cd`nHddc4X~4^+Ks>0J0gUe1dR*iEPFx14zCa zc%FaiFOoNzqa%6?l{toQXFCd8Z<>rhK9?3;g@xM8SJzG0x+o$Khm=ob{P8*C;(V4C ze0%2Fw*ZfeLHl3$bl4gP=aNyFP7@A5HE^@4-z8Xj&H(vD6p_0s@_iEcS^v~Mfh!5_ zI%R;UwdwKlW(<@QeaIk1)z93W?gRVXyJXBHO$C)4$yQ12}V} zgv#pn2Yrb_84(UVH9%virRc)hpYPmB84l1e0<|QS10{|J2iP)}_V;BMj9EG{yvVH=$FjXfRNDz}0vjiQ-{`YAAV4v&k+t)hpf8LXg+^rU{Qeo?Kr5~n zN=*~TpS%tUg@*Qe7ymyS9QqeLnZ3T%v38bpw_~GY?dPx#1am@3R0s$N2z&@+hyVZrzez+vR9J<@SFvu>P!v7)IY}+m)Kw*_w910o1+jF< z(xIYAFtrP`vKYGX4@fOj)rnN%AG&mM3mt%sfvRhV3?LYS%8)`77~;f8A&Gq$(u9yU z#I_vuOxJ#X_ni0cyVv�-|igFg0^Uh-Cm-0vQoW0|3dA07U?&6ufsl=k2rwH;7*u z_5qK~xu%aT5E~HD1F0qJ5bP%va`Mpm5=p?>9`xB8=C%l)0+I+sd|640#EWk=XXn-v z)B_9PkvZ4&(dGnH z*@gjPBbY37RZ+qL~#;1kOVg6wq(fFP?#WUh;!khB_Q z;TZ-2GHUo|qlFSMWDds%0ZR$CJDJd7_DK010p|ib|PPNoSm+i-m$tpF)x~&2u9SDf+czbnoH?*T_p9SN2||6VWo zB>@01_SpSEk4v$JgUHk4(%5?KbN|qlKO^0$7S3yxMG@x0W=9`$ON6=eT4k|+.el-tree-node__content{ + background: #36B29E1a; + // border-right: 2px solid #36B29E; + box-shadow: inset -4px 0px 0px 0px #36B29E; +} + + diff --git a/src/assets/styles/index.scss b/src/assets/styles/index.scss index 71f1aed..fbfe653 100644 --- a/src/assets/styles/index.scss +++ b/src/assets/styles/index.scss @@ -191,6 +191,12 @@ aside { .text-center { text-align: center } +.text-left { + text-align: left; +} +.text-right{ + text-align: right; +} .sub-navbar { height: 50px; diff --git a/src/layout/components/Navbar.vue b/src/layout/components/Navbar.vue index 9819808..3e3c21d 100644 --- a/src/layout/components/Navbar.vue +++ b/src/layout/components/Navbar.vue @@ -144,7 +144,7 @@ export default { sessionStorage.setItem("topTab", e); this.$store.dispatch("changeTopTab", e); this.$router.replace({ - path: "/", + path: `/`, query: { timestamp: new Date().getTime(), }, diff --git a/src/permission.js b/src/permission.js index cdb36f6..3efbe42 100644 --- a/src/permission.js +++ b/src/permission.js @@ -23,7 +23,6 @@ router.beforeEach((to, from, next) => { store.dispatch('GetInfo').then(res => { // 拉取user_info const roles = res.roles - console.log('GenerateRoutes >>>>> ') store.dispatch('GenerateRoutes', { roles }).then(accessRoutes => { // 测试 默认静态页面 // store.dispatch('permission/generateRoutes', { roles }).then(accessRoutes => { @@ -40,7 +39,6 @@ router.beforeEach((to, from, next) => { }) } else { if(!store.getters.permission_add_routes.length){ - console.log('GenerateRoutes >>>>> ') store.dispatch('GenerateRoutes').then(accessRoutes => { // 测试 默认静态页面 // store.dispatch('permission/generateRoutes', { roles }).then(accessRoutes => { diff --git a/src/router/index.js b/src/router/index.js index 3201505..00643fa 100644 --- a/src/router/index.js +++ b/src/router/index.js @@ -157,7 +157,7 @@ const router = createRouter() // 注册一个全局前置守卫 router.beforeEach((to, from, next) => { - + if (to.path === "/singleLogin") { console.log("单点登录设置token", to.query.token); //判断当前路由是否需要进行权限控制 if (to.query.token) { diff --git a/src/store/modules/permission.js b/src/store/modules/permission.js index db81dab..381b131 100644 --- a/src/store/modules/permission.js +++ b/src/store/modules/permission.js @@ -167,7 +167,7 @@ function filterAsyncRouter(asyncRouterMap) { return asyncRouterMap.filter((route) => { if (route.component) { // Layout组件特殊处理 - if (route.component === 'Layout') { + if ( route.component === 'Layout') { route.component = Layout; } else { route.component = loadView(route.component); @@ -202,6 +202,24 @@ function resolveChildrenRoutes(routes, pickRoute = permission.state.selectTab) { path: `${parentRoute.path}/${v.path}` }; }) || []; + + newChildrenRoutes = newChildrenRoutes.map(v=> { + if(v.path && v.path != '/' && (!v.children || !v.children.length)){ + // 为了让非目录的一级菜单正常展示 + return { + path: '/', + orderNum: v.orderNum, + meta: v.meta, + component: Layout, + hidden: v.hidden, + children: [ + v + ] + } + } else { + return v + } + }) } } return { diff --git a/src/views/aiSupervision/waterSetting/runScene/layerTree/index.js b/src/views/aiSupervision/waterSetting/runScene/layerTree/index.js index 539c17d..a2f940b 100644 --- a/src/views/aiSupervision/waterSetting/runScene/layerTree/index.js +++ b/src/views/aiSupervision/waterSetting/runScene/layerTree/index.js @@ -183,6 +183,7 @@ const zoomToLayerActions = { // 添加图层 export async function addLayer(layerData) { + console.log('addLayer-layerData >>>>> ', layerData) const { layerType, url, id } = layerData; let action = null; // 超图 S3M图层 diff --git a/src/views/components/SyMixMap.vue b/src/views/components/SyMixMap.vue index 892268e..f0398f1 100644 --- a/src/views/components/SyMixMap.vue +++ b/src/views/components/SyMixMap.vue @@ -23,9 +23,7 @@ const viewerClick = (e) => { if (e.graphic?._style?.canEdit) { currentGraphic = e.graphic; plot.edit(e.graphic, () => { - console.log('编辑viewerClick >>>>> ', e.graphic, graphicsList) let res = graphicsList.find(item => item.graphicId === e.graphic.graphicId); - console.log('res >>>>> ', res) if(res){ res.position = e.graphic.position; res.positions = e.graphic.positions; @@ -201,14 +199,14 @@ export default { // ); setTimeout(() => { viewer.scene.camera.setView({ - destination: new Cesium.Cartesian3.fromDegrees(113.27, 23.13, this.defaultHeight), - // orientation: { - // heading: 0, - // pitch: -90, - // roll: 0, - // }, - duration: 2, - }); + destination: new Cesium.Cartesian3.fromDegrees(113.27, 23.13, this.defaultHeight), + // orientation: { + // heading: 0, + // pitch: -90, + // roll: 0, + // }, + duration: 2, + }); }, 300); }, handleKeyUpFunc(e){ diff --git a/src/views/mobilePage/index.vue b/src/views/mobilePage/index.vue index f6889dc..3ab4467 100644 --- a/src/views/mobilePage/index.vue +++ b/src/views/mobilePage/index.vue @@ -1,6 +1,11 @@ diff --git a/src/views/reservoir/safeMonitorSetting/index.vue b/src/views/reservoir/safeMonitorSetting/index.vue new file mode 100644 index 0000000..868185e --- /dev/null +++ b/src/views/reservoir/safeMonitorSetting/index.vue @@ -0,0 +1,359 @@ + + + diff --git a/src/views/reservoir/safeOperation/components/BaseInfo.vue b/src/views/reservoir/safeOperation/components/BaseInfo.vue new file mode 100644 index 0000000..3c0be5c --- /dev/null +++ b/src/views/reservoir/safeOperation/components/BaseInfo.vue @@ -0,0 +1,751 @@ + + + diff --git a/src/views/reservoir/safeOperation/components/ProjectDetail.vue b/src/views/reservoir/safeOperation/components/ProjectDetail.vue new file mode 100644 index 0000000..6a0251a --- /dev/null +++ b/src/views/reservoir/safeOperation/components/ProjectDetail.vue @@ -0,0 +1,38 @@ + + + diff --git a/src/views/reservoir/safeOperation/components/RealTimeMonitor.vue b/src/views/reservoir/safeOperation/components/RealTimeMonitor.vue new file mode 100644 index 0000000..d962716 --- /dev/null +++ b/src/views/reservoir/safeOperation/components/RealTimeMonitor.vue @@ -0,0 +1,185 @@ + + + + diff --git a/src/views/reservoir/safeOperation/index.vue b/src/views/reservoir/safeOperation/index.vue new file mode 100644 index 0000000..ca941aa --- /dev/null +++ b/src/views/reservoir/safeOperation/index.vue @@ -0,0 +1,381 @@ + + + + diff --git a/src/views/reservoir/safeOperation/js/initEcharts.js b/src/views/reservoir/safeOperation/js/initEcharts.js new file mode 100644 index 0000000..28ef4de --- /dev/null +++ b/src/views/reservoir/safeOperation/js/initEcharts.js @@ -0,0 +1,124 @@ +// 倒立柱状图,y轴inverse +export const initReverseLineOptions = () => { + return { + title: { + // text: "统计", + }, + legend: { + orient: "horizontal", + top: "2%", + }, + grid: { + left: "10%", + right: "10%", + bottom: "10%", + top: '10%', + containLabel: true, + }, + tooltip: { + trigger: "axis", + axisPointer: { + type: "cross", + label: { + backgroundColor: "#283b56", + }, + }, + }, + xAxis: [ + { + type: "category", + name: "时间", + position: "bottom", + axisLine: { + show: true, + }, + axisTick: { + alignWithLabel: true, + }, + data: ['00:00','02:00','04:00','06:00','08:00','10:00','12:00', + '14:00','16:00','18:00','20:00','22:00'], + }, + ], + yAxis: [ + { + type: "value", + inverse: true, + name: "降雨量(mm)", + nameLocation: 'start', + }, + ], + series: [ + { + color: "#4a66bb", + type: 'line', + smooth: true, + name: '降雨量', + areaStyle: {}, + data: [0, 10, 4, 8, 1, 6, 3, 5, 2, 7, 9, 11], + }, + ], + }; +}; + +// 双y轴柱状图 +export const doubleYAxisOptions = () => { + return { + title: { + // text: "统计", + }, + grid: { + left: "10%", + right: "10%", + bottom: "10%", + top: '10%', + containLabel: true, + }, + tooltip: { + trigger: "axis", + axisPointer: { + type: "cross", + label: { + backgroundColor: "#283b56", + }, + }, + }, + xAxis:[ + { + type: 'category', + name: '时间', + nameLocation: 'middle', + nameGap: 30, + data: ['00:00','02:00','04:00','06:00','08:00','10:00','12:00', + '14:00','16:00','18:00','20:00','22:00'], + } + ], + yAxis: [ + { + type: 'value', + name: '降雨量(mm)', + nameLocation: 'end', + }, + { + type: 'value', + name: '温度(℃)', + position: 'right', + nameLocation: 'end', + } + ], + series: [ + { + name: '降雨量', + type: 'line', + smooth: true, + data: [0, 10, 4, 8, 1, 6, 3, 5, 2, 7, 9, 11], + }, + { + name: '温度', + type: 'line', + smooth: true, + yAxisIndex: 1, + data: [24,28,26,30,25,27,29,31,23,22,21,20], + } + ] + } +} diff --git a/src/views/reservoir/safeOperation/js/mapUtils.js b/src/views/reservoir/safeOperation/js/mapUtils.js new file mode 100644 index 0000000..19fde01 --- /dev/null +++ b/src/views/reservoir/safeOperation/js/mapUtils.js @@ -0,0 +1,119 @@ +import axios from 'axios' + +const identifyLayerActions = { + '021102': async (params) => { + return new Promise(async (resolve, reject) => { + const { url, input_geometry, geometry_type, layers = 'all', returnGeometry = false, tolerance = 1 } = params; + const result = await axios.get(`${url}.json`); + if (result.status === 200 && result.data) { + const { xmin, ymin, xmax, ymax } = result.data.fullExtent; + const mapExtent = `${xmin},${ymin},${xmax},${ymax}`; + const data = await axios.get( + `${url}/identify?geometry=${input_geometry}&geometryType=${geometry_type}&layers=${layers}&returnGeometry=${returnGeometry}&mapExtent=${mapExtent}&imageDisplay=600,550,96&tolerance=${tolerance}&out_fields=*&f=json` + ); + if (data.status === 200 && data.data) { + resolve(data.data); + } else { + resolve(null); + } + } + }); + }, + '030300': async (params) => { + console.log(params); + }, + '081100': async (params) => { + return new Promise(async (resolve, reject) => { + const { queryMode, bufferDistance, geometry, url, layerTable, layerName, k } = params; + const queryUrl = url.split('maps/')[0].replace('map-', 'data-'); + let requestUrl = `${queryUrl}data/featureResults.rjson?returnContent=true`; + if (k) { + requestUrl += `&k=${k}`; + } + const result = await axios.post( + requestUrl, + JSON.stringify({ + datasetNames: [layerTable || layerName], + getFeatureMode: queryMode, + bufferDistance, + geometry + }), + { + headers: { + 'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8' + } + } + ); + resolve(result); + }); + } +}; + +export const queryLayersByPos = (position, layerList = [], cb) => { + + const { lng, lat } = position; + const layers = layerList + layers.forEach(async (layer) => { + const action = identifyLayerActions[layer.layerType]; + switch (layer.layerType) { + case '021102': { + const input_geometry = `${lng},${lat}`; + const geometry_type = 'esriGeometryPoint'; + const result = await action({ + input_geometry, + geometry_type, + url: layer.url + }); + let res; + if (result?.results?.length > 0) { + res = result.results[0] + } + if(cb) cb(res) + break; + } + case '030300': + break; + case '081100': { + const queryMode = 'BUFFER'; + const bufferDistance = 0.0005; // 缓冲距离大概是50米 + const spatialQueryMode = 'INTERSECT'; + const geometry = { + id: 0, + style: null, + parts: [1], + points: [ + { + x: lng, + y: lat + } + ], + type: 'POINT' + }; + let type = ''; + let isSite = false; + let layerTable = ''; + if (layer.extendData) { + const extendData = JSON.parse(layer.extendData); + + } + const result = await action({ + queryMode, + spatialQueryMode, + bufferDistance, + geometry, + layerName: layer.text, + layerTable, + url: layer.url, + k: layer.serviceToken + }); + if ([200, 201].includes(result.status)) { + console.log('处理业务数据 >>>>>> ', result) + + } + break; + } + default: + break; + } + }); +};