Browse Source

feat: 水库第一版需求

sy-water-data-board-ui
panyuyi 6 months ago
parent
commit
f50451fcb8
  1. 4
      package.json
  2. 44
      src/api/reservoir/index.js
  3. BIN
      src/assets/image/right.png
  4. BIN
      src/assets/image/warning.png
  5. 7
      src/assets/styles/element-ui.scss
  6. 6
      src/assets/styles/index.scss
  7. 2
      src/layout/components/Navbar.vue
  8. 2
      src/permission.js
  9. 2
      src/router/index.js
  10. 20
      src/store/modules/permission.js
  11. 1
      src/views/aiSupervision/waterSetting/runScene/layerTree/index.js
  12. 18
      src/views/components/SyMixMap.vue
  13. 26
      src/views/mobilePage/index.vue
  14. 359
      src/views/reservoir/safeMonitorSetting/index.vue
  15. 751
      src/views/reservoir/safeOperation/components/BaseInfo.vue
  16. 38
      src/views/reservoir/safeOperation/components/ProjectDetail.vue
  17. 185
      src/views/reservoir/safeOperation/components/RealTimeMonitor.vue
  18. 381
      src/views/reservoir/safeOperation/index.vue
  19. 124
      src/views/reservoir/safeOperation/js/initEcharts.js
  20. 119
      src/views/reservoir/safeOperation/js/mapUtils.js

4
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"
]
}
}

44
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'
})
}

BIN
src/assets/image/right.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 866 B

BIN
src/assets/image/warning.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 789 B

7
src/assets/styles/element-ui.scss

@ -83,4 +83,11 @@
box-sizing: content-box;
}
.el-tree.el-tree--highlight-current .el-tree-node.is-current>.el-tree-node__content{
background: #36B29E1a;
// border-right: 2px solid #36B29E;
box-shadow: inset -4px 0px 0px 0px #36B29E;
}

6
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;

2
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(),
},

