1. 调整moment本地化问题
2. 功能完善与调整
This commit is contained in:
parent
07c264a6f8
commit
2e8f41d5d0
@ -16,18 +16,22 @@
|
||||
<strong>We're sorry but <%= htmlWebpackPlugin.options.title %> doesn't work properly without JavaScript enabled.
|
||||
Please enable it to continue.</strong>
|
||||
</noscript>
|
||||
|
||||
<div id="app"></div>
|
||||
<!-- built files will be auto injected -->
|
||||
<script src="https://cdn.jsdelivr.net/npm/vue@2.6.0"></script>
|
||||
<script src="https://cdn.jsdelivr.net/npm/vue-router@3.1.3"></script>
|
||||
<script src="https://cdn.jsdelivr.net/npm/vuex@3.6.0"></script>
|
||||
|
||||
<script src="https://cdn.jsdelivr.net/npm/js-md5@0.7.3"></script>
|
||||
<script src="https://cdn.jsdelivr.net/npm/moment@2.29.1"></script>
|
||||
<script src="https://cdn.jsdelivr.net/npm/moment@2.29.1/dist/locale/zh-cn.js"></script>
|
||||
<script src="https://cdn.jsdelivr.net/npm/ant-design-vue@1.7.2/dist/antd.min.js"></script>
|
||||
<script src="https://cdn.jsdelivr.net/npm/axios@0.21.0/dist/axios.min.js"></script>
|
||||
<script src="https://cdn.jsdelivr.net/npm/echarts@4.9.0/dist/echarts.common.min.js"></script>
|
||||
<script src="https://cdn.jsdelivr.net/npm/v-charts@1.19.0/lib/index.min.js"></script>
|
||||
<script src="https://cdn.jsdelivr.net/gh/openlayers/openlayers.github.io@master/en/v6.4.3/build/ol.js"></script>
|
||||
<!-- built files will be auto injected -->
|
||||
|
||||
</body>
|
||||
|
||||
</html>
|
@ -16,14 +16,14 @@
|
||||
>
|
||||
<img :src="logo" />
|
||||
<p>
|
||||
<span style="color:white;font-size: 26px;font-weight: bold;text-shadow: 0 0 10px black;">CVEO水质监测平台</span>
|
||||
<span style="color:white;font-size: 26px;font-weight: bold;text-shadow: 0 0 10px black;">湖北富瑞尔科技有限公司水质监测平台</span>
|
||||
</p>
|
||||
<div style="color:white;font-size: 13px;font-weight: bold;text-shadow: 0 0 7px black;">
|
||||
<p>
|
||||
当前版本: 1.0.2
|
||||
当前版本: 1.1.0
|
||||
</p>
|
||||
<p>
|
||||
后台版本: 1.0.0
|
||||
后台版本: 1.1.0
|
||||
</p>
|
||||
<p>
|
||||
版本记录:
|
||||
@ -39,6 +39,11 @@
|
||||
<p>
|
||||
2020-12-7:
|
||||
1.0.2版本,修复字体背景遮挡问题
|
||||
</p>
|
||||
<p>
|
||||
2021-1-4:
|
||||
1.1.0版本,添加分时数据查询功能,提供表格与图表两种方式,对数据时间范围进行限制
|
||||
后台进行调整,对分时数据时间范围进行限制
|
||||
</p>
|
||||
</div>
|
||||
</a-col>
|
||||
@ -149,12 +154,15 @@ export default {
|
||||
*/
|
||||
let results = [
|
||||
getData(URL_MAP.DEVICE_LIST),
|
||||
getData(URL_MAP.SENSOR_LIST)
|
||||
getData(URL_MAP.SENSOR_LIST),
|
||||
getData(URL_MAP.PROJECT_LIST),
|
||||
getData(URL_MAP.RULES_LIST),
|
||||
]
|
||||
data = await Promise.all(results)
|
||||
this.$store.commit('deviceList', data[0].data)
|
||||
this.$store.commit('sensorList', data[1].data)
|
||||
|
||||
this.$store.commit('projectList', data[2].data)
|
||||
this.$store.commit('ruleList', data[3].data)
|
||||
let path = decodeURIComponent(this.$route.query.redirect || "/");
|
||||
this.$router.push({ path: path });
|
||||
} catch (e) {
|
||||
|
@ -2,10 +2,20 @@
|
||||
<a-layout>
|
||||
<a-layout-header style="height: 110px">
|
||||
<a-row>
|
||||
<a-col :span="12" style="color: white">
|
||||
<a-col :span="11" style="color: white">
|
||||
<span class="w-title">水质监测平台</span>
|
||||
</a-col>
|
||||
<a-col :span="2" :offset="10">
|
||||
<div style="position:absolute;right:100px;">
|
||||
<span style="margin-right: 24px">
|
||||
<a-avatar @click="dayLimit=true" style="background-color:#f56a00" shape="square" icon="exclamation-circle"/>
|
||||
</span>
|
||||
<span >
|
||||
<a-badge :count="1"
|
||||
><a-avatar @click="dayLogs=true" style="background-color:#ff0000" shape="square" icon="warning" />
|
||||
</a-badge>
|
||||
</span>
|
||||
</div>
|
||||
<div style="position:absolute;right:0;">
|
||||
<a-popover :title="username" trigger="hover" placement="bottom">
|
||||
<template slot="content">
|
||||
<p v-if="!isAnyone" style="cursor: pointer" @click="changePasswd">
|
||||
@ -15,7 +25,7 @@
|
||||
</template>
|
||||
<a-avatar :size="48" icon="user" />
|
||||
</a-popover>
|
||||
</a-col>
|
||||
</div>
|
||||
</a-row>
|
||||
<a-row>
|
||||
<a-menu
|
||||
@ -32,7 +42,25 @@
|
||||
><icon-font type="wt-iconsearch" />数据查询</span
|
||||
>
|
||||
<a-menu-item key="detail-search">
|
||||
<icon-font type="wt-iconxiangxi" />详细数据
|
||||
<icon-font type="wt-iconxiangxi" />分时数据
|
||||
</a-menu-item>
|
||||
<a-menu-item key="means">
|
||||
<icon-font type="wt-iconxiangxi" />均值数据
|
||||
</a-menu-item>
|
||||
<a-menu-item key="qa-day">
|
||||
<icon-font type="wt-iconxiangxi" />水质质量日报
|
||||
</a-menu-item>
|
||||
<a-menu-item key="lur-mean">
|
||||
<icon-font type="wt-iconxiangxi" />水质指标统计
|
||||
</a-menu-item>
|
||||
<a-menu-item key="qa-sts">
|
||||
<icon-font type="wt-iconxiangxi" />水质质量类别统计
|
||||
</a-menu-item>
|
||||
<a-menu-item key="lur-sts">
|
||||
<icon-font type="wt-iconxiangxi" />水质指标超标统计
|
||||
</a-menu-item>
|
||||
<a-menu-item key="yl-sts">
|
||||
<icon-font type="wt-iconxiangxi" />水质超标处理记录
|
||||
</a-menu-item>
|
||||
</a-sub-menu>
|
||||
<a-menu-item key="analysis">
|
||||
@ -46,7 +74,7 @@
|
||||
</a-layout-header>
|
||||
<a-layout-content>
|
||||
<keep-alive>
|
||||
<router-view />
|
||||
<router-view />
|
||||
</keep-alive>
|
||||
</a-layout-content>
|
||||
<a-modal
|
||||
@ -57,35 +85,57 @@
|
||||
>
|
||||
<password-change @ok="logout" @cancle="passwd_visible = false" />
|
||||
</a-modal>
|
||||
<a-modal
|
||||
v-model="dayLimit"
|
||||
:title="'日均值限定'"
|
||||
:destroyOnClose="true"
|
||||
:footer="null"
|
||||
>
|
||||
<day-limit ></day-limit>
|
||||
</a-modal>
|
||||
<a-modal
|
||||
v-model="dayLogs"
|
||||
:title="'超标报警'"
|
||||
:destroyOnClose="true"
|
||||
:footer="null"
|
||||
:width="900"
|
||||
>
|
||||
<day-logs ></day-logs>
|
||||
</a-modal>
|
||||
</a-layout>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import IconFont from "@/components/icon";
|
||||
import Logs from "@/components/logs/Index";
|
||||
import { logout } from "@/utils/http";
|
||||
import PasswordChange from "./admin/forms/PasswordChange.vue";
|
||||
import DayLimit from './logs/DayLimit.vue';
|
||||
import DayLogs from './logs/DayLogs.vue';
|
||||
export default {
|
||||
components: {
|
||||
"icon-font": IconFont,
|
||||
PasswordChange,
|
||||
DayLimit,
|
||||
DayLogs
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
current: ["map-layout"],
|
||||
currentComp: "map-layout",
|
||||
passwd_visible: false,
|
||||
dayLimit:false,
|
||||
dayLogs:false,
|
||||
};
|
||||
},
|
||||
watch:{
|
||||
currentComp: function(old, newVal) {
|
||||
if(old === newVal){
|
||||
return
|
||||
watch: {
|
||||
currentComp: function (old, newVal) {
|
||||
if (old === newVal) {
|
||||
return;
|
||||
}
|
||||
this.$router.push({
|
||||
name: this.currentComp
|
||||
})
|
||||
}
|
||||
name: this.currentComp,
|
||||
});
|
||||
},
|
||||
},
|
||||
computed: {
|
||||
isAdmin() {
|
||||
@ -115,10 +165,11 @@ export default {
|
||||
},
|
||||
},
|
||||
mounted() {
|
||||
|
||||
this.$router.push({
|
||||
name:this.currentComp
|
||||
})
|
||||
}
|
||||
name: this.currentComp,
|
||||
});
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
|
@ -24,6 +24,11 @@
|
||||
<a-icon type="user" />
|
||||
<span>人员</span>
|
||||
</a-menu-item>
|
||||
|
||||
<a-menu-item key="rules-table">
|
||||
<a-icon type="info" />
|
||||
<span>规则</span>
|
||||
</a-menu-item>
|
||||
</a-menu>
|
||||
</a-layout-sider>
|
||||
<a-layout>
|
||||
@ -41,12 +46,14 @@ import DeviceTable from './tables/DeviceTable';
|
||||
import ProjectTable from './tables/ProjectTable';
|
||||
import UserTable from './tables/UserTable';
|
||||
import { getData, URL_MAP } from "@/utils/http";
|
||||
import RulesTable from './tables/RulesTable';
|
||||
export default {
|
||||
components: {
|
||||
'sensor-table':SensorTable,
|
||||
'device-table':DeviceTable,
|
||||
'project-table':ProjectTable,
|
||||
'user-table':UserTable
|
||||
'user-table':UserTable,
|
||||
'rules-table':RulesTable
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
|
165
src/components/admin/forms/RuleDetail.vue
Normal file
165
src/components/admin/forms/RuleDetail.vue
Normal file
@ -0,0 +1,165 @@
|
||||
<template>
|
||||
<div>
|
||||
<a-form-model
|
||||
:model="form"
|
||||
:label-col="{ span: 4 }"
|
||||
:wrapper-col="{ span: 14 }"
|
||||
>
|
||||
<a-form-model-item label="项目">
|
||||
<a-select
|
||||
show-search
|
||||
v-model="form.project"
|
||||
@search="searchPorjects"
|
||||
:filter-option="false"
|
||||
:not-found-content="fetching ? undefined : null"
|
||||
>
|
||||
<a-spin v-if="fetching" slot="notFoundContent" size="small" />
|
||||
<a-select-option v-for="u in projects" :key="u._id">
|
||||
{{ u.name }}
|
||||
</a-select-option>
|
||||
</a-select>
|
||||
</a-form-model-item>
|
||||
<a-form-model-item label="设备">
|
||||
<a-select
|
||||
show-search
|
||||
v-model="form.device"
|
||||
@search="searchDevices"
|
||||
:filter-option="false"
|
||||
:not-found-content="fetching ? undefined : null"
|
||||
>
|
||||
<a-spin v-if="fetching" slot="notFoundContent" size="small" />
|
||||
<a-select-option v-for="u in devices" :key="u._id">
|
||||
{{ u.device_name }}
|
||||
</a-select-option>
|
||||
</a-select>
|
||||
</a-form-model-item>
|
||||
<a-form-model-item label="参数">
|
||||
<a-select
|
||||
show-search
|
||||
v-model="form.sensor"
|
||||
@search="searchSensors"
|
||||
:filter-option="false"
|
||||
:not-found-content="fetching ? undefined : null"
|
||||
>
|
||||
<a-spin v-if="fetching" slot="notFoundContent" size="small" />
|
||||
<a-select-option v-for="u in sensors" :key="u._id">
|
||||
{{ u.name }}
|
||||
</a-select-option>
|
||||
</a-select>
|
||||
</a-form-model-item>
|
||||
<a-form-model-item label="范围">
|
||||
<span><a-input-number v-model="form.allow_min" ></a-input-number> - <a-input-number v-model="form.allow_max"></a-input-number></span>
|
||||
</a-form-model-item>
|
||||
<a-form-model-item :wrapper-col="{ span: 14, offset: 4 }">
|
||||
<a-button type="primary" @click="onSubmit"> 确认 </a-button>
|
||||
<a-button style="margin-left: 10px" @click="$emit('cancle')">
|
||||
关闭
|
||||
</a-button>
|
||||
</a-form-model-item>
|
||||
</a-form-model>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { mergeList } from "@/utils/utils";
|
||||
import { getData, URL_MAP } from "@/utils/http";
|
||||
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
form: {
|
||||
_id: "",
|
||||
project: "",
|
||||
device: "",
|
||||
sensor: "",
|
||||
allow_min: 0,
|
||||
allow_max: 0,
|
||||
one_error_duration: 0,
|
||||
total_error_duration: 0,
|
||||
total_duration: 0,
|
||||
one_null_duration: 0,
|
||||
total_null_duration: 0,
|
||||
total_null: 0,
|
||||
},
|
||||
|
||||
projects: [],
|
||||
sensors: [],
|
||||
devices: [],
|
||||
fetching: false,
|
||||
};
|
||||
},
|
||||
computed: {},
|
||||
props: {
|
||||
detail: Object,
|
||||
},
|
||||
methods: {
|
||||
onSubmit() {
|
||||
// console.log(this.form)
|
||||
this.$emit("ok", this.form);
|
||||
},
|
||||
async searchPorjects(value) {
|
||||
this.fetching = true;
|
||||
try {
|
||||
let data = await getData(URL_MAP.PROJECT_LIST, {
|
||||
name__icontains: name,
|
||||
});
|
||||
this.projects = mergeList(data.data, this.projects);
|
||||
} catch (e) {
|
||||
console.log(e);
|
||||
} finally {
|
||||
this.fetching = false;
|
||||
}
|
||||
},
|
||||
async searchSensors(name) {
|
||||
this.fetching = true;
|
||||
try {
|
||||
let data = await getData(URL_MAP.SENSOR_LIST, {
|
||||
name__icontains: name,
|
||||
});
|
||||
this.sensors = mergeList(data.data, this.sensors);
|
||||
} catch (e) {
|
||||
console.log(e);
|
||||
} finally {
|
||||
this.fetching = false;
|
||||
}
|
||||
},
|
||||
async searchDevices(value) {
|
||||
this.fetching = true;
|
||||
try {
|
||||
let data = await getData(URL_MAP.DEVICE_LIST, {
|
||||
device_name__icontains: name,
|
||||
});
|
||||
this.devices = mergeList(data.data, this.devices);
|
||||
} catch (e) {
|
||||
console.log(e);
|
||||
} finally {
|
||||
this.fetching = false;
|
||||
}
|
||||
},
|
||||
},
|
||||
mounted() {
|
||||
for (let key in this.form) {
|
||||
this.form[key] = this.detail[key];
|
||||
}
|
||||
if(this.form.project) {
|
||||
this.projects = [ Object.assign({}, this.form.project) ]
|
||||
this.form.project = this.form.project._id
|
||||
}
|
||||
if(this.form.device) {
|
||||
this.devices = [ Object.assign({}, this.form.device) ]
|
||||
this.form.device = this.form.device._id
|
||||
}
|
||||
if(this.form.sensor) {
|
||||
this.sensors = [ Object.assign({}, this.form.sensor) ]
|
||||
this.form.sensor = this.form.sensor._id
|
||||
}
|
||||
// this.form.project = this.form.managers.map(v => v._id)
|
||||
// this.form.normals = this.form.normals.map(v => v._id)
|
||||
// this.managers = this.detail.managers
|
||||
// this.normals = this.detail.normals
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
<style>
|
||||
</style>
|
@ -139,7 +139,7 @@ export default {
|
||||
try {
|
||||
if (!this.isCreate) {
|
||||
form["id"] = form["_id"];
|
||||
console.log(form)
|
||||
// console.log(form)
|
||||
let data = await patchJSON(URL_MAP.DEVICE_DETAIL, form);
|
||||
} else {
|
||||
form["id"] = form["_id"];
|
||||
|
177
src/components/admin/tables/RulesTable.vue
Normal file
177
src/components/admin/tables/RulesTable.vue
Normal file
@ -0,0 +1,177 @@
|
||||
<template>
|
||||
<div style="margin: 20px">
|
||||
<a-row style="margin-bottom: 20px">
|
||||
<a-button type="primary" @click="handleCreate">添加</a-button>
|
||||
</a-row>
|
||||
<a-table
|
||||
:columns="tableCols"
|
||||
:data-source="tableRows"
|
||||
:loading="loading"
|
||||
:rowKey="idName"
|
||||
@change="handleTableChange"
|
||||
>
|
||||
<span slot="device" slot-scope="device">
|
||||
<a-tag >
|
||||
{{ device ? device.device_name : 'null' }}
|
||||
</a-tag>
|
||||
</span>
|
||||
<span slot="sensor" slot-scope="sensor">
|
||||
<a-tag >
|
||||
{{ sensor ? sensor.name : 'null' }}
|
||||
</a-tag>
|
||||
</span>
|
||||
<span slot="normals" slot-scope="normals">
|
||||
<a-tag v-for="item in normals" :key="item._id">
|
||||
{{ item.name }}
|
||||
</a-tag>
|
||||
</span>
|
||||
<span slot="action" slot-scope="record">
|
||||
<a-button size="small" type="link" @click="() => handleDetail(record)"
|
||||
>查看</a-button
|
||||
>
|
||||
<a-divider type="vertical" />
|
||||
<a-button type="danger" size="small" @click="() => handleDelete(record)"
|
||||
>删除</a-button
|
||||
>
|
||||
</span>
|
||||
</a-table>
|
||||
<a-modal
|
||||
v-model="visible"
|
||||
:title="isCreate ? '添加项目' : '查看项目'"
|
||||
:destroyOnClose="true"
|
||||
:footer="null"
|
||||
>
|
||||
<rule-detail
|
||||
:detail="record"
|
||||
@ok="handleOk"
|
||||
@cancle="visible = false"
|
||||
/>
|
||||
</a-modal>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { deleteJSON, getData, patchJSON, postJSON, URL_MAP } from "@/utils/http";
|
||||
import RuleDetail from '../forms/RuleDetail.vue';
|
||||
|
||||
export default {
|
||||
components: {
|
||||
RuleDetail,
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
tableRows: [],
|
||||
tableCols: [
|
||||
{
|
||||
dataIndex: "device",
|
||||
key: "device",
|
||||
title: "设备名",
|
||||
scopedSlots: { customRender: "device" },
|
||||
},
|
||||
{
|
||||
dataIndex: "sensor",
|
||||
key: "sensor",
|
||||
title: "参数",
|
||||
scopedSlots: { customRender: "sensor" },
|
||||
},
|
||||
{
|
||||
dataIndex: "allow_min",
|
||||
key: "allow_min",
|
||||
title: "最小值",
|
||||
},
|
||||
{
|
||||
dataIndex: "allow_max",
|
||||
key: "allow_max",
|
||||
title: "最大值",
|
||||
},
|
||||
{
|
||||
key: "action",
|
||||
title: "操作",
|
||||
scopedSlots: { customRender: "action" },
|
||||
},
|
||||
],
|
||||
pages: {},
|
||||
loading: false,
|
||||
listUrl: URL_MAP.RULES_LIST,
|
||||
detailUrl: URL_MAP.RULES_DETAIL,
|
||||
idName: "_id",
|
||||
visible: false,
|
||||
record: {},
|
||||
isCreate: false,
|
||||
};
|
||||
},
|
||||
methods: {
|
||||
handleTableChange(pagination, filters, sorter) {
|
||||
console.log(pagination);
|
||||
},
|
||||
async fetch(params) {
|
||||
this.loading = true;
|
||||
try {
|
||||
let results = await getData(this.listUrl, params);
|
||||
let data = results.data;
|
||||
const pagination = { ...this.pages };
|
||||
pagination.total = data.length;
|
||||
this.tableRows = data;
|
||||
this.pages = pagination;
|
||||
} catch (e) {
|
||||
console.log(e);
|
||||
} finally {
|
||||
this.loading = false;
|
||||
}
|
||||
},
|
||||
handleDetail(record) {
|
||||
this.visible = true;
|
||||
this.record = record;
|
||||
},
|
||||
async handleDelete(record) {
|
||||
this.loading = true
|
||||
try{
|
||||
await deleteJSON(this.detailUrl, { 'id': record._id })
|
||||
await this.fetch({})
|
||||
}catch(e)
|
||||
{
|
||||
console.log(e)
|
||||
}
|
||||
finally{
|
||||
this.loading = false
|
||||
}
|
||||
|
||||
},
|
||||
async handleOk(form) {
|
||||
this.visible = false;
|
||||
this.loading = true;
|
||||
try {
|
||||
if (!this.isCreate) {
|
||||
form["id"] = form[this.idName];
|
||||
let data = await patchJSON(this.detailUrl, form);
|
||||
} else {
|
||||
form[this.idName] = undefined;
|
||||
let data = await postJSON(this.listUrl, form);
|
||||
}
|
||||
await this.fetch({});
|
||||
} catch (e) {
|
||||
console.log(e);
|
||||
} finally {
|
||||
this.isCreate = false;
|
||||
this.loading = false;
|
||||
}
|
||||
},
|
||||
handleCreate() {
|
||||
this.isCreate = true;
|
||||
this.visible = true
|
||||
this.record = {
|
||||
device: null,
|
||||
project: null,
|
||||
sensor: null,
|
||||
|
||||
};
|
||||
},
|
||||
},
|
||||
mounted() {
|
||||
this.fetch({});
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
<style>
|
||||
</style>
|
@ -1,13 +1,129 @@
|
||||
<template>
|
||||
<div></div>
|
||||
<div style="height: calc(100vh - 110px)">
|
||||
<a-layout :theme="'light'" style="height: calc(100vh - 110px)">
|
||||
<a-layout-sider :theme="'light'" :width="300" style="padding: 20px">
|
||||
<div style="text-align: center; font-size: 16px">选择站点</div>
|
||||
<a-divider />
|
||||
<a-tree
|
||||
v-model="checkedKeys"
|
||||
checkable
|
||||
:selected-keys="selectedKeys"
|
||||
:auto-expand-parent="true"
|
||||
:tree-data="treeData"
|
||||
@select="onSelect"
|
||||
showLine
|
||||
>
|
||||
<a-icon slot="switcherIcon" type="down" />
|
||||
</a-tree>
|
||||
</a-layout-sider>
|
||||
<a-layout style="padding: 20px">
|
||||
<a-layout-header style="background: #fff; padding: 15px 0 5px 15px">
|
||||
<a-radio-group default-value="a" button-style="solid" style="display: block; line-height: 32px">
|
||||
<a-radio-button value="a"> 小时值分析 </a-radio-button>
|
||||
<a-radio-button value="b"> 日均值分析 </a-radio-button>
|
||||
<a-radio-button value="c"> 水质指标统计 </a-radio-button>
|
||||
<a-radio-button value="d"> 质量等级统计 </a-radio-button>
|
||||
<a-radio-button value="e"> 质量对比分析 </a-radio-button>
|
||||
</a-radio-group>
|
||||
<span>
|
||||
检测项:
|
||||
<a-select placeholder="选择检测项" mode="multiple" style="min-width: 150px">
|
||||
<a-select-option value="0"> pH </a-select-option>
|
||||
</a-select>
|
||||
日期:
|
||||
<a-range-picker
|
||||
separator="至"
|
||||
:placeholder="['开始日期', '结束日期']"
|
||||
:defaultValue="datetimeRange"
|
||||
@change="dateRangeChange"
|
||||
></a-range-picker>
|
||||
<a-button style="margin-left: 15px" type="primary" icon="bar-chart"
|
||||
>分析</a-button
|
||||
>
|
||||
</span>
|
||||
</a-layout-header>
|
||||
<a-layout-content style="padding: 20px 0 20px 0">
|
||||
<a-row>
|
||||
图表类型:
|
||||
<a-select placeholder="选择类型" style="min-width: 150px">
|
||||
<a-select-option value="0"> 单站点多指标分析 </a-select-option>
|
||||
<a-select-option value="1"> 多站点多指标分析 </a-select-option>
|
||||
</a-select>
|
||||
</a-row>
|
||||
</a-layout-content>
|
||||
</a-layout>
|
||||
</a-layout>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
checkedKeys: ["all"],
|
||||
autoExpandParent: true,
|
||||
selectedKeys: [],
|
||||
treeData: [],
|
||||
datetimeRange: [],
|
||||
columns: [],
|
||||
data: [],
|
||||
};
|
||||
},
|
||||
computed: {
|
||||
sensorList() {
|
||||
return this.$store.getters.sensorList;
|
||||
},
|
||||
deviceList() {
|
||||
return this.$store.getters.deviceList;
|
||||
},
|
||||
},
|
||||
methods: {
|
||||
async fetch() {},
|
||||
onSelect() {},
|
||||
dateRangeChange() {},
|
||||
},
|
||||
mounted() {
|
||||
const columns = [
|
||||
{
|
||||
title: "站点名",
|
||||
dataIndex: "name",
|
||||
},
|
||||
{
|
||||
title: "时间",
|
||||
dataIndex: "time",
|
||||
},
|
||||
];
|
||||
this.sensorList.forEach((sensor) => {
|
||||
columns.push({
|
||||
title: sensor.param_name,
|
||||
children: [
|
||||
{
|
||||
title: sensor.uint || "-",
|
||||
dataIndex: sensor.param_key,
|
||||
},
|
||||
],
|
||||
});
|
||||
});
|
||||
|
||||
}
|
||||
this.columns = columns;
|
||||
|
||||
const deviceTree = [];
|
||||
this.deviceList.forEach((device) => {
|
||||
deviceTree.push({
|
||||
title: device.device_name,
|
||||
key: device._id,
|
||||
});
|
||||
});
|
||||
this.treeData = [
|
||||
{
|
||||
title: "设备",
|
||||
key: "all",
|
||||
children: deviceTree,
|
||||
},
|
||||
];
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
<style>
|
||||
|
||||
</style>
|
139
src/components/charts/BaseIndexChart.vue
Normal file
139
src/components/charts/BaseIndexChart.vue
Normal file
@ -0,0 +1,139 @@
|
||||
<template>
|
||||
<div>
|
||||
<div
|
||||
v-if="hasData"
|
||||
id="index-chart"
|
||||
ref="indexChart"
|
||||
:style="{ width:width, height:height }"
|
||||
/>
|
||||
<a-empty v-else />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
chartId:'index-chart-'
|
||||
};
|
||||
},
|
||||
props: {
|
||||
width: String,
|
||||
height: String,
|
||||
rawData: Array,
|
||||
setting: Object,
|
||||
},
|
||||
watch: {
|
||||
rawData(val, newVal) {
|
||||
this.initChart();
|
||||
},
|
||||
},
|
||||
computed: {
|
||||
hasData() {
|
||||
return this.rawData.length > 0;
|
||||
},
|
||||
},
|
||||
methods: {
|
||||
initChart() {
|
||||
let e = this.$refs['indexChart']
|
||||
if(!e)return
|
||||
let myChart = echarts.init(e);
|
||||
const { title, xAxis, series, seriesName, seriesType, yRange } = this.setting;
|
||||
let option = {
|
||||
title: {
|
||||
text: title,
|
||||
left:'center'
|
||||
},
|
||||
tooltip: {
|
||||
trigger: "axis",
|
||||
},
|
||||
xAxis: {
|
||||
data: this.rawData.map(function (item) {
|
||||
return item[xAxis];
|
||||
}),
|
||||
},
|
||||
yAxis: {
|
||||
min: yRange[0] - (yRange[1] - yRange[0]) * 0.05,
|
||||
max: yRange[1] + (yRange[1] - yRange[0]) * 0.05,
|
||||
splitLine: {
|
||||
show: false
|
||||
}
|
||||
},
|
||||
dataZoom: [
|
||||
{
|
||||
// startValue: '2014-06-01'
|
||||
},
|
||||
{
|
||||
type: "inside",
|
||||
},
|
||||
],
|
||||
toolbox: {
|
||||
left: "left",
|
||||
feature: {
|
||||
dataZoom: {
|
||||
yAxisIndex: "none",
|
||||
},
|
||||
restore: {},
|
||||
saveAsImage: {},
|
||||
},
|
||||
},
|
||||
visualMap: {
|
||||
show: true,
|
||||
top: 40,
|
||||
right: 50,
|
||||
type:'piecewise',
|
||||
text:'图例',
|
||||
pieces: [
|
||||
{
|
||||
gte: yRange[0],
|
||||
lte: yRange[1],
|
||||
color: '#0000ff',
|
||||
},
|
||||
{
|
||||
gt: yRange[1],
|
||||
color: "#ff0000",
|
||||
},
|
||||
{
|
||||
gt: yRange[1],
|
||||
color: "#ff0000",
|
||||
},
|
||||
],
|
||||
categories:['合格','不合格'],
|
||||
outOfRange: {
|
||||
color: "#0000ff",
|
||||
},
|
||||
},
|
||||
series: {
|
||||
name: seriesName,
|
||||
type: seriesType,
|
||||
data: this.rawData.map(function (item) {
|
||||
return item[series];
|
||||
}),
|
||||
markLine: {
|
||||
silent: true,
|
||||
data: [
|
||||
{
|
||||
yAxis: yRange[0],
|
||||
},
|
||||
{
|
||||
yAxis: yRange[1],
|
||||
},
|
||||
],
|
||||
},
|
||||
},
|
||||
};
|
||||
console.log(option)
|
||||
myChart.setOption(option);
|
||||
},
|
||||
},
|
||||
mounted() {
|
||||
// console.log(this.rawData)
|
||||
|
||||
this.initChart();
|
||||
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
<style>
|
||||
</style>
|
0
src/components/charts/TempChart.vue
Normal file
0
src/components/charts/TempChart.vue
Normal file
115
src/components/logs/DayLimit.vue
Normal file
115
src/components/logs/DayLimit.vue
Normal file
@ -0,0 +1,115 @@
|
||||
<template>
|
||||
<div>
|
||||
<a-table style="margin-bottom:5px;border:solid 1px;" :columns="dayMeanColumns" :data-source="dayMeanData" :pagination="false" bordered>
|
||||
</a-table>
|
||||
<a-table style="margin-bottom:5px;border:solid 1px;" :columns="QaColumns" :data-source="QaData" :pagination="false" bordered>
|
||||
</a-table>
|
||||
<a-table style="margin-bottom:5px;border:solid 1px;" :columns="dayCountColumns" :data-source="dayCountData" :pagination="false" bordered>
|
||||
</a-table>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
dayMeanColumns: [
|
||||
{
|
||||
title: "检测项",
|
||||
dataIndex: "param_name",
|
||||
},
|
||||
{
|
||||
title: "日均值最小值",
|
||||
dataIndex: "day_min",
|
||||
},
|
||||
{
|
||||
title: "日均值最大值",
|
||||
dataIndex: "day_max",
|
||||
},
|
||||
|
||||
{
|
||||
title: "月超标限定",
|
||||
dataIndex: "month",
|
||||
},
|
||||
],
|
||||
QaColumns:[
|
||||
{
|
||||
title: "检测项",
|
||||
dataIndex: "param_name",
|
||||
},
|
||||
{
|
||||
title: "截至今日合格率",
|
||||
dataIndex: "day_min",
|
||||
},
|
||||
{
|
||||
title: "月度合格率",
|
||||
dataIndex: "day_max",
|
||||
},
|
||||
|
||||
{
|
||||
title: "年度合格率",
|
||||
dataIndex: "month",
|
||||
},
|
||||
],
|
||||
dayCountColumns:[
|
||||
{
|
||||
title: "检测项",
|
||||
dataIndex: "param_name",
|
||||
},
|
||||
{
|
||||
title: "截至今日超标天数",
|
||||
dataIndex: "day_min",
|
||||
},
|
||||
{
|
||||
title: "剩余可超标天数",
|
||||
dataIndex: "day_max",
|
||||
},
|
||||
|
||||
{
|
||||
title: "年度可超标天数",
|
||||
dataIndex: "month",
|
||||
},
|
||||
],
|
||||
dayMeanData: [
|
||||
{
|
||||
param_name:'pH值',
|
||||
day_min:6.5,
|
||||
day_max:7.5,
|
||||
month:2
|
||||
},
|
||||
{
|
||||
param_name:'余氯',
|
||||
day_min:'-',
|
||||
day_max:1,
|
||||
month:2
|
||||
},
|
||||
{
|
||||
param_name:'浊度',
|
||||
day_min:0,
|
||||
day_max:1,
|
||||
month:1
|
||||
}
|
||||
],
|
||||
QaData:[
|
||||
{
|
||||
param_name:'水质质量合格率',
|
||||
day_min:'75%',
|
||||
day_max:'82%',
|
||||
month:'80%'
|
||||
},
|
||||
],
|
||||
dayCountData:[
|
||||
{
|
||||
param_name:'浊度',
|
||||
day_min:'2',
|
||||
day_max:'5',
|
||||
month:'30'
|
||||
},
|
||||
]
|
||||
};
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
<style>
|
||||
</style>
|
81
src/components/logs/DayLogs.vue
Normal file
81
src/components/logs/DayLogs.vue
Normal file
@ -0,0 +1,81 @@
|
||||
<template>
|
||||
<div>
|
||||
<a-table
|
||||
style="margin-bottom: 5px; border: solid 1px"
|
||||
:columns="columns"
|
||||
:data-source="data"
|
||||
bordered
|
||||
>
|
||||
<span slot="action">
|
||||
<a-button type="primary" size="small">处理</a-button>
|
||||
<a-divider type="vertical" />
|
||||
<a-button size="small">忽略</a-button>
|
||||
</span>
|
||||
</a-table>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import Moment from '@/components/utils/moment.zh_cn'
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
columns: [
|
||||
{
|
||||
title: "地点",
|
||||
dataIndex: "location",
|
||||
},
|
||||
{
|
||||
title: "详情",
|
||||
dataIndex: "detail",
|
||||
},
|
||||
{
|
||||
title: "数值",
|
||||
dataIndex: "number",
|
||||
},
|
||||
|
||||
{
|
||||
title: "时间",
|
||||
dataIndex: "time",
|
||||
},
|
||||
{
|
||||
title: "处理情况",
|
||||
dataIndex: "logs",
|
||||
},
|
||||
{
|
||||
title: "操作",
|
||||
key: "action",
|
||||
scopedSlots: { customRender: "action" },
|
||||
},
|
||||
],
|
||||
|
||||
data: [
|
||||
{
|
||||
location: '武昌区',
|
||||
detail: '翡翠一品游泳池 余氯超标',
|
||||
number: 2.5,
|
||||
time: Moment().date(12).format('lll'),
|
||||
logs:'未处理',
|
||||
},
|
||||
{
|
||||
location: '武昌区',
|
||||
detail: '翡翠一品游泳池 余氯超标',
|
||||
number: 1.5,
|
||||
time: Moment().date(11).format('lll'),
|
||||
logs:'未处理',
|
||||
},
|
||||
{
|
||||
location: '武昌区',
|
||||
detail: '翡翠一品游泳池 浊度超标',
|
||||
number: 1.2,
|
||||
time: Moment().date(3).format('lll'),
|
||||
logs:'未处理',
|
||||
},
|
||||
],
|
||||
};
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
<style>
|
||||
</style>
|
@ -1,13 +0,0 @@
|
||||
<template>
|
||||
<div></div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
|
||||
}
|
||||
</script>
|
||||
|
||||
<style>
|
||||
|
||||
</style>
|
@ -8,6 +8,56 @@
|
||||
type="primary"
|
||||
@click="loadBaseData"
|
||||
></a-button>
|
||||
<div class="map-tip">
|
||||
<a-row style="margin-bottom: 10px; color: white"> 图例 </a-row>
|
||||
<a-row :gutter="2">
|
||||
<a-col :span="8">
|
||||
<div>
|
||||
<img :src="waterImg" width="25px" />
|
||||
</div>
|
||||
</a-col>
|
||||
<a-col :span="16"> 水质检测仪 </a-col>
|
||||
</a-row>
|
||||
</div>
|
||||
<div class="tags-bottom">
|
||||
<a-row :gutter="2">
|
||||
<a-col :span="6">
|
||||
<div>
|
||||
<a-tag color="#279DF2"> 正常 </a-tag>
|
||||
</div>
|
||||
</a-col>
|
||||
<a-col :span="6">
|
||||
<div>
|
||||
<a-tag color="#F56A00"> 预警 </a-tag>
|
||||
</div>
|
||||
</a-col>
|
||||
<a-col :span="6">
|
||||
<div>
|
||||
<a-tag color="#f00"> 超标 </a-tag>
|
||||
</div>
|
||||
</a-col>
|
||||
<a-col :span="6">
|
||||
<div>
|
||||
<a-tag color="#888"> 离线 </a-tag>
|
||||
</div>
|
||||
</a-col>
|
||||
</a-row>
|
||||
</div>
|
||||
<div class="right-botton" @click="rightShow = true" v-show="!rightShow">
|
||||
<a-icon type="caret-left" />
|
||||
</div>
|
||||
<div class="right-table-container" v-if="rightShow">
|
||||
<right-table @close="rightShow = false" />
|
||||
</div>
|
||||
<div class="top-sensor-bar">
|
||||
<a-button-group>
|
||||
<a-button type="primary" size="large"> 全选 </a-button>
|
||||
<a-button size="large"> pH </a-button>
|
||||
<a-button size="large"> 浊度 </a-button>
|
||||
<a-button size="large"> 余氯 </a-button>
|
||||
<a-button size="large"> 温度 </a-button>
|
||||
</a-button-group>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
@ -15,10 +65,12 @@
|
||||
// import { fromLonLat, toLonLat } from "ol/proj.js";
|
||||
const { fromLonLat, toLonLat } = ol.proj;
|
||||
import { getData, login, logout, URL_MAP } from "@/utils/http";
|
||||
import RightTable from "./RightTable.vue";
|
||||
|
||||
let map = null;
|
||||
|
||||
export default {
|
||||
components: { RightTable },
|
||||
data() {
|
||||
return {
|
||||
view: new ol.View({
|
||||
@ -28,6 +80,8 @@ export default {
|
||||
waterLayer: "",
|
||||
projection: "",
|
||||
center: fromLonLat([114.3, 30.6]),
|
||||
waterImg: require("@/assets/water.png"),
|
||||
rightShow: false,
|
||||
};
|
||||
},
|
||||
computed: {
|
||||
@ -41,7 +95,7 @@ export default {
|
||||
methods: {
|
||||
mapinit() {
|
||||
this.projection = ol.proj.get("EPSG:3857");
|
||||
|
||||
|
||||
this.waterLayer = this.getDeviceVectorLayer();
|
||||
var AMapLayer = new ol.layer.Tile({
|
||||
// source: new ol.source.XYZ({
|
||||
@ -125,4 +179,63 @@ export default {
|
||||
</script>
|
||||
|
||||
<style>
|
||||
.tags-bottom {
|
||||
position: absolute;
|
||||
bottom: 10px;
|
||||
left: 200px;
|
||||
width: 200px;
|
||||
padding: 5px;
|
||||
background-color: #00000052;
|
||||
border-radius: 4px;
|
||||
}
|
||||
.map-tip {
|
||||
position: absolute;
|
||||
bottom: 10px;
|
||||
left: 10px;
|
||||
width: 180px;
|
||||
background: #00000096;
|
||||
padding: 10px 20px 20px 20px;
|
||||
border-radius: 5px;
|
||||
color: white;
|
||||
}
|
||||
.right-botton {
|
||||
position: absolute;
|
||||
right: 0px;
|
||||
width: 20px;
|
||||
height: 100px;
|
||||
top: 50%;
|
||||
border-radius: 5px 0 0 5px;
|
||||
background-color: #096dd9b5;
|
||||
padding: 40px 0 0 0;
|
||||
color: white;
|
||||
cursor: pointer;
|
||||
}
|
||||
.right-table-container {
|
||||
position: absolute;
|
||||
right: 0px;
|
||||
width: 500px;
|
||||
height: 700px;
|
||||
bottom: 70px;
|
||||
background: white;
|
||||
border: solid 2px black;
|
||||
opacity: 0.9;
|
||||
padding: 20px;
|
||||
border-radius: 10px 0 0 10px;
|
||||
box-shadow: 1px 1px 14px 4px;
|
||||
}
|
||||
.top-sensor-bar {
|
||||
position: absolute;
|
||||
top: 130px;
|
||||
width: fit-content;
|
||||
background: #00000096;
|
||||
margin: 0px auto;
|
||||
left: 0;
|
||||
right: 0;
|
||||
/* padding: 10px; */
|
||||
color: white;
|
||||
border-radius: 5px;
|
||||
align-items: center;
|
||||
text-align: center;
|
||||
box-shadow: 0px 0px 14px 4px #000000ad;
|
||||
}
|
||||
</style>
|
59
src/components/map/RightTable.vue
Normal file
59
src/components/map/RightTable.vue
Normal file
@ -0,0 +1,59 @@
|
||||
<template>
|
||||
<div>
|
||||
<div @click="$emit('close')" style="position:absolute;right:20px;cursor:pointer;z-index:999;">
|
||||
<a-icon type="close" />
|
||||
</div>
|
||||
<a-form :label-col="{ span: 6 }" :wrapper-col="{ span: 12 }">
|
||||
<a-form-item label="站点类型">
|
||||
<a-select placeholder="选择类型" >
|
||||
<a-select-option value="0"> 水质监测仪 </a-select-option>
|
||||
</a-select>
|
||||
</a-form-item>
|
||||
<a-form-item label="监测指标">
|
||||
<a-select placeholder="选择指标">
|
||||
<a-select-option :key="sensor._id" v-value="sensor.param_key" v-for="sensor in sensorList"> {{sensor.param_name}} </a-select-option>
|
||||
</a-select>
|
||||
</a-form-item>
|
||||
</a-form>
|
||||
<a-table style="border-top:solid" :columns="columns" :data-source="data"> </a-table>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
columns: [
|
||||
{
|
||||
title: "站点",
|
||||
dataIndex: "name",
|
||||
key: "name",
|
||||
},
|
||||
{
|
||||
title: "浊度",
|
||||
dataIndex: "lur",
|
||||
key: "lur",
|
||||
},
|
||||
{
|
||||
title: "排名",
|
||||
key: "sort",
|
||||
dataIndex: "sort",
|
||||
},
|
||||
],
|
||||
data: [],
|
||||
};
|
||||
},
|
||||
computed: {
|
||||
sensorList() {
|
||||
return this.$store.getters.sensorList
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
|
||||
},
|
||||
async mounted() {},
|
||||
};
|
||||
</script>
|
||||
|
||||
<style>
|
||||
</style>
|
@ -1,131 +1,319 @@
|
||||
<template>
|
||||
<div>
|
||||
<a-row>
|
||||
<a-col :span="12">
|
||||
<a-range-picker
|
||||
separator="至"
|
||||
:placeholder="['开始日期', '结束日期']"
|
||||
:defaultValue="datetimeRange"
|
||||
@change="dateRangeChange"
|
||||
></a-range-picker>
|
||||
</a-col>
|
||||
<a-col :span="12">
|
||||
<a-select
|
||||
v-model="device"
|
||||
placeholder="请选择"
|
||||
@change="onDeviceChange"
|
||||
|
||||
<div style="height: calc(100vh - 110px)">
|
||||
<a-layout :theme="'light'" style="height: calc(100vh - 110px)">
|
||||
<a-layout-sider :theme="'light'" :width="300" style="padding: 20px">
|
||||
<div style="text-align: center; font-size: 16px">选择站点</div>
|
||||
<a-divider />
|
||||
<a-tree
|
||||
v-model="checkedKeys"
|
||||
checkable
|
||||
:selected-keys="selectedKeys"
|
||||
:auto-expand-parent="autoExpandParent"
|
||||
:tree-data="treeData"
|
||||
@check="onSelect"
|
||||
showLine
|
||||
>
|
||||
<a-select-option
|
||||
v-for="item in deviceList"
|
||||
:key="item._id"
|
||||
|
||||
:value="item._id"
|
||||
> {{item.device_name}} </a-select-option>
|
||||
</a-select>
|
||||
</a-col>
|
||||
</a-row>
|
||||
<a-spin :spinning="loading">
|
||||
<a-row>
|
||||
<SZJCChart :dataRow="waterData" :labelMap="labelMap"></SZJCChart>
|
||||
</a-row>
|
||||
</a-spin>
|
||||
<a-icon slot="switcherIcon" type="down" />
|
||||
</a-tree>
|
||||
</a-layout-sider>
|
||||
<a-layout style="padding: 20px">
|
||||
<a-layout-header style="background: #fff; padding: 15px 0 5px 15px">
|
||||
<a-radio-group
|
||||
default-value="1-hours"
|
||||
button-style="solid"
|
||||
style="display: block; line-height: 32px"
|
||||
@change="handleTimeRadioClick"
|
||||
>
|
||||
<a-radio-button
|
||||
v-for="item in timeRadios"
|
||||
:key="item.value"
|
||||
:value="item.value"
|
||||
>
|
||||
{{ item.name }}
|
||||
</a-radio-button>
|
||||
</a-radio-group>
|
||||
<a-radio-group
|
||||
default-value="chart"
|
||||
button-style="solid"
|
||||
@change="handleRadioClick"
|
||||
>
|
||||
<a-radio-button
|
||||
v-for="item in radios"
|
||||
:key="item.value"
|
||||
:value="item.value"
|
||||
>
|
||||
{{ item.name }}
|
||||
</a-radio-button>
|
||||
</a-radio-group>
|
||||
<span style="margin-left: 30px"
|
||||
><a-button @click="getData"> 刷新数据</span
|
||||
>
|
||||
</a-layout-header>
|
||||
<a-layout-content style="padding: 20px 0 20px 0">
|
||||
<a-spin :spinning="loading">
|
||||
<a-table
|
||||
v-if="currentType === 'table'"
|
||||
:columns="columns"
|
||||
:data-source="waterData"
|
||||
bordered
|
||||
:pagination="pagination"
|
||||
size="middle"
|
||||
@change="handleTableChange"
|
||||
>
|
||||
<span slot="device" slot-scope="record">
|
||||
{{ deviceNames[record.device_id] }}
|
||||
</span>
|
||||
</a-table>
|
||||
<div v-if="currentType === 'chart'">
|
||||
<a-row v-for="chart in chartSettings" :key="chart.series" style="margin-bottom:30px;">
|
||||
<base-index-chart
|
||||
:height="'300px'"
|
||||
:width="'100%'"
|
||||
:rawData="waterData"
|
||||
:setting="chart"
|
||||
/>
|
||||
</a-row>
|
||||
</div>
|
||||
<!-- -->
|
||||
</a-spin>
|
||||
</a-layout-content>
|
||||
</a-layout>
|
||||
</a-layout>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import SZJCChart from "./SZJCChart";
|
||||
// import SZJCChart from "./SZJCChart";
|
||||
import { getData, URL_MAP } from "@/utils/http";
|
||||
import Moment from 'moment'
|
||||
import { processWater } from '@/utils/water'
|
||||
import Moment from "@/components/utils/moment.zh_cn";
|
||||
import { processWater } from "@/utils/water";
|
||||
import BaseIndexChart from "../charts/BaseIndexChart.vue";
|
||||
export default {
|
||||
components: {
|
||||
SZJCChart,
|
||||
BaseIndexChart
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
datetimeRange: [Moment().hour(0).minute(0).second(0), Moment()],
|
||||
update: false,
|
||||
device: "",
|
||||
deviceList: [],
|
||||
deviceInstance: {},
|
||||
labelMap: {},
|
||||
checkedKeys: [],
|
||||
expandedKeys: [],
|
||||
autoExpandParent: true,
|
||||
selectedKeys: [],
|
||||
treeData: [],
|
||||
waterData: [],
|
||||
pagination: {
|
||||
total: 0,
|
||||
pageSize: 10,
|
||||
current: 0,
|
||||
},
|
||||
loading: false,
|
||||
update: false,
|
||||
startTime: Moment().subtract(1, "hours"),
|
||||
endTime: Moment(),
|
||||
deviceNames: {},
|
||||
timeRadios: [
|
||||
{
|
||||
value: "5-minutes",
|
||||
name: "最近5分钟",
|
||||
},
|
||||
{
|
||||
value: "15-minutes",
|
||||
name: "最近15分钟",
|
||||
},
|
||||
{
|
||||
value: "30-minutes",
|
||||
name: "最近30分钟",
|
||||
},
|
||||
{
|
||||
value: "1-hours",
|
||||
name: "最近1小时",
|
||||
},
|
||||
{
|
||||
value: "3-hours",
|
||||
name: "最近3小时",
|
||||
},
|
||||
{
|
||||
value: "6-hours",
|
||||
name: "最近6小时",
|
||||
},
|
||||
{
|
||||
value: "1-days",
|
||||
name: "最近24小时",
|
||||
},
|
||||
],
|
||||
radios: [
|
||||
{
|
||||
value: "table",
|
||||
name: "表格",
|
||||
},
|
||||
{
|
||||
value: "chart",
|
||||
name: "图形",
|
||||
},
|
||||
],
|
||||
currentType: "chart",
|
||||
chartSettings: [],
|
||||
};
|
||||
},
|
||||
watch: {
|
||||
device: function (old, newVal) {
|
||||
for (let i = 0; i < this.deviceList.length; i++) {
|
||||
if (this.deviceList[i]._id === newVal) {
|
||||
this.deviceInstance = this.deviceList[i];
|
||||
break;
|
||||
}
|
||||
}
|
||||
computed: {
|
||||
sensorList() {
|
||||
return this.$store.getters.sensorList;
|
||||
},
|
||||
deviceList() {
|
||||
return this.$store.getters.deviceList;
|
||||
},
|
||||
ruleList() {
|
||||
return this.$store.getters.ruleList;
|
||||
},
|
||||
},
|
||||
methods: {
|
||||
async initSeting() {
|
||||
let sensors = (await getData(URL_MAP.SENSOR_LIST)).data
|
||||
const labelMap = {}
|
||||
sensors.forEach(s => labelMap[s.param_key] = s.param_name)
|
||||
this.labelMap = labelMap
|
||||
},
|
||||
|
||||
async initDevice() {
|
||||
const device_ = (await getData(URL_MAP.DEVICE_LIST)).data;
|
||||
try {
|
||||
const device = device_.filter((item) => item.state == 1);
|
||||
this.deviceList = device;
|
||||
device.forEach((item) => {
|
||||
Object.keys(this.labelMap).forEach((k) => {
|
||||
if (item[k + "_factor"] === undefined) {
|
||||
item[k + "_factor"] = 1;
|
||||
}
|
||||
});
|
||||
// console.log(this.ruleList)
|
||||
const columns = [
|
||||
{
|
||||
title: "站点名",
|
||||
key: "device_name",
|
||||
scopedSlots: { customRender: "device" },
|
||||
},
|
||||
{
|
||||
title: "时间",
|
||||
dataIndex: "time_str",
|
||||
},
|
||||
];
|
||||
const ruleSlot = {};
|
||||
this.ruleList.forEach((rule) => {
|
||||
ruleSlot[rule.sensor.param_key] = {
|
||||
mmax: rule.allow_max,
|
||||
mmin: rule.allow_min,
|
||||
};
|
||||
});
|
||||
const chartSettings = [];
|
||||
this.sensorList.forEach((sensor) => {
|
||||
columns.push({
|
||||
title: sensor.param_name,
|
||||
children: [
|
||||
{
|
||||
title: sensor.uint || "-",
|
||||
dataIndex: sensor.param_key,
|
||||
customCell: (record, index) => {
|
||||
if (
|
||||
record[sensor.param_key] &&
|
||||
record[sensor.param_key] >= ruleSlot[sensor.param_key].mmin &&
|
||||
record[sensor.param_key] <= ruleSlot[sensor.param_key].mmax
|
||||
)
|
||||
return {};
|
||||
else {
|
||||
return {
|
||||
style: { color: "#ff0000" },
|
||||
};
|
||||
}
|
||||
},
|
||||
// scopedSlots: { customRender: sensor.param_key },
|
||||
},
|
||||
],
|
||||
});
|
||||
this.device = device[0]._id
|
||||
} catch (e) {
|
||||
console.log(e);
|
||||
}
|
||||
chartSettings.push({
|
||||
title: sensor.param_name,
|
||||
xAxis: "time",
|
||||
series: sensor.param_key,
|
||||
seriesName: sensor.param_name,
|
||||
seriesType: "line",
|
||||
yRange: [
|
||||
ruleSlot[sensor.param_key].mmin,
|
||||
ruleSlot[sensor.param_key].mmax,
|
||||
],
|
||||
});
|
||||
});
|
||||
this.chartSettings = chartSettings;
|
||||
// this.ruleSlot = ruleSlot;
|
||||
this.columns = columns;
|
||||
|
||||
const deviceTree = [];
|
||||
const deviceName = {};
|
||||
this.checkedKeys = [];
|
||||
this.deviceList.forEach((device) => {
|
||||
deviceTree.push({
|
||||
title: device.device_name,
|
||||
key: device._id,
|
||||
});
|
||||
deviceName[device.device_id] = device.device_name;
|
||||
this.checkedKeys.push(device._id);
|
||||
});
|
||||
this.deviceNames = deviceName;
|
||||
this.treeData = [
|
||||
{
|
||||
title: "设备",
|
||||
key: "all",
|
||||
children: deviceTree,
|
||||
},
|
||||
];
|
||||
},
|
||||
|
||||
async getData() {
|
||||
this.loading = true
|
||||
this.loading = true;
|
||||
try {
|
||||
const params = {
|
||||
'data__collect_time__gte':this.datetimeRange[0].toDate().getTime(),
|
||||
'data__collect_time__lte':this.datetimeRange[1].toDate().getTime(),
|
||||
'device_id':this.device
|
||||
timestamp__gte: this.startTime.toDate().getTime(),
|
||||
timestamp__lte: this.endTime.toDate().getTime(),
|
||||
device_id__in: this.selectedKeys,
|
||||
};
|
||||
if (this.currentType === "table") {
|
||||
params.page = this.pagination.current;
|
||||
}
|
||||
let data = await getData(URL_MAP.WATER_LIST, params)
|
||||
// console.log(data)
|
||||
this.waterData = processWater(data.data, Object.keys(this.labelMap))
|
||||
// console.log(this.waterData)
|
||||
if (this.currentType === "chart") {
|
||||
params.page = 0;
|
||||
params.page_size = 1e13;
|
||||
}
|
||||
let data = await getData(URL_MAP.WATER_LIST, params);
|
||||
|
||||
if (data.total === 0) {
|
||||
this.waterData = [];
|
||||
} else {
|
||||
this.waterData = processWater(
|
||||
data.data,
|
||||
this.sensorList.map((s) => s.param_key)
|
||||
);
|
||||
}
|
||||
|
||||
this.pagination.total = data.total;
|
||||
} catch (e) {
|
||||
console.log(e);
|
||||
this.waterData = [];
|
||||
}
|
||||
finally{
|
||||
this.loading = false
|
||||
} finally {
|
||||
this.loading = false;
|
||||
}
|
||||
},
|
||||
|
||||
onDeviceChange(value) {
|
||||
this.device = value
|
||||
handleTableChange(page, filters, sorter) {
|
||||
const pager = { ...this.pagination };
|
||||
pager.current = page.current;
|
||||
this.pagination = pager;
|
||||
this.getData();
|
||||
},
|
||||
|
||||
dateRangeChange(dates, dateStrings) {
|
||||
this.datetimeRange = dates;
|
||||
console.log(this.datetimeRange)
|
||||
console.log(this.datetimeRange);
|
||||
this.getData();
|
||||
},
|
||||
handleRadioClick(v) {
|
||||
this.currentType = v.target.value;
|
||||
},
|
||||
handleTimeRadioClick(v) {
|
||||
let now = Moment();
|
||||
let pre = Moment();
|
||||
let d = v.target.value.split("-");
|
||||
pre = pre.subtract(parseInt(d[0]), d[1]);
|
||||
this.startTime = pre;
|
||||
this.endTime = now;
|
||||
this.getData();
|
||||
},
|
||||
onSelect(keys) {
|
||||
// console.log(keys)
|
||||
this.selectedKeys = keys.filter((v) => v !== "all");
|
||||
// console.log(this.selectedKeys)
|
||||
},
|
||||
},
|
||||
|
||||
async mounted() {
|
||||
await this.initSeting();
|
||||
await this.initDevice();
|
||||
this.getData();
|
||||
},
|
||||
};
|
||||
@ -139,4 +327,7 @@ export default {
|
||||
text-align: center;
|
||||
line-height: 60px;
|
||||
}
|
||||
.error-data {
|
||||
color: rgb(255, 11, 2);
|
||||
}
|
||||
</style>
|
127
src/components/search/LurMean.vue
Normal file
127
src/components/search/LurMean.vue
Normal file
@ -0,0 +1,127 @@
|
||||
<template>
|
||||
<div style="height: calc(100vh - 110px)">
|
||||
<a-layout :theme="'light'" style="height: calc(100vh - 110px)">
|
||||
<a-layout-sider :theme="'light'" :width="300" style="padding: 20px">
|
||||
<div style="text-align: center; font-size: 16px">选择站点</div>
|
||||
<a-divider />
|
||||
<a-tree
|
||||
v-model="checkedKeys"
|
||||
checkable
|
||||
:selected-keys="selectedKeys"
|
||||
:auto-expand-parent="true"
|
||||
:tree-data="treeData"
|
||||
@select="onSelect"
|
||||
showLine
|
||||
>
|
||||
<a-icon slot="switcherIcon" type="down" />
|
||||
</a-tree>
|
||||
</a-layout-sider>
|
||||
<a-layout style="padding: 20px">
|
||||
<a-layout-header style="background: #fff; padding: 15px 0 5px 15px">
|
||||
|
||||
<span>
|
||||
<a-range-picker
|
||||
separator="至"
|
||||
:placeholder="['开始日期', '结束日期']"
|
||||
:defaultValue="datetimeRange"
|
||||
@change="dateRangeChange"
|
||||
></a-range-picker>
|
||||
<a-button style="margin-left: 15px" type="primary" icon="search"
|
||||
>查询</a-button
|
||||
>
|
||||
<a-button style="margin-left: 15px" type="primary" icon="download"
|
||||
>导出Excel</a-button
|
||||
>
|
||||
</span>
|
||||
</a-layout-header>
|
||||
<a-layout-content style="padding: 20px 0 20px 0">
|
||||
<a-table
|
||||
:columns="columns"
|
||||
:data-source="data"
|
||||
bordered
|
||||
size="middle"
|
||||
/>
|
||||
</a-layout-content>
|
||||
</a-layout>
|
||||
</a-layout>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
checkedKeys: ['all'],
|
||||
autoExpandParent: true,
|
||||
selectedKeys: [],
|
||||
treeData: [],
|
||||
datetimeRange: [],
|
||||
columns: [],
|
||||
data: [],
|
||||
};
|
||||
},
|
||||
computed: {
|
||||
sensorList() {
|
||||
return this.$store.getters.sensorList;
|
||||
},
|
||||
deviceList() {
|
||||
return this.$store.getters.deviceList;
|
||||
},
|
||||
},
|
||||
methods: {
|
||||
async fetch() {},
|
||||
onSelect() {},
|
||||
dateRangeChange() {},
|
||||
},
|
||||
mounted() {
|
||||
const columns = [
|
||||
{
|
||||
title: "站点名",
|
||||
dataIndex: "name",
|
||||
},
|
||||
{
|
||||
title: "日期",
|
||||
dataIndex: "time",
|
||||
},
|
||||
];
|
||||
this.sensorList.forEach((sensor) => {
|
||||
columns.push({
|
||||
title: sensor.param_name + '('+(sensor.uint || "-") + ')',
|
||||
children: [
|
||||
{
|
||||
title: '日均值',
|
||||
dataIndex: sensor.param_key + '1',
|
||||
},
|
||||
{
|
||||
title: '有效天数',
|
||||
dataIndex: sensor.param_key + '2',
|
||||
},
|
||||
{
|
||||
title: '超标天数',
|
||||
dataIndex: sensor.param_key + '3',
|
||||
},
|
||||
],
|
||||
});
|
||||
});
|
||||
this.columns = columns;
|
||||
|
||||
const deviceTree = [];
|
||||
this.deviceList.forEach((device) => {
|
||||
deviceTree.push({
|
||||
title: device.device_name,
|
||||
key: device._id,
|
||||
});
|
||||
});
|
||||
this.treeData = [
|
||||
{
|
||||
title: "设备",
|
||||
key: "all",
|
||||
children: deviceTree,
|
||||
},
|
||||
];
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
<style>
|
||||
</style>
|
121
src/components/search/LurSTS.vue
Normal file
121
src/components/search/LurSTS.vue
Normal file
@ -0,0 +1,121 @@
|
||||
<template>
|
||||
<div style="height: calc(100vh - 110px)">
|
||||
<a-layout :theme="'light'" style="height: calc(100vh - 110px)">
|
||||
<a-layout-sider :theme="'light'" :width="300" style="padding: 20px">
|
||||
<div style="text-align: center; font-size: 16px">选择站点</div>
|
||||
<a-divider />
|
||||
<a-tree
|
||||
v-model="checkedKeys"
|
||||
checkable
|
||||
:selected-keys="selectedKeys"
|
||||
:auto-expand-parent="true"
|
||||
:tree-data="treeData"
|
||||
@select="onSelect"
|
||||
showLine
|
||||
>
|
||||
<a-icon slot="switcherIcon" type="down" />
|
||||
</a-tree>
|
||||
</a-layout-sider>
|
||||
<a-layout style="padding: 20px">
|
||||
<a-layout-header style="background: #fff; padding: 15px 0 5px 15px">
|
||||
|
||||
<span>
|
||||
<a-range-picker
|
||||
separator="至"
|
||||
:placeholder="['开始日期', '结束日期']"
|
||||
:defaultValue="datetimeRange"
|
||||
@change="dateRangeChange"
|
||||
></a-range-picker>
|
||||
<a-button style="margin-left: 15px" type="primary" icon="search"
|
||||
>查询</a-button
|
||||
>
|
||||
<a-button style="margin-left: 15px" type="primary" icon="download"
|
||||
>导出Excel</a-button
|
||||
>
|
||||
</span>
|
||||
</a-layout-header>
|
||||
<a-layout-content style="padding: 20px 0 20px 0">
|
||||
<a-table
|
||||
:columns="columns"
|
||||
:data-source="data"
|
||||
bordered
|
||||
size="middle"
|
||||
/>
|
||||
</a-layout-content>
|
||||
</a-layout>
|
||||
</a-layout>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
checkedKeys: ['all'],
|
||||
autoExpandParent: true,
|
||||
selectedKeys: [],
|
||||
treeData: [],
|
||||
datetimeRange: [],
|
||||
columns: [],
|
||||
data: [],
|
||||
};
|
||||
},
|
||||
computed: {
|
||||
sensorList() {
|
||||
return this.$store.getters.sensorList;
|
||||
},
|
||||
deviceList() {
|
||||
return this.$store.getters.deviceList;
|
||||
},
|
||||
},
|
||||
methods: {
|
||||
async fetch() {},
|
||||
onSelect() {},
|
||||
dateRangeChange() {},
|
||||
},
|
||||
mounted() {
|
||||
const columns = [
|
||||
{
|
||||
title: "站点名",
|
||||
dataIndex: "name",
|
||||
},
|
||||
{
|
||||
title: "时间段",
|
||||
dataIndex: "range",
|
||||
},
|
||||
{
|
||||
title: '总超标(/次)',
|
||||
dataIndex: "lur-count"
|
||||
},
|
||||
{
|
||||
title: '单日最高超标(/次)',
|
||||
dataIndex: "lur-count"
|
||||
},
|
||||
{
|
||||
title: '单日最高超标(时间)',
|
||||
dataIndex: "lur-count"
|
||||
},
|
||||
];
|
||||
|
||||
this.columns = columns;
|
||||
|
||||
const deviceTree = [];
|
||||
this.deviceList.forEach((device) => {
|
||||
deviceTree.push({
|
||||
title: device.device_name,
|
||||
key: device._id,
|
||||
});
|
||||
});
|
||||
this.treeData = [
|
||||
{
|
||||
title: "设备",
|
||||
key: "all",
|
||||
children: deviceTree,
|
||||
},
|
||||
];
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
<style>
|
||||
</style>
|
217
src/components/search/Means.vue
Normal file
217
src/components/search/Means.vue
Normal file
@ -0,0 +1,217 @@
|
||||
<template>
|
||||
<div style="height: calc(100vh - 110px)">
|
||||
<a-layout :theme="'light'" style="height: calc(100vh - 110px)">
|
||||
<a-layout-sider :theme="'light'" :width="300" style="padding: 20px">
|
||||
<div style="text-align: center; font-size: 16px">选择站点</div>
|
||||
<a-divider />
|
||||
<a-tree
|
||||
v-model="checkedKeys"
|
||||
checkable
|
||||
:selected-keys="selectedKeys"
|
||||
:auto-expand-parent="true"
|
||||
:tree-data="treeData"
|
||||
@select="onSelect"
|
||||
showLine
|
||||
>
|
||||
<a-icon slot="switcherIcon" type="down" />
|
||||
</a-tree>
|
||||
</a-layout-sider>
|
||||
<a-layout style="padding: 20px">
|
||||
<a-layout-header style="background: #fff; padding: 15px 0 5px 15px">
|
||||
<a-radio-group default-value="5_min" button-style="solid" style="display: block; line-height: 32px" @click="handleRadioClick">
|
||||
<a-radio-button v-for="item in radios" :key="item.value" :value="item.value"> {{item.name}} </a-radio-button>
|
||||
</a-radio-group>
|
||||
<span>
|
||||
<a-date-picker
|
||||
:locale="locale"
|
||||
v-model="startValue"
|
||||
:disabled-date="disabledStartDate"
|
||||
format="YYYY-MM-DD"
|
||||
placeholder="开始日期"
|
||||
@openChange="handleStartOpenChange"
|
||||
/> -
|
||||
<a-date-picker
|
||||
:locale="locale"
|
||||
v-model="endValue"
|
||||
:disabled-date="disabledEndDate"
|
||||
format="YYYY-MM-DD"
|
||||
placeholder="结束日期"
|
||||
/>
|
||||
<a-button style="margin-left: 15px" type="primary" icon="search"
|
||||
>查询</a-button
|
||||
>
|
||||
</span>
|
||||
</a-layout-header>
|
||||
<a-layout-content style="padding: 20px 0 20px 0">
|
||||
<a-table
|
||||
:columns="columns"
|
||||
:data-source="data"
|
||||
bordered
|
||||
size="middle"
|
||||
/>
|
||||
</a-layout-content>
|
||||
</a-layout>
|
||||
</a-layout>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import Moment from '../utils/moment.zh_cn';
|
||||
import locale from 'ant-design-vue/es/date-picker/locale/zh_CN';
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
locale,
|
||||
checkedKeys: ['all'],
|
||||
autoExpandParent: true,
|
||||
selectedKeys: [],
|
||||
treeData: [],
|
||||
startValue: Moment().subtract(1, 'days'),
|
||||
endValue: Moment(),
|
||||
endOpen: false,
|
||||
columns: [],
|
||||
data: [],
|
||||
radios:[
|
||||
{
|
||||
value:'5_min',
|
||||
name: '5分钟值',
|
||||
rangeLimit: 7
|
||||
},
|
||||
{
|
||||
value:'1_hour',
|
||||
name: '小时值',
|
||||
rangeLimit: 7
|
||||
},
|
||||
{
|
||||
value:'day',
|
||||
name: '日均值',
|
||||
rangeLimit: 30
|
||||
},
|
||||
{
|
||||
value:'month',
|
||||
name: '月均值',
|
||||
rangeLimit: 0
|
||||
}
|
||||
],
|
||||
radioValueToRange:{
|
||||
'5_min':7,'1_hour':7,'day':30,'month':0
|
||||
},
|
||||
currentRaido:'5_min'
|
||||
};
|
||||
},
|
||||
computed: {
|
||||
sensorList() {
|
||||
return this.$store.getters.sensorList;
|
||||
},
|
||||
deviceList() {
|
||||
return this.$store.getters.deviceList;
|
||||
},
|
||||
showTime() {
|
||||
const showTimeValues = ['detail', '5_min', '1_hour']
|
||||
return showTimeValues.includes(this.currentRaido)
|
||||
}
|
||||
|
||||
},
|
||||
watch: {
|
||||
startValue(old, newVal) {
|
||||
console.log(old)
|
||||
let m = Moment(newVal).add(this.radioValueToRange[this.currentRaido], 'days')
|
||||
if(this.radioValueToRange[this.currentRaido] === 0) {
|
||||
return
|
||||
}
|
||||
if(this.endValue.valueOf() > m.valueOf()) {
|
||||
this.endValue = m
|
||||
}
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
async fetch() {},
|
||||
onSelect() {},
|
||||
dateRangeChange() {},
|
||||
handleRadioClick(v) {
|
||||
this.currentRaido = v;
|
||||
},
|
||||
disabledStartDate(startValue) {
|
||||
// const endValue = this.endValue;
|
||||
// if (!startValue || !endValue) {
|
||||
// return false;
|
||||
// }
|
||||
// let rangeDay = this.radioValueToRange[this.currentRaido]
|
||||
// if(rangeDay>0)
|
||||
// {
|
||||
// let start_end_value = endValue.subtract(rangeDay, 'days')
|
||||
// return (startValue.valueOf() < start_end_value.valueOf()) && (startValue.valueOf() > endValue.valueOf())
|
||||
// }
|
||||
return startValue.valueOf() > Moment().valueOf();
|
||||
},
|
||||
disabledEndDate(endValue) {
|
||||
const startValue = this.startValue;
|
||||
if (!endValue || !startValue) {
|
||||
return false;
|
||||
}
|
||||
let rangeDay = this.radioValueToRange[this.currentRaido]
|
||||
if(rangeDay>0)
|
||||
{
|
||||
|
||||
let start_end_value = Moment(startValue).add(rangeDay, 'days')
|
||||
// console.log(start_end_value.format('lll'), endValue.format('lll'), startValue.format('lll'))
|
||||
return !( (endValue.valueOf() <= Moment().hour(24).valueOf()) &&
|
||||
(endValue.valueOf() <= start_end_value.valueOf()) &&
|
||||
(endValue.valueOf() >= startValue.valueOf()) )
|
||||
}
|
||||
return startValue.valueOf() > endValue.valueOf() || endValue.valueOf() > Moment().valueOf();
|
||||
},
|
||||
// handleStartOpenChange(open) {
|
||||
// if (!open) {
|
||||
// this.endOpen = true;
|
||||
// }
|
||||
// },
|
||||
// handleEndOpenChange(open) {
|
||||
// this.endOpen = open;
|
||||
// },
|
||||
},
|
||||
mounted() {
|
||||
const columns = [
|
||||
{
|
||||
title: "站点名",
|
||||
dataIndex: "name",
|
||||
},
|
||||
{
|
||||
title: "时间",
|
||||
dataIndex: "time",
|
||||
},
|
||||
];
|
||||
this.sensorList.forEach((sensor) => {
|
||||
columns.push({
|
||||
title: sensor.param_name,
|
||||
children: [
|
||||
{
|
||||
title: sensor.uint || "-",
|
||||
dataIndex: sensor.param_key,
|
||||
},
|
||||
],
|
||||
});
|
||||
});
|
||||
|
||||
this.columns = columns;
|
||||
|
||||
const deviceTree = [];
|
||||
this.deviceList.forEach((device) => {
|
||||
deviceTree.push({
|
||||
title: device.device_name,
|
||||
key: device._id,
|
||||
});
|
||||
});
|
||||
this.treeData = [
|
||||
{
|
||||
title: "设备",
|
||||
key: "all",
|
||||
children: deviceTree,
|
||||
},
|
||||
];
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
<style>
|
||||
</style>
|
124
src/components/search/QaDay.vue
Normal file
124
src/components/search/QaDay.vue
Normal file
@ -0,0 +1,124 @@
|
||||
<template>
|
||||
<div style="height: calc(100vh - 110px)">
|
||||
<a-layout :theme="'light'" style="height: calc(100vh - 110px)">
|
||||
<a-layout-sider :theme="'light'" :width="300" style="padding: 20px">
|
||||
<div style="text-align: center; font-size: 16px">选择站点</div>
|
||||
<a-divider />
|
||||
<a-tree
|
||||
v-model="checkedKeys"
|
||||
checkable
|
||||
:selected-keys="selectedKeys"
|
||||
:auto-expand-parent="true"
|
||||
:tree-data="treeData"
|
||||
@select="onSelect"
|
||||
showLine
|
||||
>
|
||||
<a-icon slot="switcherIcon" type="down" />
|
||||
</a-tree>
|
||||
</a-layout-sider>
|
||||
<a-layout style="padding: 20px">
|
||||
<a-layout-header style="background: #fff; padding: 15px 0 5px 15px">
|
||||
|
||||
<span>
|
||||
<a-range-picker
|
||||
separator="至"
|
||||
:placeholder="['开始日期', '结束日期']"
|
||||
:defaultValue="datetimeRange"
|
||||
@change="dateRangeChange"
|
||||
></a-range-picker>
|
||||
<a-button style="margin-left: 15px" type="primary" icon="search"
|
||||
>查询</a-button
|
||||
>
|
||||
<a-button style="margin-left: 15px" type="primary" icon="download"
|
||||
>导出Excel</a-button
|
||||
>
|
||||
</span>
|
||||
</a-layout-header>
|
||||
<a-layout-content style="padding: 20px 0 20px 0">
|
||||
<a-table
|
||||
:columns="columns"
|
||||
:data-source="data"
|
||||
bordered
|
||||
size="middle"
|
||||
/>
|
||||
</a-layout-content>
|
||||
</a-layout>
|
||||
</a-layout>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
checkedKeys: ['all'],
|
||||
autoExpandParent: true,
|
||||
selectedKeys: [],
|
||||
treeData: [],
|
||||
datetimeRange: [],
|
||||
columns: [],
|
||||
data: [],
|
||||
};
|
||||
},
|
||||
computed: {
|
||||
sensorList() {
|
||||
return this.$store.getters.sensorList;
|
||||
},
|
||||
deviceList() {
|
||||
return this.$store.getters.deviceList;
|
||||
},
|
||||
},
|
||||
methods: {
|
||||
async fetch() {},
|
||||
onSelect() {},
|
||||
dateRangeChange() {},
|
||||
},
|
||||
mounted() {
|
||||
const columns = [
|
||||
{
|
||||
title: "站点名",
|
||||
dataIndex: "name",
|
||||
},
|
||||
{
|
||||
title: "日期",
|
||||
dataIndex: "time",
|
||||
},
|
||||
];
|
||||
this.sensorList.forEach((sensor) => {
|
||||
columns.push({
|
||||
title: sensor.param_name,
|
||||
children: [
|
||||
{
|
||||
title: sensor.uint || "-",
|
||||
dataIndex: sensor.param_key,
|
||||
},
|
||||
],
|
||||
});
|
||||
});
|
||||
columns.push({
|
||||
title:'水质质量等级',
|
||||
dataIndex:'level',
|
||||
|
||||
})
|
||||
this.columns = columns;
|
||||
|
||||
const deviceTree = [];
|
||||
this.deviceList.forEach((device) => {
|
||||
deviceTree.push({
|
||||
title: device.device_name,
|
||||
key: device._id,
|
||||
});
|
||||
});
|
||||
this.treeData = [
|
||||
{
|
||||
title: "设备",
|
||||
key: "all",
|
||||
children: deviceTree,
|
||||
},
|
||||
];
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
<style>
|
||||
</style>
|
170
src/components/search/QaSTS.vue
Normal file
170
src/components/search/QaSTS.vue
Normal file
@ -0,0 +1,170 @@
|
||||
<template>
|
||||
<div style="height: calc(100vh - 110px)">
|
||||
<a-layout :theme="'light'" style="height: calc(100vh - 110px)">
|
||||
<a-layout-sider :theme="'light'" :width="300" style="padding: 20px">
|
||||
<div style="text-align: center; font-size: 16px">选择站点</div>
|
||||
<a-divider />
|
||||
<a-tree
|
||||
v-model="checkedKeys"
|
||||
checkable
|
||||
:selected-keys="selectedKeys"
|
||||
:auto-expand-parent="true"
|
||||
:tree-data="treeData"
|
||||
@select="onSelect"
|
||||
showLine
|
||||
>
|
||||
<a-icon slot="switcherIcon" type="down" />
|
||||
</a-tree>
|
||||
</a-layout-sider>
|
||||
<a-layout style="padding: 20px">
|
||||
<a-layout-header style="background: #fff; padding: 15px 0 5px 15px">
|
||||
|
||||
<span>
|
||||
<a-range-picker
|
||||
separator="至"
|
||||
:placeholder="['开始日期', '结束日期']"
|
||||
:defaultValue="datetimeRange"
|
||||
@change="dateRangeChange"
|
||||
></a-range-picker>
|
||||
<a-button style="margin-left: 15px" type="primary" icon="search"
|
||||
>查询</a-button
|
||||
>
|
||||
<a-button style="margin-left: 15px" type="primary" icon="download"
|
||||
>导出Excel</a-button
|
||||
>
|
||||
</span>
|
||||
</a-layout-header>
|
||||
<a-layout-content style="padding: 20px 0 20px 0">
|
||||
<a-table
|
||||
:columns="columns"
|
||||
:data-source="data"
|
||||
bordered
|
||||
size="middle"
|
||||
/>
|
||||
</a-layout-content>
|
||||
</a-layout>
|
||||
</a-layout>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
checkedKeys: ['all'],
|
||||
autoExpandParent: true,
|
||||
selectedKeys: [],
|
||||
treeData: [],
|
||||
datetimeRange: [],
|
||||
columns: [],
|
||||
data: [],
|
||||
};
|
||||
},
|
||||
computed: {
|
||||
sensorList() {
|
||||
return this.$store.getters.sensorList;
|
||||
},
|
||||
deviceList() {
|
||||
return this.$store.getters.deviceList;
|
||||
},
|
||||
},
|
||||
methods: {
|
||||
async fetch() {},
|
||||
onSelect() {},
|
||||
dateRangeChange() {},
|
||||
},
|
||||
mounted() {
|
||||
const columns = [
|
||||
{
|
||||
title: "站点名",
|
||||
dataIndex: "name",
|
||||
},
|
||||
{
|
||||
title: '优',
|
||||
children:[
|
||||
{
|
||||
title: '优天数',
|
||||
dataIndex:'good_days'
|
||||
},
|
||||
{
|
||||
title: '比率',
|
||||
dataIndex:'good_ratio'
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
title: '良',
|
||||
children:[
|
||||
{
|
||||
title: '良天数',
|
||||
dataIndex:'well_days'
|
||||
},
|
||||
{
|
||||
title: '比率',
|
||||
dataIndex:'well_ratio'
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
title: '轻微超标',
|
||||
children:[
|
||||
{
|
||||
title: '轻微超标天数',
|
||||
dataIndex:'small_days'
|
||||
},
|
||||
{
|
||||
title: '比率',
|
||||
dataIndex:'small_ratio'
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
title: '严重超标',
|
||||
children:[
|
||||
{
|
||||
title: '严重超标天数',
|
||||
dataIndex:'bad_days'
|
||||
},
|
||||
{
|
||||
title: '比率',
|
||||
dataIndex:'bad_ratio'
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
title: '合计',
|
||||
children:[
|
||||
{
|
||||
title: '总天数',
|
||||
dataIndex:'all_days'
|
||||
},
|
||||
{
|
||||
title: '有效数据比例',
|
||||
dataIndex:'all_ratio'
|
||||
}
|
||||
]
|
||||
}
|
||||
];
|
||||
|
||||
this.columns = columns;
|
||||
|
||||
const deviceTree = [];
|
||||
this.deviceList.forEach((device) => {
|
||||
deviceTree.push({
|
||||
title: device.device_name,
|
||||
key: device._id,
|
||||
});
|
||||
});
|
||||
this.treeData = [
|
||||
{
|
||||
title: "设备",
|
||||
key: "all",
|
||||
children: deviceTree,
|
||||
},
|
||||
];
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
<style>
|
||||
</style>
|
133
src/components/search/YLSTS.vue
Normal file
133
src/components/search/YLSTS.vue
Normal file
@ -0,0 +1,133 @@
|
||||
<template>
|
||||
<div style="height: calc(100vh - 110px)">
|
||||
<a-layout :theme="'light'" style="height: calc(100vh - 110px)">
|
||||
<a-layout-sider :theme="'light'" :width="300" style="padding: 20px">
|
||||
<div style="text-align: center; font-size: 16px">选择站点</div>
|
||||
<a-divider />
|
||||
<a-tree
|
||||
v-model="checkedKeys"
|
||||
checkable
|
||||
:selected-keys="selectedKeys"
|
||||
:auto-expand-parent="true"
|
||||
:tree-data="treeData"
|
||||
@select="onSelect"
|
||||
showLine
|
||||
>
|
||||
<a-icon slot="switcherIcon" type="down" />
|
||||
</a-tree>
|
||||
</a-layout-sider>
|
||||
<a-layout style="padding: 20px">
|
||||
<a-layout-header style="background: #fff; padding: 15px 0 5px 15px">
|
||||
|
||||
<span>
|
||||
<a-range-picker
|
||||
separator="至"
|
||||
:placeholder="['开始日期', '结束日期']"
|
||||
:defaultValue="datetimeRange"
|
||||
@change="dateRangeChange"
|
||||
></a-range-picker>
|
||||
<a-button style="margin-left: 15px" type="primary" icon="search"
|
||||
>查询</a-button
|
||||
>
|
||||
<a-button style="margin-left: 15px" type="primary" icon="download"
|
||||
>导出Excel</a-button
|
||||
>
|
||||
</span>
|
||||
</a-layout-header>
|
||||
<a-layout-content style="padding: 20px 0 20px 0">
|
||||
<a-table
|
||||
:columns="columns"
|
||||
:data-source="data"
|
||||
bordered
|
||||
size="middle"
|
||||
/>
|
||||
</a-layout-content>
|
||||
</a-layout>
|
||||
</a-layout>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
checkedKeys: ['all'],
|
||||
autoExpandParent: true,
|
||||
selectedKeys: [],
|
||||
treeData: [],
|
||||
datetimeRange: [],
|
||||
columns: [],
|
||||
data: [],
|
||||
};
|
||||
},
|
||||
computed: {
|
||||
sensorList() {
|
||||
return this.$store.getters.sensorList;
|
||||
},
|
||||
deviceList() {
|
||||
return this.$store.getters.deviceList;
|
||||
},
|
||||
},
|
||||
methods: {
|
||||
async fetch() {},
|
||||
onSelect() {},
|
||||
dateRangeChange() {},
|
||||
},
|
||||
mounted() {
|
||||
const columns = [
|
||||
{
|
||||
title: "站点名",
|
||||
dataIndex: "name",
|
||||
},
|
||||
{
|
||||
title: "时间段",
|
||||
dataIndex: "range",
|
||||
},
|
||||
{
|
||||
title: '检测值',
|
||||
dataIndex: "lur-count"
|
||||
},
|
||||
{
|
||||
title: '超标比率',
|
||||
dataIndex: "lur-count"
|
||||
},
|
||||
{
|
||||
title: '是否处理',
|
||||
dataIndex: "lur-count"
|
||||
},
|
||||
{
|
||||
title: '处理人',
|
||||
dataIndex: "lur-count"
|
||||
},
|
||||
{
|
||||
title: '处理时间',
|
||||
dataIndex: "lur-count"
|
||||
},
|
||||
{
|
||||
title: '处理概述',
|
||||
dataIndex: "lur-count"
|
||||
},
|
||||
];
|
||||
|
||||
this.columns = columns;
|
||||
|
||||
const deviceTree = [];
|
||||
this.deviceList.forEach((device) => {
|
||||
deviceTree.push({
|
||||
title: device.device_name,
|
||||
key: device._id,
|
||||
});
|
||||
});
|
||||
this.treeData = [
|
||||
{
|
||||
title: "设备",
|
||||
key: "all",
|
||||
children: deviceTree,
|
||||
},
|
||||
];
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
<style>
|
||||
</style>
|
115
src/components/utils/moment.zh_cn.js
Normal file
115
src/components/utils/moment.zh_cn.js
Normal file
@ -0,0 +1,115 @@
|
||||
import Moment from 'moment'
|
||||
Moment.locale('zh-cn', {
|
||||
months: '一月_二月_三月_四月_五月_六月_七月_八月_九月_十月_十一月_十二月'.split(
|
||||
'_'
|
||||
),
|
||||
monthsShort: '1月_2月_3月_4月_5月_6月_7月_8月_9月_10月_11月_12月'.split(
|
||||
'_'
|
||||
),
|
||||
weekdays: '星期日_星期一_星期二_星期三_星期四_星期五_星期六'.split('_'),
|
||||
weekdaysShort: '周日_周一_周二_周三_周四_周五_周六'.split('_'),
|
||||
weekdaysMin: '日_一_二_三_四_五_六'.split('_'),
|
||||
longDateFormat: {
|
||||
LT: 'HH:mm',
|
||||
LTS: 'HH:mm:ss',
|
||||
L: 'YYYY/MM/DD',
|
||||
LL: 'YYYY年M月D日',
|
||||
LLL: 'YYYY年M月D日Ah点mm分',
|
||||
LLLL: 'YYYY年M月D日ddddAh点mm分',
|
||||
l: 'YYYY/M/D',
|
||||
ll: 'YYYY年M月D日',
|
||||
lll: 'YYYY年M月D日 HH:mm',
|
||||
llll: 'YYYY年M月D日dddd HH:mm',
|
||||
},
|
||||
meridiemParse: /凌晨|早上|上午|中午|下午|晚上/,
|
||||
meridiemHour: function (hour, meridiem) {
|
||||
if (hour === 12) {
|
||||
hour = 0;
|
||||
}
|
||||
if (meridiem === '凌晨' || meridiem === '早上' || meridiem === '上午') {
|
||||
return hour;
|
||||
} else if (meridiem === '下午' || meridiem === '晚上') {
|
||||
return hour + 12;
|
||||
} else {
|
||||
// '中午'
|
||||
return hour >= 11 ? hour : hour + 12;
|
||||
}
|
||||
},
|
||||
meridiem: function (hour, minute, isLower) {
|
||||
var hm = hour * 100 + minute;
|
||||
if (hm < 600) {
|
||||
return '凌晨';
|
||||
} else if (hm < 900) {
|
||||
return '早上';
|
||||
} else if (hm < 1130) {
|
||||
return '上午';
|
||||
} else if (hm < 1230) {
|
||||
return '中午';
|
||||
} else if (hm < 1800) {
|
||||
return '下午';
|
||||
} else {
|
||||
return '晚上';
|
||||
}
|
||||
},
|
||||
calendar: {
|
||||
sameDay: '[今天]LT',
|
||||
nextDay: '[明天]LT',
|
||||
nextWeek: function (now) {
|
||||
if (now.week() !== this.week()) {
|
||||
return '[下]dddLT';
|
||||
} else {
|
||||
return '[本]dddLT';
|
||||
}
|
||||
},
|
||||
lastDay: '[昨天]LT',
|
||||
lastWeek: function (now) {
|
||||
if (this.week() !== now.week()) {
|
||||
return '[上]dddLT';
|
||||
} else {
|
||||
return '[本]dddLT';
|
||||
}
|
||||
},
|
||||
sameElse: 'L',
|
||||
},
|
||||
dayOfMonthOrdinalParse: /\d{1,2}(日|月|周)/,
|
||||
ordinal: function (number, period) {
|
||||
switch (period) {
|
||||
case 'd':
|
||||
case 'D':
|
||||
case 'DDD':
|
||||
return number + '日';
|
||||
case 'M':
|
||||
return number + '月';
|
||||
case 'w':
|
||||
case 'W':
|
||||
return number + '周';
|
||||
default:
|
||||
return number;
|
||||
}
|
||||
},
|
||||
relativeTime: {
|
||||
future: '%s后',
|
||||
past: '%s前',
|
||||
s: '几秒',
|
||||
ss: '%d 秒',
|
||||
m: '1 分钟',
|
||||
mm: '%d 分钟',
|
||||
h: '1 小时',
|
||||
hh: '%d 小时',
|
||||
d: '1 天',
|
||||
dd: '%d 天',
|
||||
w: '1 周',
|
||||
ww: '%d 周',
|
||||
M: '1 个月',
|
||||
MM: '%d 个月',
|
||||
y: '1 年',
|
||||
yy: '%d 年',
|
||||
},
|
||||
week: {
|
||||
// GB/T 7408-1994《数据元和交换格式·信息交换·日期和时间表示法》与ISO 8601:1988等效
|
||||
dow: 1, // Monday is the first day of the week.
|
||||
doy: 4, // The week that contains Jan 4th is the first week of the year.
|
||||
},
|
||||
});
|
||||
|
||||
export default Moment
|
@ -1,4 +1,5 @@
|
||||
import axios from "axios";
|
||||
import qs from 'qs'
|
||||
|
||||
const backendUrl = '/backend/'
|
||||
const geoServerUrl = '/geoserver/'
|
||||
@ -20,17 +21,18 @@ export const URL_MAP = {
|
||||
CHANGE_PASSWD: 'current/chpass/',
|
||||
RESET_PASSWD: 'passwd/reset/',
|
||||
POSITION_LIST: 'position/',
|
||||
POSITION_DETAIL: 'position/detail/'
|
||||
POSITION_DETAIL: 'position/detail/',
|
||||
RULES_LIST: 'parammanager/',
|
||||
RULES_DETAIL: 'parammanager/detail/'
|
||||
|
||||
}
|
||||
|
||||
export async function login(username, passwd, uuid, capthe)
|
||||
{
|
||||
export async function login(username, passwd, uuid, capthe) {
|
||||
let response = await instance.post('auth', {
|
||||
'username':username,
|
||||
'password':passwd,
|
||||
'uuid':uuid,
|
||||
'captch':capthe
|
||||
'username': username,
|
||||
'password': passwd,
|
||||
'uuid': uuid,
|
||||
'captch': capthe
|
||||
})
|
||||
let data = await response.data
|
||||
let token = data.access_token
|
||||
@ -46,16 +48,19 @@ export function setAuth(auth) {
|
||||
instance.defaults.headers['Authorization'] = 'JWT ' + auth;
|
||||
}
|
||||
|
||||
export async function logout()
|
||||
{
|
||||
export async function logout() {
|
||||
instance.defaults.headers['Authorization'] = ''
|
||||
}
|
||||
|
||||
export async function getData(url, json) {
|
||||
let response = await instance.get(url, {
|
||||
params: json
|
||||
,
|
||||
paramsSerializer: function (params) {
|
||||
return qs.stringify(params, { arrayFormat: 'repeat' })
|
||||
}
|
||||
})
|
||||
|
||||
|
||||
let data = await response.data
|
||||
return data
|
||||
}
|
||||
@ -63,7 +68,7 @@ export async function getData(url, json) {
|
||||
export async function postJSON(url, json) {
|
||||
const headerJSON = {
|
||||
"Content-Type": "application/json"
|
||||
};
|
||||
};
|
||||
let response = await instance.post(url, JSON.stringify(json), { headers: headerJSON })
|
||||
let data = await response.data
|
||||
return data
|
||||
@ -72,7 +77,7 @@ export async function postJSON(url, json) {
|
||||
export async function putJSON(url, json) {
|
||||
const headerJSON = {
|
||||
"Content-Type": "application/json"
|
||||
};
|
||||
};
|
||||
let response = await instance.put(url, JSON.stringify(json), { headers: headerJSON })
|
||||
let data = await response.data
|
||||
return data
|
||||
@ -81,7 +86,7 @@ export async function putJSON(url, json) {
|
||||
export async function patchJSON(url, json) {
|
||||
const headerJSON = {
|
||||
"Content-Type": "application/json"
|
||||
};
|
||||
};
|
||||
let response = await instance.patch(url, JSON.stringify(json), { headers: headerJSON })
|
||||
let data = await response.data
|
||||
return data
|
||||
@ -90,8 +95,8 @@ export async function patchJSON(url, json) {
|
||||
export async function deleteJSON(url, json) {
|
||||
const headerJSON = {
|
||||
"Content-Type": "application/json"
|
||||
};
|
||||
let response = await instance.delete(url, { data:json })
|
||||
};
|
||||
let response = await instance.delete(url, { data: json })
|
||||
let data = await response.data
|
||||
return data
|
||||
}
|
@ -9,6 +9,12 @@ Vue.use(VueRouter)
|
||||
const funcRoutes = [
|
||||
{ path:'map-layout', name:'map-layout', component: ()=>import(/* webpackChunkName: "map-layout" */ '@/components/map/Index' ) },
|
||||
{ path:'detail-search', name:'detail-search', component: ()=>import(/* webpackChunkName: "detail-search" */ '@/components/search/Index' ) },
|
||||
{ path:'means', name:'means', component: ()=>import(/* webpackChunkName: "means" */ '@/components/search/Means' ) },
|
||||
{ path:'qa-day', name:'qa-day', component: ()=>import(/* webpackChunkName: "qa-day" */ '@/components/search/QaDay' ) },
|
||||
{ path:'lur-mean', name:'lur-mean', component: ()=>import(/* webpackChunkName: "lur-mean" */ '@/components/search/LurMean' ) },
|
||||
{ path:'qa-sts', name:'qa-sts', component: ()=>import(/* webpackChunkName: "qa-sts" */ '@/components/search/QaSTS' ) },
|
||||
{ path:'lur-sts', name:'lur-sts', component: ()=>import(/* webpackChunkName: "lur-sts" */ '@/components/search/LurSTS' ) },
|
||||
{ path:'yl-sts', name:'yl-sts', component: ()=>import(/* webpackChunkName: "yl-sts" */ '@/components/search/YLSTS' ) },
|
||||
{ path:'admin', name:'admin', component: ()=>import(/* webpackChunkName: "admin" */ '@/components/admin/Index' ) },
|
||||
{ path:'analysis', name:'analysis', component: ()=>import(/* webpackChunkName: "analysis" */ '@/components/analysis/Index' ) },
|
||||
]
|
||||
@ -65,5 +71,5 @@ router.beforeEach((to, from, next) => {
|
||||
next()
|
||||
}
|
||||
})
|
||||
|
||||
console.log(router)
|
||||
export default router
|
@ -27,7 +27,8 @@ const store = new Vuex.Store({
|
||||
cacheData:{},
|
||||
deviceList:[],
|
||||
projectList:[],
|
||||
sensorList:[]
|
||||
sensorList:[],
|
||||
ruleList:[]
|
||||
},
|
||||
mutations: {
|
||||
phone(state, o) {
|
||||
@ -52,6 +53,9 @@ const store = new Vuex.Store({
|
||||
},
|
||||
sensorList(state, o) {
|
||||
state.sensorList = o
|
||||
},
|
||||
ruleList(state, o) {
|
||||
state.ruleList = o
|
||||
}
|
||||
},
|
||||
getters: {
|
||||
@ -120,6 +124,9 @@ const store = new Vuex.Store({
|
||||
sensorList(state) {
|
||||
return state.sensorList
|
||||
},
|
||||
ruleList(state) {
|
||||
return state.ruleList
|
||||
},
|
||||
username(state, getters) {
|
||||
if (getters.isLogin)
|
||||
{
|
||||
|
@ -1,3 +1,5 @@
|
||||
import Moment from 'com/utils/moment.zh_cn'
|
||||
|
||||
export function processWater(water, label){
|
||||
|
||||
const waters = []
|
||||
@ -8,9 +10,10 @@ export function processWater(water, label){
|
||||
if(!!w.data) {
|
||||
n[key] = w.data[key]
|
||||
}
|
||||
|
||||
} )
|
||||
n['time'] = new Date(w.data.collect_time)
|
||||
n['key'] = w._id.$oid
|
||||
n['time_str'] = Moment(w.timestamp).format('lll')
|
||||
n['time'] = Moment(w.timestamp).toDate()
|
||||
waters.push(n)
|
||||
} )
|
||||
return waters
|
||||
|
@ -1,4 +1,5 @@
|
||||
const path = require('path')
|
||||
const { env } = require('process')
|
||||
|
||||
module.exports = {
|
||||
publicPath: '/',
|
||||
@ -10,7 +11,8 @@ module.exports = {
|
||||
proxy: {
|
||||
'/backend': {
|
||||
// target: 'http://223.75.53.208:8081',
|
||||
target: 'http://121.36.155.145:10025/',
|
||||
// target: 'http://121.36.155.145:10025/',
|
||||
target: 'http://127.0.0.1:7788/'
|
||||
}
|
||||
}
|
||||
},
|
||||
@ -31,7 +33,7 @@ module.exports = {
|
||||
'com': path.resolve(__dirname, 'src', 'components')
|
||||
}
|
||||
},
|
||||
externals: {
|
||||
externals: true ? {
|
||||
'vue': 'Vue',
|
||||
'vuex':'Vuex',
|
||||
'antd': 'antd',
|
||||
@ -41,6 +43,13 @@ module.exports = {
|
||||
'axios': 'axios',
|
||||
'v-charts':'VCharts',
|
||||
'ol':'ol'
|
||||
}: {
|
||||
'antd': 'antd',
|
||||
'ol':'ol',
|
||||
'v-charts':'VCharts',
|
||||
"moment": "moment",
|
||||
"md5": "js-md5",
|
||||
'axios': 'axios',
|
||||
},
|
||||
module: {
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user