|
|
@ -1,25 +1,24 @@ |
|
|
|
<template> |
|
|
|
|
|
|
|
<div class="tabs"> |
|
|
|
<div class="tab-item" @click="onTabClick('MWR')" :class="{'active': currentTab === 'MWR'}"> |
|
|
|
<div :class="{'active': currentTab === 'MWR'}" class="tab-item" @click="onTabClick('MWR')"> |
|
|
|
质控对比 |
|
|
|
<img src="/images/line.png" v-if="currentTab === 'MWR'" /> |
|
|
|
<img v-if="currentTab === 'MWR'" src="/images/line.png"/> |
|
|
|
</div> |
|
|
|
<div class="tab-item" @click="onTabClick('kuoxian')" :class="{'active': currentTab === 'kuoxian'}"> |
|
|
|
<div :class="{'active': currentTab === 'kuoxian'}" class="tab-item" @click="onTabClick('kuoxian')"> |
|
|
|
垂直廓线 |
|
|
|
<img src="/images/line.png" v-if="currentTab === 'kuoxian'" /> |
|
|
|
<img v-if="currentTab === 'kuoxian'" src="/images/line.png"/> |
|
|
|
</div> |
|
|
|
<div class="tab-item" @click="onTabClick('shixu')" :class="{'active': currentTab === 'shixu'}"> |
|
|
|
<div :class="{'active': currentTab === 'shixu'}" class="tab-item" @click="onTabClick('shixu')"> |
|
|
|
对流指数 |
|
|
|
<img src="/images/line.png" v-if="currentTab === 'shixu'" /> |
|
|
|
<img v-if="currentTab === 'shixu'" src="/images/line.png"/> |
|
|
|
</div> |
|
|
|
<div class="tab-item" @click="onTabClick('T-logP')" :class="{'active': currentTab === 'T-logP'}"> |
|
|
|
<div :class="{'active': currentTab === 'T-logP'}" class="tab-item" @click="onTabClick('T-logP')"> |
|
|
|
T-logP图 |
|
|
|
<img src="/images/line.png" v-if="currentTab === 'T-logP'" /> |
|
|
|
<img v-if="currentTab === 'T-logP'" src="/images/line.png"/> |
|
|
|
</div> |
|
|
|
<div class="tab-item" @click="onTabClick('shixu_BPFY')" :class="{'active': currentTab === 'shixu_BPFY'}"> |
|
|
|
<div :class="{'active': currentTab === 'shixu_BPFY'}" class="tab-item" @click="onTabClick('shixu_BPFY')"> |
|
|
|
BP反演产品 |
|
|
|
<img src="/images/line.png" v-if="currentTab === 'shixu_BPFY'" /> |
|
|
|
<img v-if="currentTab === 'shixu_BPFY'" src="/images/line.png"/> |
|
|
|
</div> |
|
|
|
</div> |
|
|
|
<div class="main"> |
|
|
@ -27,18 +26,19 @@ |
|
|
|
<div class="menu-item"> |
|
|
|
<h2 class="tip">区域选择</h2> |
|
|
|
<el-row :gutter="12"> |
|
|
|
<el-col :span="8"><span @click="onRegionClick('jiangning')" :class="{'active': currentRegion === 'jiangning'}">江宁</span></el-col> |
|
|
|
<el-col :span="8"><span :class="{'active': currentRegion === 'jiangning'}" |
|
|
|
@click="onRegionClick('jiangning')">江宁</span></el-col> |
|
|
|
</el-row> |
|
|
|
</div> |
|
|
|
<div class="menu-item"> |
|
|
|
<h2 class="tip">分辨率选择</h2> |
|
|
|
<el-row :gutter="12"> |
|
|
|
<el-col :span="8" ><span @click="onElementClick('six-minute', -2, 6,0)" :class="{'active': currentElement === 'six-minute'}">6分钟</span></el-col> |
|
|
|
<el-col :span="8" ><span @click="onElementClick('half-hour', -12, 30,-2)" :class="{'active': currentElement === 'half-hour'}">30分钟</span></el-col> |
|
|
|
<el-col :span="8" ><span @click="onElementClick('one-hour', -24, 60,-4)" :class="{'active': currentElement === 'one-hour'}">1小时</span></el-col> |
|
|
|
<!-- <el-col :span="8" ><span @click="onElementClick('CAPE')" :class="{'active': currentElement === 'CAPE'}">CAPE</span></el-col>--> |
|
|
|
<!-- <el-col :span="8" ><span @click="onElementClick('CIN')" :class="{'active': currentElement === 'CIN'}">CIN</span></el-col>--> |
|
|
|
|
|
|
|
<el-col :span="8"><span :class="{'active': currentElement === 'six-minute'}" |
|
|
|
@click="onElementClick('six-minute', -2, 6,0)">6分钟</span></el-col> |
|
|
|
<el-col :span="8"><span :class="{'active': currentElement === 'half-hour'}" |
|
|
|
@click="onElementClick('half-hour', -12, 30,-2)">30分钟</span></el-col> |
|
|
|
<el-col :span="8"><span :class="{'active': currentElement === 'one-hour'}" |
|
|
|
@click="onElementClick('one-hour', -24, 60,-4)">1小时</span></el-col> |
|
|
|
</el-row> |
|
|
|
</div> |
|
|
|
</div> |
|
|
@ -46,30 +46,34 @@ |
|
|
|
<div class="toolbar"> |
|
|
|
|
|
|
|
<!--6分钟--> |
|
|
|
<div class="times sixMinute" v-if="currentElement === 'six-minute'"> |
|
|
|
<div class="time-item" v-for="(time, index) in times" :key="index" :class="{'active': currentTime === time.date, 'first-hour': time.minute === '00'}"> |
|
|
|
<div v-if="currentElement === 'six-minute'" class="times sixMinute"> |
|
|
|
<div v-for="(time, index) in times" :key="index" |
|
|
|
:class="{'active': currentTime === time.date, 'first-hour': time.minute === '00'}" class="time-item"> |
|
|
|
<span class="hour">{{ time.hour }}</span> |
|
|
|
<span class="time" @click="onTimeClick(time, index)">{{ time.minute }}</span> |
|
|
|
</div> |
|
|
|
</div> |
|
|
|
|
|
|
|
<!--30分钟--> |
|
|
|
<div class="times halfHour" v-if="currentElement === 'half-hour'"> |
|
|
|
<div class="time-item" v-for="(time, index) in times" :key="index" :class="{'active': currentTime === time.date}"> |
|
|
|
<div v-if="currentElement === 'half-hour'" class="times halfHour"> |
|
|
|
<div v-for="(time, index) in times" :key="index" :class="{'active': currentTime === time.date}" |
|
|
|
class="time-item"> |
|
|
|
<span class="hour ">{{ time.hour }}</span> |
|
|
|
<span class="time" @click="onTimeClick(time, index)">{{ time.minute }}</span> |
|
|
|
</div> |
|
|
|
</div> |
|
|
|
|
|
|
|
<!--1小时--> |
|
|
|
<div class="times oneHour" v-if="currentElement === 'one-hour'"> |
|
|
|
<div class="time-item" v-for="(time, index) in times" :key="index" :class="{'active': currentTime === time.date}"> |
|
|
|
<div v-if="currentElement === 'one-hour'" class="times oneHour"> |
|
|
|
<div v-for="(time, index) in times" :key="index" :class="{'active': currentTime === time.date}" |
|
|
|
class="time-item"> |
|
|
|
<span class="hour">{{ time.hour }}</span> |
|
|
|
<span class="time" @click="onTimeClick(time, index)">{{ time.minute }}</span> |
|
|
|
</div> |
|
|
|
</div> |
|
|
|
|
|
|
|
<el-date-picker v-model="date" type="date" placeholder="请选择" :clearable="false" :editable="false" class="date-picker" @change="onChange"> |
|
|
|
<el-date-picker v-model="date" :clearable="false" :editable="false" class="date-picker" placeholder="请选择" |
|
|
|
type="date" @change="onChange"> |
|
|
|
</el-date-picker> |
|
|
|
<div class="control-btn"> |
|
|
|
<span @click="onPrevDayClick"><img src="/images/prev.png"/></span> |
|
|
@ -85,26 +89,11 @@ |
|
|
|
</el-option> |
|
|
|
</el-select> |
|
|
|
<p class="unit">时</p> |
|
|
|
<!-- <div class="refresh-btn" @click="onRefreshClick">--> |
|
|
|
<!-- <img src="/images/refresh.png" />--> |
|
|
|
<!-- </div>--> |
|
|
|
<!-- <div class="btns-group" v-if="currentTab==='kuoxian' || currentTab==='T-logP'">--> |
|
|
|
<!-- <span @click="onPlayClick">{{isPlay ? '暂停动画' : '播放动画'}}</span>--> |
|
|
|
<!-- <a @click="onDownloadClick">下载动画</a>--> |
|
|
|
<!-- <a id="weboDownload" download :href="downloadSrc" class="hide">下载隐藏层</a>--> |
|
|
|
<!-- </div>--> |
|
|
|
</div> |
|
|
|
<div class="picture-view"> |
|
|
|
<!-- <span class="arrow arrow-prev" @click="onPrevImgClick"><img src="/images/prev-btn.png" /></span>--> |
|
|
|
<!-- <span class="arrow arrow-next" @click="onNextImgClick"><img src="/images/next-btn.png" /></span>--> |
|
|
|
<!-- <span class="save-btn" @click="onSaveClick" v-if="currentTab === 'MWR'"><img src="/images/save.png" /></span>--> |
|
|
|
<!-- <a :href="downloadImgUrl" download class="save-btn" v-else><img src="/images/save.png" /></a>--> |
|
|
|
<!-- <div class="download-pictures hide" id="pictures">--> |
|
|
|
<!-- <a v-for="(url, index) in urls" :key="index" download></a>--> |
|
|
|
<!-- </div>--> |
|
|
|
|
|
|
|
<!--质控对比--> |
|
|
|
<div class="picture-container contrast-picture-container" v-if="currentTab === 'MWR'"> |
|
|
|
<div v-if="currentTab === 'MWR'" class="picture-container contrast-picture-container"> |
|
|
|
<div class="picture"> |
|
|
|
<h2 class="title">{{ titleStartTime }}~{{ titleEndTime }}温度原始数据</h2> |
|
|
|
<canvas id='original-data-canvas'></canvas> |
|
|
@ -120,7 +109,7 @@ |
|
|
|
</div> |
|
|
|
|
|
|
|
<!--BP反演产品--> |
|
|
|
<div class="picture-container contrast-picture-container" v-if="currentTab === 'shixu_BPFY'"> |
|
|
|
<div v-if="currentTab === 'shixu_BPFY'" class="picture-container contrast-picture-container"> |
|
|
|
<div class="picture"> |
|
|
|
<h2 class="title">{{ titleStartTime }}~{{ titleEndTime }}BP反演温度</h2> |
|
|
|
<canvas id="BP-temp"></canvas> |
|
|
@ -135,11 +124,21 @@ |
|
|
|
</div> |
|
|
|
</div> |
|
|
|
|
|
|
|
<div class="picture-container contrast-picture-container" v-if="currentTab === 'kuoxian'"> |
|
|
|
<div v-if="currentTab === 'kuoxian'" class="picture-container contrast-picture-container"> |
|
|
|
<h2>{{ BPTitleTime }}温度、相对湿度、水汽密度廓线</h2> |
|
|
|
<div id="container" style="width:100%;height:100%"></div> |
|
|
|
</div> |
|
|
|
|
|
|
|
<div v-if="currentTab === 'shixu'" class="picture-container contrast-picture-container"> |
|
|
|
<div class="picture"> |
|
|
|
<h2 class="title">{{ titleStartTime }}~{{ titleEndTime }}对流有效位能CAPE</h2> |
|
|
|
<div id="convectiveHighChartCAPE" style="width:100%;height:75%"></div> |
|
|
|
</div> |
|
|
|
<div class="picture"> |
|
|
|
<h2 class="title">{{ titleStartTime }}~{{ titleEndTime }}对流抑制势能CIN</h2> |
|
|
|
<div id="convectiveHighChartCIN" style="width:100%;height:75%"></div> |
|
|
|
</div> |
|
|
|
</div> |
|
|
|
</div> |
|
|
|
</div> |
|
|
|
</div> |
|
|
@ -150,12 +149,22 @@ |
|
|
|
import moment from "moment"; |
|
|
|
import {get} from '../uilts/axios'; |
|
|
|
import {BoxDrawer, ColorChart, createEmptyCanvas} from "../uilts/box-drawer"; |
|
|
|
import * as Highcharts from 'highcharts'; |
|
|
|
import {Constant} from "../model/constant"; |
|
|
|
import {HighChartCreate} from "../model/high-chart-create"; |
|
|
|
import {ElMessage, ElMessageBox} from 'element-plus' |
|
|
|
export default { |
|
|
|
name: 'MicrowaveRadiation', |
|
|
|
setup() { |
|
|
|
let timer = null; |
|
|
|
let verticalProfileHighChart = null; |
|
|
|
let creates: { |
|
|
|
verticalProfile: HighChartCreate |
|
|
|
convectiveIndexProfileTimeChartCAPE: HighChartCreate |
|
|
|
convectiveIndexProfileTimeChartCIN: HighChartCreate |
|
|
|
} = { |
|
|
|
verticalProfile: null, |
|
|
|
convectiveIndexProfileTimeChartCAPE: null, |
|
|
|
convectiveIndexProfileTimeChartCIN: null |
|
|
|
} |
|
|
|
|
|
|
|
let options = reactive({ |
|
|
|
currentTab: 'MWR', |
|
|
@ -191,7 +200,6 @@ |
|
|
|
apiTimeInterval: 6, |
|
|
|
onPitchTime: 0, |
|
|
|
BPTitleTime: null, |
|
|
|
|
|
|
|
highChartXAxis: [], |
|
|
|
}); |
|
|
|
|
|
|
@ -205,140 +213,69 @@ |
|
|
|
} |
|
|
|
|
|
|
|
onMounted(() => { |
|
|
|
// initEcharts(null) |
|
|
|
initTimeLine() |
|
|
|
initHours(); |
|
|
|
setTimeout(() => { |
|
|
|
changeColor() |
|
|
|
}, 100) |
|
|
|
reloadData() |
|
|
|
|
|
|
|
}) |
|
|
|
|
|
|
|
const onTabClick = (name) => { |
|
|
|
options.currentTab = name; |
|
|
|
options.currentElement = 'six-minute' |
|
|
|
setTimeout(() => { |
|
|
|
initEcharts(name); |
|
|
|
reloadChangeData(); |
|
|
|
}, 500) |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
const initEcharts = (name) => { |
|
|
|
if ( name === 'kuoxian'){ |
|
|
|
verticalProfileHighChart = Highcharts.chart('container', { |
|
|
|
credits: { |
|
|
|
enabled: false |
|
|
|
}, |
|
|
|
chart: { |
|
|
|
type: 'line', |
|
|
|
inverted: true |
|
|
|
}, |
|
|
|
title: { |
|
|
|
text: null |
|
|
|
}, |
|
|
|
subtitle: { |
|
|
|
text: null |
|
|
|
}, |
|
|
|
xAxis: { |
|
|
|
reversed: false, |
|
|
|
title: { |
|
|
|
enabled: true, |
|
|
|
text: '高度(km)' |
|
|
|
}, |
|
|
|
categories: options.highChartXAxis, |
|
|
|
showLastLabel: true, |
|
|
|
showFirstLabel: true, |
|
|
|
}, |
|
|
|
yAxis: [ |
|
|
|
{ |
|
|
|
title: { |
|
|
|
text: '温度T(degree)', |
|
|
|
}, |
|
|
|
max: 10, |
|
|
|
min: -40, |
|
|
|
tickInterval: 10, |
|
|
|
tickAmount: 6, |
|
|
|
lineWidth: 1, |
|
|
|
opposite:true |
|
|
|
}, |
|
|
|
{ |
|
|
|
title: { |
|
|
|
text: '相对湿度RH(%)' |
|
|
|
}, |
|
|
|
max: 100, |
|
|
|
min: 0, |
|
|
|
tickInterval: 10, |
|
|
|
tickAmount: 11, |
|
|
|
lineWidth: 1, |
|
|
|
}, |
|
|
|
{ |
|
|
|
title: { |
|
|
|
text: '水汽密度Q(g/kg)' |
|
|
|
}, |
|
|
|
labels: { |
|
|
|
formatter: function() { |
|
|
|
return this.value.toFixed(1); |
|
|
|
} |
|
|
|
}, |
|
|
|
// allowDecimals: true, |
|
|
|
max: 10.0, |
|
|
|
min: 0.0, |
|
|
|
tickInterval: 1.0, |
|
|
|
tickAmount: 11, |
|
|
|
lineWidth: 1, |
|
|
|
}, |
|
|
|
], |
|
|
|
legend: { |
|
|
|
layout: 'vertical', |
|
|
|
align: 'right', |
|
|
|
verticalAlign: 'middle' |
|
|
|
}, |
|
|
|
tooltip: { |
|
|
|
headerFormat: '<b>{series.name}</b><br/>', |
|
|
|
pointFormat: '{point.category} KM: {point.y}' |
|
|
|
// pointFormatter: function () { |
|
|
|
// console.log(this) |
|
|
|
// return '{point.category} KM: {point.y}' |
|
|
|
// } |
|
|
|
}, |
|
|
|
series: [ |
|
|
|
{ |
|
|
|
name: '温度', |
|
|
|
data: [], |
|
|
|
yAxis: 0, |
|
|
|
tooltip: { |
|
|
|
valueSuffix: '℃' |
|
|
|
} |
|
|
|
}, |
|
|
|
{ |
|
|
|
name: '相对湿度', |
|
|
|
data: [], |
|
|
|
yAxis: 1, |
|
|
|
tooltip: { |
|
|
|
valueSuffix: '%' |
|
|
|
} |
|
|
|
}, |
|
|
|
{ |
|
|
|
name: '水汽密度', |
|
|
|
data: [], |
|
|
|
yAxis: 2, |
|
|
|
tooltip: { |
|
|
|
valueSuffix: 'g/Kg' |
|
|
|
} |
|
|
|
} |
|
|
|
] |
|
|
|
}); |
|
|
|
} |
|
|
|
if (name === 'kuoxian') |
|
|
|
verticalProfileInit() |
|
|
|
else if (name === 'shixu') { |
|
|
|
convectiveIndexProfileTimeChartInitCAPE() |
|
|
|
convectiveIndexProfileTimeChartInitCIN() |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
const verticalProfileInit = () => { |
|
|
|
creates.verticalProfile = new HighChartCreate('container'); |
|
|
|
creates.verticalProfile.setChart(true); |
|
|
|
creates.verticalProfile.setXAxis('高度(km)', false); |
|
|
|
creates.verticalProfile.setYAxis('温度T(degree)', 10, -40, 10, 6, true); |
|
|
|
creates.verticalProfile.setYAxis('相对湿度RH(%)', 100, 0, 10, 6); |
|
|
|
creates.verticalProfile.setYAxis('水汽密度Q(g/kg)', 10, 0, 1, 11); |
|
|
|
creates.verticalProfile.setLegend(); |
|
|
|
creates.verticalProfile.setTooltip('{point.category} KM: {point.y}'); |
|
|
|
creates.verticalProfile.setSeries('温度', 0, '℃', '#F49927'); |
|
|
|
creates.verticalProfile.setSeries('相对湿度', 1, '%', '#3534FD'); |
|
|
|
creates.verticalProfile.setSeries('水汽密度', 2, 'g/Kg', '#6AB312'); |
|
|
|
creates.verticalProfile.init(); |
|
|
|
} |
|
|
|
|
|
|
|
const convectiveIndexProfileTimeChartInitCAPE = () => { |
|
|
|
creates.convectiveIndexProfileTimeChartCAPE = new HighChartCreate('convectiveHighChartCAPE'); |
|
|
|
creates.convectiveIndexProfileTimeChartCAPE.setChart(); |
|
|
|
creates.convectiveIndexProfileTimeChartCAPE.setXAxis( '时间(时/分)', false); |
|
|
|
creates.convectiveIndexProfileTimeChartCAPE.setYAxis('CAPE(J/kg)', 500, 0, 100); |
|
|
|
creates.convectiveIndexProfileTimeChartCAPE.setTooltip('{point.category}: {point.y}(J/kg)'); |
|
|
|
creates.convectiveIndexProfileTimeChartCAPE.setSeries('CAPE') |
|
|
|
creates.convectiveIndexProfileTimeChartCAPE.init(); |
|
|
|
} |
|
|
|
|
|
|
|
const convectiveIndexProfileTimeChartInitCIN = () => { |
|
|
|
creates.convectiveIndexProfileTimeChartCIN = new HighChartCreate('convectiveHighChartCIN'); |
|
|
|
creates.convectiveIndexProfileTimeChartCIN.setChart(); |
|
|
|
creates.convectiveIndexProfileTimeChartCIN.setXAxis( '时间(时/分)', false); |
|
|
|
creates.convectiveIndexProfileTimeChartCIN.setYAxis('CIE(J/kg)', 500, 0, 100); |
|
|
|
creates.convectiveIndexProfileTimeChartCIN.setTooltip('{point.category}: {point.y}(J/kg)'); |
|
|
|
creates.convectiveIndexProfileTimeChartCIN.setSeries('CIN') |
|
|
|
creates.convectiveIndexProfileTimeChartCIN.init(); |
|
|
|
} |
|
|
|
|
|
|
|
const onRegionClick = (region) => { |
|
|
|
options.currentRegion = region; |
|
|
|
// cancelActive(); |
|
|
|
// if (options.currentTab === 'MWR') |
|
|
|
// activeContrastImage(); |
|
|
|
// else |
|
|
|
// activeImage(moment(options.times[options.index].date).hour(), moment(options.times[options.index].date).minute()); |
|
|
|
} |
|
|
|
|
|
|
|
const onElementClick = (element, apiTimeLength, apiTimeInterval, onPitchTime) => { |
|
|
@ -346,7 +283,7 @@ |
|
|
|
options.apiTimeLength = apiTimeLength; |
|
|
|
options.currentElement = element; |
|
|
|
options.onPitchTime = onPitchTime |
|
|
|
initTimeLine(reloadData) |
|
|
|
initTimeLine(reloadChangeData) |
|
|
|
if (element === 'six-minute') { |
|
|
|
setTimeout(() => { |
|
|
|
changeColor() |
|
|
@ -354,24 +291,6 @@ |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
//质控对比图片 |
|
|
|
// const activeContrastImage = () => { |
|
|
|
// options.contrast.noQCImgUrl = MicrowaveRadiationConfig.getUrl(options.currentRegion, options.currentTab + '_noQC', moment(options.currentTime, 'YYYY-MM-DD')); |
|
|
|
// options.contrast.noQCImgPreview = [options.contrast.noQCImgUrl]; |
|
|
|
// options.contrast.checkImgUrl = MicrowaveRadiationConfig.getUrl(options.currentRegion, options.currentTab + '_check', moment(options.currentTime, 'YYYY-MM-DD')); |
|
|
|
// options.contrast.checkImgPreview = [options.contrast.checkImgUrl]; |
|
|
|
// options.contrast.fillingImgUrl = MicrowaveRadiationConfig.getUrl(options.currentRegion, options.currentTab + '_filling', moment(options.currentTime, 'YYYY-MM-DD')); |
|
|
|
// options.contrast.fillingImgPreview = [options.contrast.fillingImgUrl]; |
|
|
|
// } |
|
|
|
|
|
|
|
// const activeImage = (hour, minute) => { |
|
|
|
// let time = moment(options.date).hour(hour).minute(minute); |
|
|
|
// let type = options.currentTab === 'T-logP' ? options.currentTab : (options.currentTab + '_' + options.currentElement); |
|
|
|
// options.imgUrl = MicrowaveRadiationConfig.getUrl(options.currentRegion, type, time); |
|
|
|
// console.log(options.imgUrl) |
|
|
|
// options.srcList = [options.imgUrl]; |
|
|
|
// } |
|
|
|
|
|
|
|
const onImageLoad = (event) => { |
|
|
|
if (event.currentTarget.getAttribute('src') !== '/images/default-picture.png') |
|
|
|
converToBase64(options.imgUrl); |
|
|
@ -379,74 +298,14 @@ |
|
|
|
return |
|
|
|
} |
|
|
|
|
|
|
|
// const onDownloadClick = () => { |
|
|
|
// post("/image/createGif", prepareParams(), 'application/json').then((response: any) => { |
|
|
|
// if (response.error != 0){ |
|
|
|
// return; |
|
|
|
// } |
|
|
|
// fetch(response.data).then(res => { |
|
|
|
// return res.blob(); |
|
|
|
// }).then(blob => { |
|
|
|
// let reader = new FileReader(); |
|
|
|
// reader.onloadend = function(){ |
|
|
|
// options.downloadSrc = reader.result; |
|
|
|
// |
|
|
|
// setTimeout(() => { |
|
|
|
// document.getElementById("weboDownload").click(); |
|
|
|
// options.downloadSrc = null; |
|
|
|
// }, 500); |
|
|
|
// }; |
|
|
|
// reader.readAsDataURL(blob); |
|
|
|
// }).catch(console.error); |
|
|
|
// }) |
|
|
|
// } |
|
|
|
|
|
|
|
//请求参数 |
|
|
|
// const prepareParams = () => { |
|
|
|
// let time = options.currentTab === 'MWR' ? moment(options.days[0].date).format("YYYYMMDDHHmmss") + '-' + moment(options.days[options.days.length - 1].date).format("YYYYMMDDHHmmss") : moment(options.times[0].date).format("YYYYMMDDHHmmss") + '-' + moment(options.times[options.times.length - 1].date).format("YYYYMMDDHHmmss"); |
|
|
|
// return { |
|
|
|
// model: 'weibo', |
|
|
|
// station: options.currentRegion, |
|
|
|
// elementCode: options.currentType, |
|
|
|
// type: options.currentTab, |
|
|
|
// time: time, |
|
|
|
// urls: options.currentTab === 'MWR' ? prepareContrastUrls() : prepareUrls() |
|
|
|
// } |
|
|
|
// } |
|
|
|
|
|
|
|
// const prepareUrls = () => { |
|
|
|
// let urls = []; |
|
|
|
// for(let index = 0, len = options.times.length; index < len; index++){ |
|
|
|
// let time = moment(options.times[index].date); |
|
|
|
// let type = options.currentTab === 'T-logP' ? options.currentTab : (options.currentTab + '_' + options.currentElement); |
|
|
|
// urls.push(MicrowaveRadiationConfig.getUrl(options.currentRegion, type, time)); |
|
|
|
// } |
|
|
|
// return urls; |
|
|
|
// } |
|
|
|
|
|
|
|
// const prepareContrastUrls = () => { |
|
|
|
// let urls = []; |
|
|
|
// for(let i = 0, len = options.days.length; i < len; i++){ |
|
|
|
// let time = moment(options.days[i].date); |
|
|
|
// urls.push( |
|
|
|
// MicrowaveRadiationConfig.getUrl(options.currentRegion, options.currentTab + '_noQC', time), |
|
|
|
// MicrowaveRadiationConfig.getUrl(options.currentRegion, options.currentTab + '_check', time), |
|
|
|
// MicrowaveRadiationConfig.getUrl(options.currentRegion, options.currentTab + '_filling', time) |
|
|
|
// ); |
|
|
|
// } |
|
|
|
// return urls; |
|
|
|
// } |
|
|
|
|
|
|
|
const converToBase64 = (path) => { |
|
|
|
let img = new Image(); |
|
|
|
img.src = path; |
|
|
|
let canvas = document.createElement("canvas") as HTMLCanvasElement; |
|
|
|
canvas.width = img.width; |
|
|
|
canvas.height = img.height; |
|
|
|
|
|
|
|
let ctx = canvas.getContext("2d"); |
|
|
|
let base64 = ''; |
|
|
|
|
|
|
|
img.setAttribute("crossOrigin", 'Anonymous') |
|
|
|
img.onload = function () { |
|
|
|
ctx.drawImage(img, 0, 0); |
|
|
@ -498,18 +357,6 @@ |
|
|
|
reloadChangeData() |
|
|
|
} |
|
|
|
|
|
|
|
// const onDayClick = (time, index) => { |
|
|
|
// options.currentTime = time.date; |
|
|
|
// options.index = index; |
|
|
|
// cancelActive(); |
|
|
|
// activeContrastImage(); |
|
|
|
// } |
|
|
|
|
|
|
|
// const cancelActive = () => { |
|
|
|
// clearTimer(); |
|
|
|
// options.isPlay = false; |
|
|
|
// } |
|
|
|
|
|
|
|
//上一天 |
|
|
|
const onPrevDayClick = () => { |
|
|
|
options.date = moment(options.date).add(-1, 'day').format('YYYY-MM-DD'); |
|
|
@ -517,7 +364,6 @@ |
|
|
|
options.titleStartTime = moment(options.date).hour(parseInt(options.currentHour) + options.apiTimeLength).minute(options.currentElement === 'six-minute' ? 36 : 30).format('YYYY-MM-DD HH:mm:ss'); |
|
|
|
options.titleEndTime = moment(options.date).hour(parseInt(options.currentHour)).minute(options.currentElement === 'six-minute' ? 30 : 0).format('YYYY-MM-DD HH:mm:ss'); |
|
|
|
reloadChangeData() |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
//下一天 |
|
|
@ -529,32 +375,6 @@ |
|
|
|
reloadChangeData() |
|
|
|
} |
|
|
|
|
|
|
|
// const onPrevImgClick = () => { |
|
|
|
// prevElement(); |
|
|
|
// } |
|
|
|
|
|
|
|
// const onNextImgClick = () => { |
|
|
|
// nextElement(); |
|
|
|
// } |
|
|
|
|
|
|
|
// const prevElement = () => { |
|
|
|
// let element = getCurrentElement(); |
|
|
|
// |
|
|
|
// options.index--; |
|
|
|
// if (options.index < 0) |
|
|
|
// options.index = element.childElementCount - 1; |
|
|
|
// |
|
|
|
// setCurrentPlayElement(element); |
|
|
|
// } |
|
|
|
|
|
|
|
// const nextElement = () => { |
|
|
|
// let element = getCurrentElement(); |
|
|
|
// options.index++; |
|
|
|
// if (options.index > element.childElementCount - 1) |
|
|
|
// options.index = 0; |
|
|
|
// |
|
|
|
// setCurrentPlayElement(element); |
|
|
|
// } |
|
|
|
//重置时间 |
|
|
|
const onRefreshClick = () => { |
|
|
|
let element = getCurrentElement(); |
|
|
@ -578,12 +398,10 @@ |
|
|
|
const timeExcute = () => { |
|
|
|
clearTimer(); |
|
|
|
let element = getCurrentElement(); |
|
|
|
|
|
|
|
timer = setInterval(() => { |
|
|
|
options.index++; |
|
|
|
if (options.index > element.childElementCount - 1) |
|
|
|
options.index = 0; |
|
|
|
|
|
|
|
setCurrentPlayElement(element); |
|
|
|
}, 2000) |
|
|
|
} |
|
|
@ -600,13 +418,12 @@ |
|
|
|
const setCurrentPlayElement = (element) => { |
|
|
|
for (let i = 0; i < element.childElementCount; i++) |
|
|
|
element.children[i].classList.remove('active'); |
|
|
|
|
|
|
|
element.children[options.index].classList.add('active'); |
|
|
|
if (options.currentTab === 'MWR') { |
|
|
|
options.currentTime = options.days[options.index].date; |
|
|
|
} else { |
|
|
|
options.currentTime = options.times[options.index].date; |
|
|
|
} |
|
|
|
else { |
|
|
|
options.currentTime = options.times[options.index].date;} |
|
|
|
} |
|
|
|
|
|
|
|
const onChange = () => { |
|
|
@ -629,6 +446,7 @@ |
|
|
|
BPVaporDensityData() |
|
|
|
BPRelativeHumidityData() |
|
|
|
} |
|
|
|
|
|
|
|
const reloadChangeData = () => { |
|
|
|
if (options.currentTab === 'MWR') |
|
|
|
reloadData() |
|
|
@ -636,36 +454,12 @@ |
|
|
|
reloadBPData() |
|
|
|
else if (options.currentTab === 'kuoxian') { |
|
|
|
BPBrokenLineData() |
|
|
|
} else if (options.currentTab === 'shixu') { |
|
|
|
convectiveIndexCAPEData() |
|
|
|
convectiveIndexCINData() |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
// const onSaveClick = () => { |
|
|
|
// let pictures = document.getElementById('pictures'); |
|
|
|
// options.urls = [options.contrast.noQCImgUrl, options.contrast.checkImgUrl, options.contrast.fillingImgUrl]; |
|
|
|
// for (let i = 0; i < options.urls.length; i++) { |
|
|
|
// let img = new Image(); |
|
|
|
// img.src = options.urls[i]; |
|
|
|
// let canvas = document.createElement("canvas") as HTMLCanvasElement; |
|
|
|
// canvas.width = img.width; |
|
|
|
// canvas.height = img.height; |
|
|
|
// |
|
|
|
// let ctx = canvas.getContext("2d"); |
|
|
|
// let base64 = ''; |
|
|
|
// |
|
|
|
// img.setAttribute("crossOrigin",'Anonymous'); |
|
|
|
// img.onload = function() { |
|
|
|
// ctx.drawImage(img, 0, 0); |
|
|
|
// base64 = canvas.toDataURL("image/png"); |
|
|
|
// pictures.children[i].setAttribute('href', base64); |
|
|
|
// |
|
|
|
// let button: HTMLElement = pictures.children[i] as HTMLElement; |
|
|
|
// setTimeout(() => { |
|
|
|
// button.click(); |
|
|
|
// }, 500); |
|
|
|
// }; |
|
|
|
// } |
|
|
|
// } |
|
|
|
|
|
|
|
const changeColor = () => { |
|
|
|
let timeLine = document.querySelectorAll('.time-item') |
|
|
|
timeLine.forEach((item: any, index) => { |
|
|
@ -676,13 +470,11 @@ |
|
|
|
}) |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// 重新加载质控对比数据 |
|
|
|
const reloadQualityComparison = () => { |
|
|
|
const startTime = moment(options.currentTime).add(options.apiTimeLength, 'h').add(options.apiTimeInterval, 'm').format('YYYY-MM-DD HH:mm:00'); |
|
|
|
const params = prepareApiParams(401, startTime, options.titleEndTime); |
|
|
|
get('/njplatform/radardata/getOriginRangeData',params,'http://rdp.nagr.com.cn:18080').then((response: any)=> { |
|
|
|
get('/njplatform/radardata/getOriginRangeData', params, Constant.baseUrl).then((response: any) => { |
|
|
|
clearBoxDrawer(drawers.originalDrawer); |
|
|
|
clearBoxDrawer(drawers.abnormalDrawer); |
|
|
|
if (response.code != 200 || response.data.radar_data.length === 0) { |
|
|
@ -700,7 +492,7 @@ |
|
|
|
const reloadQualityInterpolation = () => { |
|
|
|
const startTime = moment(options.currentTime).add(options.apiTimeLength, 'h').add(options.apiTimeInterval, 'm').format('YYYY-MM-DD HH:mm:00'); |
|
|
|
const params = prepareApiParams(401, startTime, options.titleEndTime); |
|
|
|
get('/njplatform/radardata/getBpRangeData',params,'http://rdp.nagr.com.cn:18080').then((response: any)=> { |
|
|
|
get('/njplatform/radardata/getBpRangeData', params, Constant.baseUrl).then((response: any) => { |
|
|
|
clearBoxDrawer(drawers.interpolateDrawer); |
|
|
|
if (response.code != 200 || response.data.radar_data.length === 0) { |
|
|
|
if (options.currentTab === 'MWR') |
|
|
@ -713,7 +505,6 @@ |
|
|
|
drawers.interpolateDrawer = new BoxDrawer(1500, 500, prepareTmpOriginalColors(), response.data, 'interpolate-canvas', '℃'); |
|
|
|
else if (options.currentTab === 'shixu_BPFY') |
|
|
|
drawers.interpolateDrawer = new BoxDrawer(1500, 500, prepareBPTempColors(), response.data, 'BP-temp', '(degree)'); |
|
|
|
|
|
|
|
// options.contrast.fillingImgUrl = drawers.interpolateDrawer.base64Image; |
|
|
|
}) |
|
|
|
} |
|
|
@ -723,7 +514,7 @@ |
|
|
|
const reloadBPRelativeHumidity = () => { |
|
|
|
const startTime = moment(options.currentTime).add(options.apiTimeLength, 'h').add(options.apiTimeInterval, 'm').format('YYYY-MM-DD HH:mm:00'); |
|
|
|
const params = prepareApiParams(404, startTime, options.titleEndTime); |
|
|
|
get('/njplatform/radardata/getBpRangeData',params,'http://rdp.nagr.com.cn:18080').then((response: any)=> { |
|
|
|
get('/njplatform/radardata/getBpRangeData', params, Constant.baseUrl).then((response: any) => { |
|
|
|
clearBoxDrawer(drawers.BPRelativeHumidity); |
|
|
|
if (response.code != 200 || response.data.radar_data.length === 0) { |
|
|
|
createEmptyCanvas('BP-relative-humidity', 1500, 500); |
|
|
@ -737,11 +528,10 @@ |
|
|
|
const reloadBPVaporDensity = () => { |
|
|
|
const startTime = moment(options.currentTime).add(options.apiTimeLength, 'h').add(options.apiTimeInterval, 'm').format('YYYY-MM-DD HH:mm:00'); |
|
|
|
const params = prepareApiParams(402, startTime, options.titleEndTime); |
|
|
|
get('/njplatform/radardata/getBpRangeData',params,'http://rdp.nagr.com.cn:18080').then((response: any)=> { |
|
|
|
console.log(response) |
|
|
|
get('/njplatform/radardata/getBpRangeData', params, Constant.baseUrl).then((response: any) => { |
|
|
|
clearBoxDrawer(drawers.BPVaporDensity); |
|
|
|
if (response.code != 200 || response.data.radar_data.length === 0) { |
|
|
|
createEmptyCanvas('BP-relative-humidity', 1500, 500); |
|
|
|
createEmptyCanvas('BP-vapor-density', 1500, 500); |
|
|
|
return; |
|
|
|
} |
|
|
|
drawers.BPVaporDensity = new BoxDrawer(1500, 500, prepareBPVaporDensityColors(), response.data, 'BP-vapor-density', '(g/kg)'); |
|
|
@ -752,35 +542,42 @@ |
|
|
|
const BPTempData = () => { |
|
|
|
const startTime = moment(options.currentTime).add(options.apiTimeLength, 'h').add(options.apiTimeInterval, 'm').format('YYYY-MM-DD HH:mm:00'); |
|
|
|
const params = prepareApiParams(401, startTime, options.titleEndTime); |
|
|
|
get('/njplatform/radardata/getBpRangeData',params,'http://rdp.nagr.com.cn:18080').then((response: any)=> { |
|
|
|
verticalProfileHighChart.series[0].setData(getVerticalProfileResponseData(response)); |
|
|
|
get('/njplatform/radardata/getBpRangeData', params, Constant.baseUrl).then((response: any) => { |
|
|
|
creates.verticalProfile.updateSeries(0, getVerticalProfileResponseData(response)); |
|
|
|
}) |
|
|
|
} |
|
|
|
|
|
|
|
const BPVaporDensityData = () => { |
|
|
|
const startTime = moment(options.currentTime).add(options.apiTimeLength, 'h').add(options.apiTimeInterval, 'm').format('YYYY-MM-DD HH:mm:00'); |
|
|
|
const params = prepareApiParams(402, startTime, options.titleEndTime); |
|
|
|
get('/njplatform/radardata/getBpRangeData',params,'http://rdp.nagr.com.cn:18080').then((response: any)=> { |
|
|
|
verticalProfileHighChart.series[2].setData(getVerticalProfileResponseData(response)); |
|
|
|
get('/njplatform/radardata/getBpRangeData', params, Constant.baseUrl).then((response: any) => { |
|
|
|
creates.verticalProfile.updateSeries(2, getVerticalProfileResponseData(response)); |
|
|
|
}) |
|
|
|
} |
|
|
|
|
|
|
|
const BPRelativeHumidityData = () => { |
|
|
|
const startTime = moment(options.currentTime).add(options.apiTimeLength, 'h').add(options.apiTimeInterval, 'm').format('YYYY-MM-DD HH:mm:00'); |
|
|
|
const params = prepareApiParams(404, startTime, options.titleEndTime); |
|
|
|
get('/njplatform/radardata/getBpRangeData',params,'http://rdp.nagr.com.cn:18080').then((response: any)=> { |
|
|
|
// BPResponseData(response, options.BPTempTimeData); |
|
|
|
verticalProfileHighChart.series[1].setData(getVerticalProfileResponseData(response)); |
|
|
|
get('/njplatform/radardata/getBpRangeData', params, Constant.baseUrl).then((response: any) => { |
|
|
|
creates.verticalProfile.updateSeries(1, getVerticalProfileResponseData(response)); |
|
|
|
}) |
|
|
|
} |
|
|
|
|
|
|
|
const getVerticalProfileResponseData = (response) => { |
|
|
|
if (response.code != 200 || response.data.radar_data.length === 0) { |
|
|
|
if (response.code != 200 || response.data == null || response.data.radar_data.length === 0) { |
|
|
|
options.BPTitleTime = null; |
|
|
|
ElMessage({ |
|
|
|
showClose: true, |
|
|
|
message: '请求接口无数据', |
|
|
|
icon: '', |
|
|
|
type: null, |
|
|
|
grouping: true, |
|
|
|
duration: 1500 |
|
|
|
}) |
|
|
|
return []; |
|
|
|
} |
|
|
|
|
|
|
|
verticalProfileHighChart.xAxis[0].setCategories(response.data.radar_info.map(r => r.col_factor)); |
|
|
|
creates.verticalProfile.updateXAxis(response.data.radar_info.map(r => r.col_factor)); |
|
|
|
// verticalProfileHighChart.xAxis[0].setCategories(response.data.radar_info.map(r => r.col_factor)); |
|
|
|
response.data.radar_data.sort((x, y) => { |
|
|
|
return moment(x.data_time).isBefore(moment(y.data_time)); |
|
|
|
}); |
|
|
@ -793,6 +590,52 @@ |
|
|
|
return optionData; |
|
|
|
} |
|
|
|
|
|
|
|
const convectiveIndexCAPEData = () => { |
|
|
|
const startTime = moment(options.currentTime).add(options.apiTimeLength, 'h').add(options.apiTimeInterval, 'm').format('YYYY-MM-DD HH:mm:00'); |
|
|
|
const params = prepareApiParams('cape', startTime, options.titleEndTime); |
|
|
|
get('/njplatform/radardata/getBpRangeData', params, Constant.baseUrl).then((response: any) => { |
|
|
|
let data = convectiveIndexResponseData(response); |
|
|
|
creates.convectiveIndexProfileTimeChartCAPE.updateSeries(0,data[0]) |
|
|
|
creates.convectiveIndexProfileTimeChartCAPE.updateXAxis(data[1], 0) |
|
|
|
}) |
|
|
|
} |
|
|
|
|
|
|
|
const convectiveIndexCINData = () => { |
|
|
|
const startTime = moment(options.currentTime).add(options.apiTimeLength, 'h').add(options.apiTimeInterval, 'm').format('YYYY-MM-DD HH:mm:00'); |
|
|
|
const params = prepareApiParams('cin', startTime, options.titleEndTime); |
|
|
|
get('/njplatform/radardata/getBpRangeData', params, Constant.baseUrl).then((response: any) => { |
|
|
|
let data = convectiveIndexResponseData(response); |
|
|
|
creates.convectiveIndexProfileTimeChartCIN.updateSeries(0,data[0]) |
|
|
|
creates.convectiveIndexProfileTimeChartCIN.updateXAxis(data[1], 0) |
|
|
|
}) |
|
|
|
} |
|
|
|
|
|
|
|
const convectiveIndexResponseData = (response) => { |
|
|
|
if (response.code != 200 || response.data == null || response.data.radar_data.length === 0) { |
|
|
|
ElMessage({ |
|
|
|
showClose: true, |
|
|
|
message: '请求接口无数据', |
|
|
|
icon: '', |
|
|
|
type: null, |
|
|
|
grouping: true, |
|
|
|
duration: 1500 |
|
|
|
}) |
|
|
|
return [[], []]; |
|
|
|
} |
|
|
|
let radarData = response.data.radar_data; |
|
|
|
let times = []; |
|
|
|
let values = []; |
|
|
|
radarData.forEach(item => { |
|
|
|
if (item.f001 >= 10000) { |
|
|
|
item.f001 = 0 |
|
|
|
} |
|
|
|
times.push(moment(item.data_time).format('HH:mm')) |
|
|
|
values.push(item.f001) |
|
|
|
}); |
|
|
|
|
|
|
|
return [values, times]; |
|
|
|
} |
|
|
|
|
|
|
|
const clearBoxDrawer = (boxDrawer: BoxDrawer) => { |
|
|
|
if (boxDrawer == null) return; |
|
|
|
boxDrawer.close(); |
|
|
@ -803,7 +646,8 @@ |
|
|
|
'#FEA61B', '#FDED2A', '#C1FE46', '#7AFD86', |
|
|
|
'#2BFDCD', '#05E6FD', '#14A0FA', '#1B5AFB', |
|
|
|
'#1C1FF9', '#1310C4', '#09067C'], |
|
|
|
[ 999, 30, 25, 20, 15, 10, 5, 0, -5, -10, -15, -20, -25, -30, -35, -999]); |
|
|
|
[999, 30, 25, 20, 15, 10, 5, 0, -5, -10, -15, -20, -25, -30, -35, -999] |
|
|
|
); |
|
|
|
} |
|
|
|
|
|
|
|
const prepareBPTempColors = () => { |
|
|
@ -811,25 +655,26 @@ |
|
|
|
'#FEBF14', '#EFFE24', '#9FFE61', '#52FEAA', |
|
|
|
'#03FEF8', '#0AB8FD', '#1069FD', '#1222FD', |
|
|
|
'#0C0AC9', '#05037D'], |
|
|
|
[ 999, 12, 8, 4, 0, -4, -8, -12, -16, -20, -24, -28, -32, -36, -999]); |
|
|
|
[999, 12, 8, 4, 0, -4, -8, -12, -16, -20, -24, -28, -32, -36, -999] |
|
|
|
); |
|
|
|
} |
|
|
|
|
|
|
|
const prepareBPRelativeHumidityColors = () => { |
|
|
|
return new ColorChart(['#860100', '#F60301', '#FF6708', '#FED718', |
|
|
|
'#B3FE4F', '#3EFEBD', '#07CFFE', '#1061FD', |
|
|
|
'#100DED', '#05037D'], |
|
|
|
[ 999, 90, 80, 70, 60, 50, 40, 30, 20, 10, -999]) |
|
|
|
[999, 90, 80, 70, 60, 50, 40, 30, 20, 10, -999] |
|
|
|
) |
|
|
|
} |
|
|
|
|
|
|
|
const prepareBPVaporDensityColors = () => { |
|
|
|
return new ColorChart(['#860100', '#F60301', '#FF6708', '#FED718', |
|
|
|
'#B3FE4F', '#3EFEBD', '#07CFFE', '#1061FD', |
|
|
|
'#100DED', '#05037D'], |
|
|
|
[ 999, 9, 8, 7, 6, 5, 4, 3, 2, 1, -999]) |
|
|
|
[999, 9, 8, 7, 6, 5, 4, 3, 2, 1, -999] |
|
|
|
) |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
const prepareApiParams = (radarDataCode, startTime, endTime) => { |
|
|
|
return { |
|
|
|
radar_data_code: radarDataCode, |
|
|
@ -848,19 +693,14 @@ |
|
|
|
onRegionClick, |
|
|
|
onElementClick, |
|
|
|
onTimeClick, |
|
|
|
// onDayClick, |
|
|
|
onPrevDayClick, |
|
|
|
onNextDayClick, |
|
|
|
// onPrevImgClick, |
|
|
|
// onNextImgClick, |
|
|
|
onRefreshClick, |
|
|
|
onPlayClick, |
|
|
|
onChange, |
|
|
|
onImageLoad, |
|
|
|
// onDownloadClick, |
|
|
|
// onSaveClick, |
|
|
|
changeColor, |
|
|
|
// onImageMove |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
@ -873,6 +713,7 @@ |
|
|
|
width: calc(~"100% - 2.5rem"); |
|
|
|
margin: 0 auto; |
|
|
|
align-items: center; |
|
|
|
|
|
|
|
.picture { |
|
|
|
width: 100%; |
|
|
|
//flex-direction: column; |
|
|
@ -882,6 +723,7 @@ |
|
|
|
#BP-temp, #BP-relative-humidity, #BP-vapor-density { |
|
|
|
transform: scale(0.5, 0.4); |
|
|
|
} |
|
|
|
|
|
|
|
.title { |
|
|
|
//padding-bottom: 0; |
|
|
|
font-size: 0.22rem; |
|
|
|