H 2022-11-02 17:52:06 +08:00
commit e18166f91b
8 changed files with 441 additions and 64 deletions

View File

@ -74,7 +74,7 @@ export function deleteDevice(device, mode: ErrorMessageMode = 'modal') {
* @description: * @description:
*/ */
export function getAgriculturalBasic( export function getAgriculturalBasic(
params = { per_page: 999999, page: 1 }, params: any = { per_page: 999999, page: 1, parent_id: 0, type: 2 },
mode: ErrorMessageMode = 'modal', mode: ErrorMessageMode = 'modal',
) { ) {
return defHttp.get( return defHttp.get(
@ -115,3 +115,63 @@ export function getCropYieldCategoryStatics(params, mode: ErrorMessageMode = 'mo
}, },
) )
} }
/**
* @description:线
*
*/
export function getCropYieldTotalChart(params, mode: ErrorMessageMode = 'modal') {
return defHttp.get(
{
url: '/api/crop-yield-total-chart',
params,
},
{
errorMessageMode: mode,
},
)
}
/**
* @description:线
*
*/
export function getCropYieldTotalListt(params, mode: ErrorMessageMode = 'modal') {
return defHttp.get(
{
url: '/api/crop-yield-total-list',
params,
},
{
errorMessageMode: mode,
},
)
}
/**
* @description:-+
*
*/
export function getDeviceBaseDataStatics(params, mode: ErrorMessageMode = 'modal') {
return defHttp.get(
{
url: '/api/device-base-data-statics',
params,
},
{
errorMessageMode: mode,
},
)
}
/**
* @description:
*
*/
export function getAgriculturalDeviceBasic(params, mode: ErrorMessageMode = 'modal') {
return defHttp.get(
{
url: '/api/agricultural-device-basic',
params,
},
{
errorMessageMode: mode,
},
)
}

View File

@ -42,3 +42,28 @@ svg,
span { span {
outline: none; outline: none;
} }
.dropdownClass {
.ant-dropdown-menu {
border: 1px solid rgba(57, 102, 132, 1);
color: #fff;
background: rgba(28, 44, 52, .9);
max-height: 200px;
overflow-y: auto;
.ant-dropdown-menu-item{
color: white;
&:hover{
background:rgba(62, 97, 114, 0.6);
}
}
}
.ant-popover-arrow {
right: 42px;
.ant-popover-arrow-content {
display: none;
background-color: rgba(57, 102, 132, 1) !important;
}
}
}

View File

@ -1,18 +1,143 @@
<template> <template>
<div class="w-314px"> <div class="w-314px flex h-full flex-col">
<div <div
class="text-18px mt-19px text-center bg-clip-text text-transparent bg-gradient-to-t from-[#76E9F0] to-[#A7E6EE]" class="text-18px h-60px leading-60px text-center bg-clip-text text-transparent bg-gradient-to-t from-[#76E9F0] to-[#A7E6EE]"
>城镇农业产业情况</div >城镇农业产业情况</div
> >
<div class="text-right text-11px leading-17px text-white mr-42px"> 单位 </div>
<div :style="{ height: chartHeight + 'px' }" class="mt-20px min-h-200px" ref="chartRef"> </div>
</div> </div>
</template> </template>
<script lang="ts"> <script lang="ts">
import { defineComponent } from 'vue' import { defineComponent, reactive, Ref, ref, onMounted, computed, watch } from 'vue'
import { getCropYieldTotalListt } from '/@/api/sys/other'
// import echarts from '/@/utils/lib/echarts'
import { useECharts } from '/@/hooks/web/useECharts'
import { useVisualizationStore } from '/@/store/modules/visualization'
import { sortBy } from 'lodash-es'
const visualizationStore = useVisualizationStore()
const chartRef = ref<HTMLDivElement | null>(null)
export default defineComponent({ export default defineComponent({
setup() { setup() {
return {} const { setOptions } = useECharts(chartRef as Ref<HTMLDivElement>)
const Data = reactive({
list: [] as any,
})
const chartHeight = computed(() => {
return Data.list.length * 34 + Data.list.length * 12
})
function chatInit() {
setOptions({
legend: {
show: false,
},
tooltip: {
trigger: 'axis',
axisPointer: {
type: 'shadow',
},
},
xAxis: {
max: 'value',
axisTick: {
show: false,
},
axisLabel: {
show: false,
},
axisLine: {
show: false,
},
axisPointer: {
show: false,
},
splitLine: {
show: false,
},
},
yAxis: {
type: 'category',
data: Data.list?.map((e) => e.y) ?? [],
axisLabel: {
color: '#fff',
},
axisTick: {
show: false,
},
axisLine: {
show: false,
},
splitLine: {
show: false,
},
},
series: [
{
type: 'bar',
data: Data.list?.map((e) => e.value) ?? [],
label: {
show: true,
position: 'inside',
color: '#fff',
valueAnimation: true,
},
itemStyle: {
color: 'rgba(117, 232, 238, 0.5)',
},
barWidth: 34,
},
],
grid: { left: '2%', right: '2%', top: '0%', bottom: '2%', containLabel: true },
animationDuration: 0,
animationDurationUpdate: 3000,
animationEasing: 'linear',
animationEasingUpdate: 'linear',
})
}
async function getData() {
const { list } = await getCropYieldTotalListt({
year: visualizationStore.getYear,
category_id: null,
})
const arr = [] as { value: string | number; y: string | number }[]
for (const key in list) {
if (Object.prototype.hasOwnProperty.call(list, key)) {
arr.push({
value: list[key],
y: key,
})
}
}
Data.list = sortBy(arr, (e) => {
return e.value
})
chatInit()
}
watch(
() => visualizationStore.getYear,
() => {
getData()
},
)
onMounted(() => {
getData()
})
return {
chartHeight,
chartRef,
}
}, },
}) })
</script> </script>