2
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 => {

2
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) {

20
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 {

1
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图层

18
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){

26
src/views/mobilePage/index.vue

@ -1,6 +1,11 @@
<template>
<div class="mobile-page">
<iframe v-if="h5Src" class="iframe-page" :src="h5Src" title="Mobile Page"></iframe>
<iframe
v-if="h5Src"
class="iframe-page"
:src="h5Src"
title="Mobile Page"
></iframe>
</div>
</template>
<script>
@ -8,26 +13,25 @@ import { getToken } from "@/utils/auth";
export default {
data() {
return {
h5Src: '',
h5Src: "",
};
},
created() {
const isProDuction = process.env.NODE_ENV === "production";
const topTab = sessionStorage.getItem("topTab");
console.log(topTab)
// h5
const devSrc = topTab === 'sluice'
? "http://172.16.35.166:8002/mobileH5/SZengineeringInspectionList"
: 'http://172.16.35.166:8002/mobileH5/engineeringInspectionList';
const devSrc =
topTab === "sluice"
? "http://172.16.35.166:8002/mobileH5/SZengineeringInspectionList"
: "http://172.16.35.166:8002/mobileH5/engineeringInspectionList";
// prod
// const proSrc = 'http://shuili-h5.product.dev.com:30115/'
//
const currentUrl = topTab === 'sluice'
? window.location.origin + "/mobileH5/SZengineeringInspectionList"
: window.location.origin + '/mobileH5/engineeringInspectionList';
console.log("currentUrl:", currentUrl);
const currentUrl =
topTab === "sluice"
? window.location.origin + "/mobileH5/SZengineeringInspectionList"
: window.location.origin + "/mobileH5/engineeringInspectionList";
this.h5Src = `${isProDuction ? currentUrl : devSrc}?t=${getToken()}`;
console.log(123123)
},
};
</script>

359
src/views/reservoir/safeMonitorSetting/index.vue

@ -0,0 +1,359 @@
<template>
<div class="safe-monitor-setting-page">
<TopBackTitle :showBackBtn="false"></TopBackTitle>
<div class="container-box flex p-16">
<div class="tree-box">
<el-input v-model="filterText" placeholder="请输入关键字"></el-input>
<el-tree
class="filter-tree mt-10"
highlight-current
:data="treeData"
:props="defaultProps"
lazy
:load="loadTree"
:filter-node-method="filterNode"
@node-click="handleClickTree"
ref="tree"
>
</el-tree>
</div>
<div class="content-box" ref="contentRef">
<div class="flex items-center">
<span>测点编码</span>
<el-input
class="w-200"
size="small"
v-model="searchCode"
placeholder="请输入"
></el-input>
<span class="ml-24">测点类型</span>
<el-select size="small" class="w-200" v-model="searchType">
<el-option label="全部" value=""></el-option>
<el-option
v-for="item in searchTypeOptions"
:label="item.dictLabel"
:value="item.dictValue"
:key="dictValue"
></el-option>
</el-select>
</div>
<el-table
class="mt-12"
:data="tableData"
border
style="width: 100%"
:height="tableHeight"
>
<el-table-column type="index" label="序号" width="60">
</el-table-column>
<el-table-column prop="name" label="测点名称"> </el-table-column>
<el-table-column prop="code" label="测站编码"> </el-table-column>
<el-table-column prop="type" label="测站类型"> </el-table-column>
<el-table-column prop="code" label="采集方式"> </el-table-column>
<el-table-column prop="source" label="数据来源"> </el-table-column>
<el-table-column label="操作" width="100">
<template slot-scope="scope">
<el-button type="text" @click="handleSetForm(scope.row)"
>配置</el-button
>
</template>
</el-table-column>
</el-table>
<div class="mt-24 flex justify-end">
<el-pagination
background
layout="prev, pager, next"
:page-size="params.pageSize"
:total="params.total"
>
</el-pagination>
</div>
<div class="bottom-box">
<div class="flex items-center">
<div class="w-180 text-right flex-shrink-0">预警类型</div>
<el-select class="w-200" v-model="currentForm.warnType">
<el-option label="日降雨" value="1"></el-option>
<el-option label="x小时累计降雨" value="2"></el-option>
</el-select>
<div class="ml-10">日降雨指本日8时至次日8时</div>
</div>
<div v-for="(item, index) in currentForm.noticeList" :key="index">
<div class="flex items-center mt-10">
<div class="w-180 text-right flex-shrink-0">设置预警值</div>
<el-input
class="w-200"
v-model="item.warnValue"
placeholder="请输入"
></el-input>
<div class="ml-10">mm/d</div>
<i
v-if="
currentForm.noticeList.length > 1 &&
index != currentForm.noticeList.length - 1
"
class="el-icon-remove ml-18 font-18 cursor-pointer"
@click="handleRemoveNoticeItem(index)"
></i>
<i
v-else
class="el-icon-circle-plus ml-18 font-18 cursor-pointer"
@click="handleAddNoticeItem"
></i>
</div>
<div class="flex items-center mt-10">
<div class="w-180 text-right flex-shrink-0">预警通知人</div>
<el-select
class="w-200"
filterable
v-model="item.userId"
remote
:remote-method="searchUser"
value-key="id"
placeholder="请输入关键词搜索用户"
>
<el-option
v-for="item in userList"
:key="item.id"
:label="item.name"
:value="item.id"
></el-option>
</el-select>
</div>
</div>
<div class="flex items-start mt-10">
<div class="w-180 text-right flex-shrink-0">通知模板</div>
<el-input
class=""
type="textarea"
placeholder="请输入"
:rows="4"
v-model="currentForm.notifyText"
></el-input>
</div>
<div class="flex justify-end mt-16">
<el-button type="primary" @click="handleSaveRowForm"
>保存</el-button
>
</div>
</div>
</div>
</div>
</div>
</template>
<script>
import TopBackTitle from "@/components/TopBackTitle";
import { getAreasData } from "@/api/areas/index";
import { getDicts } from "@/api/management";
import { listUser } from "@/api/system/user";
export default {
components: { TopBackTitle },
data() {
return {
filterText: "",
treeData: [],
defaultProps: {
children: "children",
label: "label",
isLeaf: "leaf",
},
params: {
pageSize: 20,
pageNum: 1,
total: 0,
},
searchCode: "",
searchType: "",
searchTypeOptions: [],
userList: [],
tableData: [{}, {}],
currentForm: {
noticeList: [
{
warnType: "",
userId: "",
},
],
notifyText: `{通知人name}同志,现发生【水库名称】【测站点编码】{预警类型name},预警数值【监测值、监测日期时间】,请您严格履行责任人防汛职责,(核对水库数据,提交相关水行政主管单位、联系仪器厂商校准仪器),保证水库数据准确。【广东省水利厅】`,
},
tableHeight: null,
};
},
watch: {
filterText(val) {
this.$refs.tree.filter(val);
},
},
created() {
this.getTreeData();
this.searchUser("");
//
getDicts("measurement_point_type").then((res) => {
if (res.data && Array.isArray(res.data)) {
this.searchTypeOptions = res.data;
}
});
},
mounted() {
let h = this.$refs.contentRef.offsetHeight - 418 - 30;
this.tableHeight = h > 0 ? h : 300;
},
methods: {
//
getTreeData() {
getAreasData().then((items) => {
let res = [];
let getChildren = (res, pid) => {
for (const i of items.data) {
if (i.parentid === pid) {
const newItem = {
label: i.name,
value: i.id,
};
if (i.layer != 3) newItem.children = [];
res.push(newItem);
getChildren(newItem.children, newItem.value);
}
}
};
getChildren(res, items.data[0].parentid);
this.treeData = res;
});
},
//
searchUser(e) {
listUser({
data: {
timeView: {
timeField: "create_time",
},
},
cv: {
name: "nickName",
type: "like",
value: e,
},
pageSize: 100,
pageNum: 1,
}).then((res) => {
this.userList =
res.records?.map((v) => {
return {
id: v.id,
name: v.nickName,
uid: v.uuid,
};
}) || [];
});
},
filterNode(value, data) {
if (!value) return true;
return data.label.indexOf(value) !== -1;
},
loadTree(node, resolve) {
console.log("node >>>>> ", node);
if (node.level === 0) {
return resolve(node.data);
} else {
if (node.data.isEnd) {
return resolve([]);
} else if (node.data.children?.length) {
return resolve(node.data.children);
} else if (!node.isLeaf) {
setTimeout(() => {
resolve([
{
id: 111,
label: "xxx水库",
isEnd: true,
leaf: true,
},
]);
}, 800);
} else {
resolve();
}
}
},
handleClickTree(data, node) {
console.log("handleClickTree >>>>> ", data, node);
if (node.isLeaf) {
console.log("点击叶子节点----加载水库列表 >>>> ");
}
},
handleAddNoticeItem() {
this.currentForm.noticeList.push({
warnValue: "",
userId: "",
});
},
handleRemoveNoticeItem(index) {
this.currentForm.noticeList.splice(index, 1);
},
handleSetForm(row) {
this.currentForm = {
noticeList: row.noticeList || [
{
warnValue: "",
userId: "",
},
],
warnType: row.warnType,
notifyText: row.notifyText || "",
};
},
handleSaveRowForm() {},
},
};
</script>
<style scoped lang="scss">
.safe-monitor-setting-page {
position: relative;
font-size: 14px;
height: 100%;
.container-box {
height: calc(100% - 56px);
}
.tree-box {
flex-shrink: 0;
width: 240px;
padding: 12px;
background: #fff;
border-radius: 2px;
}
.content-box {
flex: 1;
background: #fff;
margin-left: 10px;
padding: 12px;
overflow: auto;
}
.bottom-box {
border: 1px solid #ccc;
padding: 10px;
margin-top: 16px;
background: #f4f5f7;
}
.w-100 {
width: 100px;
}
.w-180 {
width: 180px;
}
.w-200 {
width: 200px;
}
}
</style>

751
src/views/reservoir/safeOperation/components/BaseInfo.vue

@ -0,0 +1,751 @@
<template>
<div class="baseInfo-page">
<el-tabs v-model="activeName" @tab-click="handleChangeTab">
<el-tab-pane label="水库信息" name="1">
<div>水库基本信息</div>
<el-descriptions
class="mt-16"
:column="3"
border
:labelStyle="{
'text-align': 'left',
width: '120px',
height: '50px',
}"
:contentStyle="{ minWidth: '180px' }"
>
<el-descriptions-item>
<template slot="label"> 水库名称 </template>
{{ this.form.resName }}
</el-descriptions-item>
<el-descriptions-item>
<template slot="label"> 水库代码 </template>
{{ this.form.resCode }}
</el-descriptions-item>
<el-descriptions-item>
<template slot="label"> 水库注册登记号 </template>
{{ this.form.registerCode }}
</el-descriptions-item>
<el-descriptions-item>
<template slot="label"> 水库功能 </template>
{{ this.form.resAction }}
</el-descriptions-item>
<el-descriptions-item>
<template slot="label"> 水库类型 </template>
{{ this.form.resType }}
</el-descriptions-item>
<el-descriptions-item>
<template slot="label"> 水库状态 </template>
{{ this.form.resState }}
</el-descriptions-item>
<el-descriptions-item>
<template slot="label"> 工程规模 </template>
{{ this.form.engScal }}
</el-descriptions-item>
<el-descriptions-item>
<template slot="label"> 工程等别 </template>
{{ this.form.engGrad }}
</el-descriptions-item>
<el-descriptions-item>
<template slot="label"> 曾用名 </template>
{{ this.form.oldName }}
</el-descriptions-item>
<el-descriptions-item>
<template slot="label"> 水库中心经度 </template>
{{ this.form.resCenLong }}
</el-descriptions-item>
<el-descriptions-item>
<template slot="label"> 水库中心纬度 </template>
{{ this.form.resCenLat }}
</el-descriptions-item>
<el-descriptions-item>
<template slot="label"> 归口管理部门 </template>
{{ this.form.admDep }}
</el-descriptions-item>
<el-descriptions-item>
<template slot="label"> 水库主管部门 </template>
{{ this.form.cmun }}
</el-descriptions-item>
<el-descriptions-item>
<template slot="label"> 水库管理部门 </template>
{{ "" }}
</el-descriptions-item>
<el-descriptions-item>
<template slot="label"> 所在行政区划 </template>
{{ "" }}
</el-descriptions-item>
<el-descriptions-item>
<template slot="label"> 所在流域 </template>
{{ this.form.localBasin }}
</el-descriptions-item>
<el-descriptions-item>
<template slot="label"> 所在河流 </template>
{{ this.form.localRiver }}
</el-descriptions-item>
<el-descriptions-item>
<template slot="label"> 水准基面 </template>
{{ "" }}
</el-descriptions-item>
<el-descriptions-item>
<template slot="label"> 是否注册 </template>
{{ "" }}
</el-descriptions-item>
<el-descriptions-item>
<template slot="label"> 左下角经度 </template>
{{ "" }}
</el-descriptions-item>
<el-descriptions-item>
<template slot="label"> 左下角纬度 </template>
{{ "" }}
</el-descriptions-item>
<el-descriptions-item>
<template slot="label"> 右上角经度 </template>
{{ "" }}
</el-descriptions-item>
<el-descriptions-item>
<template slot="label"> 右上角纬度 </template>
{{ "" }}
</el-descriptions-item>
<el-descriptions-item>
<template slot="label"> 水库所在位置 </template>
{{ this.form.resLoc }}
</el-descriptions-item>
<el-descriptions-item>
<template slot="label"> 水库管理单位 </template>
{{ this.form.mnun }}
</el-descriptions-item>
<el-descriptions-item>
<template slot="label"> 工程建设情况 </template>
{{ this.form.engStat }}
</el-descriptions-item>
<el-descriptions-item>
<template slot="label"> 有效年份 </template>
{{ "" }}
</el-descriptions-item>
<el-descriptions-item>
<template slot="label"> 主要建筑物级别 </template>
{{ "" }}
</el-descriptions-item>
<el-descriptions-item>
<template slot="label"> 控制流域面积 </template>
{{ this.form.watShedArea }}
</el-descriptions-item>
<el-descriptions-item>
<template slot="label"> 河道长度 </template>
{{ "" }}
</el-descriptions-item>
<el-descriptions-item>
<template slot="label"> 河道比降 </template>
{{ "" }}
</el-descriptions-item>
<el-descriptions-item>
<template slot="label"> 多年平均径流量 </template>
{{ this.form.avanrnam }}
</el-descriptions-item>
<el-descriptions-item>
<template slot="label"> 多年平均降水量 </template>
{{ this.form.avanpram }}
</el-descriptions-item>
<el-descriptions-item>
<template slot="label"> 多年平均流沙量 </template>
{{ this.form.avansdam }}
</el-descriptions-item>
<el-descriptions-item>
<template slot="label"> 设计重现期 </template>
{{ this.form.dsrcin }}
</el-descriptions-item>
<el-descriptions-item>
<template slot="label"> 设计洪峰流量 </template>
{{ this.form.dspkfl }}
</el-descriptions-item>
<el-descriptions-item>
<template slot="label"> 设计1日洪水洪量(万m³) </template>
{{ "" }}
</el-descriptions-item>
<el-descriptions-item>
<template slot="label"> 设计3日洪水洪量(万m³) </template>
{{ "" }}
</el-descriptions-item>
<el-descriptions-item>
<template slot="label"> 校核重现期 </template>
{{ this.form.chrcin }}
</el-descriptions-item>
<el-descriptions-item>
<template slot="label"> 校核洪峰流量 </template>
{{ this.form.chpkfl }}
</el-descriptions-item>
<el-descriptions-item>
<template slot="label"> 校核洪水历时 </template>
{{ "" }}
</el-descriptions-item>
<el-descriptions-item>
<template slot="label"> 校核洪水总量 </template>
{{ this.form.chflvl }}
</el-descriptions-item>
<el-descriptions-item>
<template slot="label"> 设计洪水位 </template>
{{ this.form.dsfllv }}
</el-descriptions-item>
<el-descriptions-item>
<template slot="label"> 校核洪水位 </template>
{{ this.form.chfllv }}
</el-descriptions-item>
<el-descriptions-item>
<template slot="label"> 防洪高水位 </template>
{{ this.form.uppLevFlco }}
</el-descriptions-item>
<el-descriptions-item>
<template slot="label"> 防洪限制水位库容 </template>
{{ this.form.flLowLimLevCap }}
</el-descriptions-item>
<el-descriptions-item>
<template slot="label"> 正常蓄水位 </template>
{{ this.form.normWatLev }}
</el-descriptions-item>
<el-descriptions-item>
<template slot="label"> 正常蓄水位相应水面面积 </template>
{{ "" }}
</el-descriptions-item>
<el-descriptions-item>
<template slot="label"> 正常蓄水位相应库容 </template>
{{ this.form.normPoolStagCap }}
</el-descriptions-item>
<el-descriptions-item>
<template slot="label"> 死水位 </template>
{{ this.form.deadLev }}
</el-descriptions-item>
<el-descriptions-item>
<template slot="label"> 总库容 </template>
{{ this.form.totCap }}
</el-descriptions-item>
<el-descriptions-item>
<template slot="label"> 调节库容 </template>
{{ this.form.storFlCap }}
</el-descriptions-item>
<el-descriptions-item>
<template slot="label"> 死库容 </template>
{{ this.form.deadCap }}
</el-descriptions-item>
<el-descriptions-item>
<template slot="label"> 防洪库容 </template>
{{ this.form.flcoCap }}
</el-descriptions-item>
<el-descriptions-item>
<template slot="label"> 兴利库容 </template>
{{ "" }}
</el-descriptions-item>
<el-descriptions-item>
<template slot="label"> 坝址控制流域面积 </template>
{{ this.form.watShedArea }}
</el-descriptions-item>
<el-descriptions-item>
<template slot="label"> 地震基本烈度 </template>
{{ "" }}
</el-descriptions-item>
<el-descriptions-item>
<template slot="label"> 地震动峰值加速度 </template>
{{ "" }}
</el-descriptions-item>
<el-descriptions-item>
<template slot="label"> 设防地震烈度 </template>
{{ "" }}
</el-descriptions-item>
<el-descriptions-item>
<template slot="label"> 集雨面积 </template>
{{ "" }}
</el-descriptions-item>
<el-descriptions-item>
<template slot="label"> 下泄生态流量 </template>
{{ "" }}
</el-descriptions-item>
<el-descriptions-item>
<template slot="label"> 数据来源 </template>
{{ "" }}
</el-descriptions-item>
<el-descriptions-item>
<template slot="label"> 数据创建时间 </template>
{{ this.form.createTime }}
</el-descriptions-item>
<el-descriptions-item>
<template slot="label"> 备注 </template>
{{ this.form.note }}
</el-descriptions-item>
</el-descriptions>
<el-descriptions
class="mt-16"
:column="2"
border
:labelStyle="{
'text-align': 'left',
width: '120px',
height: '100px',
}"
:contentStyle="{ minWidth: '180px' }"
>
<el-descriptions-item :span="2">
<template slot="label"> 水库概况 </template>
{{ this.form.resOv }}
</el-descriptions-item>
</el-descriptions>
<div class="mt-16">水库建设时间</div>
<el-descriptions
class="mt-16"
:column="2"
border
:labelStyle="{
'text-align': 'left',
width: '120px',
height: '60px',
}"
:contentStyle="{ minWidth: '180px' }"
>
<el-descriptions-item>
<template slot="label"> 开工时间 </template>
{{ this.form.startDate }}
</el-descriptions-item>
<el-descriptions-item>
<template slot="label"> 完工时间 </template>
{{ this.form.compDate }}
</el-descriptions-item>
</el-descriptions>
<div class="mt-16">最近异常加固改造时间</div>
<el-descriptions
class="mt-16"
:column="2"
border
:labelStyle="{
'text-align': 'left',
width: '120px',
height: '60px',
}"
:contentStyle="{ minWidth: '180px' }"
>
<el-descriptions-item>
<template slot="label"> 更新时间 </template>
{{ this.form.updateTime }}
</el-descriptions-item>
</el-descriptions>
</el-tab-pane>
<el-tab-pane label="水文特征" name="2">
<div>水库水文特征</div>
<el-descriptions
class="mt-16"
:column="3"
border
:labelStyle="{
'text-align': 'left',
width: '120px',
height: '50px',
}"
:contentStyle="{ minWidth: '180px' }"
>
<el-descriptions-item>
<template slot="label"> 控制流域面积(km²) </template>
{{ this.form.watShedArea }}
</el-descriptions-item>
<el-descriptions-item>
<template slot="label"> 多年平均降雨量(mm) </template>
{{ this.form.avanpram }}
</el-descriptions-item>
<el-descriptions-item>
<template slot="label"> 多年平均径流量(万m³) </template>
{{ this.form.avanrnam }}
</el-descriptions-item>
<el-descriptions-item>
<template slot="label"> 多年平均输沙两(万t) </template>
{{ this.form.avansdam }}
</el-descriptions-item>
<el-descriptions-item>
<template slot="label"> 多年平均最低气温() </template>
{{ this.form.myavgmintp }}
</el-descriptions-item>
<el-descriptions-item>
<template slot="label"> 多年平均蒸发量(mm) </template>
{{ this.form.avanev }}
</el-descriptions-item>
<el-descriptions-item>
<template slot="label"> 多年平均含沙量(kg/m³) </template>
{{ "" }}
</el-descriptions-item>
<el-descriptions-item>
<template slot="label"> 水库调节性能 </template>
{{ "" }}
</el-descriptions-item>
<el-descriptions-item>
<template slot="label"> 正常蓄水位相应水面面积(km²) </template>
{{ "" }}
</el-descriptions-item>
<el-descriptions-item>
<template slot="label"> 防洪高水位(m) </template>
{{ this.form.uppLevFlco }}
</el-descriptions-item>
<el-descriptions-item>
<template slot="label"> 死水位(m) </template>
{{ this.form.deadLev }}
</el-descriptions-item>
<el-descriptions-item>
<template slot="label"> 橙色预警水位(m) </template>
{{ "" }}
</el-descriptions-item>
<el-descriptions-item>
<template slot="label"> 红色预警水位(m) </template>
{{ "" }}
</el-descriptions-item>
<el-descriptions-item>
<template slot="label"> 黄色预警水位(m) </template>
{{ "" }}
</el-descriptions-item>
<el-descriptions-item>
<template slot="label"> 汛期开始日期 </template>
{{ "" }}
</el-descriptions-item>
<el-descriptions-item>
<template slot="label"> 汛期结束日期 </template>
{{ "" }}
</el-descriptions-item>
<el-descriptions-item>
<template slot="label"> 水准基面 </template>
{{ "" }}
</el-descriptions-item>
<el-descriptions-item>
<template slot="label"> 备注 </template>
{{ this.form.note }}
</el-descriptions-item>
</el-descriptions>
<div class="mt-16">设计洪水</div>
<el-descriptions
class="mt-16"
:column="3"
border
:labelStyle="{
'text-align': 'left',
width: '120px',
height: '50px',
}"
:contentStyle="{ minWidth: '180px' }"
>
<el-descriptions-item>
<template slot="label"> 校核洪峰流量(m³/s) </template>
{{ this.form.chpkfl }}
</el-descriptions-item>
<el-descriptions-item>
<template slot="label"> 设计洪峰流量(m³/s) </template>
{{ this.form.dspkfl }}
</el-descriptions-item>
<el-descriptions-item>
<template slot="label"> 设计洪水位(m) </template>
{{ this.form.dsfllv }}
</el-descriptions-item>
<el-descriptions-item>
<template slot="label"> 校核洪水位(m) </template>
{{ this.form.chfllv }}
</el-descriptions-item>
<el-descriptions-item>
<template slot="label"> 设计1日洪水洪量(万m³) </template>
{{ "" }}
</el-descriptions-item>
<el-descriptions-item>
<template slot="label"> 设计3日洪水洪量(万m³) </template>
{{ "" }}
</el-descriptions-item>
<el-descriptions-item>
<template slot="label"> 校核洪水历时(d) </template>
{{ "" }}
</el-descriptions-item>
<el-descriptions-item>
<template slot="label"> 洪水总量 </template>
{{ "" }}
</el-descriptions-item>
</el-descriptions>
<div class="mt-16">汛期限制水位</div>
<el-descriptions
class="mt-16"
:column="3"
border
:labelStyle="{
'text-align': 'left',
width: '120px',
height: '50px',
}"
:contentStyle="{ minWidth: '180px' }"
>
<el-descriptions-item>
<template slot="label"> 设计重现期 </template>
{{ this.form.dsrcin }}
</el-descriptions-item>
<el-descriptions-item>
<template slot="label"> 河道比降 </template>
{{ "" }}
</el-descriptions-item>
<el-descriptions-item>
<template slot="label"> 河道长度 </template>
{{ "" }}
</el-descriptions-item>
<el-descriptions-item>
<template slot="label"> 汛期限制水位主汛期 </template>
{{ "" }}
</el-descriptions-item>
</el-descriptions>
<div class="mt-16">库容</div>
<el-descriptions
class="mt-16"
:column="3"
border
:labelStyle="{
'text-align': 'left',
width: '120px',
height: '50px',
}"
:contentStyle="{ minWidth: '180px' }"
>
<el-descriptions-item>
<template slot="label"> 兴利库容 </template>
{{ "" }}
</el-descriptions-item>
<el-descriptions-item>
<template slot="label"> 总库容(m³) </template>
{{ this.form.totCap }}
</el-descriptions-item>
<el-descriptions-item>
<template slot="label"> 防洪库容(m³) </template>
{{ this.form.flcoCap }}
</el-descriptions-item>
<el-descriptions-item>
<template slot="label"> 调节库容(m³) </template>
{{ this.form.storFlCap }}
</el-descriptions-item>
<el-descriptions-item>
<template slot="label"> 死库容(m³) </template>
{{ this.form.deadCap }}
</el-descriptions-item>
</el-descriptions>
</el-tab-pane>
<el-tab-pane label="库容曲线" name="3">
<div class="chart-container" ref="lineChartRef"></div>
</el-tab-pane>
<el-tab-pane label="责任人信息" name="4">
<div>责任人信息</div>
<el-table
class="mt-16"
:data="dutyPersonList"
border
style="width: 100%"
>
<el-table-column type="index" label="序号" width="60">
</el-table-column>
<el-table-column prop="dutyName" label="负责人" width="120">
</el-table-column>
<el-table-column prop="dutyType" label="负责人类别" width="120">
</el-table-column>
<el-table-column prop="phone" label="电话"> </el-table-column>
<el-table-column prop="manageUnit" label="单位"> </el-table-column>
<el-table-column prop="createTime" label="数据创建时间">
</el-table-column>
</el-table>
</el-tab-pane>
</el-tabs>
</div>
</template>
<script>
import * as echarts from "echarts";
import {
getReservoirBaseDetailData,
getReservoirRsppDetailData,
} from "@/api/reservoir";
export default {
data() {
return {
myChart: null,
code: null,
activeName: "1",
typeApi: {
["1"]: this.initBaseAndRsppInfo,
["2"]: this.initBaseAndRsppInfo,
["3"]: this.initEchart,
["4"]: null,
},
form: {},
dutyPersonList: [
// {
// id: "12312",
// dutyName: "",
// dutyType: "0",
// phone: "10086",
// manageUnit: "",
// createTime: "2024-10-18 14:01:32",
// },
],
};
},
created() {},
methods: {
initBaseInfo(code) {
getReservoirBaseDetailData(code).then((res) => {
if (res?.data) {
console.log("getReservoirBaseDetailData >>>>> ", res.data);
this.form = {
...this.form,
...res.data,
};
}
});
},
initRsppInfo(code) {
getReservoirRsppDetailData(code).then((res) => {
if (res?.data) {
Object.keys(res.data).forEach((key) => {
this.form[key] = res.data[key];
});
}
});
},
initBaseAndRsppInfo(code) {
this.initBaseInfo(code);
this.initRsppInfo(code);
},
initData(code) {
console.log("code >>>>> ", code);
this.code = code;
this.activeName = "1";
this.initBaseAndRsppInfo(code);
},
initEchart() {
let chartDom = this.$refs.lineChartRef;
if (!chartDom) return;
if (this.myChart) {
this.myChart.dispose();
}
this.myChart = echarts.init(chartDom);
let option;
option = {
title: {
// text: "World Population",
},
color: ["#38A0FF", "#4CCA73", "#FBD437"],
tooltip: {
trigger: "axis",
axisPointer: {
type: "cross",
label: {
backgroundColor: "#283b56",
},
},
},
legend: {
orient: "horizontal",
bottom: "2%",
},
grid: {
left: "10%",
right: "10%",
top: "10%",
bottom: "12%",
containLabel: true,
},
xAxis: [
{
type: "category",
name: "库容",
nameLocation: "middle",
nameGap: 24,
axisLine: {
show: true,
lineStyle: {
color: "green",
},
},
axisTick: {
alignWithLabel: true,
},
data: [0, 100, 200, 300, 400, 500],
},
{
type: "category",
name: "面积(km²)",
nameLocation: "middle",
position: "top",
nameGap: 24,
axisLine: {
onZero: false,
show: true,
lineStyle: {
// color: "red",
},
},
data: [0, 5000, 10000, 15000, 20000, 25000],
},
],
yAxis: [
{
type: "value",
name: "水位(mm)",
position: "left",
nameLocation: "middle",
nameGap: 40,
axisLine: {
onZero: false,
show: true,
},
axisLabel: {
formatter: "{value}",
},
},
// {
// type: "value",
// name: "test1",
// position: "right",
// nameLocation: "middle",
// axisLine: {
// onZero: false,
// show: true,
// color: "red",
// },
// alignTicks: true,
// axisLabel: {
// formatter: "{value}?",
// },
// },
],
series: [
{
type: "line",
color: "#0000f7",
name: "库容",
data: [0, 10, 20, 30, 40],
},
{
type: "line",
color: "#00f400",
name: "面积",
data: [0, 2890, 3543, 2938, 329],
},
],
};
option && this.myChart.setOption(option);
window.addEventListener("resize", function () {
myChart.resize();
});
},
handleChangeTab() {
this.typeApi[this.activeName] && this.typeApi[this.activeName](this.code);
},
},
};
</script>
<style scoped lang="scss">
.baseInfo-page {
padding: 0 12px;
.chart-container {
width: 480px;
height: 480px;
}
}
</style>

