点击弹窗

new-map
ihzero 2023-05-15 22:46:57 +08:00
parent a246f09958
commit b46e7810a9
10 changed files with 627 additions and 7 deletions

View File

@ -160,6 +160,21 @@ export function getDeviceBaseDataStatics(params, mode: ErrorMessageMode = 'none'
},
)
}
/**
* @description:-+V2
*
*/
export function getDeviceBaseDataStaticsV2(params, mode: ErrorMessageMode = 'none') {
return defHttp.get(
{
url: '/api/device-base-data-statics-v2',
params,
},
{
errorMessageMode: mode,
},
)
}
/**
* @description:
*"1": "监控设备",
@ -264,6 +279,20 @@ export function getRiceShrimpPrice(params?, mode: ErrorMessageMode = 'none') {
},
)
}
/**
* @description: - -
*/
export function getRiceShrimpWeekPrice(params?, mode: ErrorMessageMode = 'none') {
return defHttp.get(
{
url: '/api/charts/rice-shrimp-weekly-price',
params,
},
{
errorMessageMode: mode,
},
)
}
/**
* @description:
*/

View File

@ -20,6 +20,7 @@
<DXCY v-if="leftType == 'DXCY'" width="810px" height="600px" />
<DXLX v-if="leftType == 'DXLX'" width="810px" height="600px" />
<DZWZ v-if="leftType == 'DZWZ'" width="810px" height="600px" />
<DXJGWEEK v-if="leftType == 'DXJG'" width="810px" height="600px" />
</div>
</a-modal>
</div>
@ -31,12 +32,14 @@
import DXCY from './components/DXCY.vue'
import DXLX from './components/DXLX.vue'
import DZWZ from './components/DZWZ.vue'
import DXJGWEEK from './components/DXJGWEEK.vue'
export default defineComponent({
components: {
[Modal.name]: Modal,
DXCY,
DZWZ,
DXLX,
DXJGWEEK,
},
props: {
visible: {

View File

@ -0,0 +1,207 @@
<template>
<div class="modelRef">
<a-modal
v-bind="getBindValue"
:bodyStyle="{ background: '#233741', color: '#fff' }"
destroyOnClose
:width="1250"
wrapClassName="cu-map-modal"
:getContainer="getContainer"
>
<template #closeIcon>
<img
class="w-22px h-22px inline text-0"
src="../../assets/images/model-close-icon.png"
alt=""
srcset=""
/>
</template>
<div class="w-full">
<div class="flex items-center justify-between px-14px relative flex-none">
<div
class="flex items-center bg-clip-text text-transparent bg-gradient-to-t from-[#76E9F0] to-[#A7E6EE]"
>
<span class="block w-8.5px h-8.5px rounded-full bg-[#6CCDDA]"></span>
<span class="ml-10.5px text-18px font-pmzd">{{ boxTitle }}</span>
</div>
<div class="absolute left-100px right-100px text-center">
<div
class="text-center bg-clip-text text-transparent bg-gradient-to-t from-[#76E9F0] to-[#A7E6EE] text-14px font-bold"
>{{ props.parmas.base_name }}</div
>
</div>
</div>
<div class="grid grid-cols-3 gap-3 mt-30px">
<div v-for="(item, i) in chartList" :key="i">
<LineChart :data="item" />
</div>
</div>
</div>
</a-modal>
</div>
</template>
<script lang="ts">
import { Modal } from 'ant-design-vue'
import { defineComponent, computed, ref, unref, watchEffect, watch } from 'vue'
import LineChart from './components/LineCharts.vue'
import { getDeviceBaseDataStaticsV2 } from '/@/api/sys/other'
const defaultList = {
2: [
{
key: 'temperature',
unit: ' ℃',
name: '温度',
},
{
key: 'conductivity',
unit: 'us/cm',
name: '电导率 ',
},
{
key: 'humidity',
unit: '%',
name: '湿度',
},
{
key: 'n',
unit: 'mg/kg',
name: '氮',
},
{
key: 'p',
unit: 'mg/kg',
name: '磷',
},
{
key: 'k',
unit: 'mg/kg',
name: '钾',
},
],
3: [
{
key: 'turbidity',
unit: 'NTU',
name: '浊度',
},
{
key: 'chlorine',
unit: 'mg/L',
name: '余氯',
},
{
key: 'ph',
unit: 'PH',
name: 'PH值',
},
{
key: 'temperature',
unit: '℃',
name: '温度',
},
{
key: 'oxygen',
unit: 'mg/L',
name: '溶解氧',
},
{
key: 'conductivity',
unit: 'uS/cm',
name: '电导率',
},
],
}
export default defineComponent({
components: {
[Modal.name]: Modal,
LineChart,
},
props: {
visible: {
type: Boolean,
},
parmas: {
type: Object,
default: () => ({}),
},
},
setup(props, { attrs }) {
const modelVisible = ref(false)
const chartList = ref([])
const currentList = computed(() => {
return defaultList[props.parmas.device_type]
})
const boxTitle = computed(() => {
return props.parmas.device_type == 3 ? '水质监测数据' : '土壤监测数'
})
const getContainer = () => {
if (document.body.clientWidth < 3000) return document.body
return document.body.querySelector(`.modelRef`)
}
const getBindValue = computed(() => {
const attr = {
...attrs,
...unref(props),
visible: unref(modelVisible),
maskClosable: false,
}
return attr
})
async function getData() {
const resData = await getDeviceBaseDataStaticsV2({
device_columns: props.parmas.desList,
base_id: props.parmas.base_id,
device_type: props.parmas.device_type,
})
const arr = []
for (const key in resData) {
arr.push({
key,
...(currentList.value.find((item) => item.key == key) ?? {}),
...resData[key],
})
}
chartList.value = arr
}
watchEffect(() => {
modelVisible.value = !!props.visible
})
watch(
() => props.visible,
(val) => {
if (val) {
getData()
}
},
)
return {
chartList,
boxTitle,
props,
getContainer,
getBindValue,
modelVisible,
}
},
})
</script>
<style lang="less">
.cu-map-modal {
.ant-modal {
top: 30px;
}
}
</style>

View File

@ -35,7 +35,7 @@
},
width: {
type: String as PropType<string>,
default: '200px',
default: '100%',
},
height: {
type: String as PropType<string>,

View File

@ -7,7 +7,16 @@
</template>
<script lang="ts">
import { defineComponent, reactive, ref, Ref, onBeforeMount, onBeforeUnmount, watch } from 'vue'
import {
defineComponent,
reactive,
ref,
Ref,
onBeforeMount,
onBeforeUnmount,
watch,
onMounted,
} from 'vue'
import Box from './Box.vue'
import { useECharts } from '/@/hooks/web/useECharts'
import { getRiceShrimpPrice } from '/@/api/sys/other'
@ -256,6 +265,14 @@
},
)
onMounted(() => {
getInstance()
?.getZr()
?.on('click', () => {
rootEmitter.emit('leftModel:click', 'DXJG')
})
})
return {
tabList,
currentTab,

View File

@ -0,0 +1,172 @@
<template>
<Box title="稻虾每周价格(元/斤)">
<div class="h-full flex flex-col">
<div class="flex-1" ref="chartRef"> </div>
<div class="text-right">
<Pagination
v-model:current="current"
v-model:pageSize="pageSize"
:total="52"
:showSizeChanger="false"
@change="changePage"
/>
</div>
</div>
</Box>
</template>
<script lang="ts">
import { defineComponent, reactive, ref, Ref, onBeforeMount } from 'vue'
import Box from './Box.vue'
import { useECharts } from '/@/hooks/web/useECharts'
import { getRiceShrimpWeekPrice } from '/@/api/sys/other'
import { chartLineColors } from './colors'
import { Pagination } from 'ant-design-vue'
export default defineComponent({
components: {
Box,
Pagination,
},
setup() {
const current = ref(1)
const pageSize = ref(10)
const Data = reactive({
x_axis: [],
series: [],
})
const chartRef = ref<HTMLDivElement | null>(null)
const { setOptions } = useECharts(chartRef as Ref<HTMLDivElement>)
function changePage(page: number) {
current.value = page
chartsInit()
}
// let legendData = [] as any
function formatChartData() {
const obj = {
legendData: [] as any,
series: [] as any,
}
Data.series.forEach(({ name, data }, index) => {
const color = chartLineColors[index % chartLineColors.length]
obj.legendData.push(name + '')
obj.series.push({
name: name,
data: data.slice((current.value - 1) * pageSize.value, current.value * pageSize.value),
type: 'line',
smooth: false,
itemStyle: {
color: color.itemColor,
},
areaStyle: {
color: color.areaColor,
},
})
})
// legendData = obj.legendData
return obj
}
const chartsInit = () => {
const obj = formatChartData()
setOptions({
grid: { left: '2%', right: '20px', top: '10%', bottom: '2%', containLabel: true },
legend: {
data: obj.legendData,
top: '0%',
right: '0',
textStyle: {
color: '#ffffff',
},
},
tooltip: {
trigger: 'axis',
axisPointer: {
lineStyle: {
width: 1,
color: '#019680',
},
},
},
xAxis: {
type: 'category',
data: Data.x_axis.slice(
(current.value - 1) * pageSize.value,
current.value * pageSize.value,
),
boundaryGap: false,
axisTick: {
show: false,
},
axisLine: {
show: false,
},
axisLabel: {
color: '#fff',
},
},
yAxis: [
{
type: 'value',
axisTick: {
show: false,
},
// min: 0,
nameTextStyle: {
color: '#fff',
},
splitLine: {
lineStyle: {
type: 'solid',
color: '#8EEEFF',
opacity: 0.3,
},
},
axisLabel: {
color: '#fff',
formatter: (e) => {
return e
},
},
},
],
series: obj.series,
animationDuration: 2000,
})
}
async function getData() {
const resData = await getRiceShrimpWeekPrice()
Data.x_axis = resData.x_axis
Data.series = resData.series
chartsInit()
}
onBeforeMount(() => {
getData()
})
return {
changePage,
chartRef,
current,
pageSize,
}
},
})
</script>
<style scoped lang="less">
.active {
@apply font-bold text-15px text-[#76E9F0];
}
</style>

View File

@ -0,0 +1,132 @@
<template>
<div class="bg-[#1D2D35] p-10px">
<div class="text-base">{{ props.data.name }}{{ props.data.unit }}</div>
<div ref="chartRef" class="w-full h-300px"></div>
</div>
</template>
<script lang="ts" setup>
import dayjs from 'dayjs'
import { Ref, ref, watch, reactive } from 'vue'
import { useECharts } from '/@/hooks/web/useECharts'
import { chartLineColors } from './colors'
const props = defineProps({
loading: Boolean,
data: {
type: Object as PropType<object>,
default: () => {},
},
})
const chartRef = ref<HTMLDivElement | null>(null)
const { setOptions } = useECharts(chartRef as Ref<HTMLDivElement>)
const Data = reactive({
x_axis: [],
series: [],
})
function formatChartData(otherData) {
const obj = {
legendData: [] as any,
series: [] as any,
}
otherData.series.forEach(({ name, data }, index) => {
const color = chartLineColors[index % chartLineColors.length]
obj.legendData.push(name + '')
obj.series.push({
name: name,
data: data,
type: 'line',
smooth: false,
itemStyle: {
color: color.itemColor,
},
areaStyle: {
color: color.areaColor,
},
})
})
return obj
}
watch(
() => props.data,
(e) => {
if (e) {
console.log(e)
console.log({
x_axis: e.x_axis,
series: e.series,
})
Data.x_axis = e.x_axis
Data.series = e.series
const obj = formatChartData({
x_axis: e.x_axis,
series: e.series,
})
setOptions({
grid: { left: '2%', right: '20px', top: '10%', bottom: '2%', containLabel: true },
legend: {
data: obj.legendData,
top: '0%',
right: '0',
textStyle: {
color: '#ffffff',
},
},
tooltip: {
trigger: 'axis',
axisPointer: {
lineStyle: {
width: 1,
color: '#019680',
},
},
},
xAxis: {
type: 'category',
data: Data.x_axis.map((item) => dayjs(item).format('HH:mm')),
axisTick: {
show: false,
},
axisLine: {
show: false,
},
},
yAxis: [
{
type: 'value',
axisTick: {
show: false,
},
splitLine: {
lineStyle: {
type: 'dashed',
},
},
},
],
series: obj.series,
// dataZoom: [
// {
// type: 'inside', //sliderinside
// show: false,
// xAxisIndex: 0,
// },
// ],
})
}
},
{
immediate: true,
},
)
</script>
<style scoped></style>

View File

@ -49,7 +49,16 @@
</template>
<script lang="ts">
import { defineComponent, reactive, ref, Ref, onBeforeMount, computed, toRefs } from 'vue'
import {
defineComponent,
reactive,
ref,
Ref,
onBeforeMount,
computed,
toRefs,
onMounted,
} from 'vue'
import Box from './Box.vue'
import { useECharts } from '/@/hooks/web/useECharts'
import { getAgriculturalDeviceBasic, getDeviceBaseDataStatics } from '/@/api/sys/other'
@ -115,7 +124,7 @@
const chartRef = ref<HTMLDivElement | null>(null)
const { setOptions } = useECharts(chartRef as Ref<HTMLDivElement>)
const { setOptions, getInstance } = useECharts(chartRef as Ref<HTMLDivElement>)
const currentTabValue = computed(
() => Data.tabList.find((e) => e.id == Data.currentTab)?.name ?? '',
@ -284,6 +293,19 @@
})
}
onMounted(() => {
getInstance()
?.getZr()
?.on('click', () => {
rootEmitter.emit('rightModel:click', {
base_id: props.baseId ?? Data.currentTab,
device_type: 3,
desList: desList.map(({ key }) => key).join(','),
baseName: currentTabValue.value,
})
})
})
return {
currentMenuObj,
...toRefs(Data),

View File

@ -49,7 +49,16 @@
</template>
<script lang="ts">
import { defineComponent, reactive, ref, Ref, onBeforeMount, computed, toRefs } from 'vue'
import {
defineComponent,
reactive,
ref,
Ref,
onBeforeMount,
computed,
toRefs,
onMounted,
} from 'vue'
import Box from './Box.vue'
import { useECharts } from '/@/hooks/web/useECharts'
import { getAgriculturalDeviceBasic, getDeviceBaseDataStatics } from '/@/api/sys/other'
@ -115,7 +124,7 @@
const chartRef = ref<HTMLDivElement | null>(null)
const { setOptions } = useECharts(chartRef as Ref<HTMLDivElement>)
const { setOptions, getInstance } = useECharts(chartRef as Ref<HTMLDivElement>)
const currentTabValue = computed(
() => Data.tabList.find((e) => e.id == Data.currentTab)?.name ?? '',
@ -280,6 +289,19 @@
})
}
onMounted(() => {
getInstance()
?.getZr()
?.on('click', () => {
rootEmitter.emit('rightModel:click', {
base_id: props.baseId ?? Data.currentTab,
device_type: 2,
desList: desList.map(({ key }) => key).join(','),
baseName: currentTabValue.value,
})
})
})
return {
...toRefs(Data),
currentTabValue,

View File

@ -33,7 +33,7 @@
</div>
<div class="flex">
<div class="mr-10px">
<!-- <JK :width="`${addW + 440}px`" height="390px" /> -->
<JK :width="`${addW + 440}px`" height="390px" />
<SBYXZT class="mt-10px" :width="`${addW + 440}px`" height="314px" />
</div>
<div class="">
@ -53,6 +53,7 @@
:baseData="baseData"
/>
<LeftModal v-model:visible="leftMapModal" :footer="null" :type="leftType" />
<RightModal v-model:visible="rightMapModal" :footer="null" :parmas="rightParmas" />
<!-- </div> -->
</ScaleScreen>
</template>
@ -86,6 +87,7 @@
import { Modal } from 'ant-design-vue'
import MapModal from './MapModal.vue'
import LeftModal from './LeftModal.vue'
import RightModal from './RightModal.vue'
import { createVContext } from './useVContext'
import mitt from '/@/utils/mitt'
import Build from './components/cavas'
@ -119,6 +121,7 @@
Footer,
MapModal,
LeftModal,
RightModal,
},
setup() {
const cavsRef = ref<HTMLDivElement | null>(null)
@ -131,6 +134,8 @@
leftType: '',
})
const rightParmas = reactive({})
const addW = computed(() => (isScroll.value ? 10 : 0))
async function getWarning() {
@ -192,6 +197,7 @@
const visibleMapModal = ref<boolean>(false)
const leftMapModal = ref<boolean>(false)
const rightMapModal = ref<boolean>(false)
onMounted(() => {
updateSize()
@ -212,6 +218,14 @@
obj.leftType = e
leftMapModal.value = true
})
vEmitter.on('rightModel:click', (e) => {
rightParmas.base_id = e.base_id
rightParmas.desList = e.desList
rightParmas.device_type = e.device_type
rightParmas.base_name = e.baseName
rightMapModal.value = true
})
vEmitter.on('map:click', () => {
// visibleMapModal.value = true
})
@ -229,12 +243,14 @@
})
return {
rightParmas,
cavsRef,
...toRefs(obj),
addW,
isScroll,
visibleMapModal,
leftMapModal,
rightMapModal,
}
},
})