View File

@ -1,17 +1,32 @@
<template> <template>
<Box title="监控"> <Box title="监控">
<div class="h-full flex flex-col"> <div class="h-full flex flex-col">
<div class="py-10px"> <div class="py-10px relative">
<ul class="flex items-center justify-center m-0"> <div
<li class="text-center bg-clip-text text-transparent bg-gradient-to-t from-[#76E9F0] to-[#A7E6EE] text-15px font-bold"
class="mx-11px text-white text-12px cursor-pointer" >
:class="{ active: currentTab == item.key }" {{ currentTabValue }}
@click="changeTab(item.key)" </div>
v-for="item in tabList" <div class="absolute right-18px top-1/2 transform -translate-y-1/2">
:key="item.key" <Dropdown
>{{ item.value }}</li overlayClassName="dropdownClass"
placement="bottomRight"
trigger="click"
:style="{ height: '300px' }"
> >
</ul> <div class="cursor-pointer">
<span class="text-white text-12px">更多</span>
<DownOutlined :style="{ fontSize: '12px', color: '#FFF' }" />
</div>
<template #overlay>
<Menu @click="onMenuClick">
<menu-item v-for="item in tabList" :key="item.key">
<div>{{ item.value }}</div>
</menu-item>
</Menu>
</template>
</Dropdown>
</div>
</div> </div>
<div class="flex-1 px-11px"> <div class="flex-1 px-11px">
<div class="h-196px border border-solid"></div> <div class="h-196px border border-solid"></div>
@ -26,11 +41,19 @@
</template> </template>
<script lang="ts"> <script lang="ts">
import { defineComponent, reactive, ref, Ref, onMounted } from 'vue' import { defineComponent, reactive, ref, onMounted, onBeforeMount, computed } from 'vue'
import { DownOutlined } from '@ant-design/icons-vue'
import { Dropdown, Menu } from 'ant-design-vue'
import { getDeviceBaseDataStatics } from '/@/api/sys/other'
import { useVisualizationStore } from '/@/store/modules/visualization'
import Box from './Box.vue' import Box from './Box.vue'
export default defineComponent({ export default defineComponent({
components: { components: {
Box, Box,
Dropdown,
DownOutlined,
Menu,
MenuItem: Menu.Item,
}, },
setup() { setup() {
const tabList = reactive([ const tabList = reactive([
@ -47,15 +70,25 @@
value: '基地3', value: '基地3',
}, },
]) ])
const visualizationStore = useVisualizationStore()
const currentTab = ref<String>('0') const currentTab = ref<String>('0')
const chartRef = ref<HTMLDivElement | null>(null) const chartRef = ref<HTMLDivElement | null>(null)
const changeTab = (key: String) => { const currentTabValue = computed(() => tabList.find((e) => e.key == currentTab.value)?.value)
async function getDevice() {
await getDeviceBaseDataStatics({
base_id: visualizationStore.getAddresId,
// device_type,
})
}
function onMenuClick({ key }) {
if (currentTab.value == key) return if (currentTab.value == key) return
currentTab.value = key currentTab.value = key
} }
onBeforeMount(() => {})
onMounted(() => {}) onMounted(() => {})
@ -63,7 +96,8 @@
tabList, tabList,
currentTab, currentTab,
chartRef, chartRef,
changeTab, currentTabValue,
onMenuClick,
} }
}, },
}) })

View File

