DSDSWeb/src/views/statistics/UuvUnitStatistics.vue

882 lines
26 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<template>
<div class="statistics">
<div class="banner">
<div class="banner-select-text banner-static-title">{{ currentTitle }}</div>
<div class="numbers">
<div v-for="(item, index) in numbers" :key="index" class="item">
<div class="value">{{ item.value }}<span class="unit">{{ item.unit }}</span></div>
<div class="label">{{ item.label }}</div>
</div>
</div>
</div>
<div class="unit-toolbar">
<div class="unit-toolbar-inner">
<div class="unit-filter-box">
<span class="banner-unit-label">统计单位</span>
<el-select
v-model="selectedUnits"
class="banner-unit-select"
multiple
filterable
clearable
size="small"
placeholder="请选择单位(不选表示全部)"
value-key="unit_name"
collapse-tags
@change="onBannerUnitsChange"
>
<el-option
v-for="unit in unitOptions"
:key="unit.unit_id || unit.unit_name"
:label="unit.unit_name"
:value="unit"
/>
</el-select>
</div>
</div>
</div>
<!-- 地图板块-->
<div class="map-module">
<div class="bezel">
<div class="map-title">参航单位</div>
<div id="baiduCesiumContainer" ref="baiduCesiumContainer" style="height: 100%;width:100%;" />
</div>
<div class="bezel">
<div class="map-title">航次地图</div>
<div class="map-year-panel">
<span class="map-year-label">年份</span>
<el-date-picker
v-model="voyageYear"
type="year"
size="small"
placeholder="全部"
class="map-year"
clearable
format="yyyy"
@change="selectVoyageYear"
/>
</div>
<div id="cesiumContainer" ref="cesiumContainer" style="height: 100%;width:100%;" />
</div>
</div>
<!-- echarts板块-->
<div class="echarts-module">
<div class="bezel">
<BarChart
:title="barVoyageCount.title"
:chart-data="barVoyageCount.salesData"
:categories="barVoyageCount.productCategories"
chart-type="single"
/>
</div>
<div class="bezel">
<BarChart
:title="barVoyageDays.title"
:chart-data="barVoyageDays.salesData"
:categories="barVoyageDays.productCategories"
chart-type="single"
/>
</div>
<div class="bezel">
<BarChart
:title="barPeopleDiving.title"
:chart-data="barPeopleDiving.salesData"
:categories="barPeopleDiving.productCategories"
chart-type="multiple"
/>
</div>
<div class="bezel">
<BarChart
:title="barFirstPeopleDiving.title"
:chart-data="barFirstPeopleDiving.salesData"
:categories="barFirstPeopleDiving.productCategories"
chart-type="multiple"
/>
</div>
<div class="bezel">
<BarChart
:title="mixedMileage.title"
:chart-data="mixedMileage.series"
:categories="mixedMileage.categories"
chart-type="mixed"
:dual-y-axis="true"
left-axis-name="次数"
right-axis-name="天数"
/>
</div>
</div>
</div>
</template>
<script>
import BarChart from './components/BarChart.vue'
import { setImageryViewModels } from '../../utils/common'
import { unitTotal, hovUnit, hovDiving } from '../../api/statistics'
import { getYearRange } from '../../utils/index'
const Cesium = window.Cesium
/**
* @param {*} v 原始值
* @returns {number}
*/
function num(v) {
if (v == null || v === '') return 0
const n = Number(v)
return Number.isFinite(n) ? n : 0
}
export default {
components: {
BarChart
},
data() {
return {
currentTitle: '参航单位统计',
voyageYear: '',
unitOptions: [],
/** 与 Banner 多选绑定:筛选单位汇总图表与航次地图轨迹(空表示全部) */
selectedUnits: [],
/** unitTotal 全量缓存,便于按 Banner 选择做前端过滤 */
unitTotalRawList: [],
// 缓存 hovDiving 返回数据,便于多选单位时仅做前端过滤与重绘
hovDivingItems: [],
numbers: [
{
label: '参航单位数量',
value: '',
unit: '家'
},
{
label: '参航人数',
value: '',
unit: '人'
},
{
label: '深潜次数',
value: '',
unit: '次'
}
],
// Cesium相关 - 参航单位地图
baiduCesiumViewer: null,
baiduCesiumEntities: [], // 存储参航单位标记实体
viewer: null,
// 地图图层基础地址
CesiumHostAddr: `${window.location.protocol}//${window.location.hostname}:${window.location.port}/`,
trackLineLayers: [],
/** 航行次数(柱状) */
barVoyageCount: { title: '航行次数', salesData: [], productCategories: [] },
/** 参航天数(柱状) */
barVoyageDays: { title: '参航天数', salesData: [], productCategories: [] },
/** 参航人员数、深潜次数(柱状,多系列) */
barPeopleDiving: {
title: '参航人员数、深潜次数',
salesData: [
{ name: '参航人员数', type: 'bar', data: [] },
{ name: '深潜次数', type: 'bar', data: [] }
],
productCategories: []
},
/** 首次参航、首次深潜(柱状,多系列) */
barFirstPeopleDiving: {
title: '首次参航人数、首次深潜人数',
salesData: [
{ name: '首次参航人数', type: 'bar', data: [] },
{ name: '首次深潜人数', type: 'bar', data: [] }
],
productCategories: []
},
/** 航行次数(柱)+ 参航天数(折) */
mixedMileage: {
title: '航行次数与参航天数',
categories: [],
series: [
{ name: '航行次数', type: 'bar', data: [], yAxisIndex: 0 },
{ name: '参航天数', type: 'line', data: [], yAxisIndex: 1 }
]
}
}
},
created() {
this.loadUnitTotalFromApi()
this.getHovUnit()
this.gitHovDiving()
},
mounted() {
this.imageryViewModels = setImageryViewModels(this.CesiumHostAddr)
this.initCesium() // 初始化航次地图
this.initBaiduCesium() // 初始化参航单位地图
this.refreshTrackLines()
},
beforeDestroy() {
// 清理Cesium资源
if (this.baiduCesiumViewer) {
this.baiduCesiumViewer.destroy()
}
if (this.viewer) {
this.viewer.destroy()
}
},
methods: {
/**
* 刷新航次地图轨迹图层(按单位多选进行前端过滤)。
* @returns {void}
*/
refreshTrackLines() {
if (!this.viewer) return
this.removeSingleLineImg()
const selectedNameSet = new Set(
(this.selectedUnits || [])
.map(u => u && u.unit_name)
.filter(Boolean)
)
const selectedIdSet = new Set(
(this.selectedUnits || [])
.map(u => (u && (u.unit_id || u.unitId)) || null)
.filter(Boolean)
)
const unitFilterEnabled = selectedNameSet.size > 0 || selectedIdSet.size > 0
const itemsToShow = unitFilterEnabled
? (this.hovDivingItems || []).filter(item => {
const itemName = item.unit_name || item.unitName || item.unit_name_cn || null
const itemId = item.unit_id || item.unitId || item.unit_code || null
return selectedNameSet.has(itemName) || selectedIdSet.has(itemId)
})
: (this.hovDivingItems || [])
itemsToShow.forEach(item => {
this.addSingleLineImg(item)
})
},
/**
* Banner 统计单位多选变更:刷新汇总图表与航次地图轨迹。
* @returns {void}
*/
onBannerUnitsChange() {
this.applyFilteredUnitTotal()
this.refreshTrackLines()
},
/**
* 按 Banner 选中单位过滤 unitTotal 行,再写入 Banner 与图表。
* @returns {void}
*/
applyFilteredUnitTotal() {
const raw = this.unitTotalRawList || []
if (!raw.length) {
this.applyUnitTotalRows([])
return
}
const sel = this.selectedUnits || []
if (!sel.length) {
this.applyUnitTotalRows(raw)
return
}
const nameSet = new Set(sel.map(u => u && u.unit_name).filter(Boolean))
const filtered = raw.filter(row => nameSet.has(row.unit_name))
this.applyUnitTotalRows(filtered)
},
/**
* 拉取「单位汇总」报表(/report/unit/total.htm驱动 Banner 与各柱状图。
* @returns {void}
*/
loadUnitTotalFromApi() {
unitTotal({})
.then(res => {
const list = res && Array.isArray(res.array) ? res.array : []
this.unitTotalRawList = list
this.applyFilteredUnitTotal()
})
.catch(() => {
this.unitTotalRawList = []
this.applyUnitTotalRows([])
})
},
/**
* 将 unitTotal 返回的按单位行写入 Banner 与图表。
* @param {Object[]} list 接口 array
* @returns {void}
*/
applyUnitTotalRows(list) {
if (!list.length) {
this.numbers[0].value = ''
this.numbers[1].value = ''
this.numbers[2].value = ''
this.barVoyageCount = { title: '航行次数', salesData: [], productCategories: [] }
this.barVoyageDays = { title: '参航天数', salesData: [], productCategories: [] }
this.barPeopleDiving = {
title: '参航人员数、深潜次数',
salesData: [
{ name: '参航人员数', type: 'bar', data: [] },
{ name: '深潜次数', type: 'bar', data: [] }
],
productCategories: []
}
this.barFirstPeopleDiving = {
title: '首次参航人数、首次深潜人数',
salesData: [
{ name: '首次参航人数', type: 'bar', data: [] },
{ name: '首次深潜人数', type: 'bar', data: [] }
],
productCategories: []
}
this.mixedMileage = {
title: '航行次数与参航天数',
categories: [],
series: [
{ name: '航行次数', type: 'bar', data: [], yAxisIndex: 0 },
{ name: '参航天数', type: 'line', data: [], yAxisIndex: 1 }
]
}
return
}
const sorted = [...list].sort((a, b) => num(b.voyage_total) - num(a.voyage_total))
const names = sorted.map(r => r.unit_name || '—')
const voyage = sorted.map(r => num(r.voyage_total))
const days = sorted.map(r => num(r.voyage_days))
const member = sorted.map(r => num(r.member_total))
const drving = sorted.map(r => num(r.drving_total))
const fVoyage = sorted.map(r => num(r.f_voyage_total))
const fDrving = sorted.map(r => num(r.f_drving_total))
this.numbers[0].value = sorted.length
this.numbers[1].value = sorted.reduce((s, r) => s + num(r.member_total), 0)
this.numbers[2].value = sorted.reduce((s, r) => s + num(r.drving_total), 0)
this.barVoyageCount = {
title: '航行次数',
salesData: voyage,
productCategories: names
}
this.barVoyageDays = {
title: '参航天数',
salesData: days,
productCategories: names
}
this.barPeopleDiving = {
title: '参航人员数、深潜次数',
salesData: [
{ name: '参航人员数', type: 'bar', data: member },
{ name: '深潜次数', type: 'bar', data: drving }
],
productCategories: names
}
this.barFirstPeopleDiving = {
title: '首次参航人数、首次深潜人数',
salesData: [
{ name: '首次参航人数', type: 'bar', data: fVoyage },
{ name: '首次深潜人数', type: 'bar', data: fDrving }
],
productCategories: names
}
this.mixedMileage = {
title: '航行次数与参航天数',
categories: names,
series: [
{ name: '航行次数', type: 'bar', data: voyage, yAxisIndex: 0 },
{ name: '参航天数', type: 'line', data: days, yAxisIndex: 1 }
]
}
},
// 下潜单位统计
getHovUnit() {
hovUnit().then(res => {
// 初始化单位下拉选项(去重)
const map = new Map()
;(res.array || []).forEach(unit => {
const k = unit.unit_id || unit.unitId || unit.unit_name
if (!map.has(k)) map.set(k, unit)
})
this.unitOptions = Array.from(map.values())
// 清除之前的标记
this.clearBaiduCesiumMarkers()
// 创建参航单位标记
this.createBaiduCesiumMarkers(res.array || [])
})
},
// 创建参航单位Cesium标记点
createBaiduCesiumMarkers(units) {
if (!this.baiduCesiumViewer) return
const entities = []
units.forEach((item, index) => {
// 创建标记实体
const entity = this.baiduCesiumViewer.entities.add({
position: Cesium.Cartesian3.fromDegrees(item.unit_lon, item.unit_lat),
billboard: {
image: '../../../static/img/01.png', // 正常状态的图标
width: 32,
height: 32,
verticalOrigin: Cesium.VerticalOrigin.BOTTOM,
horizontalOrigin: Cesium.HorizontalOrigin.CENTER
},
label: {
text: item.unit_name,
font: '14pt monospace',
style: Cesium.LabelStyle.FILL_AND_OUTLINE,
outlineWidth: 2,
verticalOrigin: Cesium.VerticalOrigin.BOTTOM,
pixelOffset: new Cesium.Cartesian2(0, -40), // 标签在标记下方
fillColor: Cesium.Color.WHITE,
outlineColor: Cesium.Color.BLACK
},
unitData: item, // 存储原始数据
index: index // 存储索引
})
entities.push(entity)
})
this.baiduCesiumEntities = entities
// 调整视角以显示所有标记
if (entities.length > 0) {
this.baiduCesiumViewer.zoomTo(entities)
}
},
// 清除参航单位标记
clearBaiduCesiumMarkers() {
if (this.baiduCesiumViewer && this.baiduCesiumEntities.length > 0) {
this.baiduCesiumEntities.forEach(entity => {
this.baiduCesiumViewer.entities.remove(entity)
})
this.baiduCesiumEntities = []
}
},
// 潜次统计
gitHovDiving(params = {}) {
hovDiving(params).then(res => {
this.hovDivingItems = res.array || []
this.refreshTrackLines()
})
},
// 初始化Cesium - 参航单位地图
initBaiduCesium() {
this.baiduCesiumViewer = new Cesium.Viewer(this.$refs.baiduCesiumContainer, {
sceneMode: Cesium.SceneMode.SCENE2D,
shadows: false,
timeline: false,
baseLayerPicker: false,
imageryProviderViewModels: this.imageryViewModels,
terrainProviderViewModels: [],
fullscreenButton: false,
selectionIndicator: false,
homeButton: false,
sceneModePicker: false,
animation: false,
infoBox: false,
geocoder: false,
navigationHelpButton: false
})
this.baiduCesiumViewer._cesiumWidget._creditContainer.style.display = 'none'
this.baiduCesiumViewer.scene.sun.show = false
this.baiduCesiumViewer.scene.moon.show = false
this.baiduCesiumViewer.scene.fog.enabled = false
this.baiduCesiumViewer.scene.skyAtmosphere.show = false
this.baiduCesiumViewer.scene.sun.show = false
this.baiduCesiumViewer.scene.skyBox.show = false
this.baiduCesiumViewer.scene.globe.enableLighting = false
this.baiduCesiumViewer.shadowMap.darkness = 0.8
this.baiduCesiumViewer.scene._sunBloom = false
this.baiduCesiumViewer.scene.globe.showGroundAtmosphere = false
this.baiduCesiumViewer.scene.postProcessStages.fxaa.enabled = true
this.baiduCesiumViewer.camera.setView({
destination: Cesium.Cartesian3.fromDegrees(114.4040, 30.5196, 4000000)
})
},
// 初始化cesium
initCesium() {
Cesium.Ion.defaultAccessToken = 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJqdGkiOiJkY2Y5NWY2Ni1mODQ1LTQ3YTUtYjc4Zi1jYzhjMGI2YzcxMWYiLCJpZCI6MTI5ODMwLCJpYXQiOjE2Nzk0Njk5NTd9.DTH54ioOH-HLqeNIetBe9hFyrPOX2Vp1AQmZzw8TIZ4'
this.viewer = new Cesium.Viewer('cesiumContainer', {
sceneMode: Cesium.SceneMode.SCENE2D,
shadows: false,
timeline: false,
baseLayerPicker: false,
// 设置自定义底图
imageryProviderViewModels: this.imageryViewModels,
// 关闭默认的地形底图
terrainProviderViewModels: [],
fullscreenButton: false,
selectionIndicator: false,
homeButton: false,
sceneModePicker: false,
animation: false,
infoBox: false,
geocoder: false,
navigationHelpButton: false
})
this.viewer._cesiumWidget._creditContainer.style.display = 'none'
this.viewer.scene.sun.show = false
this.viewer.scene.moon.show = false
this.viewer.scene.fog.enabled = false
this.viewer.scene.skyAtmosphere.show = false
this.viewer.scene.sun.show = false
this.viewer.scene.skyBox.show = false
this.viewer.scene.globe.enableLighting = false
this.viewer.shadowMap.darkness = 0.8
this.viewer.scene._sunBloom = false
this.viewer.scene.globe.showGroundAtmosphere = false
this.viewer.scene.postProcessStages.fxaa.enabled = true
this.viewer.camera.setView({
// 指定相机初始位置
destination: Cesium.Cartesian3.fromDegrees(112, 18, 4000000)
})
},
// 添加轨迹图层
addSingleLineImg(item) {
const trackLine = new Cesium.WebMapTileServiceImageryProvider(
{
url: `${this.CesiumHostAddr}geoserver/gwc/service/wmts/rest/dsds:${item.diving_sn}/{TileMatrixSet}/{TileMatrixSet}:{TileMatrix}/{TileRow}/{TileCol}?format=image/png`,
layer: `dsds:${item.diving_sn}`,
style: 'default',
format: 'image/png',
tileMatrixSetID: 'EPSG:4326',
tilingScheme: new Cesium.GeographicTilingScheme()
}
)
const trackLineLayer = this.viewer.imageryLayers.addImageryProvider(trackLine)
this.trackLineLayers.push(trackLineLayer)
},
// 移除轨迹图层
removeSingleLineImg() {
if (this.viewer && this.trackLineLayers.length) {
this.trackLineLayers.forEach(line => {
this.viewer.imageryLayers.remove(line)
})
}
// 清空引用,避免重复 remove 或无限增长
this.trackLineLayers = []
},
// 选择航次地图年份
selectVoyageYear(val) {
this.removeSingleLineImg()
if (val) {
const params = getYearRange(val)
this.gitHovDiving({ ...params })
} else {
this.gitHovDiving({})
}
},
}
}
</script>
<style scoped lang="scss">
.statistics {
background-color: #ebf1f7;
.banner {
background-image: url(../../../static/images/bannerny1.jpg);
background-repeat: no-repeat;
background-position: center;
background-size: 100% 100%;
width: 100%;
height: 480px;
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
color: #fff;
.banner-topic {
font-size: 28px;
font-weight: 700;
margin-bottom: 18px;
text-shadow: 0 6px 22px rgba(0, 0, 0, 0.25);
letter-spacing: 0.02em;
}
.banner-type-dropdown {
margin-bottom: 40px;
}
.banner-static-title {
margin-bottom: 40px;
}
.banner-select-trigger {
display: inline-flex;
align-items: center;
gap: 14px;
padding: 14px 24px 14px 28px;
border: 2px solid rgba(255, 255, 255, 0.88);
border-radius: 12px;
background: rgba(8, 40, 72, 0.42);
backdrop-filter: blur(10px);
-webkit-backdrop-filter: blur(10px);
box-shadow:
0 4px 20px rgba(0, 0, 0, 0.28),
inset 0 1px 0 rgba(255, 255, 255, 0.14);
cursor: pointer;
transition:
background 0.25s ease,
border-color 0.25s ease,
box-shadow 0.25s ease,
transform 0.25s ease;
user-select: none;
outline: none;
&:hover {
background: rgba(12, 55, 95, 0.58);
border-color: rgba(255, 255, 255, 0.98);
transform: translateY(-3px);
box-shadow:
0 12px 36px rgba(0, 0, 0, 0.38),
inset 0 1px 0 rgba(255, 255, 255, 0.22);
}
&:focus-visible {
outline: 3px solid rgba(255, 255, 255, 0.85);
outline-offset: 3px;
}
}
.banner-select-text {
font-size: 52px;
font-weight: bold;
color: #fff;
line-height: 1.15;
max-width: #{"min(90vw, 920px)"};
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
.banner-select-chevron {
flex-shrink: 0;
opacity: 0.95;
filter: drop-shadow(0 1px 2px rgba(0, 0, 0, 0.35));
}
.numbers {
display: flex;
justify-content: space-between;
gap: 80px;
.item {
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
.value {
font-size: 56px;
font-weight: bold;
.unit {
font-size: 26px;
}
}
.label {
font-size: 18px;
}
}
}
}
/** Banner 下方:统计单位筛选条,整行容器 + 右侧对齐独立框 */
.unit-toolbar {
width: 100%;
padding: 8px 50px 8px;
box-sizing: border-box;
background-color: #ebf1f7;
.unit-toolbar-inner {
display: flex;
justify-content: flex-end;
align-items: center;
width: 100%;
}
.unit-filter-box {
display: flex;
align-items: center;
gap: 12px;
padding: 10px 18px;
border-radius: 10px;
background: rgba(255, 255, 255, 0.92);
border: 1px solid rgba(0, 50, 90, 0.12);
box-shadow: 0 2px 10px rgba(0, 40, 80, 0.06);
}
.banner-unit-label {
font-size: 15px;
font-weight: 600;
letter-spacing: 0.06em;
color: rgba(28, 45, 63, 0.88);
flex-shrink: 0;
}
.banner-unit-select {
width: #{"min(72vw, 520px)"};
min-width: 200px;
::v-deep .el-input__inner {
min-height: 34px;
border-radius: 8px;
border: 1px solid rgba(0, 50, 90, 0.14);
background: #fff;
font-size: 14px;
font-weight: 500;
color: #1c2d3f;
}
::v-deep .el-select__tags {
max-width: 100%;
flex-wrap: wrap;
}
}
}
.map-module {
padding: 20px 50px 50px;
display: flex;
justify-content: space-between;
gap: 50px;
.bezel {
flex: 1;
width: 100%;
height: 520px;
border-radius: 10px;
overflow: hidden;
border: 1px solid #ccc;
position: relative;
.map-title {
position: absolute;
top: 20px;
left: 20px;
color: white;
z-index: 8888;
font-size: 22px;
}
.map-year-panel {
position: absolute;
top: 16px;
right: 16px;
z-index: 8888;
display: flex;
align-items: center;
flex-wrap: wrap;
gap: 10px;
padding: 6px 10px 6px 12px;
border-radius: 10px;
background: rgba(255, 255, 255, 0.68);
border: 1px solid rgba(255, 255, 255, 0.55);
box-shadow: 0 4px 18px rgba(0, 0, 0, 0.14);
backdrop-filter: blur(12px);
-webkit-backdrop-filter: blur(12px);
transition:
background 0.25s ease,
border-color 0.25s ease,
box-shadow 0.25s ease,
transform 0.25s ease;
&:hover {
background: rgba(255, 255, 255, 0.82);
border-color: rgba(255, 255, 255, 0.92);
transform: translateY(-2px);
box-shadow: 0 10px 28px rgba(0, 0, 0, 0.2);
}
}
.map-year-label {
font-size: 13px;
font-weight: 600;
color: rgba(28, 42, 58, 0.78);
letter-spacing: 0.04em;
user-select: none;
}
.map-year {
width: 120px;
::v-deep .el-input__inner {
height: 34px;
line-height: 34px;
padding-left: 30px;
padding-right: 28px;
border-radius: 8px;
border: 1px solid rgba(0, 50, 90, 0.12);
background: rgba(255, 255, 255, 0.55);
font-size: 14px;
font-weight: 500;
color: #1c2d3f;
transition:
background 0.2s ease,
border-color 0.2s ease,
box-shadow 0.2s ease;
}
::v-deep .el-input__inner:hover,
::v-deep .el-input__inner:focus {
border-color: rgba(0, 90, 150, 0.42);
background: rgba(255, 255, 255, 0.78);
box-shadow: 0 2px 8px rgba(0, 50, 100, 0.1);
}
::v-deep .el-input__prefix {
left: 8px;
}
::v-deep .el-input__suffix {
right: 6px;
}
}
}
}
.echarts-module {
padding: 0 50px 50px;
display: grid;
grid-template-columns: repeat(3, 1fr);
gap: 50px;
grid-auto-rows: 300px;
.bezel {
width: 100%;
height: 100%;
border-radius: 10px;
overflow: hidden;
border: 1px solid #ccc;
position: relative;
.map-title {
position: absolute;
top: 20px;
left: 20px;
color: white;
z-index: 8888;
font-size: 22px;
}
}
}
}
</style>
<style lang="scss">
.banner-type-dropdown-popper.el-dropdown-menu {
min-width: 240px;
max-height: #{"min(60vh, 420px)"};
overflow-y: auto;
padding: 6px 0;
border-radius: 8px;
box-shadow: 0 8px 32px rgba(0, 0, 0, 0.35);
}
.banner-type-dropdown-popper.el-dropdown-menu .el-dropdown-menu__item {
font-size: 16px;
line-height: 22px;
padding: 14px 22px;
}
</style>