虫情监控
parent
4e93cf579a
commit
1ac3644155
|
|
@ -1000,7 +1000,7 @@ export function citydataEdit(data, mode: ErrorMessageMode = 'modal') {
|
|||
)
|
||||
}
|
||||
/**
|
||||
* @description:更新基础数据统计
|
||||
* @description:虫情图片
|
||||
*/
|
||||
export function getWormPhotos(device, params, mode: ErrorMessageMode = 'modal') {
|
||||
return defHttp.get(
|
||||
|
|
@ -1014,3 +1014,17 @@ export function getWormPhotos(device, params, mode: ErrorMessageMode = 'modal')
|
|||
},
|
||||
)
|
||||
}
|
||||
/**
|
||||
* @description:虫情统计
|
||||
*/
|
||||
export function getWormCount(device, params, mode: ErrorMessageMode = 'modal') {
|
||||
return defHttp.get(
|
||||
{
|
||||
url: `/api/devices/${device}/worm-statics`,
|
||||
params,
|
||||
},
|
||||
{
|
||||
errorMessageMode: mode,
|
||||
},
|
||||
)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -51,14 +51,14 @@ const main: AppRouteModule = {
|
|||
title: '昆虫性诱监测',
|
||||
},
|
||||
},
|
||||
// {
|
||||
// path: 'pests',
|
||||
// name: 'MainPests',
|
||||
// component: () => import('/@/views/main/pests/index.vue'),
|
||||
// meta: {
|
||||
// title: '虫情监测',
|
||||
// },
|
||||
// },
|
||||
{
|
||||
path: 'pests',
|
||||
name: 'MainPests',
|
||||
component: () => import('/@/views/main/pests/index.vue'),
|
||||
meta: {
|
||||
title: '虫情监测',
|
||||
},
|
||||
},
|
||||
{
|
||||
path: 'insecticidal-lamp',
|
||||
name: 'MainInsecticidalLamp',
|
||||
|
|
|
|||
|
|
@ -222,7 +222,6 @@
|
|||
const { data, meta } = await getWormPhotos(params.device_id, params)
|
||||
pageTotal.value = meta.total
|
||||
list.value = data
|
||||
console.log(data)
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
|
|
|
|||
|
|
@ -0,0 +1,295 @@
|
|||
<template>
|
||||
<Form ref="formRef" :model="formState">
|
||||
<Row :gutter="[16, 16]">
|
||||
<Col
|
||||
:xs="{ span: 24 }"
|
||||
:sm="{ span: 12 }"
|
||||
:md="{ span: 8 }"
|
||||
:lg="{ span: 6 }"
|
||||
:xl="{ span: 6 }"
|
||||
:xxl="{ span: 4 }"
|
||||
>
|
||||
<FormItem label="基地">
|
||||
<Select
|
||||
@select="onChange('base_id')"
|
||||
:fieldNames="{ label: 'name', value: 'id' }"
|
||||
:options="baseDate"
|
||||
v-model:value="formState.base_id"
|
||||
placeholder="请选择基地"
|
||||
/>
|
||||
</FormItem>
|
||||
</Col>
|
||||
<Col
|
||||
:xs="{ span: 24 }"
|
||||
:sm="{ span: 12 }"
|
||||
:md="{ span: 8 }"
|
||||
:lg="{ span: 6 }"
|
||||
:xl="{ span: 6 }"
|
||||
:xxl="{ span: 4 }"
|
||||
>
|
||||
<FormItem label="检测点">
|
||||
<Select
|
||||
@select="onChange('device_id')"
|
||||
placeholder="请选择检测点"
|
||||
:options="pointDate"
|
||||
v-model:value="formState.device_id"
|
||||
/>
|
||||
</FormItem>
|
||||
</Col>
|
||||
<Col
|
||||
:xs="{ span: 24 }"
|
||||
:sm="{ span: 12 }"
|
||||
:md="{ span: 8 }"
|
||||
:lg="{ span: 6 }"
|
||||
:xl="{ span: 6 }"
|
||||
:xxl="{ span: 4 }"
|
||||
>
|
||||
<FormItem label="日期">
|
||||
<RangePicker
|
||||
:disabledDate="disabledDate"
|
||||
@change="onChangTime"
|
||||
v-model:value="formState.time"
|
||||
/>
|
||||
</FormItem>
|
||||
</Col>
|
||||
<Col
|
||||
:xs="{ span: 24 }"
|
||||
:sm="{ span: 12 }"
|
||||
:md="{ span: 8 }"
|
||||
:lg="{ span: 6 }"
|
||||
:xl="{ span: 6 }"
|
||||
:xxl="{ span: 4 }"
|
||||
>
|
||||
<FormItem>
|
||||
<RadioGroup
|
||||
@change="onChange('time_interval')"
|
||||
button-style="solid"
|
||||
v-model:value="formState.time_interval"
|
||||
>
|
||||
<RadioButton value="day">今天</RadioButton>
|
||||
<RadioButton value="week">近一周</RadioButton>
|
||||
<RadioButton value="month">近一个月</RadioButton>
|
||||
</RadioGroup>
|
||||
</FormItem>
|
||||
</Col>
|
||||
</Row>
|
||||
</Form>
|
||||
<div class="mt-20px">
|
||||
<div class="h-450px" ref="pestsCountRef"></div>
|
||||
</div>
|
||||
</template>
|
||||
<script lang="ts" setup>
|
||||
import dayjs from 'dayjs'
|
||||
import { useECharts } from '/@/hooks/web/useECharts'
|
||||
import echarts from '/@/utils/lib/echarts'
|
||||
import { formatDataByObject, getWeek, getMonth } from '/@/utils/index'
|
||||
import {
|
||||
getaGriculturalDevicePoint,
|
||||
getGriculturalDeviceBasic,
|
||||
getWormCount,
|
||||
} from '/@/api/sys/user'
|
||||
import { Form, FormItem, Select, Row, Col, RangePicker, Radio } from 'ant-design-vue'
|
||||
import { reactive, ref, onMounted } from 'vue'
|
||||
const RadioButton = Radio.Button
|
||||
const RadioGroup = Radio.Group
|
||||
const pestsCountRef = ref<Ref<HTMLDivElement>>(null)
|
||||
|
||||
const { setOptions } = useECharts(pestsCountRef as Ref<HTMLDivElement>)
|
||||
|
||||
const disabledDate = (current) => {
|
||||
return current && current > dayjs().endOf('day')
|
||||
}
|
||||
|
||||
const formState = reactive({
|
||||
base_id: undefined, //基地
|
||||
device_id: undefined, //监控点
|
||||
time: undefined, //时间
|
||||
time_interval: 'week',
|
||||
})
|
||||
|
||||
const statisData = ref<any>({})
|
||||
|
||||
const baseDate = ref<any>([])
|
||||
const pointDate = ref<any>([])
|
||||
|
||||
const getBase = async () => {
|
||||
const res = await getGriculturalDeviceBasic({ device_type: 5 })
|
||||
if (res.length == 0) return
|
||||
baseDate.value = res
|
||||
if (!formState.base_id) formState.base_id = res?.[0]?.id ?? undefined
|
||||
getPoint()
|
||||
}
|
||||
|
||||
const onChangTime = (e) => {
|
||||
if (e === null) formState.time_interval = 'day'
|
||||
else formState.time_interval = ''
|
||||
getPoint()
|
||||
}
|
||||
|
||||
const onChange = (e: string | undefined) => {
|
||||
if (e === 'base_id') formState.device_id = undefined
|
||||
if (e === 'time') formState.time_interval = ''
|
||||
if (e === 'time_interval') {
|
||||
formState.time = undefined
|
||||
return getDate()
|
||||
}
|
||||
getPoint()
|
||||
}
|
||||
|
||||
// 获取监控点数据
|
||||
const getPoint = async () => {
|
||||
if (baseDate.value.length == 0) return
|
||||
const res = await getaGriculturalDevicePoint({
|
||||
device_type: 5,
|
||||
agricultural_basic: formState.base_id,
|
||||
})
|
||||
pointDate.value = formatDataByObject(res)
|
||||
if (!formState.device_id) formState.device_id = pointDate.value?.[0]?.value ?? undefined
|
||||
getDate()
|
||||
}
|
||||
|
||||
// 获取数据
|
||||
const getDate = async () => {
|
||||
const params = {
|
||||
device_id: formState.device_id,
|
||||
start_time: '',
|
||||
end_time: '',
|
||||
}
|
||||
if (formState.time) {
|
||||
params.start_time = dayjs(formState.time?.[0]).format('YYYY-MM-DD')
|
||||
params.end_time = dayjs(formState.time?.[1]).format('YYYY-MM-DD')
|
||||
}
|
||||
|
||||
if (formState.time_interval === 'week') {
|
||||
const { WeekStartDate, WeekEndDate } = getWeek()
|
||||
params.start_time = WeekStartDate
|
||||
params.end_time = WeekEndDate
|
||||
} else if (formState.time_interval === 'month') {
|
||||
const { MonthStartDate, MonthEndDate } = getMonth()
|
||||
params.start_time = MonthStartDate
|
||||
params.end_time = MonthEndDate
|
||||
} else if (formState.time_interval === 'day') {
|
||||
params.start_time = dayjs().endOf('day').format('YYYY-MM-DD')
|
||||
params.end_time = dayjs().endOf('day').format('YYYY-MM-DD')
|
||||
}
|
||||
if (params.device_id == null) return (statisData.value = {})
|
||||
console.log(params)
|
||||
|
||||
const res = await getWormCount(params.device_id, params)
|
||||
statisData.value = res
|
||||
chartsInit()
|
||||
}
|
||||
|
||||
function chartsInit() {
|
||||
const xAxis = []
|
||||
const data = []
|
||||
|
||||
Object.keys(statisData.value ?? {}).forEach((key) => {
|
||||
xAxis.push(key)
|
||||
data.push(statisData.value[key])
|
||||
})
|
||||
|
||||
setOptions({
|
||||
tooltip: {
|
||||
trigger: 'axis',
|
||||
axisPointer: {
|
||||
lineStyle: {
|
||||
width: 1,
|
||||
color: '#019680',
|
||||
},
|
||||
},
|
||||
},
|
||||
grid: {
|
||||
left: '2%',
|
||||
right: '4%',
|
||||
bottom: '4%',
|
||||
top: '16%',
|
||||
containLabel: true,
|
||||
},
|
||||
xAxis: {
|
||||
type: 'category',
|
||||
data: xAxis,
|
||||
axisLine: {
|
||||
lineStyle: {
|
||||
color: 'rgba(255, 255, 255, 0.1)',
|
||||
},
|
||||
},
|
||||
axisLabel: {
|
||||
textStyle: {
|
||||
color: '#6F8290',
|
||||
},
|
||||
},
|
||||
},
|
||||
|
||||
yAxis: {
|
||||
type: 'value',
|
||||
axisLine: {
|
||||
show: false,
|
||||
lineStyle: {
|
||||
color: 'white',
|
||||
},
|
||||
},
|
||||
splitLine: {
|
||||
show: true,
|
||||
lineStyle: {
|
||||
color: 'rgba(255,255,255,0.3)',
|
||||
},
|
||||
},
|
||||
axisLabel: {
|
||||
textStyle: {
|
||||
color: '#6F8290',
|
||||
},
|
||||
},
|
||||
},
|
||||
|
||||
series: [
|
||||
{
|
||||
name: '1',
|
||||
type: 'bar',
|
||||
barWidth: '12px',
|
||||
itemStyle: {
|
||||
normal: {
|
||||
color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
|
||||
{
|
||||
offset: 0,
|
||||
color: 'rgba(166, 233, 215, 1)',
|
||||
},
|
||||
{
|
||||
offset: 1,
|
||||
color: 'rgba(72, 151, 94, 0)',
|
||||
},
|
||||
]),
|
||||
barBorderRadius: 12,
|
||||
},
|
||||
},
|
||||
data: data,
|
||||
},
|
||||
// {
|
||||
// name: '2',
|
||||
// type: 'bar',
|
||||
// barWidth: '12px',
|
||||
// itemStyle: {
|
||||
// normal: {
|
||||
// color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
|
||||
// {
|
||||
// offset: 0,
|
||||
// color: 'rgba(229, 231, 89, 0.95)',
|
||||
// },
|
||||
// {
|
||||
// offset: 1,
|
||||
// color: 'rgba(134, 231, 89, 0)',
|
||||
// },
|
||||
// ]),
|
||||
// barBorderRadius: 11,
|
||||
// },
|
||||
// },
|
||||
// data: [400, 500, 500, 500, 500, 400, 200, 100],
|
||||
// },
|
||||
],
|
||||
})
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
getBase()
|
||||
})
|
||||
</script>
|
||||
|
|
@ -0,0 +1,230 @@
|
|||
<template>
|
||||
<PageWrapper>
|
||||
<Card>
|
||||
<Form ref="formRef" :model="formState">
|
||||
<Row :gutter="[16, 16]">
|
||||
<Col
|
||||
:xs="{ span: 24 }"
|
||||
:sm="{ span: 12 }"
|
||||
:md="{ span: 8 }"
|
||||
:lg="{ span: 6 }"
|
||||
:xl="{ span: 6 }"
|
||||
:xxl="{ span: 4 }"
|
||||
>
|
||||
<FormItem label="基地">
|
||||
<Select
|
||||
@select="onChange('base_id')"
|
||||
:fieldNames="{ label: 'name', value: 'id' }"
|
||||
:options="baseDate"
|
||||
v-model:value="formState.base_id"
|
||||
placeholder="请选择基地"
|
||||
/>
|
||||
</FormItem>
|
||||
</Col>
|
||||
<Col
|
||||
:xs="{ span: 24 }"
|
||||
:sm="{ span: 12 }"
|
||||
:md="{ span: 8 }"
|
||||
:lg="{ span: 6 }"
|
||||
:xl="{ span: 6 }"
|
||||
:xxl="{ span: 4 }"
|
||||
>
|
||||
<FormItem label="检测点">
|
||||
<Select
|
||||
@select="onChange('device_id')"
|
||||
placeholder="请选择检测点"
|
||||
:options="pointDate"
|
||||
v-model:value="formState.device_id"
|
||||
/>
|
||||
</FormItem>
|
||||
</Col>
|
||||
<Col
|
||||
:xs="{ span: 24 }"
|
||||
:sm="{ span: 12 }"
|
||||
:md="{ span: 8 }"
|
||||
:lg="{ span: 6 }"
|
||||
:xl="{ span: 6 }"
|
||||
:xxl="{ span: 4 }"
|
||||
>
|
||||
<FormItem label="日期">
|
||||
<RangePicker
|
||||
:disabledDate="disabledDate"
|
||||
@change="onChangTime"
|
||||
v-model:value="formState.time"
|
||||
/>
|
||||
</FormItem>
|
||||
</Col>
|
||||
<Col
|
||||
:xs="{ span: 24 }"
|
||||
:sm="{ span: 12 }"
|
||||
:md="{ span: 8 }"
|
||||
:lg="{ span: 6 }"
|
||||
:xl="{ span: 6 }"
|
||||
:xxl="{ span: 4 }"
|
||||
>
|
||||
<FormItem>
|
||||
<RadioGroup
|
||||
@change="onChange('time_interval')"
|
||||
button-style="solid"
|
||||
v-model:value="formState.time_interval"
|
||||
>
|
||||
<RadioButton value="day">今天</RadioButton>
|
||||
<RadioButton value="week">近一周</RadioButton>
|
||||
<RadioButton value="month">近一个月</RadioButton>
|
||||
</RadioGroup>
|
||||
</FormItem>
|
||||
</Col>
|
||||
</Row>
|
||||
</Form>
|
||||
|
||||
<List
|
||||
:grid="{ gutter: 16, xs: 1, sm: 2, md: 2, lg: 3, xl: 4, xxl: 5, column: 8 }"
|
||||
:data-source="list"
|
||||
>
|
||||
<template #renderItem="{ item }">
|
||||
<List-item>
|
||||
<Card :hoverable="true" class="card" :bodyStyle="{ padding: 0 }">
|
||||
<div>
|
||||
<a-image :src="item.url" />
|
||||
</div>
|
||||
<div class="text-gray-500 px-5 py-3"> 时间: {{ item.time }} </div>
|
||||
</Card>
|
||||
</List-item>
|
||||
</template>
|
||||
</List>
|
||||
<div class="text-right">
|
||||
<pagination
|
||||
size="small"
|
||||
v-model:current="pageCurrent"
|
||||
v-model:page-size="pageSize"
|
||||
:total="pageTotal"
|
||||
show-less-items
|
||||
showSizeChanger
|
||||
:pageSizeOptions="['8']"
|
||||
:show-total="(total) => `共 ${total} 条数据`"
|
||||
@change="getData"
|
||||
/>
|
||||
</div>
|
||||
</Card>
|
||||
</PageWrapper>
|
||||
</template>
|
||||
<script lang="ts" setup>
|
||||
import dayjs from 'dayjs'
|
||||
import { formatDataByObject, getWeek, getMonth } from '/@/utils/index'
|
||||
import {
|
||||
getaGriculturalDevicePoint,
|
||||
getGriculturalDeviceBasic,
|
||||
getWormPhotos,
|
||||
} from '/@/api/sys/user'
|
||||
import { PageWrapper } from '/@/components/Page'
|
||||
import {
|
||||
Card,
|
||||
Form,
|
||||
FormItem,
|
||||
Select,
|
||||
Row,
|
||||
Col,
|
||||
RangePicker,
|
||||
Radio,
|
||||
List,
|
||||
Image,
|
||||
Pagination,
|
||||
} from 'ant-design-vue'
|
||||
import { reactive, ref, onMounted } from 'vue'
|
||||
const RadioButton = Radio.Button
|
||||
const RadioGroup = Radio.Group
|
||||
const ListItem = List.Item
|
||||
const AImage = Image
|
||||
|
||||
const disabledDate = (current) => {
|
||||
return current && current > dayjs().endOf('day')
|
||||
}
|
||||
|
||||
const formState = reactive({
|
||||
base_id: undefined, //基地
|
||||
device_id: undefined, //监控点
|
||||
time: undefined, //时间
|
||||
time_interval: 'day',
|
||||
})
|
||||
|
||||
const pageCurrent = ref(1)
|
||||
const pageTotal = ref(0)
|
||||
const pageSize = ref(20)
|
||||
|
||||
const baseDate = ref<any>([])
|
||||
const pointDate = ref<any>([])
|
||||
const list = ref<any>([])
|
||||
|
||||
const getBase = async () => {
|
||||
const res = await getGriculturalDeviceBasic({ device_type: 5 })
|
||||
if (res.length == 0) return
|
||||
baseDate.value = res
|
||||
if (!formState.base_id) formState.base_id = res?.[0]?.id ?? undefined
|
||||
getPoint()
|
||||
}
|
||||
|
||||
const onChangTime = (e) => {
|
||||
if (e === null) formState.time_interval = 'day'
|
||||
else formState.time_interval = ''
|
||||
getPoint()
|
||||
}
|
||||
|
||||
const onChange = (e: string | undefined) => {
|
||||
if (e === 'base_id') formState.device_id = undefined
|
||||
if (e === 'time') formState.time_interval = ''
|
||||
if (e === 'time_interval') {
|
||||
formState.time = undefined
|
||||
return getData()
|
||||
}
|
||||
getPoint()
|
||||
}
|
||||
|
||||
// 获取监控点数据
|
||||
const getPoint = async () => {
|
||||
if (baseDate.value.length == 0) return
|
||||
const res = await getaGriculturalDevicePoint({
|
||||
device_type: 5,
|
||||
agricultural_basic: formState.base_id,
|
||||
})
|
||||
pointDate.value = formatDataByObject(res)
|
||||
if (!formState.device_id) formState.device_id = pointDate.value?.[0]?.value ?? undefined
|
||||
getData()
|
||||
}
|
||||
|
||||
// 获取数据
|
||||
const getData = async () => {
|
||||
const params = {
|
||||
per_page: pageSize.value,
|
||||
page: pageCurrent.value,
|
||||
device_id: formState.device_id,
|
||||
start_time: '',
|
||||
end_time: '',
|
||||
}
|
||||
|
||||
if (formState.time) {
|
||||
params.start_time = dayjs(formState.time?.[0]).format('YYYY-MM-DD')
|
||||
params.end_time = dayjs(formState.time?.[1]).format('YYYY-MM-DD')
|
||||
}
|
||||
|
||||
if (formState.time_interval === 'week') {
|
||||
const { WeekStartDate, WeekEndDate } = getWeek()
|
||||
params.start_time = WeekStartDate
|
||||
params.end_time = WeekEndDate
|
||||
} else if (formState.time_interval === 'month') {
|
||||
const { MonthStartDate, MonthEndDate } = getMonth()
|
||||
params.start_time = MonthStartDate
|
||||
params.end_time = MonthEndDate
|
||||
} else if (formState.time_interval === 'day') {
|
||||
params.start_time = dayjs().endOf('day').format('YYYY-MM-DD')
|
||||
params.end_time = dayjs().endOf('day').format('YYYY-MM-DD')
|
||||
}
|
||||
if (params.device_id == null) return (list.value = [])
|
||||
const { data, meta } = await getWormPhotos(params.device_id, params)
|
||||
pageTotal.value = meta.total
|
||||
list.value = data
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
getBase()
|
||||
})
|
||||
</script>
|
||||
|
|
@ -1,9 +1,45 @@
|
|||
<template>
|
||||
<PageWrapper>
|
||||
<Card>虫情监测</Card>
|
||||
<Card>
|
||||
<tabs :animated="false">
|
||||
<template v-for="item in achieveList" :key="item.key">
|
||||
<tab-pane>
|
||||
<template #tab>
|
||||
<span> {{ item.name }}</span>
|
||||
</template>
|
||||
<component :is="item.component" />
|
||||
</tab-pane>
|
||||
</template>
|
||||
</tabs>
|
||||
</Card>
|
||||
</PageWrapper>
|
||||
</template>
|
||||
<script setup lang="ts">
|
||||
import { Card } from 'ant-design-vue'
|
||||
<script lang="ts" setup>
|
||||
import { Card, Tabs } from 'ant-design-vue'
|
||||
import { PageWrapper } from '/@/components/Page'
|
||||
import CountChart from './components/CountChart.vue'
|
||||
import Images from './components/Images.vue'
|
||||
// import { ref } from 'vue'
|
||||
|
||||
const TabPane = Tabs.TabPane
|
||||
export interface TabItem {
|
||||
key: string
|
||||
name: string
|
||||
component: any
|
||||
iconComponent: string
|
||||
}
|
||||
const achieveList: TabItem[] = [
|
||||
{
|
||||
key: '1',
|
||||
name: '虫情统计',
|
||||
component: CountChart,
|
||||
iconComponent: 'VideoCameraOutlined',
|
||||
},
|
||||
{
|
||||
key: '2',
|
||||
name: '虫情图片',
|
||||
component: Images,
|
||||
iconComponent: 'PlayCircleOutlined',
|
||||
},
|
||||
]
|
||||
</script>
|
||||
|
|
|
|||
Loading…
Reference in New Issue