@ -5,19 +5,30 @@
> >
历年产值趋势 历年产值趋势
</div> </div>
<div class="h-200px mt-30px" ref="chartRef"> 1 </div> <div class="h-220px mt-10px" ref="chartRef"> 1 </div>
</div> </div>
</template> </template>
<script setup lang="ts"> <script setup lang="ts">
import { Ref, ref, onMounted } from 'vue' import { Ref, ref, onMounted, reactive, watch } from 'vue'
import { useECharts } from '/@/hooks/web/useECharts' import { useECharts } from '/@/hooks/web/useECharts'
import { getCropYieldTotalChart } from '/@/api/sys/other'
import echarts from '/@/utils/lib/echarts' import echarts from '/@/utils/lib/echarts'
import { useVisualizationStore } from '/@/store/modules/visualization'
const chartRef = ref<HTMLDivElement | null>(null) const chartRef = ref<HTMLDivElement | null>(null)
const Data = reactive({
list: [] as any,
})
const { setOptions } = useECharts(chartRef as Ref<HTMLDivElement>) const { setOptions } = useECharts(chartRef as Ref<HTMLDivElement>)
onMounted(() => {
const visualizationStore = useVisualizationStore()
function chatInit() {
setOptions({ setOptions({
grid: { left: '2%', right: '2%', top: '4%', bottom: '2%', containLabel: true }, grid: { left: '2%', right: '2%', top: '10%', bottom: '2%', containLabel: true },
tooltip: { tooltip: {
trigger: 'axis', trigger: 'axis',
axisPointer: { axisPointer: {
@ -29,7 +40,7 @@
}, },
xAxis: { xAxis: {
type: 'category', type: 'category',
data: [...new Array(10)].map((_item, index) => `${index + 6}:00`), data: Data.list?.map((e) => e.x) ?? [],
axisTick: { axisTick: {
show: false, show: false,
}, },
@ -60,7 +71,7 @@
], ],
series: [ series: [
{ {
data: [11, 22, 40, 18, 3, 55, 66, 33, 14, 30], data: Data.list?.map((e) => e.y) ?? [],
type: 'bar', type: 'bar',
label: { label: {
show: true, show: true,
@ -82,6 +93,32 @@
}, },
], ],
}) })
}
async function getData() {
const { list } = await getCropYieldTotalChart({ base_id: visualizationStore.getAddresId })
const arr = [] as { x: string | number; y: string | number }[]
for (const key in list) {
if (Object.prototype.hasOwnProperty.call(list, key)) {
arr.push({
y: list[key],
x: key,
})
}
}
Data.list = arr
chatInit()
}
watch(
() => visualizationStore.getAddresId,
() => {
getData()
},
)
onMounted(() => {
getData()
}) })
</script> </script>

View File

@ -147,8 +147,7 @@
for (const key in list) { for (const key in list) {
if (Object.prototype.hasOwnProperty.call(list, key)) { if (Object.prototype.hasOwnProperty.call(list, key)) {
arr.push({ arr.push({
// value: list[key], value: list[key],
value: parseInt(Math.random() * 100),
name: key, name: key,
}) })
} }

View File

@ -1,5 +1,19 @@
<template> <template>
<Box title="气象数据"> <Box title="气象数据">
<template #right>
<div class="w-250px flex justify-end">
<a-tabs
:tabBarGutter="14"
v-model:activeKey="activeKey"
:tab-position="mode"
:style="{ height: '48px', color: 'white' }"
@tabScroll="callback"
color="red"
>
<a-tab-pane v-for="i in 10" :key="i" :tab="`Tab-${i}`" />
</a-tabs>
</div>
</template>
<div class="pl-23px py-23px"> <div class="pl-23px py-23px">
<div class="grid grid-cols-3 gap-20px"> <div class="grid grid-cols-3 gap-20px">
<div v-for="item in 6" :key="item"> <div v-for="item in 6" :key="item">
@ -17,17 +31,68 @@
</template> </template>
<script lang="ts"> <script lang="ts">
import { defineComponent } from 'vue' import { defineComponent, ref } from 'vue'
import type { TabsProps } from 'ant-design-vue'
import Box from './Box.vue' import Box from './Box.vue'
import { Tabs, TabPane } from 'ant-design-vue'
export default defineComponent({ export default defineComponent({
components: { components: {
Box, Box,
[Tabs.name]: Tabs,
[TabPane.name]: TabPane,
}, },
setup() { setup() {
return {} const mode = ref<TabsProps['tabPosition']>('top')
const activeKey = ref(1)
const callback: TabsProps['onTabScroll'] = (val) => {
console.log(val)
}
return {
mode,
callback,
activeKey,
}
}, },
}) })
</script> </script>
<style scoped></style> <style scoped lang="less">
::v-deep(.ant-tabs-nav) {
&::before {
border: none;
}
.ant-tabs-ink-bar {
@apply bg-[#76E9F0];
}
.ant-tabs-tab {
&:hover {
@apply text-[#76E9F0];
}
}
.ant-tabs-tab-active {
.ant-tabs-tab-btn {
@apply text-[#76E9F0];
}
}
}
</style>
<style>
.ant-tabs-dropdown {
/* background: red; */
}
.ant-tabs-dropdown-menu {
border: 1px solid #396684;
background: rgba(28, 44, 52, 0.9);
}
.ant-tabs-dropdown-menu-item {
color: white;
}
</style>

View File

@ -1,17 +1,35 @@
<template> <template>
<Box title="监控"> <Box title="设备运行状态">
<div class="h-full flex flex-col"> <div class="h-full flex flex-col">
<div class="py-10px"> <div class="py-10px relative">
<ul class="flex items-center justify-center m-0"> <div
<li class="text-center bg-clip-text text-transparent bg-gradient-to-t from-[#76E9F0] to-[#A7E6EE] text-15px font-bold"
class="mx-11px text-white text-12px cursor-pointer" >
:class="{ active: currentTab == item.key }" {{ currentTabValue }}
@click="changeTab(item.key)" </div>
v-for="item in tabList" <div
:key="item.key" class="absolute right-18px top-1/2 transform -translate-y-1/2"
>{{ item.value }}</li v-if="tabList.length > 1"
>
<Dropdown
overlayClassName="dropdownClass"
placement="bottomRight"
trigger="click"
:style="{ height: '300px' }"
> >
</ul> <div class="cursor-pointer">
<span class="text-white text-12px">更多</span>
<DownOutlined :style="{ fontSize: '12px', color: '#FFF' }" />
</div>
<template #overlay>
<Menu @click="onMenuClick">
<menu-item v-for="item in tabList" :key="item.id">
<div>{{ item.name }}</div>
</menu-item>
</Menu>
</template>
</Dropdown>
</div>
</div> </div>
<div class="flex-1 px-30px grid grid-cols-2 gap-y-10px gap-x-90px pb-16px"> <div class="flex-1 px-30px grid grid-cols-2 gap-y-10px gap-x-90px pb-16px">
<div class="flex items-center" v-for="item in 4" :key="item"> <div class="flex items-center" v-for="item in 4" :key="item">
@ -40,46 +58,60 @@
</template> </template>
<script lang="ts"> <script lang="ts">
import { defineComponent, reactive, ref, Ref, onMounted } from 'vue' import { defineComponent, reactive, ref, onMounted, onBeforeMount, toRefs, computed } from 'vue'
import { SvgIcon } from '/@/components/Icon' import { SvgIcon } from '/@/components/Icon'
import Box from './Box.vue' import Box from './Box.vue'
import { getAgriculturalBasic } from '/@/api/sys/other'
import { useVisualizationStore } from '/@/store/modules/visualization'
import { Dropdown, Menu } from 'ant-design-vue'
import { DownOutlined } from '@ant-design/icons-vue'
export default defineComponent({ export default defineComponent({
components: { components: {
Box, Box,
SvgIcon, SvgIcon,
Dropdown,
Menu,
MenuItem: Menu.Item,
DownOutlined,
}, },
setup() { setup() {
const tabList = reactive([ const Data = reactive({
{ tabList: ref<any>([]),
key: '0', currentTab: ref<number | string>(''),
value: '基地1', })
},
{
key: '1',
value: '基地2',
},
{
key: '2',
value: '基地3',
},
])
const currentTab = ref<String>('0')
const chartRef = ref<HTMLDivElement | null>(null) const chartRef = ref<HTMLDivElement | null>(null)
const changeTab = (key: String) => { const visualizationStore = useVisualizationStore()
if (currentTab.value == key) return
currentTab.value = key const currentTabValue = computed(
() => Data.tabList.find((e) => e.id == Data.currentTab)?.name ?? '',
)
function onMenuClick({ key }) {
if (Data.currentTab == key) return
Data.currentTab = key
} }
onMounted(() => {}) async function getDevices() {
const resData = await getAgriculturalBasic({
parent_id: visualizationStore.getAddresId,
type: 1,
})
Data.tabList = resData
if (resData.length) Data.currentTab = resData[0].id
}
onBeforeMount(() => {})
onMounted(() => {
getDevices()
})
return { return {
tabList, ...toRefs(Data),
currentTab, currentTabValue,
chartRef, chartRef,
changeTab, onMenuClick,
} }
}, },
}) })