38
src/views/reservoir/safeOperation/components/ProjectDetail.vue

@ -0,0 +1,38 @@
<template>
<div class="project-detail-page">
<el-tabs :tab-position="'left'" v-model="activeTab">
<el-tab-pane label="基础信息" name="1">
<BaseInfo ref="baseInfoRef"></BaseInfo>
</el-tab-pane>
<el-tab-pane label="实时监测" name="2">
<RealTimeMonitor ref="realTimeMonitor"></RealTimeMonitor>
</el-tab-pane>
<el-tab-pane :disabled="true" label="监测预警" name="3"
>监测预警未确定需求</el-tab-pane
>
</el-tabs>
</div>
</template>
<script>
import BaseInfo from "./BaseInfo.vue";
import RealTimeMonitor from "./RealTimeMonitor.vue";
export default {
components: { BaseInfo, RealTimeMonitor },
data() {
return {
activeTab: "1",
};
},
created() {},
methods: {
initData(code) {
this.$refs.baseInfoRef.initData(code);
this.$refs.realTimeMonitor.initData(code);
},
},
};
</script>
<style scoped lang="scss">
.project-detail-page {
}
</style>

185
src/views/reservoir/safeOperation/components/RealTimeMonitor.vue

@ -0,0 +1,185 @@
<!-- 实时监测 -->
<template>
<div class="real-time-monitor-page">
<el-tabs v-model="activeName">
<el-tab-pane label="过程线分析" name="1">
<div class="flex items-center">
<div>
开始日期
<el-date-picker
v-model="paramsData.startDate"
type="date"
placeholder="选择日期"
>
</el-date-picker>
</div>
<div class="ml-8">
结束日期
<el-date-picker
v-model="paramsData.endDate"
type="date"
placeholder="选择日期"
>
</el-date-picker>
</div>
<el-button type="primary" class="!ml-16" @click="handleSearch"
>查询</el-button
>
<el-button @click="handleReset">重置</el-button>
</div>
<div class="mt-12 flex content-box">
<div class="tree-box">
<el-input placeholder="输入关键字进行过滤" v-model="filterText">
</el-input>
<el-tree
class="filter-tree"
:data="treeData"
:props="defaultProps"
default-expand-all
:filter-node-method="filterNode"
@node-click="handleClickTreeNode"
ref="tree"
>
</el-tree>
</div>
<div class="echarts-box">
<div class="title">统计图</div>
<div ref="echartsRef" class="echart-dom"></div>
</div>
</div>
</el-tab-pane>
</el-tabs>
</div>
</template>
<script>
import * as echarts from "echarts";
import { initReverseLineOptions, doubleYAxisOptions } from "../js/initEcharts";
export default {
data() {
return {
activeName: "1",
filterText: "",
myChart: null,
treeData: [
{
label: "xxx水库",
value: "xxxreservoir",
children: [
{
label: "xx环境量",
value: "xxxenv1",
children: [
{
label: "xx雨量站",
value: "xxxrain1",
type: "1",
},
{
label: "xx水位站",
value: "xxxwater1",
type: "2",
},
],
},
],
},
],
defaultProps: {
children: "children",
label: "label",
},
paramsData: {
startDate: "",
endDate: "",
},
};
},
created() {},
watch: {
filterText(val) {
this.$refs.tree.filter(val);
},
},
methods: {
initData(code) {
console.log("请求数据 >>>>>> ", code);
},
filterNode(value, data) {
if (!value) return true;
return data.label.indexOf(value) !== -1;
},
handleSearch() {},
handleReset() {
this.paramsData.startDate = "";
this.paramsData.endDate = "";
},
handleClickTreeNode(data, node) {
console.log("handleClickTreeNode >>>>> ", data, node);
if (node.isLeaf && data.type) {
// echarts
switch (data.type) {
case "1":
// echarts
if (!this.$refs.echartsRef) {
return;
}
if (this.myChart) {
this.myChart.dispose();
}
let options = initReverseLineOptions();
this.myChart = echarts.init(this.$refs.echartsRef);
options && this.myChart.setOption(options);
break;
case "2":
// echarts
if (!this.$refs.echartsRef) {
return;
}
if (this.myChart) {
this.myChart.dispose();
}
let options2 = doubleYAxisOptions();
this.myChart = echarts.init(this.$refs.echartsRef);
options2 && this.myChart.setOption(options2);
break;
default:
break;
}
}
},
},
};
</script>
<style scoped lang="scss">
.real-time-monitor-page {
.content-box {
.tree-box {
width: 240px;
border: 1px solid #f4f5f7;
border-radius: 2px;
background: #fff;
overflow: auto;
padding: 4px;
}
.echarts-box {
flex: 1;
border: 1px solid #f4f5f7;
border-radius: 2px;
background: #fff;
margin-left: 4px;
.title {
height: 32px;
line-height: 32px;
padding-left: 12px;
border-bottom: 1px solid #f4f5f7;
}
.echart-dom {
height: 360px;
}
}
}
}
</style>

