提交 8b340651 作者: 王定

合并分支

import { weatherHttp } from '/@/utils/http/axios'
import { otherHttp, weatherHttp } from '/@/utils/http/axios'
const API_KEY = '4fb5c9e814994516b6522419651f2e9e'
......@@ -22,3 +22,25 @@ export function alarm(location: string) {
url: `/weatheralert/v1/current/${location.replace(',', '/')}?key=${API_KEY}`,
})
}
// 格点天气预报-日值(降雨、大风用)
export function gridForecastDaily(location: string, day = 3) {
return weatherHttp.get({
url: `/v7/weather/${day}d?key=${API_KEY}&location=${location}`,
})
}
// 格点天气预报-小时值(温度用)
export function gridForecastHourly(location: string) {
return weatherHttp.get({
url: `/v7/weather/24h?key=${API_KEY}&location=${location}`,
})
}
// 强对流预报(自建接口)
export function severeForecast(lon: string, lat: string) {
return otherHttp.get({
url: '/weather/forecast',
params: { lon, lat },
}, { isTransformResponse: false })
}
......@@ -13,17 +13,17 @@ export default {
},
methods: {
loadLibs: loadEchartsLibs,
init() {
init(notMerge) {
// 如果已经初始化过了,就直接更新配置项
if (this.chart && this.chart.setOption) {
this.chart.setOption(this.option)
this.chart.setOption(this.option, { notMerge: notMerge || false })
return
}
// 初始化组件
const chart = window.echarts.init(document.getElementById(this.option.id))
// 设置图表配置项
chart.setOption(this.option)
chart.setOption(this.option, { notMerge: notMerge || false })
this.chart = chart
},
changeOption(option) {
......@@ -45,12 +45,20 @@ export default {
}
}
this.option = merge(this.option, option)
const notMerge = option.__notMerge
// 清除内部标记
delete option.__notMerge
if (notMerge) {
this.option = option
} else {
this.option = merge(this.option, option)
}
if (typeof window.echarts === 'object' && typeof window.echarts.init === 'function') {
this.init()
this.init(notMerge)
} else {
this.loadLibs().then(() => {
this.init()
this.init(notMerge)
})
}
},
......
......@@ -44,10 +44,10 @@ export function useEcharts<T extends EchartsInstance, P extends EChartsOption>(
return [
register,
{
setOption: (option: Partial<P>): Promise<void> => {
setOption: (option: Partial<P>, opts?: { notMerge?: boolean; lazyUpdate?: boolean }): Promise<void> => {
return new Promise((resolve) => {
tryOnMounted(() => {
getInstance()?.setOption(option)
getInstance()?.setOption(option, opts)
resolve()
})
})
......
......@@ -14,7 +14,7 @@
this.$emit('register', this)
},
methods: {
setOption(option) {
setOption(option, opts) {
// 处理tooltip formatter函数序列化
if (option.tooltip && typeof option.tooltip.formatter === 'function') {
// 将函数转换为字符串,在视图层重新构建
......@@ -25,6 +25,11 @@
id: this.id,
...option,
}
// 保存 opts 供 renderjs 层使用
if (opts?.notMerge !== undefined) {
this.option.__notMerge = opts.notMerge
}
},
},
}
......
<!-- 天气折线图弹窗 -->
<script setup lang="ts">
import dayjs from 'dayjs'
import { Echarts, useEcharts } from '@/components/Echarts'
import * as WeatherAPI from '@/api/model/weather'
const props = defineProps<{
visible: boolean
type: 'rain' | 'temp' | 'wind' | 'severe'
lon: string | number
lat: string | number
}>()
const emit = defineEmits(['close'])
const [register, chart] = useEcharts()
// 标题映射
const titleMap = {
rain: '降雨预报',
temp: '温度预报',
wind: '大风预报',
severe: '强对流预报',
}
// Y 轴单位映射
const unitMap = {
rain: 'mm',
temp: '°C',
wind: 'km/h',
severe: '',
}
// 加载状态
const loading = ref(false)
const errorMsg = ref('')
const updateText = ref('')
// 请求序号,用于取消旧请求
let requestSeq = 0
// 监听 visible/type/lon/lat 变化,拉取数据
watch(
() => [props.visible, props.type, props.lon, props.lat] as const,
async ([visible]) => {
if (!visible) {
return
}
if (!props.lon || !props.lat) {
errorMsg.value = '未设置农场坐标位置'
return
}
await fetchWeatherData()
},
{ immediate: true },
)
async function fetchWeatherData() {
const seq = ++requestSeq
loading.value = true
errorMsg.value = ''
try {
let data: any
switch (props.type) {
case 'rain':
data = await WeatherAPI.gridForecastDaily(`${props.lon},${props.lat}`, 7)
if (seq !== requestSeq) return
await nextTick()
renderRainChart(data.data)
break
case 'temp':
data = await WeatherAPI.gridForecastDaily(`${props.lon},${props.lat}`, 7)
if (seq !== requestSeq) return
await nextTick()
renderTempChart(data.data)
break
case 'wind':
data = await WeatherAPI.gridForecastDaily(`${props.lon},${props.lat}`, 7)
if (seq !== requestSeq) return
await nextTick()
renderWindChart(data.data)
break
case 'severe':
data = await WeatherAPI.severeForecast(String(props.lon), String(props.lat))
if (seq !== requestSeq) return
await nextTick()
renderSevereChart(data)
break
}
updateText.value = `数据更新时间: ${dayjs().format('YYYY-MM-DD HH:mm')}`
} catch (e: any) {
console.error('获取天气数据失败:', e)
// 如果在此期间有新请求,不覆盖其错误状态
if (seq !== requestSeq) {
return
}
errorMsg.value = '数据加载失败'
} finally {
loading.value = false
}
}
// 渲染空图表
function renderEmptyChart(hint?: string) {
chart.setOption(
{
title: { show: false },
tooltip: { show: false },
grid: { top: 60, right: 30, bottom: 40, left: 60 },
xAxis: { type: 'category', data: [], show: false },
yAxis: { type: 'value', show: false },
series: [],
graphic: {
type: 'text',
left: 'center',
top: 'middle',
style: {
text: hint || '暂无数据',
fontSize: 16,
fill: '#bbb',
},
},
},
{ notMerge: true },
)
}
function renderRainChart(data: any) {
if (!data?.daily || !Array.isArray(data.daily)) {
renderEmptyChart('暂无预报数据')
return
}
const dates = data.daily.map((d: any) => dayjs(d.fxDate).format('MM-DD'))
const precip = data.daily.map((d: any) => Number.parseFloat(d.precip) || 0)
chart.setOption(
{
title: { show: false },
tooltip: { trigger: 'axis' },
legend: {
top: 0,
textStyle: { fontSize: 14, color: '#333' },
},
grid: { top: 60, right: 30, bottom: 40, left: 60 },
xAxis: {
type: 'category',
data: dates,
axisLabel: { fontSize: 14, color: '#bbb', margin: 10 },
axisLine: { lineStyle: { color: '#eee' } },
axisTick: { show: false },
},
yAxis: {
type: 'value',
name: '(mm)',
nameTextStyle: { fontSize: 14, color: '#bbb', padding: [0, 0, 0, -10] },
axisLabel: { fontSize: 14, color: '#bbb' },
axisLine: { show: false },
axisTick: { show: false },
splitLine: { lineStyle: { type: 'dashed', color: '#eee', width: 1 } },
},
series: [
{
name: '降水量',
type: 'line',
data: precip,
smooth: true,
showSymbol: true,
symbolSize: 6,
itemStyle: { color: '#6db876' },
label: {
show: true,
position: 'top',
fontSize: 12,
color: '#666',
},
lineStyle: { color: '#6db876', width: 2 },
areaStyle: {
color: {
type: 'linear',
x: 0,
y: 0,
x2: 0,
y2: 1,
colorStops: [
{ offset: 0, color: 'rgba(109,184,118,0.3)' },
{ offset: 1, color: 'rgba(109,184,118,0)' },
],
},
},
},
],
},
{ notMerge: true },
)
}
function renderTempChart(data: any) {
if (!data?.daily || !Array.isArray(data.daily)) {
renderEmptyChart('暂无预报数据')
return
}
const dates = data.daily.map((d: any) => dayjs(d.fxDate).format('MM-DD'))
const tempMax = data.daily.map((d: any) => Number.parseFloat(d.tempMax) || 0)
const tempMin = data.daily.map((d: any) => Number.parseFloat(d.tempMin) || 0)
chart.setOption(
{
title: { show: false },
tooltip: { trigger: 'axis' },
legend: {
top: 0,
textStyle: { fontSize: 14, color: '#333' },
},
grid: { top: 60, right: 30, bottom: 40, left: 60 },
xAxis: {
type: 'category',
data: dates,
axisLabel: { fontSize: 14, color: '#bbb', margin: 10 },
axisLine: { lineStyle: { color: '#eee' } },
axisTick: { show: false },
},
yAxis: {
type: 'value',
name: '(°C)',
nameTextStyle: { fontSize: 14, color: '#bbb', padding: [0, 0, 0, -10] },
axisLabel: { fontSize: 14, color: '#bbb' },
axisLine: { show: false },
axisTick: { show: false },
splitLine: { lineStyle: { type: 'dashed', color: '#eee', width: 1 } },
},
series: [
{
name: '最高温度',
type: 'line',
data: tempMax,
smooth: true,
showSymbol: true,
symbolSize: 6,
itemStyle: { color: '#e74c3c' },
label: {
show: true,
position: 'top',
fontSize: 12,
color: '#666',
},
lineStyle: { color: '#e74c3c', width: 2 },
areaStyle: {
color: {
type: 'linear',
x: 0,
y: 0,
x2: 0,
y2: 1,
colorStops: [
{ offset: 0, color: 'rgba(231,76,60,0.3)' },
{ offset: 1, color: 'rgba(231,76,60,0)' },
],
},
},
},
{
name: '最低温度',
type: 'line',
data: tempMin,
smooth: true,
showSymbol: true,
symbolSize: 6,
itemStyle: { color: '#3498db' },
label: {
show: true,
position: 'bottom',
fontSize: 12,
color: '#666',
},
lineStyle: { color: '#3498db', width: 2 },
areaStyle: {
color: {
type: 'linear',
x: 0,
y: 0,
x2: 0,
y2: 1,
colorStops: [
{ offset: 0, color: 'rgba(52,152,219,0.2)' },
{ offset: 1, color: 'rgba(52,152,219,0)' },
],
},
},
},
],
},
{ notMerge: true },
)
}
function renderWindChart(data: any) {
if (!data?.daily || !Array.isArray(data.daily)) {
renderEmptyChart('暂无预报数据')
return
}
const dates = data.daily.map((d: any) => dayjs(d.fxDate).format('MM-DD'))
const windDay = data.daily.map((d: any) => Number.parseFloat(d.windSpeedDay) || 0)
const windNight = data.daily.map((d: any) => Number.parseFloat(d.windSpeedNight) || 0)
chart.setOption(
{
title: { show: false },
tooltip: { trigger: 'axis' },
legend: {
top: 0,
textStyle: { fontSize: 14, color: '#333' },
},
grid: { top: 60, right: 30, bottom: 40, left: 60 },
xAxis: {
type: 'category',
data: dates,
axisLabel: { fontSize: 14, color: '#bbb', margin: 10 },
axisLine: { lineStyle: { color: '#eee' } },
axisTick: { show: false },
},
yAxis: {
type: 'value',
name: '(km/h)',
nameTextStyle: { fontSize: 14, color: '#bbb', padding: [0, 0, 0, -10] },
axisLabel: { fontSize: 14, color: '#bbb' },
axisLine: { show: false },
axisTick: { show: false },
splitLine: { lineStyle: { type: 'dashed', color: '#eee', width: 1 } },
},
series: [
{
name: '白天风速',
type: 'line',
data: windDay,
smooth: true,
showSymbol: true,
symbolSize: 6,
itemStyle: { color: '#e67e22' },
label: {
show: true,
position: 'top',
fontSize: 12,
color: '#666',
},
lineStyle: { color: '#e67e22', width: 2 },
areaStyle: {
color: {
type: 'linear',
x: 0,
y: 0,
x2: 0,
y2: 1,
colorStops: [
{ offset: 0, color: 'rgba(230,126,34,0.3)' },
{ offset: 1, color: 'rgba(230,126,34,0)' },
],
},
},
},
{
name: '夜间风速',
type: 'line',
data: windNight,
smooth: true,
showSymbol: true,
symbolSize: 6,
itemStyle: { color: '#3498db' },
label: {
show: true,
position: 'bottom',
fontSize: 12,
color: '#666',
},
lineStyle: { color: '#3498db', width: 2 },
areaStyle: {
color: {
type: 'linear',
x: 0,
y: 0,
x2: 0,
y2: 1,
colorStops: [
{ offset: 0, color: 'rgba(52,152,219,0.2)' },
{ offset: 1, color: 'rgba(52,152,219,0)' },
],
},
},
},
],
},
{ notMerge: true },
)
}
function renderSevereChart(data: any) {
if (!data?.elements || !Array.isArray(data.elements) || data.elements.length === 0) {
renderEmptyChart('暂无预报数据')
return
}
const elements = data.elements
// 从第一个要素提取时间轴
const firstElement = elements[0]
if (
!firstElement?.timeDataList ||
!Array.isArray(firstElement.timeDataList) ||
firstElement.timeDataList.length === 0
) {
renderEmptyChart('暂无预报数据')
return
}
const times = firstElement.timeDataList.map((d: any) => dayjs(d.forecastTime).format('HH:mm'))
const colors = ['#e74c3c', '#3498db', '#f39c12']
const series = elements.map((el: any, idx: number) => ({
name: el.name,
type: 'line',
data: el.timeDataList.map((d: any) => d.value || 0),
smooth: true,
showSymbol: true,
symbolSize: 6,
itemStyle: { color: colors[idx % colors.length] },
label: {
show: true,
position: 'top',
fontSize: 12,
color: '#666',
},
lineStyle: { color: colors[idx % colors.length], width: 2 },
areaStyle: {
color: {
type: 'linear',
x: 0,
y: 0,
x2: 0,
y2: 1,
colorStops: [
{ offset: 0, color: `${colors[idx % colors.length]}4D` },
{ offset: 1, color: `${colors[idx % colors.length]}00` },
],
},
},
}))
// Y 轴单位:取第一个要素的单位
const unit = elements[0]?.timeDataList?.[0]?.unit || ''
chart.setOption(
{
title: { show: false },
tooltip: { trigger: 'axis' },
legend: {
top: 0,
textStyle: { fontSize: 14, color: '#333' },
},
grid: { top: 60, right: 30, bottom: 40, left: 60 },
xAxis: {
type: 'category',
data: times,
axisLabel: { fontSize: 14, color: '#bbb', margin: 10 },
axisLine: { lineStyle: { color: '#eee' } },
axisTick: { show: false },
},
yAxis: {
type: 'value',
name: `(${unit})`,
nameTextStyle: { fontSize: 14, color: '#bbb', padding: [0, 0, 0, -10] },
axisLabel: { fontSize: 14, color: '#bbb' },
axisLine: { show: false },
axisTick: { show: false },
splitLine: { lineStyle: { type: 'dashed', color: '#eee', width: 1 } },
},
series,
},
{ notMerge: true },
)
}
</script>
<template>
<view v-show="visible" class="weather-chart-overlay" @tap="emit('close')">
<view class="chart-popup" @tap.stop>
<!-- 标题栏 -->
<view class="popup-header">
<text class="popup-title">{{ titleMap[type] }}</text>
<view class="close-btn" @tap="emit('close')">
<text class="close-icon">×</text>
</view>
</view>
<!-- 加载/错误状态 -->
<view v-if="loading" class="chart-status">
<text>加载中...</text>
</view>
<view v-else-if="errorMsg" class="chart-status error">
<text>{{ errorMsg }}</text>
<view class="retry-btn" @tap="fetchWeatherData">
<text>重试</text>
</view>
</view>
<!-- 图表区域 -->
<view v-show="!loading && !errorMsg" class="chart-container">
<Echarts @register="register" class="chart-area" />
</view>
<!-- 更新时间 -->
<view v-if="updateText && !loading && !errorMsg" class="update-info">
<text class="update-text">{{ updateText }}</text>
</view>
</view>
</view>
</template>
<style lang="scss" scoped>
.weather-chart-overlay {
position: fixed;
top: 0;
left: 0;
right: 0;
bottom: 0;
z-index: 998;
display: flex;
align-items: center;
justify-content: center;
background-color: rgba(0, 0, 0, 0.3);
}
.chart-popup {
width: 90%;
max-width: 600px;
background: linear-gradient(180deg, rgba(200, 255, 200, 1) 0%, rgba(255, 255, 255, 1) 40%);
border-radius: 32rpx;
position: relative;
overflow: hidden;
transform: translateY(-40%);
}
.popup-header {
display: flex;
align-items: center;
justify-content: space-between;
padding: 10rpx 30rpx 10rpx;
.popup-title {
font-size: 36rpx;
font-weight: 600;
color: #333;
}
.close-btn {
width: 60rpx;
height: 60rpx;
display: flex;
align-items: center;
justify-content: center;
&:active {
opacity: 0.6;
}
.close-icon {
font-size: 36rpx;
color: #ccc;
font-weight: 300;
}
}
}
.chart-status {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
height: 400rpx;
font-size: 28rpx;
color: #999;
&.error {
color: #e74c3c;
}
}
.retry-btn {
margin-top: 20rpx;
padding: 16rpx 40rpx;
background-color: #5db66f;
color: #fff;
border-radius: 32rpx;
font-size: 26rpx;
&:active {
opacity: 0.8;
}
}
.chart-container {
width: 100%;
height: 350rpx;
}
.chart-area {
width: 100%;
height: 100%;
}
.update-info {
padding: 0 30rpx 20rpx;
text-align: center;
.update-text {
font-size: 20rpx;
color: #bbb;
}
}
</style>
......@@ -16,6 +16,7 @@
import { ToolBoxWidget, useToolBoxWidget } from '@/components/Map/Widgets/ToolBox'
import * as NongchangAPI from '@/api/model/nongchang'
import * as farmbaseApi from '@/api/model/farmbase'
import WeatherChartPopup from './components/WeatherChartPopup.vue'
// 页面参数
const page = reactive<Page>({
......@@ -64,7 +65,11 @@
farmbaseInfo: {},
farmbaseInfoList: [],
deviceTypeCount: [],
activeWeatherType: '' as '' | 'rain' | 'temp' | 'wind' | 'severe',
})
// 当前基地中心经纬度(用于天气接口请求)
const baseCenterLonLat = ref<[number, number] | null>(null)
onLoad(() => {
const today = dayjs()
for (let i = 0; i < 5; i++) {
......@@ -91,6 +96,51 @@
farmbaseApi.getFarmbaseInfoById({ id }).then((res) => {
model.farmbaseInfo = res
getDeviceTypeCount()
<<<<<<< HEAD
=======
// 切换基地后,将地图视角飞到当前基地上方
let geojson = res.geojson
if (typeof geojson === 'string') {
try {
geojson = JSON.parse(geojson)
} catch (e) {
geojson = null
}
}
if (geojson) {
// 直接从 geometry 坐标计算中心点和缩放范围
const coords = geojson.features?.[0]?.geometry?.coordinates?.[0]
if (coords && coords.length > 0) {
let minLon = Infinity, minLat = Infinity, maxLon = -Infinity, maxLat = -Infinity
for (const c of coords) {
if (c[0] < minLon) minLon = c[0]
if (c[0] > maxLon) maxLon = c[0]
if (c[1] < minLat) minLat = c[1]
if (c[1] > maxLat) maxLat = c[1]
}
const center: [number, number] = [(minLon + maxLon) / 2, (minLat + maxLat) / 2]
// 存储基地中心经纬度,供天气接口使用
baseCenterLonLat.value = center
// 使用 flyTo 而非 fitBounds,避免 maxBounds 约束干扰
map.flyTo({
center,
zoom: 15,
duration: 1000,
})
}
} else if (res.longitude && res.latitude) {
const center: [number, number] = [Number(res.longitude), Number(res.latitude)]
baseCenterLonLat.value = center
map.flyTo({
center,
zoom: 15,
duration: 1000,
})
} else {
console.warn('切换基地: 既没有geojson也没有经纬度')
}
>>>>>>> origin/dev
})
}
......@@ -183,6 +233,7 @@
},
),
]
<<<<<<< HEAD
addDefaultGeoJSONSource(map, `${page.id}-plot`, model.plots)
addDefaultSplotLayer(map, `${page.id}-plot`, {
paint: {
......@@ -203,6 +254,142 @@
'line-width': 2,
},
})
=======
// 为每个基地创建独立的 source 和 layer
for (let i = 0; i < farmbaseRecords.length; i++) {
const base = farmbaseRecords[i]
let geojson = base.geojson
// geojson 可能是字符串,需要解析
if (typeof geojson === 'string') {
try {
geojson = JSON.parse(geojson)
} catch (e) {
console.error(`解析基地 ${base.baseName} geojson 失败:`, e)
continue
}
}
if (!geojson) continue
// 为当前基地分配颜色
const color = colorPool[i % colorPool.length]
const sourceId = `${page.id}-base-plot-${base.id}`
const fillLayerId = `${sourceId}-fill`
const lineLayerId = `${sourceId}-line`
const labelLayerId = `${sourceId}-label`
// 处理 geojson,注入基地名称属性
const features = geojson.features ? geojson.features : [geojson]
for (const feature of features) {
feature.properties = feature.properties || {}
feature.properties.baseName = base.baseName
}
// 添加 source
addDefaultGeoJSONSource(map, sourceId, features)
// 添加填充层(直接创建,不使用 addDefaultSplotLayer)
map.addLayer({
type: 'fill',
id: fillLayerId,
source: sourceId,
paint: {
'fill-color': color.fill,
'fill-opacity': 0.5,
'fill-outline-color': color.line,
},
})
// 添加边框层
map.addLayer({
type: 'line',
id: lineLayerId,
source: sourceId,
layout: {
'line-join': 'round',
'line-cap': 'round',
},
paint: {
'line-color': color.line,
'line-width': 3,
},
})
// 添加基地名称文字标签
map.addLayer({
type: 'symbol',
id: labelLayerId,
source: sourceId,
layout: {
'text-field': ['get', 'baseName'],
'text-size': 14,
'text-anchor': 'center',
'text-offset': [0, 0],
'text-allow-overlap': true,
},
paint: {
'text-color': '#ffffff',
'text-halo-color': color.line,
'text-halo-width': 2,
},
})
}
// 将地图视角飞到第一个基地的上方
if (farmbaseRecords.length > 0) {
const firstBase = farmbaseRecords[0]
model.farmbaseInfo = firstBase
let firstGeojson = firstBase.geojson
if (typeof firstGeojson === 'string') {
try {
firstGeojson = JSON.parse(firstGeojson)
} catch (e) {
firstGeojson = null
}
}
if (firstGeojson) {
const coords = firstGeojson.features?.[0]?.geometry?.coordinates?.[0]
if (coords && coords.length > 0) {
let minLon = Infinity, minLat = Infinity, maxLon = -Infinity, maxLat = -Infinity
for (const c of coords) {
if (c[0] < minLon) minLon = c[0]
if (c[0] > maxLon) maxLon = c[0]
if (c[1] < minLat) minLat = c[1]
if (c[1] > maxLat) maxLat = c[1]
}
const center: [number, number] = [(minLon + maxLon) / 2, (minLat + maxLat) / 2]
baseCenterLonLat.value = center
map.flyTo({
center,
zoom: 15,
duration: 0,
})
}
} else if (firstBase.longitude && firstBase.latitude) {
const center: [number, number] = [Number(firstBase.longitude), Number(firstBase.latitude)]
baseCenterLonLat.value = center
map.flyTo({
center,
zoom: 15,
duration: 0,
})
}
}
getDeviceTypeCount()
// 如果农场没有 geojson 但有坐标,则使用坐标定位
if (!farmGeojson && item.longitude && item.latitude) {
model.lonlat = `${item.longitude},${item.latitude}`
} else if (!farmGeojson && !item.longitude) {
model.lonlat = '111.024108, 29.554847'
Message.toast('未设置农场坐标位置,已使用模拟位置数据')
}
// 渲染设备数据
>>>>>>> origin/dev
// 渲染设备数据
model.devices = [
......@@ -309,33 +496,33 @@ map.on('load','custom-image',()=>{
{
name: '降雨',
icon: '/static/images/codefun/rain.png',
type: 'button',
type: 'toggle' as const,
handle: () => {
Message.toast('暂无降雨数据')
onWeatherClick('rain')
},
},
{
name: '温度',
icon: '/static/images/codefun/temp.png',
type: 'button',
type: 'toggle' as const,
handle: () => {
Message.toast('暂无温度数据')
onWeatherClick('temp')
},
},
{
name: '强对流',
icon: '/static/images/codefun/severe.png',
type: 'button',
type: 'toggle' as const,
handle: () => {
Message.toast('暂无强对流数据')
onWeatherClick('severe')
},
},
{
name: '大风',
icon: '/static/images/codefun/wind.png',
type: 'button',
type: 'toggle' as const,
handle: () => {
Message.toast('暂无大风数据')
onWeatherClick('wind')
},
},
{
......@@ -377,6 +564,14 @@ map.on('load','custom-image',()=>{
},
})
}
// 天气按钮点击处理
function onWeatherClick(type: 'rain' | 'temp' | 'wind' | 'severe') {
if (model.activeWeatherType === type) {
model.activeWeatherType = ''
} else {
model.activeWeatherType = type
}
}
// 保留原有的导航栏按钮点击回调(如果有需要的话)
onNavigationBarButtonTap((e) => {
console.log(e)
......@@ -591,6 +786,13 @@ map.on('load','custom-image',()=>{
@submit-success="getDeviceTypeCount"
@close="showDialog = false"
/>
<WeatherChartPopup
:visible="model.activeWeatherType !== ''"
:type="model.activeWeatherType"
:lon="baseCenterLonLat?.[0] ?? ''"
:lat="baseCenterLonLat?.[1] ?? ''"
@close="model.activeWeatherType = ''"
/>
</view>
</template>
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论