Compare commits

...

10 Commits

  1. 1
      package.json
  2. 5
      src/components/registerGlobComp.ts
  3. 2
      src/layouts/local/dashboard/analysis/components/VisitAnalysis.vue
  4. 2
      src/main.ts
  5. 242
      src/views/achievement/achievementOverall/index.vue
  6. 10
      src/views/achievement/achievementType/api.ts
  7. 52
      src/views/achievement/achievementType/index.vue
  8. 373
      src/views/achievement/achievementType/secondTab.vue
  9. 10
      src/views/achievement/goalDistrict/api.ts
  10. 88
      src/views/achievement/goalDistrict/index.vue
  11. 10
      src/views/achievement/goalTimes/api.ts
  12. 62
      src/views/achievement/goalTimes/index.vue
  13. 1082
      src/views/pollution/manage/index.vue
  14. 41
      src/views/pollution/manage/manage.api.ts
  15. 32
      src/views/pollution/manage/manage.data.ts
  16. 110
      src/views/pollution/manage/table.vue
  17. 275
      src/views/water/waterEnvironment/fourAxis.vue
  18. 46
      src/views/water/waterEnvironment/index.vue
  19. 101
      src/views/water/waterEnvironment/singerAxis.vue
  20. 100
      src/views/water/waterEnvironment/singerBar.vue
  21. 91
      src/views/water/waterMonitor/analysis.vue
  22. 127
      src/views/water/waterMonitor/index.vue
  23. 256
      src/views/water/waterMonitor/info.vue
  24. 342
      src/views/water/waterPollution/fourAxis.vue
  25. 45
      src/views/water/waterPollution/index.vue
  26. 350
      src/views/water/waterPollution/mutiBar.vue
  27. 266
      src/views/water/waterPollution/threeAxis.vue
  28. 167
      src/views/water/waterPollution/twoBar.vue
  29. 2
      src/views/演示使用自行删除/gitee/index.vue
  30. 2
      src/views/演示使用自行删除/visit/pages/loginLine.vue
  31. 2
      vite.config.ts

1
package.json