381
src/views/reservoir/safeOperation/index.vue

@ -0,0 +1,381 @@
<template>
<div class="safe-operation">
<div id="reservoir-map-container"></div>
<!-- 按钮浮窗 -->
<el-input
class="search-input"
placeholder="请输入内容"
style="width: 240px"
size="small"
>
<el-button
type="default"
slot="append"
icon="el-icon-search"
size="small"
></el-button>
</el-input>
<div class="tool-btn">
<div class="btn mb-10 cursor-pointer" @click="showTreeBox = !showTreeBox">
图层管理
</div>
<div class="btn cursor-pointer">二维地图</div>
</div>
<!-- 树结构浮窗 -->
<Transition name="fade">
<div class="tree-box" v-if="showTreeBox">
<el-tree
@node-click="handleClickTree"
:data="treeData"
default-expand-all
node-key="id"
ref="tree"
highlight-current
:props="defaultProps"
>
<template #default="{ node, data }">
<div class="flex items-center">
<span>{{ data.text }}</span>
<img
v-if="checkList.find((v) => v === data.id)"
class="my-icon ml-4"
src="@/assets/image/right.png"
alt=""
/>
</div>
</template>
</el-tree>
</div>
</Transition>
<div class="legend-icon">
<div class="row">
<span>大型</span>
</div>
</div>
<!-- 弹窗 -->
<el-dialog title="水库弹窗" :visible.sync="showDialog" width="1080px">
<ProjectDetail ref="detailRef"></ProjectDetail>
</el-dialog>
</div>
</template>
<script>
import mitt from "mitt";
import ProjectDetail from "./components/ProjectDetail.vue";
import { getSceneListData, getLayerData } from "@/api/reservoir";
import {
addLayer,
removeLayer,
zoomToLayer,
} from "@/views/aiSupervision/waterSetting/runScene/layerTree/index";
import { queryLayersByPos } from "./js/mapUtils";
import { throttle } from "lodash-es";
const emitter = mitt();
let viewer, htmlLayer;
// let graphicsList = [];
window.panelClickFunc = function (e) {
emitter.emit("openDialog", e);
};
export default {
components: { ProjectDetail },
data() {
return {
showDialog: false,
mapType: "2D", // 3D
showTreeBox: false,
defaultProps: {
children: "layers",
label: "text",
},
layerList: [],
checkList: [],
graphicList: [],
iconType: {
["1"]: "pos_start.svg",
["2"]: "pos_end.svg",
},
treeData: [],
};
},
methods: {
initData() {
getSceneListData({
name: "水库安全运行",
}).then((res) => {
let id = res.records?.[0]?.id;
getLayerData(id).then((res) => {
console.log("res >>>>> ", res);
this.treeData = res.data.children;
});
});
},
initMap() {
viewer = new sycim.Viewer("reservoir-map-container");
window.viewer = viewer;
let baseLayer = sycim.ImageryLayerFactory.createImageryLayer(
sycim.ImageryType.ARCGIS,
{
url: "https://services.arcgisonline.com/ArcGIS/rest/services/World_Imagery/MapServer",
}
);
viewer.addBaseLayer(baseLayer);
let layer = new sycim.EntityLayer("layer");
viewer.addLayer(layer);
// plot = new sycim.Plot(viewer);
htmlLayer = new sycim.HtmlLayer("layer");
viewer.addLayer(htmlLayer);
viewer.setOptions({
globe: {
depthTestAgainstTerrain: true,
},
});
//
// viewer.on(
// sycim.SceneEventType.CAMERA_CHANGED,
// () => {
// viewer.setOptions({
// globe: {
// depthTestAgainstTerrain: viewer.cameraPosition.alt > 10000 ? false : true
// }
// });
// },
// viewer
// );
setTimeout(() => {
viewer.scene.camera.setView({
destination: new Cesium.Cartesian3.fromDegrees(113.27, 23.13, 600000),
// orientation: {
// heading: 0,
// pitch: -90,
// roll: 0,
// },
duration: 2,
});
this.viewerAddEventListener();
}, 300);
},
handleAddHtmlLayer(position, data) {
console.log("handleAddHtmlLayer-position,data >>>>> ", position, data);
htmlLayer?.clear();
let divIcon = new sycim.DivIcon(
`${position.lng}, ${position.lat}`,
`
<div class="sycim-panel" onclick="panelClickFunc(${
data.attributes.res_code
})">
<div class="panel-text">${data.attributes?.res_name || "未知"}
</div>
</div>
`
);
divIcon.setStyle({
//
distanceDisplayCondition: {
near: 0, //
far: 8000000, //
},
//
scaleByDistance: {
near: 0, //
nearValue: 1.5, //
far: 50000, //
farValue: 1, //
},
horizontalOrigin: sycim.Cesium.HorizontalOrigin.CENTER,
verticalOrigin: sycim.Cesium.VerticalOrigin.BOTTOM,
});
htmlLayer.addGraphic(divIcon);
},
//
viewerAddEventListener() {
window.viewer.on(
sycim.MouseEventType.MOUSE_MOVE,
throttle((e) => {
queryLayersByPos(e.wgs84SurfacePosition, this.layerList, (res) => {
if (res) {
this.handleAddHtmlLayer(e.wgs84SurfacePosition, res);
} else {
htmlLayer?.clear();
}
});
}, 100),
window.viewer
);
},
openDialog(e) {
console.log("openDialog >>>>> ", e);
this.showDialog = true;
this.$nextTick(() => {
// this.$refs.detailRef.initData(e);
this.$refs.detailRef.initData("440111000034");
});
},
// layer
// addLayer(originType, type, count) {
// if (!layer) {
// layer = new sycim.EntityLayer("layer").addTo(viewer);
// }
// let svg = this.iconType[type];
// if ((svg, count > 0)) {
// for (let i = 0; i < count; i++) {
// let log = 113.27 + (Math.random() > 0.5 ? 1 : -1) * 2 * Math.random();
// let lat = 23.13 + (Math.random() > 0.5 ? 1 : -1) * 2 * Math.random();
// let graphicItem = new sycim.Billboard(
// [log, lat, 0.1],
// `/icons/${svg}`
// );
// graphicItem.setStyle({
// canEdit: false,
// horizontalOrigin: sycim.HorizontalOrigin.CENTER,
// verticalOrigin: sycim.VerticalOrigin.BOTTOM,
// disableDepthTestDistance: Number.POSITIVE_INFINITY,
// });
// layer.addGraphic(graphicItem);
// this.graphicList.push({
// originType,
// type,
// graphicId: graphicItem.graphicId,
// });
// }
// this.viewerAddEventListener();
// }
// },
// removeLayer(originType, type) {
// let list = this.graphicList.filter(
// (v) => v.originType === originType && v.type === type
// );
// if (list) {
// for (let i = 0; i < list.length; i++) {
// const el = list[i];
// let graphicItem = layer?.getGraphic(el.graphicId);
// if (graphicItem) {
// layer.removeGraphic(graphicItem);
// }
// }
// }
// },
//
handleClickTree(data, node) {
console.log("data >>>>> ", data, node);
if (node.isLeaf && !data.children) {
let resId = this.checkList.find((v) => v === data.id);
if (resId) {
this.checkList = this.checkList.filter((v) => v != resId);
this.layerList = this.layerList.filter((v) => v.id != resId);
removeLayer(data);
} else {
this.checkList = [...this.checkList, data.id];
addLayer(data);
this.layerList.push(data);
}
}
},
},
created() {
this.initData();
emitter.on("openDialog", this.openDialog);
},
mounted() {
setTimeout(() => {
this.initMap();
}, 50);
},
beforeDestroy() {
window.viewer = null;
htmlLayer = null;
},
};
</script>
<style scoped lang="scss">
.safe-operation {
position: relative;
width: 100%;
height: 100%;
overflow: hidden;
#reservoir-map-container {
width: 100%;
height: 100%;
}
.search-input {
position: absolute;
font-size: 14px;
z-index: 9;
right: 148px;
top: 20px;
}
.tool-btn {
border-radius: 4px;
font-size: 14px;
padding: 12px;
background: #fff;
position: absolute;
z-index: 9;
right: 20px;
top: 20px;
.btn {
user-select: none;
}
}
.tree-box {
position: absolute;
z-index: 9;
right: 20px;
top: 100px;
border-radius: 4px;
padding: 2px;
background: #fff;
width: 240px;
min-height: 50vh;
max-height: 70vh;
padding: 12px 0;
}
.legend-icon {
border-radius: 4px;
padding: 2px;
background: #fff;
width: 100px;
position: absolute;
z-index: 9;
right: 20px;
bottom: 20px;
}
.my-icon {
width: 16px;
height: 16px;
}
}
</style>
<style lang="scss">
.sycim-panel {
padding: 10px;
background: #fff;
border-radius: 2px;
.panel-text {
color: #000;
font-size: 14px;
}
}
</style>

124
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],
}
]
}
}

119
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;
}
});
};
Loading…
Cancel
Save