@ -68,6 +68,7 @@
}
},
"dependencies": {
"@amap/amap-jsapi-loader": "^1.0.1",
"@ant-design/icons-vue": "7.0.1",
"@iconify/iconify": "3.1.1",
"@logicflow/core": "1.2.26",

5
src/components/registerGlobComp.ts

@ -1,8 +1,7 @@
import type { App } from 'vue';
import { Button } from './Button';
import { Input, Layout } from 'ant-design-vue';
import Antd from 'ant-design-vue';
import VXETable from 'vxe-table';
export function registerGlobComp(app: App) {
app.use(Input).use(Button).use(Layout).use(VXETable);
app.use(Antd).use(VXETable);
}

2
src/layouts/local/dashboard/analysis/components/VisitAnalysis.vue

@ -25,7 +25,7 @@
},
xAxis: {
type: 'category',
boundaryGap: false,
boundaryGap: true,
data: [...new Array(18)].map((_item, index) => `${index + 6}:00`),
splitLine: {
show: true,

2
src/main.ts

@ -4,7 +4,6 @@ import '@/components/VxeTable/src/css/index.scss';
import 'ant-design-vue/dist/reset.css';
// Register icon sprite
import 'virtual:svg-icons-register';
import { createApp } from 'vue';
import { registerGlobComp } from '@/components/registerGlobComp';
@ -20,7 +19,6 @@ import App from './App.vue';
async function bootstrap() {
const app = createApp(App);
// Configure store
// 配置 store
setupStore(app);

242
src/views/achievement/achievementOverall/index.vue

@ -0,0 +1,242 @@
<template>
<PageWrapper dense>
<div style="margin: 20px; border-radius: 10px; background: #fff">
<div class="tabBox">
<a-tabs v-model:activeKey="activeKey" size="large">
<a-tab-pane key="1" tab="项目综合绩效评估">
<div>
<a-table :dataSource="dataSource1" :columns="columns1" :pagination="false" bordered />
</div>
<div class="mutiTable">
<a-table :dataSource="dataSource2" :columns="columns2" :pagination="false" bordered />
</div>
</a-tab-pane>
<a-tab-pane key="2" tab="分期综合绩效评估">
<div>
<a-table :dataSource="dataSource3" :columns="columns3" :pagination="false" bordered />
</div>
</a-tab-pane>
<a-tab-pane key="3" tab="分区综合绩效评估">
<div>
<a-table :dataSource="dataSource4" :columns="columns4" :pagination="false" bordered />
</div>
<div class="mutiTable">
<a-table :dataSource="dataSource5" :columns="columns5" :pagination="false" bordered />
</div>
</a-tab-pane>
</a-tabs>
</div>
</div>
</PageWrapper>
</template>
<script setup lang="ts">
import { reactive, ref } from 'vue';
import { PageWrapper } from '@/components/Page';
const activeKey = ref('1');
const dataSource1 = ref([]);
const columns1 = [
{
title: '分类项目投资效率评价分析结果',
children: [
{
dataIndex: 'dmu',
key: 'dmu',
title: 'DMU',
width: 200,
},
{
dataIndex: 'overallEfficiency',
key: 'overallEfficiency',
title: '综合技术效率',
},
{
dataIndex: 'scale',
key: 'scale',
title: '纯技术规模',
},
{
dataIndex: 'scaleEfficiency',
key: 'scaleEfficiency',
title: '规模效率',
},
{
dataIndex: 'scalePay',
key: 'scalePay',
title: '规模报酬',
},
{
dataIndex: 'beyondEfficiency',
key: 'beyondEfficiency',
title: '超效率值',
},
],
},
];
const dataSource2 = ref([]);
const columns2 = [
{
title: '分类项目优化策略',
children: [
{
dataIndex: 'dmu',
key: 'dmu',
title: 'DMU',
width: 200,
},
{
dataIndex: 'type',
key: 'type',
title: '类别',
},
{
dataIndex: 'actualScore',
key: 'actualScore',
title: '实际评分',
},
{
dataIndex: 'idealScore',
key: 'idealScore',
title: '理想评分',
},
{
dataIndex: 'difference',
key: 'difference',
title: '差值',
},
{
dataIndex: 'differencePercent',
key: 'differencePercent',
title: '百分比',
},
],
},
];
const dataSource3 = ref([]);
const columns3 = [
{
title: '各周期评价分析结果',
children: [
{
dataIndex: 'date',
key: 'date',
title: '时期',
width: 200,
},
{
dataIndex: 'overallEfficiency',
key: 'overallEfficiency',
title: '综合技术效率',
},
{
dataIndex: 'scale',
key: 'scale',
title: '纯技术规模',
},
{
dataIndex: 'scaleEfficiency',
key: 'scaleEfficiency',
title: '规模效率',
},
{
dataIndex: 'scalePay',
key: 'scalePay',
title: '规模报酬',
},
{
dataIndex: 'beyondEfficiency',
key: 'beyondEfficiency',
title: '超效率值',
},
],
},
];
const dataSource4 = ref([]);
const columns4 = [
{
title: '各控制区效率评价分析结果',
children: [
{
dataIndex: 'dmu',
key: 'dmu',
title: 'DMU',
width: 200,
},
{
dataIndex: 'overallEfficiency',
key: 'overallEfficiency',
title: '综合技术效率',
},
{
dataIndex: 'scale',
key: 'scale',
title: '纯技术规模',
},
{
dataIndex: 'scaleEfficiency',
key: 'scaleEfficiency',
title: '规模效率',
},
{
dataIndex: 'scalePay',
key: 'scalePay',
title: '规模报酬',
},
{
dataIndex: 'beyondEfficiency',
key: 'beyondEfficiency',
title: '超效率值',
},
],
},
];
const dataSource5 = ref([]);
const columns5 = [
{
title: 'XXX区优化策略',
children: [
{
dataIndex: 'dmu',
key: 'dmu',
title: 'DMU',
width: 200,
},
{
dataIndex: 'type',
key: 'type',
title: '类别',
},
{
dataIndex: 'actualScore',
key: 'actualScore',
title: '实际评分',
},
{
dataIndex: 'idealScore',
key: 'idealScore',
title: '理想评分',
},
{
dataIndex: 'difference',
key: 'difference',
title: '差值',
},
{
dataIndex: 'differencePercent',
key: 'differencePercent',
title: '百分比',
},
],
},
];
</script>
<style lang="less">
.mutiTable {
margin: 20px 0;
}
.tabBox {
margin: 20px;
}
</style>

10
src/views/achievement/achievementType/api.ts

@ -0,0 +1,10 @@
import { defHttp } from '@/utils/http/axios';
enum Api {
list = '/evr/project/getInfoList',
}
export function list(params?: any) {
return defHttp.get({ url: Api.list, params });
}

52
src/views/achievement/achievementType/index.vue

@ -0,0 +1,52 @@
<template>
<PageWrapper dense>
<div style="margin: 20px; border-radius: 10px; background: #fff">
<div class="tabBox">
<a-tabs v-model:activeKey="activeKey" size="large">
<a-tab-pane key="城镇污水处理及配套" tab="城镇污水处理及配套">
<secondTab :loading="loading" type="城镇污水处理及配套"/>
</a-tab-pane>
<a-tab-pane key="河道整治" tab="河道整治">
<secondTab :loading="loading" type="河道整治" />
</a-tab-pane>
<a-tab-pane key="农业农村面源污染治理" tab="农业农村面源污染治理">
<secondTab :loading="loading" type="农业农村面源污染治理" />
</a-tab-pane>
<a-tab-pane key="饮用水源地保护建设" tab="饮用水源地保护建设">
<secondTab :loading="loading" type="饮用水源地保护建设"/>
</a-tab-pane>
<a-tab-pane key="内源治理" tab="内源治理">
<secondTab :loading="loading" type="内源治理" />
</a-tab-pane>
<a-tab-pane key="水资源综合利用及调度" tab="水资源综合利用及调度">
<secondTab :loading="loading" type="水资源综合利用及调度"/>
</a-tab-pane>
</a-tabs>
</div>
</div>
</PageWrapper>
</template>
<script setup lang="ts">
import { ref } from 'vue';
import { PageWrapper } from '@/components/Page';
import secondTab from './secondTab.vue';
import {list} from './api'
// const tabChange = async(key) =>{
// const res = await list({projectTypeList:key})
// }
const activeKey = ref<String>('城镇污水处理及配套');
const loading = ref(false);
</script>
<style lang="less">
.tabBox {
margin: 20px;
}
.title {
margin: 10px 0;
font-size: 20px;
font-weight: 550;
}
</style>

373
src/views/achievement/achievementType/secondTab.vue

@ -0,0 +1,373 @@
<template>
<div class="tabBox">
<a-tabs v-model:activeKey="subTab">
<a-tab-pane key="a" tab="项目实施绩效">
<div>{{ msg }}</div>
<div class="md:flex enter-y">
<div class="md:w-1/2 w-full">
<Card title="污水处理能力" :loading="loading">
<div ref="chartRef1" :style="{ width, height }"></div>
</Card>
</div>
<div class="md:w-1/2 w-full">
<Card title="污染负荷变化" :loading="loading">
<div ref="chartRef2" :style="{ width, height }"></div>
</Card>
</div>
</div>
<div class="md:flex enter-y">
<div class="md:w-1/2 w-full">
<Card title="排水管网长度" :loading="loading">
<div ref="chartRef3" :style="{ width, height }"></div>
</Card>
</div>
<div class="md:w-1/2 w-full">
<Card title="垃圾处理能力" :loading="loading">
<div ref="chartRef4" :style="{ width, height }"></div>
</Card>
</div>
</div>
</a-tab-pane>
<a-tab-pane key="b" tab="技术应用绩效">
<div class="md:flex enter-y">
<div class="md:w-1/2 w-full">
<Card title="城镇污水处理技术" :loading="loading">
<div class="md:flex enter-y">
<div ref="chartRef5" :style="{ width, height }" class="md:w-1/2 w-full"></div>
<div class="md:w-1/2 w-full" style="margin-top: 5%">
<div style="font-weight: 600; font-size: 20px">技术优势明显</div>
<div
>技术优势明显技术优势明显技术优势明显技术优势明显技术优势明显技术优势明显技术优势明显技术优势明显技术优势明显技术优势明显技术优势明显技术优势明显技术优势明显技术优势明显技术优势明显技术优势明显</div
>
</div>
</div>
</Card>
</div>
<div class="md:w-1/2 w-full">
<Card title="城市面源污染控制技术" :loading="loading">
<div class="md:flex enter-y">
<div ref="chartRef6" :style="{ width, height }" class="md:w-1/2 w-full"></div>
<div class="md:w-1/2 w-full" style="margin-top: 5%">
<div style="font-weight: 600; font-size: 20px">技术改进空间较大</div>
<div
>技术优势明显技术优势明显技术优势明显技术优势明显技术优势明显技术优势明显技术优势明显技术优势明显技术优势明显技术优势明显技术优势明显技术优势明显技术优势明显技术优势明显技术优势明显技术优势明显</div
>
</div>
</div>
</Card>
</div>
</div>
<div class="mutiTable">
<a-table :dataSource="dataSource1" :columns="columns1" :pagination="false" bordered />
</div>
</a-tab-pane>
<a-tab-pane key="c" tab="项目管理绩效">
<div class="mutiTable">
<a-table :dataSource="dataSource2" :columns="columns2" :pagination="false" bordered />
</div>
<div style="padding:0 20px">
技术优势明显技术优势明显技术优势明显技术优势明技术优势明显技术优势明显技术优势明显技术优势明技术优势明显技术优势明显技术优势明显技术优势明技术优势明显技术优势明显技术优势明显技术优势明技术优势明显技术优势明显技术优势明显技术优势明技术优势明显技术优势明显技术优势明显技术优势明
</div>
</a-tab-pane>
</a-tabs>
</div>
</template>
<script setup lang="ts">
import { watch, ref, Ref, watchEffect } from 'vue';
import { useECharts } from '@/hooks/web/useECharts';
import { Card } from 'ant-design-vue';
import {list } from './api'
const subTab = ref<String>('a');
const props = defineProps({
loading: Boolean,
width: {
type: String as PropType<string>,
default: '100%',
},
height: {
type: String as PropType<string>,
default: '300px',
},
type:{
type: String as any,
default:'城镇污水处理及配套'
}
});
const getInfo = () =>{
const res = list({projectTypeList:props.type})
console.log(res)
}
getInfo()
const dataSource1 = ref([]);
const columns1 = [
{
dataIndex: 'projectDate',
key: 'projectDate',
title: '项目时期',
width: 200,
},
{
dataIndex: 'projectName',
key: 'projectName',
title: '项目名称',
},
{
dataIndex: 'projectTech',
key: 'projectTech',
title: '水环境保护治理技术',
},
{
dataIndex: 'techName',
key: 'techName',
title: '技术名称',
},
];
const dataSource2 = ref([]);
const columns2 = [
{
dataIndex: 'type',
key: 'type',
title: '项目类别',
width: 200,
},
{
dataIndex: 'feasibleApproval',
key: 'feasibleApproval',
title: '可行批复',
},
{
dataIndex: 'firstDesign',
key: 'firstDesign',
title: '前期设计',
},
{
dataIndex: 'investResource',
key: 'investResource',
title: '资金来源',
},
{
dataIndex: 'acceptApproval',
key: 'acceptApproval',
title: '验收方式',
},
{
dataIndex: 'patrol',
key: 'patrol',
title: '巡查模式',
},
{
dataIndex: 'manage',
key: 'manage',
title: '管理模式',
},
{
dataIndex: 'status',
key: 'status',
title: '运行情况',
},
];
const chartRef1 = ref<HTMLDivElement | null>(null);
const chartRef2 = ref<HTMLDivElement | null>(null);
const chartRef3 = ref<HTMLDivElement | null>(null);
const chartRef4 = ref<HTMLDivElement | null>(null);
const chartRef5 = ref<HTMLDivElement | null>(null);
const chartRef6 = ref<HTMLDivElement | null>(null);
const setOptions1 = useECharts(chartRef1 as Ref<HTMLDivElement>).setOptions;
const setOptions2 = useECharts(chartRef2 as Ref<HTMLDivElement>).setOptions;
const setOptions3 = useECharts(chartRef3 as Ref<HTMLDivElement>).setOptions;
const setOptions4 = useECharts(chartRef4 as Ref<HTMLDivElement>).setOptions;
const setOptions5 = useECharts(chartRef5 as Ref<HTMLDivElement>).setOptions;
const setOptions6 = useECharts(chartRef6 as Ref<HTMLDivElement>).setOptions;
const msg = ref('的浮点数的独立访客数量粉丝的疯狂收到了啊啊啊啊防腐剂非黑即佛金额');
watch(
() => subTab.value,
() => {
if (subTab.value == 'a') {
setOptions1({
tooltip: {},
xAxis: {
type: 'category',
data: ['"九五"', '"十五"', '"十一五"', '"十二五"', '"十三五"'],
},
yAxis: {
type: 'value',
name: '处理能力:万(m³/d)', //
nameLocation: 'end', // start/center/end
nameTextStyle: {
color: '#666',
fontSize: 12,
align: 'left', //
padding: [0, 0, 0, -30], // [,,,]
},
},
series: [
{
data: [120, 200, 150, 80, 99],
stack: 'total',
type: 'bar',
itemStyle: {},
},
],
});
setOptions2({
tooltip: {
trigger: 'axis',
},
grid: {
left: '3%',
right: '4%',
bottom: '3%',
containLabel: true,
},
legend: {
data: ['cod', 'tn×10', 'tp×100'],
},
xAxis: {
type: 'category',
boundaryGap: false,
data: ['"九五"', '"十五"', '"十一五"', '"十二五"', '"十三五"'],
},
yAxis: {
type: 'value',
name: '生产量(吨)', //
nameLocation: 'end', // start/center/end
nameTextStyle: {
color: '#666',
fontSize: 12,
align: 'left', //
padding: [0, 0, 0, -30], // [,,,]
},
},
series: [
{
name: 'cod',
data: [90, 200, 150, 80, 70],
type: 'line',
itemStyle: {},
},
{
name: 'tn×10',
data: [78, 123, 29, 45, 99],
type: 'line',
itemStyle: {},
},
{
name: 'tp×100',
data: [134, 131, 39, 67, 156],
type: 'line',
itemStyle: {},
},
],
});
setOptions3({
tooltip: {},
xAxis: {
type: 'category',
data: ['"九五"', '"十五"', '"十一五"', '"十二五"', '"十三五"'],
},
yAxis: {
type: 'value',
name: '市政排水管网总长度(m)', //
nameLocation: 'end', // start/center/end
nameTextStyle: {
color: '#666',
fontSize: 12,
align: 'left', //
padding: [0, 0, 0, -30], // [,,,]
},
},
series: [
{
data: [120, 200, 150, 80, 70],
type: 'bar',
itemStyle: {},
},
],
});
setOptions4({
tooltip: {},
xAxis: {
type: 'category',
data: ['"九五"', '"十五"', '"十一五"', '"十二五"', '"十三五"'],
},
yAxis: {
type: 'value',
name: '新增城镇生活垃圾处理量(t/d)', //
nameLocation: 'end', // start/center/end
nameTextStyle: {
color: '#666',
fontSize: 12,
align: 'left', //
padding: [0, 0, 0, -30], // [,,,]
},
},
series: [
{
data: [120, 200, 150, 80, 70],
type: 'bar',
itemStyle: {},
},
],
});
} else if (subTab.value == 'b') {
setOptions5({
tooltip: {
trigger: 'item',
},
legend: {
top: '10%',
left: 'center',
},
series: [
{
name: '城镇污水处理技术',
type: 'pie',
radius: '50%',
data: [
{ value: 1048, name: '好' },
{ value: 735, name: '较好' },
{ value: 580, name: '中等' },
{ value: 484, name: '较差' },
{ value: 300, name: '差' },
],
},
],
});
setOptions6({
tooltip: {
trigger: 'item',
},
legend: {
top: '10%',
left: 'center',
},
series: [
{
name: '城市面源污染控制技术',
type: 'pie',
radius: '50%',
data: [
{ value: 1048, name: '好' },
{ value: 735, name: '较好' },
{ value: 580, name: '中等' },
{ value: 484, name: '较差' },
{ value: 300, name: '差' },
],
},
],
});
}
},
{ immediate: true },
);
</script>
<style lang="less">
.tabBox {
margin: 20px;
}
.mutiTable {
margin: 20px 0;
}
</style>

10
src/views/achievement/goalDistrict/api.ts

@ -0,0 +1,10 @@
import { defHttp } from '@/utils/http/axios';
enum Api {
list = '/evr/area/getList',
}
export function list(params?: any) {
return defHttp.get({ url: Api.list, params });
}

88
src/views/achievement/goalDistrict/index.vue

@ -0,0 +1,88 @@
<template>
<PageWrapper dense>
<div style="margin: 1%; padding: 1%; border-radius: 10px; background: #fff">
<span>控制区</span>
<a-input v-model:value="district" style="width:180px"></a-input>
<a-button type="primary" @click="search" style="margin-left: 20px;">查询</a-button>
<div v-for="(i, index) in goalDistrictInfo" style="margin: 20px 0" :key="index">
<div style="margin: 10px">{{ i.description }}</div>
<div>
<a-table :dataSource="i.areaInfo" :columns="columns" :pagination="false" bordered />
</div>
</div>
</div>
</PageWrapper>
</template>
<script setup lang="ts">
import { ref } from 'vue';
import { PageWrapper } from '@/components/Page';
import {list} from './api'
//
const district = ref('');
const districtOptions = ref([
]);
const search = async() =>{
const res = await list({district:district.value})
goalDistrictInfo.value = res
console.log(res)
}
const goalDistrictInfo = ref([
])
const columns = [
{
dataIndex: 'district',
key: 'district',
title: '控制区',
customCell: (_, index) => {
if (index === 0) {
return { rowSpan: 3 };
} else {
return { rowSpan: 0 };
}
},
},
{
dataIndex: 'river',
key: 'river',
title: '水体',
},
{
dataIndex: 'controlSection',
key: 'controlSection',
title: '控制断面',
},
{
dataIndex: 'goal',
key: 'goal',
title: '目标',
},
{
dataIndex: 'thirdFive',
key: 'thirdFive',
title: '十一五',
},
{
dataIndex: 'fourthFive',
key: 'fourthFive',
title: '十二五',
},
{
dataIndex: 'fifthFive',
key: 'fifthFive',
title: '十三五',
},
];
</script>
<style lang="less">
.tabBox {
margin: 20px;
}
.title {
margin: 10px 0;
font-size: 20px;
font-weight: 550;
}
</style>

10
src/views/achievement/goalTimes/api.ts

@ -0,0 +1,10 @@
import { defHttp } from '@/utils/http/axios';
enum Api {
list = '/evr/project/getInvestmentStats',
}
export function list(params?: any) {
return defHttp.get({ url: Api.list, params });
}

62
src/views/achievement/goalTimes/index.vue

@ -0,0 +1,62 @@
<template>
<PageWrapper dense>
<div style="margin: 1%; padding: 1%; border-radius: 10px; background: #fff">
<div v-for="(i, index) in description" style="margin: 20px 0 20px 20px" :key="index">{{
i
}}</div>
<div>
<a-table :dataSource="projectInfo" :columns="columns" :pagination="false" />
</div>
</div>
</PageWrapper>
</template>
<script setup lang="ts">
import { ref } from 'vue';
import { PageWrapper } from '@/components/Page';
import {list} from './api'
const description = ref([])
const columns = [
{
dataIndex: 'date',
key: 'date',
title: '时期',
},
{
dataIndex: 'planInvest',
key: 'planInvest',
title: '规划投资(亿元)',
},
{
dataIndex: 'actualInvest',
key: 'actualInvest',
title: '实际完成投资(亿元)',
},
{
dataIndex: 'investPercent',
key: 'investPercent',
title: '完成投资率%',
},
];
const projectInfo = ref([
]);
const getInfo = async() =>{
const res = await list()
description.value = res.description
projectInfo.value = res.projectInfo
console.log(res)
}
getInfo()
</script>
<style lang="less">
.tabBox {
margin: 20px;
}
.title {
margin: 10px 0;
font-size: 20px;
font-weight: 550;
}
</style>

1082
src/views/pollution/manage/index.vue

File diff suppressed because it is too large

41
src/views/pollution/manage/manage.api.ts

@ -0,0 +1,41 @@
import {commonExport } from '@/api/base';
import { defHttp } from '@/utils/http/axios';
enum Api {
root = '/evr/project',
list = '/evr/project/list',
export = '/evr/project/export',
listUpload = '/evr/excel/uploadProjectInfo',
}
export function list(params?: any) {
return defHttp.get({ url: Api.list, params });
}
export function exportExcel(data: any) {
return commonExport(Api.export, data);
}
export function getInfo(id: any) {
return defHttp.get({ url: `${Api.root}/${id}` });
}
export function add(data: any) {
return defHttp.post({ url: Api.root, data });
}
export function update(data: any) {
return defHttp.put({ url: Api.root, data });
}
export function removeByIds(ids: any) {
return defHttp.deleteWithMsg<void>({ url: `${Api.root}/${ids.join(',')}` });
}
export function listUpload(params: any) {
return defHttp.post({
url: Api.listUpload,
headers: { 'Content-Type': 'multipart/form-data' },
params,
});
}

32
src/views/pollution/manage/manage.data.ts

@ -0,0 +1,32 @@
import { BasicColumn } from '@/components/Table';
import { FormSchema } from '@/components/Form';
export const formSchemas: FormSchema[] = [
{
label: '项目名称',
field: 'projectName',
component: 'Input',
componentProps: {
placeholder: '输入项目名称',
},
},
];
export const columns: BasicColumn[] = [
{
title: '项目时期',
dataIndex: 'projectDate',
},
{
title: '项目名称',
dataIndex: 'projectName',
},
{
title: '规划投资(万元)',
dataIndex: 'planInvest',
},
{
title: '实际投资(万元)',
dataIndex: 'acualInvest',
},
];

110
src/views/pollution/manage/table.vue

@ -0,0 +1,110 @@
<template>
<PageWrapper dense>
<BasicTable @register="registerTable">
<template #toolbar>
<a-button type="primary" @click="handleAdd">新增</a-button>
<a-upload
name="file"
:before-upload="beforeUpload"
@change="importChange"
:showUploadList="false"
>
<a-button type="primary"> 导入 </a-button>
</a-upload>
</template>
<template #bodyCell="{ column, record }">
<template v-if="column && record && column.key === 'action'">
<!-- 完成/撤销不显示 -->
<TableAction
stopButtonPropagation
:actions="[
{
label: '修改',
icon: IconEnum.EDIT,
onClick: handleEdit.bind(null, record),
},
{
label: '删除',
icon: IconEnum.DELETE,
danger: true,
popConfirm: {
placement: 'left',
title: `是否删除[${record.id}]?`,
confirm: handleDelete.bind(null, record),
},
},
]"
/>
</template>
</template>
</BasicTable>
</PageWrapper>
</template>
<script setup lang="ts">
import { PageWrapper } from '@/components/Page';
import { BasicTable, useTable, TableAction } from '@/components/Table';
import { list, removeByIds, listUpload } from './manage.api.ts';
import { formSchemas, columns } from './manage.data';
import { IconEnum } from '@/enums/appEnum';
import { useGo } from '@/hooks/web/usePage';
import { PageEnum } from '@/enums/pageEnum';
defineOptions({ name: 'Manage' });
const [registerTable, { reload }] = useTable({
title: '项目管理',
api: list,
showIndexColumn: false,
rowKey: 'id',
useSearchForm: true,
formConfig: {
schemas: formSchemas,
name: 'manage',
baseColProps: {
xs: 24,
sm: 24,
md: 24,
lg: 6,
},
},
columns: columns,
actionColumn: {
width: 200,
title: '操作',
key: 'action',
fixed: 'right',
},
});
function handleEdit(record: any) {
go({ path: '/pollution/manage' as PageEnum, query: { id: record.id, type: 'update' } });
}
function handleAdd() {
go({ path: '/pollution/manage' as PageEnum, query: { type: 'add' } });
}
function handleImport() {
go({ path: '/pollution/manage' as PageEnum, query: { type: 'add' } });
}
async function handleDelete(record: any) {
await removeByIds([record.id]);
await reload();
}
//
const beforeUpload = async (file: any) => {
console.log(file);
const params = {
file: file,
};
await listUpload(params);
return false;
};
const importChange = () => {
reload();
};
//
const go = useGo();
</script>
<style scoped></style>

275
src/views/water/waterEnvironment/fourAxis.vue

@ -0,0 +1,275 @@
<template>
<div class="tabBox">
<div class="md:flex enter-y">
<div class="md:w-1/2 w-full">
<Card :title="title[0]" :loading="loading">
<div ref="chartRef1" :style="{ width, height }"></div>
</Card>
</div>
<div class="md:w-1/2 w-full">
<Card :title="title[1]" :loading="loading">
<div ref="chartRef2" :style="{ width, height }"></div>
</Card>
</div>
</div>
<div class="md:flex enter-y">
<div class="md:w-1/2 w-full">
<Card :title="title[2]" :loading="loading">
<div ref="chartRef3" :style="{ width, height }"></div>
</Card>
</div>
<div class="md:w-1/2 w-full">
<Card :title="title[3]" :loading="loading">
<div ref="chartRef4" :style="{ width, height }"></div>
</Card>
</div>
</div>
</div>
</template>
<script setup lang="ts">
import { watch, ref, Ref, watchEffect } from 'vue';
import { useECharts } from '@/hooks/web/useECharts';
import { Card } from 'ant-design-vue';
const subTab = ref<String>('a');
const props = defineProps({
loading: Boolean,
width: {
type: String as PropType<string>,
default: '100%',
},
height: {
type: String as PropType<string>,
default: '300px',
},
title:{
type: String as PropType<any>,
default: '300px',
}
});
const chartRef1 = ref<HTMLDivElement | null>(null);
const chartRef2 = ref<HTMLDivElement | null>(null);
const chartRef3 = ref<HTMLDivElement | null>(null);
const chartRef4 = ref<HTMLDivElement | null>(null);
const setOptions1 = useECharts(chartRef1 as Ref<HTMLDivElement>).setOptions;
const setOptions2 = useECharts(chartRef2 as Ref<HTMLDivElement>).setOptions;
const setOptions3 = useECharts(chartRef3 as Ref<HTMLDivElement>).setOptions;
const setOptions4 = useECharts(chartRef4 as Ref<HTMLDivElement>).setOptions;
watch(
() => subTab.value,
() => {
setOptions1({
tooltip: {
trigger: 'axis',
},
grid: {
left: '3%',
right: '4%',
bottom: '3%',
containLabel: true,
},
legend: {
data: ['cod', 'tn×10', 'tp×100'],
},
xAxis: {
type: 'category',
boundaryGap: true,
data: ['"1995"', '"1996"', '"1997"', '"1998"', '"1999"','"2000"', '"2001"', '"2002"', '"2003"', '"2004"'],
},
yAxis: {
type: 'value',
name: 'COD(mg/l)', //
nameLocation: 'end', // start/center/end
nameTextStyle: {
color: '#666',
fontSize: 12,
align: 'left', //
padding: [0, 0, 0, -30], // [,,,]
},
},
series: [
{
name: 'cod',
data: [90, 200, 150, 80, 70,78, 123, 29, 45, 99],
type: 'line',
itemStyle: {},
},
{
name: 'tn×10',
data: [78, 123, 29, 45, 99,134, 131, 39, 67, 156],
type: 'line',
itemStyle: {},
},
{
name: 'tp×100',
data: [100, 100, 100, 100, 100,100, 100, 100, 100, 100],
type: 'line',
itemStyle: {},
},
],
});
setOptions2({
tooltip: {
trigger: 'axis',
},
grid: {
left: '3%',
right: '4%',
bottom: '3%',
containLabel: true,
},
legend: {
data: ['cod', 'tn×10', 'tp×100'],
},
xAxis: {
type: 'category',
boundaryGap: true,
data: ['"1995"', '"1996"', '"1997"', '"1998"', '"1999"','"2000"', '"2001"', '"2002"', '"2003"', '"2004"'],
},
yAxis: {
type: 'value',
name: 'TP(mg/l)', //
nameLocation: 'end', // start/center/end
nameTextStyle: {
color: '#666',
fontSize: 12,
align: 'left', //
padding: [0, 0, 0, -30], // [,,,]
},
},
series: [
{
name: 'cod',
data: [90, 200, 150, 80, 70,78, 123, 29, 45, 99],
type: 'line',
itemStyle: {},
},
{
name: 'tn×10',
data: [78, 123, 29, 45, 99,134, 131, 39, 67, 156],
type: 'line',
itemStyle: {},
},
{
name: 'tp×100',
data: [100, 100, 100, 100, 100,100, 100, 100, 100, 100],
type: 'line',
itemStyle: {},
},
],
});
setOptions3({
tooltip: {
trigger: 'axis',
},
grid: {
left: '3%',
right: '4%',
bottom: '3%',
containLabel: true,
},
legend: {
data: ['cod', 'tn×10', 'tp×100'],
},
xAxis: {
type: 'category',
boundaryGap: true,
data: ['"1995"', '"1996"', '"1997"', '"1998"', '"1999"','"2000"', '"2001"', '"2002"', '"2003"', '"2004"'],
},
yAxis: {
type: 'value',
name: 'TN(mg/l)', //
nameLocation: 'end', // start/center/end
nameTextStyle: {
color: '#666',
fontSize: 12,
align: 'left', //
padding: [0, 0, 0, -30], // [,,,]
},
},
series: [
{
name: 'cod',
data: [90, 200, 150, 80, 70,78, 123, 29, 45, 99],
type: 'line',
itemStyle: {},
},
{
name: 'tn×10',
data: [78, 123, 29, 45, 99,134, 131, 39, 67, 156],
type: 'line',
itemStyle: {},
},
{
name: 'tp×100',
data: [100, 100, 100, 100, 100,100, 100, 100, 100, 100],
type: 'line',
itemStyle: {},
},
],
});
setOptions4({
tooltip: {
trigger: 'axis',
},
grid: {
left: '3%',
right: '4%',
bottom: '3%',
containLabel: true,
},
legend: {
data: ['cod', 'tn×10', 'tp×100'],
},
xAxis: {
type: 'category',
boundaryGap: true,
data: ['"1995"', '"1996"', '"1997"', '"1998"', '"1999"','"2000"', '"2001"', '"2002"', '"2003"', '"2004"'],
},
yAxis: {
type: 'value',
name: 'cod(mg/l)', //
nameLocation: 'end', // start/center/end
nameTextStyle: {
color: '#666',
fontSize: 12,
align: 'left', //
padding: [0, 0, 0, -30], // [,,,]
},
},
series: [
{
name: 'cod',
data: [90, 200, 150, 80, 70,78, 123, 29, 45, 99],
type: 'line',
itemStyle: {},
},
{
name: 'tn×10',
data: [78, 123, 29, 45, 99,134, 131, 39, 67, 156],
type: 'line',
itemStyle: {},
},
{
name: 'tp×100',
data: [100, 100, 100, 100, 100,100, 100, 100, 100, 100],
type: 'line',
itemStyle: {},
},
],
});
},
{ immediate: true },
);
</script>
<style lang="less">
.tabBox {
margin: 20px;
}
.mutiTable {
margin: 20px 0;
}
</style>

46
src/views/water/waterEnvironment/index.vue

@ -0,0 +1,46 @@
<template>
<PageWrapper dense>
<div style="margin: 20px; border-radius: 10px; background: #fff">
<div class="tabBox">
<a-tabs v-model:activeKey="activeKey" size="large">
<a-tab-pane key="1" tab="水质变化">
<fourAxis :loading="loading" :title="secondTabTitle1"/>
</a-tab-pane>
<a-tab-pane key="2" tab="富营养状况变化">
<singerAxis :loading="loading" />
</a-tab-pane>
<a-tab-pane key="3" tab="蓝藻水华变化">
<fourAxis :loading="loading":title="secondTabTitle3" />
</a-tab-pane>
<a-tab-pane key="4" tab="河流水质变化" >
<singerBar :loading="loading" />
</a-tab-pane>
</a-tabs>
</div>
</div>
</PageWrapper>
</template>
<script setup lang="ts">
import { ref } from 'vue';
import { PageWrapper } from '@/components/Page';
import fourAxis from './fourAxis.vue';
import singerAxis from './singerAxis.vue';
import singerBar from './singerBar.vue';
const activeKey = ref<String>('1');
const loading = ref(false);
const secondTabTitle1 = ['COD','TP','TN','其他']
const secondTabTitle3 = ['水体叶绿素a浓度年均变化','蓝藻富集重点水域水体叶绿素a浓度年均变化','多年蓝藻水华各月发生状况','其他']
</script>
<style lang="less">
.tabBox {
margin: 20px;
}
.title {
margin: 10px 0;
font-size: 20px;
font-weight: 550;
}
</style>

101
src/views/water/waterEnvironment/singerAxis.vue

@ -0,0 +1,101 @@
<template>
<div class="tabBox">
<Card title="富营养化指数" :loading="loading">
<div ref="chartRef1" :style="{ width, height }"></div>
</Card>
</div>
</template>
<script setup lang="ts">
import { watch, ref, Ref, watchEffect } from 'vue';
import { useECharts } from '@/hooks/web/useECharts';
import { Card } from 'ant-design-vue';
const subTab = ref<String>('a');
const props = defineProps({
loading: Boolean,
width: {
type: String as PropType<string>,
default: '100%',
},
height: {
type: String as PropType<string>,
default: '300px',
},
});
const chartRef1 = ref<HTMLDivElement | null>(null);
const setOptions1 = useECharts(chartRef1 as Ref<HTMLDivElement>).setOptions;
watch(
() => subTab.value,
() => {
setOptions1({
tooltip: {
trigger: 'axis',
},
grid: {
left: '3%',
right: '4%',
bottom: '3%',
containLabel: true,
},
legend: {
data: ['cod', 'tn×10', 'tp×100'],
},
xAxis: {
type: 'category',
boundaryGap: true,
data: [
'"1995"',
'"1996"',
'"1997"',
'"1998"',
'"1999"',
'"2000"',
'"2001"',
'"2002"',
'"2003"',
'"2004"',
],
},
yAxis: {
type: 'value',
name: '富营养化指数', //
nameLocation: 'end', // start/center/end
nameTextStyle: {
color: '#666',
fontSize: 12,
align: 'left', //
padding: [0, 0, 0, -30], // [,,,]
},
},
series: [
{
name: 'cod',
data: [90, 200, 150, 80, 70, 78, 123, 29, 45, 99],
type: 'line',
itemStyle: {},
},
{
name: 'tn×10',
data: [78, 123, 29, 45, 99, 134, 131, 39, 67, 156],
type: 'line',
itemStyle: {},
},
{
name: 'tp×100',
data: [100, 100, 100, 100, 100, 100, 100, 100, 100, 100],
type: 'line',
itemStyle: {},
},
],
});
},
{ immediate: true },
);
</script>
<style lang="less">
.tabBox {
margin: 20px;
}
</style>

100
src/views/water/waterEnvironment/singerBar.vue

@ -0,0 +1,100 @@
<template>
<div class="tabBox">
<Card title="富营养化指数" :loading="loading">
<div ref="chartRef1" :style="{ width, height }"></div>
</Card>
</div>
</template>
<script setup lang="ts">
import { watch, ref, Ref, watchEffect } from 'vue';
import { useECharts } from '@/hooks/web/useECharts';
import { Card } from 'ant-design-vue';
const subTab = ref<String>('a');
const props = defineProps({
loading: Boolean,
width: {
type: String as PropType<string>,
default: '100%',
},
height: {
type: String as PropType<string>,
default: '300px',
},
});
const chartRef1 = ref<HTMLDivElement | null>(null);
const setOptions1 = useECharts(chartRef1 as Ref<HTMLDivElement>).setOptions;
watch(
() => subTab.value,
() => {
setOptions1({
tooltip: {
},
grid: {
left: '3%',
right: '4%',
bottom: '3%',
containLabel: true,
},
legend: {
data: ['cod', 'tn×10', 'tp×100'],
},
xAxis: {
type: 'category',
boundaryGap: true,
data: [
'"1995"',
'"1996"',
'"1997"',
'"1998"',
'"1999"',
'"2000"',
'"2001"',
'"2002"',
'"2003"',
'"2004"',
],
},
yAxis: {
type: 'value',
name: '富营养化指数', //
nameLocation: 'end', // start/center/end
nameTextStyle: {
color: '#666',
fontSize: 12,
align: 'left', //
padding: [0, 0, 0, -30], // [,,,]
},
},
series: [
{
name: 'cod',
data: [90, 200, 150, 80, 70, 78, 123, 29, 45, 99],
type: 'bar',
itemStyle: {},
},
{
name: 'tn×10',
data: [78, 123, 29, 45, 99, 134, 131, 39, 67, 156],
type: 'bar',
itemStyle: {},
},
{
name: 'tp×100',
data: [100, 100, 100, 100, 100, 100, 100, 100, 100, 100],
type: 'bar',
itemStyle: {},
},
],
});
},
{ immediate: true },
);
</script>
<style lang="less">
.tabBox {
margin: 20px;
}
</style>

91
src/views/water/waterMonitor/analysis.vue

@ -0,0 +1,91 @@
<template>
<div class="tabBox">
<Card title="氨氮曲线图" :loading="loading">
<div ref="chartRef1" :style="{ width, height }"></div>
</Card>
</div>
</template>
<script setup lang="ts">
import { watch, ref, Ref, watchEffect } from 'vue';
import { useECharts } from '@/hooks/web/useECharts';
import { Card } from 'ant-design-vue';
const subTab = ref<String>('a');
const props = defineProps({
loading: Boolean,
width: {
type: String as PropType<string>,
default: '100%',
},
height: {
type: String as PropType<string>,
default: '300px',
},
});
const chartRef1 = ref<HTMLDivElement | null>(null);
const setOptions1 = useECharts(chartRef1 as Ref<HTMLDivElement>).setOptions;
watch(
() => subTab.value,
() => {
setOptions1({
tooltip: {
trigger: 'axis',
},
grid: {
left: '3%',
right: '4%',
bottom: '3%',
containLabel: true,
},
legend: {
data: ['cod', 'tn×10', 'tp×100'],
},
xAxis: {
type: 'category',
boundaryGap: true,
data: [
'2025-5-12',
'2025-5-13',
'2025-5-14',
'2025-5-15',
'2025-5-16',
'2025-5-17',
'2025-5-18',
'2025-5-19',
'2025-5-20',
'2025-5-12',
'2025-5-21',
'2025-5-22',
],
},
yAxis: {
type: 'value',
name: '氨氮曲线图', //
nameLocation: 'end', // start/center/end
nameTextStyle: {
color: '#666',
fontSize: 12,
align: 'left', //
padding: [0, 0, 0, -30], // [,,,]
},
},
series: [
{
name: '氨氮',
data: [90, 200, 150, 80, 70, 78, 123, 29, 45, 99],
type: 'line',
itemStyle: {},
},
],
});
},
{ immediate: true },
);
</script>
<style lang="less">
.tabBox {
margin: 20px;
}
</style>

127
src/views/water/waterMonitor/index.vue

@ -0,0 +1,127 @@
<template>
<PageWrapper dense>
<div style="margin: 20px; border-radius: 10px; background: #fff">
<div class="tabBox">
<a-tabs v-model:activeKey="activeKey" size="large">
<a-tab-pane key="总览" tab="总览">
<div style="margin: 1%; padding: 1%; border-radius: 10px; background: #fff">
<span>监测因子</span>
<a-select
v-model:value="searchInfo.monitorType"
style="width: 180px"
:options="monitorTypeOptions"
placeholder="请选择"
allowClear
/>
<span style="margin-left: 20px">时间</span>
<a-select
v-model:value="searchInfo.timeType"
style="width: 180px"
:options="timeTypeOptions"
placeholder="请选择"
allowClear
/>
<a-button type="primary" @click="search" style="margin-left: 20px">查询</a-button>
<div id="amapContainer" style="height: 80vh; margin-top: 10px"> </div>
</div>
</a-tab-pane>
<a-tab-pane key="实时数据" tab="实时数据">
<info></info>
</a-tab-pane>
<a-tab-pane key="曲线分析" tab="曲线分析">
<analysis></analysis>
</a-tab-pane>
</a-tabs>
</div>
</div>
</PageWrapper>
</template>
<script setup lang="ts">
import { ref, reactive, onMounted } from 'vue';
import { PageWrapper } from '@/components/Page';
import AMapLoader from '@amap/amap-jsapi-loader';
import info from './info.vue'
import analysis from './analysis.vue';
const activeKey = ref('总览');
const searchInfo = reactive({
monitorType: null,
timeType: null,
});
const monitorTypeOptions = [
{
value: 'PH',
},
{
value: 'DO',
},
{
value: 'COD',
},
{
value: 'TP',
},
{
value: 'NH3-N',
},
];
const timeTypeOptions = [
{
value: '实时数据',
},
{
value: '日均值',
},
{
value: '月均值',
},
];
const search = async () => {};
const points = ref<any>([
{
longitude: 119.21,
latitude: 29.7,
},
]);
onMounted(() => {
AMapLoader.load({
key: '786a2e7cc6d4be5ba1d6174a0aa10f2b',
version: '2.0',
plugins: [], //
})
.then((AMap) => {
const map = new AMap.Map('amapContainer', {
zoom: 10, //
center: [119.0426, 29.6], //
});
//
points.value.forEach((point) => {
const marker = new AMap.Marker({
position: new AMap.LngLat(point.longitude, point.latitude),
title: point.station,
});
marker.on('click', () => {
console.log('1');
});
map.add(marker);
});
})
.catch((e) => {
console.error(e); //
});
});
</script>
<style lang="less">
.tabBox {
margin: 10px;
}
.title {
margin: 10px 0;
font-size: 20px;
font-weight: 550;
}
</style>

256
src/views/water/waterMonitor/info.vue

@ -0,0 +1,256 @@
<template>
<div class="tabBox">
<div class="md:flex enter-y">
<div class="md:w-1/3 w-full">
<Card title="污染源统计" :loading="loading">
<div ref="chartRef1" :style="{ width, height }"></div>
</Card>
</div>
<div class="md:w-1/3 w-full">
<Card title="水源统计" :loading="loading">
<div class="md:flex enter-y">
<div class="md:w-1/2 w-full" ref="chartRef2" :style="{ width, height }"> </div>
<div class="md:w-1/2 w-full">
<div>
<span style="font-weight: 600">全区水质前三</span>
<div v-for="(item, index) in topThree" :key="index">
{{ index }}- {{ item.name }}{{ item.percent }}
</div>
</div>
<div style="top: 50%; position: absolute">
<span style="font-weight: 600">全区水质后三</span>
<div v-for="(item, index) in lastThree" :key="index">
{{ index }}- {{ item.name }}{{ item.percent }}
</div>
</div>
</div>
</div>
</Card>
</div>
<div class="md:w-1/3 w-full">
<Card title="河道统计" :loading="loading">
<div ref="chartRef3" :style="{ width, height }"></div>
</Card>
</div>
</div>
<div>
<Card :loading="loading">
<div>
<a-table :dataSource="dataSource" :columns="columns" :pagination="false" bordered />
</div>
</Card>
</div>
</div>
</template>
<script setup lang="ts">
import { watch, ref, Ref, watchEffect } from 'vue';
import { useECharts } from '@/hooks/web/useECharts';
import { Card } from 'ant-design-vue';
const subTab = ref<String>('a');
const props = defineProps({
loading: Boolean,
width: {
type: String as PropType<string>,
default: '100%',
},
height: {
type: String as PropType<string>,
default: '300px',
},
});
const topThree = [
{
name: 'xx',
percent: '100%',
},
{
name: 'xx',
percent: '98%',
},
{
name: 'xx',
percent: '95%',
},
];
const lastThree = [
{
name: 'xx',
percent: '60%',
},
{
name: 'xx',
percent: '55%',
},
{
name: 'xx',
percent: '39%',
},
];
const chartRef1 = ref<HTMLDivElement | null>(null);
const setOptions1 = useECharts(chartRef1 as Ref<HTMLDivElement>).setOptions;
const chartRef2 = ref<HTMLDivElement | null>(null);
const setOptions2 = useECharts(chartRef2 as Ref<HTMLDivElement>).setOptions;
const chartRef3 = ref<HTMLDivElement | null>(null);
const setOptions3 = useECharts(chartRef3 as Ref<HTMLDivElement>).setOptions;
const dataSource = ref([])
const columns = [
{
dataIndex: 'index',
key: 'index',
title: '序号',
customCell: (_, index:any) => {
return index
},
},
{
dataIndex: 'monitorTime',
key: 'monitorTime',
title: '监测时间',
},
{
dataIndex: 'ph',
key: 'ph',
title: 'PH值(6-9)',
},
{
dataIndex: 'oxygenDemand',
key: 'oxygenDemand',
title: '化学需氧量(250mg/L)',
},
{
dataIndex: 'ammoniaOxygen',
key: 'ammoniaOxygen',
title: '氨氧(mg/L)',
},
{
dataIndex: 'flowRate',
key: 'flowRate',
title: '废水瞬时流量(升/秒)',
},
{
dataIndex: 'restChlorine',
key: 'restChlorine',
title: '总余氯(8mg/L)',
},
];
watch(
() => subTab.value,
() => {
setOptions1({
tooltip: {
trigger: 'item',
formatter: '{a} <br/>{b}: {c} ({d}%)', // {d}%
},
legend: {
top: '5%',
left: 'center',
},
series: [
{
name: '污染源统计',
type: 'pie',
radius: ['40%', '70%'],
avoidLabelOverlap: false,
label: {
show: false,
position: 'center',
},
labelLine: {
show: false,
},
data: [
{ value: 1048, name: '污水处理厂' },
{ value: 735, name: '工业污染源' },
{ value: 580, name: '畜禽养殖场' },
],
},
],
});
setOptions2({
tooltip: {
trigger: 'item',
formatter: '{a} <br/>{b}:({d}%)', // {d}%
},
legend: {
top: '5%',
left: 'center',
},
series: [
{
name: '全区水质达标率',
type: 'pie',
radius: ['40%', '70%'],
avoidLabelOverlap: false,
label: {
show: false,
position: 'center',
},
labelLine: {
show: false,
},
data: [
{ value: 800, name: '达标数' },
{ value: 200, name: '未达标' },
],
},
],
graphic: {
elements: [
{
type: 'text',
left: 'center', //
bottom: '5%', //
style: {
text: '良好',
fontSize: 20,
fontWeight: 'bold',
fill: '#00a854',
align: 'center',
},
},
],
},
});
setOptions3({
tooltip: {
trigger: 'item',
formatter: '{a} <br/>{b}: {c} ({d}%)', // {d}%
},
legend: {
top: '5%',
left: 'center',
},
series: [
{
name: '河道统计',
type: 'pie',
radius: ['40%', '70%'],
avoidLabelOverlap: false,
label: {
show: false,
position: 'center',
},
labelLine: {
show: false,
},
data: [
{ value: 42, name: '河长' },
{ value: 20, name: '工作人员' },
{ value: 10, name: '公示牌' },
{ value: 3, name: '排污口数量' },
],
},
],
});
},
{ immediate: true },
);
</script>
<style lang="less">
.tabBox {
margin: 20px;
}
</style>

342
src/views/water/waterPollution/fourAxis.vue

@ -0,0 +1,342 @@
<template>
<div class="tabBox">
<div class="md:flex enter-y">
<div class="md:w-1/2 w-full">
<Card :title="title[0]" :loading="loading">
<div ref="chartRef1" :style="{ width, height }"></div>
</Card>
</div>
<div class="md:w-1/2 w-full">
<Card :title="title[1]" :loading="loading">
<div ref="chartRef2" :style="{ width, height }"></div>
</Card>
</div>
</div>
<div class="md:flex enter-y">
<div class="md:w-1/2 w-full">
<Card :title="title[2]" :loading="loading">
<div ref="chartRef3" :style="{ width, height }"></div>
</Card>
</div>
<div class="md:w-1/2 w-full">
<Card :title="title[3]" :loading="loading">
<div ref="chartRef4" :style="{ width, height }"></div>
</Card>
</div>
</div>
</div>
</template>
<script setup lang="ts">
import { watch, ref, Ref, watchEffect } from 'vue';
import { useECharts } from '@/hooks/web/useECharts';
import { Card } from 'ant-design-vue';
const subTab = ref<String>('a');
const props = defineProps({
loading: Boolean,
width: {
type: String as PropType<string>,
default: '100%',
},
height: {
type: String as PropType<string>,
default: '300px',
},
title: {
type: String as PropType<any>,
default: '300px',
},
});
const chartRef1 = ref<HTMLDivElement | null>(null);
const chartRef2 = ref<HTMLDivElement | null>(null);
const chartRef3 = ref<HTMLDivElement | null>(null);
const chartRef4 = ref<HTMLDivElement | null>(null);
const setOptions1 = useECharts(chartRef1 as Ref<HTMLDivElement>).setOptions;
const setOptions2 = useECharts(chartRef2 as Ref<HTMLDivElement>).setOptions;
const setOptions3 = useECharts(chartRef3 as Ref<HTMLDivElement>).setOptions;
const setOptions4 = useECharts(chartRef4 as Ref<HTMLDivElement>).setOptions;
watch(
() => subTab.value,
() => {
setOptions1({
tooltip: {
trigger: 'axis',
},
grid: {
left: '3%',
right: '4%',
bottom: '3%',
containLabel: true,
},
legend: {
data: ['COD/10', 'NH3-N', 'TN', 'TP'],
},
xAxis: {
type: 'category',
boundaryGap: true,
data: [
'"1995"',
'"1996"',
'"1997"',
'"1998"',
'"1999"',
'"2000"',
'"2001"',
'"2002"',
'"2003"',
'"2004"',
],
},
yAxis: {
type: 'value',
name: '排放量/吨', //
nameLocation: 'end', // start/center/end
nameTextStyle: {
color: '#666',
fontSize: 12,
align: 'left', //
padding: [0, 0, 0, -30], // [,,,]
},
},
series: [
{
name: 'COD/10',
data: [90, 200, 150, 80, 70, 78, 123, 29, 45, 99],
type: 'line',
itemStyle: {},
},
{
name: 'NH3-N',
data: [132, 23, 42, 88, 66, 77, 99, 111, 122, 133],
type: 'line',
itemStyle: {},
},
{
name: 'TN',
data: [78, 123, 29, 45, 99, 134, 131, 39, 67, 156],
type: 'line',
itemStyle: {},
},
{
name: 'TP',
data: [100, 100, 100, 100, 100, 100, 100, 100, 100, 100],
type: 'line',
itemStyle: {},
},
],
});
setOptions2({
tooltip: {
trigger: 'axis',
},
grid: {
left: '3%',
right: '4%',
bottom: '3%',
containLabel: true,
},
legend: {
data: ['COD', 'NH3-N', 'TN', 'TP'],
},
xAxis: {
type: 'category',
boundaryGap: true,
data: [
'"1995"',
'"1996"',
'"1997"',
'"1998"',
'"1999"',
'"2000"',
'"2001"',
'"2002"',
'"2003"',
'"2004"',
],
},
yAxis: {
type: 'value',
name: '汇入量/吨', //
nameLocation: 'end', // start/center/end
nameTextStyle: {
color: '#666',
fontSize: 12,
align: 'left', //
padding: [0, 0, 0, -30], // [,,,]
},
},
series: [
{
name: 'COD',
data: [90, 200, 150, 80, 70, 78, 123, 29, 45, 99],
type: 'line',
itemStyle: {},
},
{
name: 'NH3-N',
data: [132, 23, 42, 88, 66, 77, 99, 111, 122, 133],
type: 'line',
itemStyle: {},
},
{
name: 'TN',
data: [78, 123, 29, 45, 99, 134, 131, 39, 67, 156],
type: 'line',
itemStyle: {},
},
{
name: 'TP',
data: [100, 100, 100, 100, 100, 100, 100, 100, 100, 100],
type: 'line',
itemStyle: {},
},
],
});
setOptions3({
tooltip: {
trigger: 'axis',
},
grid: {
left: '3%',
right: '4%',
bottom: '3%',
containLabel: true,
},
legend: {
data: ['COD','NH3-N','TN', 'TP'],
},
xAxis: {
type: 'category',
boundaryGap: true,
data: [
'"1995"',
'"1996"',
'"1997"',
'"1998"',
'"1999"',
'"2000"',
'"2001"',
'"2002"',
'"2003"',
'"2004"',
],
},
yAxis: {
type: 'value',
name: '生产量/吨', //
nameLocation: 'end', // start/center/end
nameTextStyle: {
color: '#666',
fontSize: 12,
align: 'left', //
padding: [0, 0, 0, -30], // [,,,]
},
},
series: [
{
name: 'COD',
data: [90, 200, 150, 80, 70, 78, 123, 29, 45, 99],
type: 'line',
itemStyle: {},
},
{
name: 'NH3-N',
data: [132, 23, 42, 88, 66, 77, 99, 111, 122, 133],
type: 'line',
itemStyle: {},
},
{
name: 'TN',
data: [78, 123, 29, 45, 99, 134, 131, 39, 67, 156],
type: 'line',
itemStyle: {},
},
{
name: 'TP',
data: [100, 100, 100, 100, 100, 100, 100, 100, 100, 100],
type: 'line',
itemStyle: {},
},
],
});
setOptions4({
tooltip: {
trigger: 'axis',
},
grid: {
left: '3%',
right: '4%',
bottom: '3%',
containLabel: true,
},
legend: {
data: ['COD','NH3-N','TN', 'TP'],
},
xAxis: {
type: 'category',
boundaryGap: true,
data: [
'"1995"',
'"1996"',
'"1997"',
'"1998"',
'"1999"',
'"2000"',
'"2001"',
'"2002"',
'"2003"',
'"2004"',
],
},
yAxis: {
type: 'value',
name: '汇入量/吨', //
nameLocation: 'end', // start/center/end
nameTextStyle: {
color: '#666',
fontSize: 12,
align: 'left', //
padding: [0, 0, 0, -30], // [,,,]
},
},
series: [
{
name: 'COD',
data: [90, 200, 150, 80, 70, 78, 123, 29, 45, 99],
type: 'line',
itemStyle: {},
},
{
name: 'NH3-N',
data: [132, 23, 42, 88, 66, 77, 99, 111, 122, 133],
type: 'line',
itemStyle: {},
},
{
name: 'TN',
data: [78, 123, 29, 45, 99, 134, 131, 39, 67, 156],
type: 'line',
itemStyle: {},
},
{
name: 'TP',
data: [100, 100, 100, 100, 100, 100, 100, 100, 100, 100],
type: 'line',
itemStyle: {},
},
],
});
},
{ immediate: true },
);
</script>
<style lang="less">
.tabBox {
margin: 20px;
}
.mutiTable {
margin: 20px 0;
}
</style>

45
src/views/water/waterPollution/index.vue

@ -0,0 +1,45 @@
<template>
<PageWrapper dense>
<div style="margin: 20px; border-radius: 10px; background: #fff">
<div class="tabBox">
<a-tabs v-model:activeKey="activeKey" size="large">
<a-tab-pane key="1" tab="污染源负荷变化">
<twoBar :loading="loading" />
</a-tab-pane>
<a-tab-pane key="2" tab="点源污染变化">
<threeAxis :loading="loading" />
</a-tab-pane>
<a-tab-pane key="3" tab="面源污染变化">
<fourAxis :loading="loading" :title="secondTabTitle1" />
</a-tab-pane>
<a-tab-pane key="4" tab="污染负荷汇入变化">
<mutiBar :loading="loading" />
</a-tab-pane>
</a-tabs>
</div>
</div>
</PageWrapper>
</template>
<script setup lang="ts">
import { ref } from 'vue';
import { PageWrapper } from '@/components/Page';
import twoBar from './twoBar.vue';
import threeAxis from './threeAxis.vue';
import fourAxis from './fourAxis.vue';
import mutiBar from './mutiBar.vue';
const activeKey = ref<String>('1');
const loading = ref(false);
const secondTabTitle1 = ['农业农村面源污染负荷排放量变化趋势', '农业农村面源污染汇入量变化趋势', '城市面源产生量变化趋势', '城市面源汇入量变化趋势'];
</script>
<style lang="less">
.tabBox {
margin: 20px;
}
.title {
margin: 10px 0;
font-size: 20px;
font-weight: 550;
}
</style>

350
src/views/water/waterPollution/mutiBar.vue

@ -0,0 +1,350 @@
<template>
<div class="tabBox">
<div class="md:flex enter-y">
<div class="md:w-1/2 w-full">
<Card title="1988年" :loading="loading">
<div ref="chartRef1" :style="{ width, height }"></div>
</Card>
</div>
<div class="md:w-1/2 w-full">
<Card title="2000年" :loading="loading">
<div ref="chartRef2" :style="{ width, height }"></div>
</Card>
</div>
</div>
<div class="md:flex enter-y">
<div class="md:w-1/2 w-full">
<Card title="2005年" :loading="loading">
<div ref="chartRef3" :style="{ width, height }"></div>
</Card>
</div>
<div class="md:w-1/2 w-full">
<Card title="2020年" :loading="loading">
<div ref="chartRef4" :style="{ width, height }"></div>
</Card>
</div>
</div>
<div>
<Card title="污染负荷构成特征变化" :loading="loading">
<div ref="chartRef5" :style="{ width, height }"></div>
</Card>
</div>
</div>
</template>
<script setup lang="ts">
import { watch, ref, Ref, watchEffect } from 'vue';
import { useECharts } from '@/hooks/web/useECharts';
import { Card } from 'ant-design-vue';
const subTab = ref<String>('a');
const props = defineProps({
loading: Boolean,
width: {
type: String as PropType<string>,
default: '100%',
},
height: {
type: String as PropType<string>,
default: '300px',
},
});
const chartRef1 = ref<HTMLDivElement | null>(null);
const setOptions1 = useECharts(chartRef1 as Ref<HTMLDivElement>).setOptions;
const chartRef2 = ref<HTMLDivElement | null>(null);
const setOptions2 = useECharts(chartRef2 as Ref<HTMLDivElement>).setOptions;
const chartRef3 = ref<HTMLDivElement | null>(null);
const setOptions3 = useECharts(chartRef3 as Ref<HTMLDivElement>).setOptions;
const chartRef4 = ref<HTMLDivElement | null>(null);
const setOptions4 = useECharts(chartRef4 as Ref<HTMLDivElement>).setOptions;
const chartRef5 = ref<HTMLDivElement | null>(null);
const setOptions5 = useECharts(chartRef5 as Ref<HTMLDivElement>).setOptions;
watch(
() => subTab.value,
() => {
setOptions1({
tooltip: {},
grid: {
left: '3%',
right: '4%',
bottom: '3%',
containLabel: true,
},
legend: {
data: ['未收集点源', '城市面源', '农业农村面源'],
},
xAxis: {
type: 'category',
boundaryGap: true,
data: ['COD', 'TN', 'TP'],
},
yAxis: {
type: 'value',
name: '污染负荷率', //
nameLocation: 'end', // start/center/end
nameTextStyle: {
color: '#666',
fontSize: 12,
align: 'left', //
padding: [0, 0, 0, -30], // [,,,]
},
},
series: [
{
name: '未收集点源',
data: [90, 200, 150],
type: 'bar',
barWidth: '10px',
itemStyle: {},
},
{
name: '城市面源',
data: [78, 123, 29],
type: 'bar',
barWidth: '10px',
itemStyle: {},
},
{
name: '农业农村面源',
data: [100, 100, 100],
type: 'bar',
barWidth: '10px',
itemStyle: {},
},
],
});
setOptions2({
tooltip: {},
grid: {
left: '3%',
right: '4%',
bottom: '3%',
containLabel: true,
},
legend: {
data: ['污水处理厂尾水', '未收集点源', '城市面源', '农业农村面源'],
},
xAxis: {
type: 'category',
boundaryGap: true,
data: ['COD', 'TN', 'TP'],
},
yAxis: {
type: 'value',
name: '污染负荷率', //
nameLocation: 'end', // start/center/end
nameTextStyle: {
color: '#666',
fontSize: 12,
align: 'left', //
padding: [0, 0, 0, -30], // [,,,]
},
},
series: [
{
name: '污水处理厂尾水',
data: [90, 200, 150, 99],
type: 'bar',
barWidth: '10px',
itemStyle: {},
},
{
name: '未收集点源',
data: [78, 123, 29, 99],
type: 'bar',
barWidth: '10px',
itemStyle: {},
},
{
name: '城市面源',
data: [100, 100, 100, 99],
type: 'bar',
barWidth: '10px',
itemStyle: {},
},
{
name: '农业农村面源',
data: [100, 100, 100, 99],
type: 'bar',
barWidth: '10px',
itemStyle: {},
},
],
});
setOptions3({
tooltip: {},
grid: {
left: '3%',
right: '4%',
bottom: '3%',
containLabel: true,
},
legend: {
data: ['污水处理厂尾水', '未收集点源', '城市面源', '农业农村面源'],
},
xAxis: {
type: 'category',
boundaryGap: true,
data: ['COD', 'TN', 'TP'],
},
yAxis: {
type: 'value',
name: '污染负荷率', //
nameLocation: 'end', // start/center/end
nameTextStyle: {
color: '#666',
fontSize: 12,
align: 'left', //
padding: [0, 0, 0, -30], // [,,,]
},
},
series: [
{
name: '污水处理厂尾水',
data: [90, 200, 150, 99],
type: 'bar',
barWidth: '10px',
itemStyle: {},
},
{
name: '未收集点源',
data: [78, 123, 29, 99],
type: 'bar',
barWidth: '10px',
itemStyle: {},
},
{
name: '城市面源',
data: [100, 100, 100, 99],
type: 'bar',
barWidth: '10px',
itemStyle: {},
},
{
name: '农业农村面源',
data: [100, 100, 100, 99],
type: 'bar',
barWidth: '10px',
itemStyle: {},
},
],
});
setOptions4({
tooltip: {},
grid: {
left: '3%',
right: '4%',
bottom: '3%',
containLabel: true,
},
legend: {
data: ['污水处理厂尾水', '未收集点源', '城市面源', '农业农村面源'],
},
xAxis: {
type: 'category',
boundaryGap: true,
data: ['COD', 'TN', 'TP'],
},
yAxis: {
type: 'value',
name: '污染负荷率', //
nameLocation: 'end', // start/center/end
nameTextStyle: {
color: '#666',
fontSize: 12,
align: 'left', //
padding: [0, 0, 0, -30], // [,,,]
},
},
series: [
{
name: '污水处理厂尾水',
data: [90, 200, 150, 99],
type: 'bar',
barWidth: '10px',
itemStyle: {},
},
{
name: '未收集点源',
data: [78, 123, 29, 99],
type: 'bar',
barWidth: '10px',
itemStyle: {},
},
{
name: '城市面源',
data: [100, 100, 100, 99],
type: 'bar',
barWidth: '10px',
itemStyle: {},
},
{
name: '农业农村面源',
data: [100, 100, 100, 99],
type: 'bar',
barWidth: '10px',
itemStyle: {},
},
],
});
setOptions5({
tooltip: {},
grid: {
left: '3%',
right: '4%',
bottom: '3%',
containLabel: true,
},
legend: {
data: ['2000', '2005', '2020'],
},
xAxis: {
type: 'category',
boundaryGap: true,
data: ['XX区', 'XX区', 'XX区', 'XX区', 'XX区'],
},
yAxis: {
type: 'value',
name: '污染负荷率', //
nameLocation: 'end', // start/center/end
nameTextStyle: {
color: '#666',
fontSize: 12,
align: 'left', //
padding: [0, 0, 0, -30], // [,,,]
},
},
series: [
{
name: '2000',
data: [90, 200, 150,66,77],
type: 'bar',
barWidth: '10px',
itemStyle: {},
},
{
name: '2005',
data: [78, 123, 29,55,99],
type: 'bar',
barWidth: '10px',
itemStyle: {},
},
{
name: '2020',
data: [100, 100, 100,88,111],
type: 'bar',
barWidth: '10px',
itemStyle: {},
},
],
});
},
{ immediate: true },
);
</script>
<style lang="less">
.tabBox {
margin: 20px;
}
</style>

266
src/views/water/waterPollution/threeAxis.vue

@ -0,0 +1,266 @@
<template>
<div class="tabBox">
<div class="md:flex enter-y">
<div class="md:w-1/3 w-full">
<Card title="污染负荷产生量变化趋势" :loading="loading">
<div ref="chartRef1" :style="{ width, height }"></div>
</Card>
</div>
<div class="md:w-1/3 w-full">
<Card title="污染负荷削减量变化趋势" :loading="loading">
<div ref="chartRef2" :style="{ width, height }"></div>
</Card>
</div>
<div class="md:w-1/3 w-full">
<Card title="污染环境负荷变化趋势" :loading="loading">
<div ref="chartRef3" :style="{ width, height }"></div>
</Card>
</div>
</div>
</div>
</template>
<script setup lang="ts">
import { watch, ref, Ref, watchEffect } from 'vue';
import { useECharts } from '@/hooks/web/useECharts';
import { Card } from 'ant-design-vue';
const subTab = ref<String>('a');
const props = defineProps({
loading: Boolean,
width: {
type: String as PropType<string>,
default: '100%',
},
height: {
type: String as PropType<string>,
default: '300px',
},
title: {
type: String as PropType<any>,
default: '300px',
},
});
const chartRef1 = ref<HTMLDivElement | null>(null);
const chartRef2 = ref<HTMLDivElement | null>(null);
const chartRef3 = ref<HTMLDivElement | null>(null);
const setOptions1 = useECharts(chartRef1 as Ref<HTMLDivElement>).setOptions;
const setOptions2 = useECharts(chartRef2 as Ref<HTMLDivElement>).setOptions;
const setOptions3 = useECharts(chartRef3 as Ref<HTMLDivElement>).setOptions;
watch(
() => subTab.value,
() => {
setOptions1({
tooltip: {
trigger: 'axis',
},
grid: {
left: '3%',
right: '4%',
bottom: '3%',
containLabel: true,
},
legend: {
data: ['COD', 'NH3-N', 'TN', 'TP'],
},
xAxis: {
type: 'category',
boundaryGap: true,
data: [
'"1995"',
'"1996"',
'"1997"',
'"1998"',
'"1999"',
'"2000"',
'"2001"',
'"2002"',
'"2003"',
'"2004"',
],
},
yAxis: {
type: 'value',
name: '生产量/吨', //
nameLocation: 'end', // start/center/end
nameTextStyle: {
color: '#666',
fontSize: 12,
align: 'left', //
padding: [0, 0, 0, -30], // [,,,]
},
},
series: [
{
name: 'COD/10',
data: [90, 200, 150, 80, 70, 78, 123, 29, 45, 99],
type: 'line',
itemStyle: {},
},
{
name: 'NH3-N',
data: [132, 23, 42, 88, 66, 77, 99, 111, 122, 133],
type: 'line',
itemStyle: {},
},
{
name: 'TN',
data: [78, 123, 29, 45, 99, 134, 131, 39, 67, 156],
type: 'line',
itemStyle: {},
},
{
name: 'TP',
data: [100, 100, 100, 100, 100, 100, 100, 100, 100, 100],
type: 'line',
itemStyle: {},
},
],
});
setOptions2({
tooltip: {
trigger: 'axis',
},
grid: {
left: '3%',
right: '4%',
bottom: '3%',
containLabel: true,
},
legend: {
data: ['COD', 'NH3-N', 'TN', 'TP'],
},
xAxis: {
type: 'category',
boundaryGap: true,
data: [
'"1995"',
'"1996"',
'"1997"',
'"1998"',
'"1999"',
'"2000"',
'"2001"',
'"2002"',
'"2003"',
'"2004"',
],
},
yAxis: {
type: 'value',
name: '削减量/吨', //
nameLocation: 'end', // start/center/end
nameTextStyle: {
color: '#666',
fontSize: 12,
align: 'left', //
padding: [0, 0, 0, -30], // [,,,]
},
},
series: [
{
name: 'COD',
data: [90, 200, 150, 80, 70, 78, 123, 29, 45, 99],
type: 'line',
itemStyle: {},
},
{
name: 'NH3-N',
data: [132, 23, 42, 88, 66, 77, 99, 111, 122, 133],
type: 'line',
itemStyle: {},
},
{
name: 'TN',
data: [78, 123, 29, 45, 99, 134, 131, 39, 67, 156],
type: 'line',
itemStyle: {},
},
{
name: 'TP',
data: [100, 100, 100, 100, 100, 100, 100, 100, 100, 100],
type: 'line',
itemStyle: {},
},
],
});
setOptions3({
tooltip: {
trigger: 'axis',
},
grid: {
left: '3%',
right: '4%',
bottom: '3%',
containLabel: true,
},
legend: {
data: ['COD', 'NH3-N', 'TN', 'TP'],
},
xAxis: {
type: 'category',
boundaryGap: true,
data: [
'"1995"',
'"1996"',
'"1997"',
'"1998"',
'"1999"',
'"2000"',
'"2001"',
'"2002"',
'"2003"',
'"2004"',
],
},
yAxis: {
type: 'value',
name: '变化量/吨', //
nameLocation: 'end', // start/center/end
nameTextStyle: {
color: '#666',
fontSize: 12,
align: 'left', //
padding: [0, 0, 0, -30], // [,,,]
},
},
series: [
{
name: 'COD',
data: [90, 200, 150, 80, 70, 78, 123, 29, 45, 99],
type: 'line',
itemStyle: {},
},
{
name: 'NH3-N',
data: [132, 23, 42, 88, 66, 77, 99, 111, 122, 133],
type: 'line',
itemStyle: {},
},
{
name: 'TN',
data: [78, 123, 29, 45, 99, 134, 131, 39, 67, 156],
type: 'line',
itemStyle: {},
},
{
name: 'TP',
data: [100, 100, 100, 100, 100, 100, 100, 100, 100, 100],
type: 'line',
itemStyle: {},
},
],
});
},
{ immediate: true },
);
</script>
<style lang="less">
.tabBox {
margin: 20px;
}
.mutiTable {
margin: 20px 0;
}
</style>

167
src/views/water/waterPollution/twoBar.vue

@ -0,0 +1,167 @@
<template>
<div class="tabBox">
<div class="md:flex enter-y">
<div class="md:w-1/2 w-full">
<Card title="2020年污染负荷(按来源构成)" :loading="loading">
<div ref="chartRef1" :style="{ width, height }"></div>
</Card>
</div>
<div class="md:w-1/2 w-full">
<Card title="2020年污染负荷(空间分布)" :loading="loading">
<div ref="chartRef2" :style="{ width, height }"></div>
</Card>
</div>
</div>
</div>
</template>
<script setup lang="ts">
import { watch, ref, Ref, watchEffect } from 'vue';
import { useECharts } from '@/hooks/web/useECharts';
import { Card } from 'ant-design-vue';
const subTab = ref<String>('a');
const props = defineProps({
loading: Boolean,
width: {
type: String as PropType<string>,
default: '100%',
},
height: {
type: String as PropType<string>,
default: '300px',
},
});
const chartRef1 = ref<HTMLDivElement | null>(null);
const setOptions1 = useECharts(chartRef1 as Ref<HTMLDivElement>).setOptions;
const chartRef2 = ref<HTMLDivElement | null>(null);
const setOptions2 = useECharts(chartRef2 as Ref<HTMLDivElement>).setOptions;
watch(
() => subTab.value,
() => {
setOptions1({
tooltip: {},
grid: {
left: '3%',
right: '4%',
bottom: '3%',
containLabel: true,
},
legend: {
data: ['COD', 'NH3-N', 'TN', 'TP'],
},
xAxis: {
type: 'category',
boundaryGap: true,
data: ['水质净化厂尾水', '未收集点源', '城市面源', '农业农村面源', '水土流失'],
},
yAxis: {
type: 'value',
name: '污染负荷率', //
nameLocation: 'end', // start/center/end
nameTextStyle: {
color: '#666',
fontSize: 12,
align: 'left', //
padding: [0, 0, 0, -30], // [,,,]
},
},
series: [
{
name: 'COD',
data: [90, 200, 150, 80, 70],
type: 'bar',
barWidth: '10px',
itemStyle: {},
},
{
name: 'NH3-N',
data: [132, 23, 42, 88, 66],
type: 'bar',
barWidth: '10px',
itemStyle: {},
},
{
name: 'TN',
data: [78, 123, 29, 45, 99],
type: 'bar',
barWidth: '10px',
itemStyle: {},
},
{
name: 'TP',
data: [100, 100, 100, 100, 100],
type: 'bar',
barWidth: '10px',
itemStyle: {},
},
],
});
setOptions2({
tooltip: {},
grid: {
left: '3%',
right: '4%',
bottom: '3%',
containLabel: true,
},
legend: {
data: ['COD', 'NH3-N', 'TN', 'TP'],
},
xAxis: {
type: 'category',
boundaryGap: true,
data: ['XX区', 'XX区', 'XX区', 'XX区', 'XX区'],
},
yAxis: {
type: 'value',
name: '污染负荷率', //
nameLocation: 'end', // start/center/end
nameTextStyle: {
color: '#666',
fontSize: 12,
align: 'left', //
padding: [0, 0, 0, -30], // [,,,]
},
},
series: [
{
name: 'COD',
data: [90, 200, 150, 80, 70],
type: 'bar',
barWidth: '10px',
itemStyle: {},
},
{
name: 'NH3-N',
data: [132, 23, 42, 88, 66],
type: 'bar',
barWidth: '10px',
itemStyle: {},
},
{
name: 'TN',
data: [78, 123, 29, 45, 99],
type: 'bar',
barWidth: '10px',
itemStyle: {},
},
{
name: 'TP',
data: [100, 100, 100, 100, 100],
type: 'bar',
barWidth: '10px',
itemStyle: {},
},
],
});
},
{ immediate: true },
);
</script>
<style lang="less">
.tabBox {
margin: 20px;
}
</style>

2
src/views/演示使用自行删除/gitee/index.vue

@ -37,7 +37,7 @@
},
xAxis: {
type: 'category',
boundaryGap: false,
boundaryGap: true,
data: resp.starList.map((item) => item.date),
},
yAxis: {

2
src/views/演示使用自行删除/visit/pages/loginLine.vue

@ -38,7 +38,7 @@
},
xAxis: {
type: 'category',
boundaryGap: false,
boundaryGap: true,
data: data.date,
},
yAxis: {

2
vite.config.ts

@ -17,7 +17,7 @@ export default defineApplicationConfig({
server: {
proxy: {
'/basic-api': {
target: 'http://localhost:8080',
target: 'http://10.1.21.250:8085',
changeOrigin: true,
ws: true,
rewrite: (path) => path.replace(new RegExp(`^/basic-api`), ''),

Loading…
Cancel
Save