366 lines
11 KiB
Vue
366 lines
11 KiB
Vue
<template>
|
|
<div class="AiDvRender" style="width: 100%; height: 100%;">
|
|
<ai-dv-display v-if="currentType === 'display'" :title="data.title" :list="values"/>
|
|
<ai-dv-tabs v-else-if="currentType=='tabs'" :config="data" :theme="theme"/>
|
|
<ai-dv-panel
|
|
style="height: 100%; width: 100%;"
|
|
v-else
|
|
:padding="data.padding"
|
|
:title="data.title"
|
|
:theme="theme"
|
|
:border="data.border || ''">
|
|
<AiDvSummary v-if="currentType === 'summary'" :theme="theme" :summaryTitle="data.summaryTitle"
|
|
:key="`summary${index}`" :type="data.display"
|
|
:data="values"/>
|
|
<AiSwiper v-else-if="currentType === 'swiper'" :heigth="'100%'" :data="values" :dotIndicator="data.dotIndicator"/>
|
|
<dv-scroll-board
|
|
v-if="currentType === 'table'"
|
|
:class="'dvScrollBoard' + theme"
|
|
:config="formatTable(values, data.isShowIndex, data.rowNum)"
|
|
:key="data.height"
|
|
:theme="theme"
|
|
:style="{height: data.height + 'px', width: '100%'}"/>
|
|
<ai-echart-v2 v-else-if="/Chart/.test(currentType)"
|
|
style="height: 100%; width: 100%;"
|
|
:ref="'chart' + index"
|
|
:key="`chart-${index}`"
|
|
:theme="theme"
|
|
:data="values"
|
|
:tpl="currentType"
|
|
:ops="data.echartOps"/>
|
|
<AiDvTable
|
|
v-else-if="currentType === 'AiDvTable'"
|
|
:heigth="'100%'"
|
|
:stripe="data.stripe"
|
|
:theme="theme"
|
|
:isShowIndex="data.isShowIndex"
|
|
:config="data.config"
|
|
:data="values" :simple="data.simple==1">
|
|
</AiDvTable>
|
|
<AiRanking
|
|
v-else-if="currentType === 'AiRanking'"
|
|
:theme="theme"
|
|
:heigth="'100%'"
|
|
:subType="data.subType"
|
|
:data="values">
|
|
</AiRanking>
|
|
<AiDvMap v-else-if="currentType === 'AiDvMap'" style="width: 100%; height: 100%" :theme="theme" :geo-json="data.geoJson" :data="values"/>
|
|
<ai-map v-else-if="currentType=='map'" :mask="data.mask === '1'" :areaId="data.areaId" :is3d="data.is3d==1"
|
|
:is3dAround="data.is3dAround === '1'"
|
|
:map-style="`amap://styles/${data.mapStyle}`" :pulseLines="data.pulseLines==1" :map.sync="map"
|
|
:lib.sync="lib"
|
|
:onlyShowArea="data.limitArea==1" :satellite="data.layers=='satellite'">
|
|
<div class="mapInfoWin" v-show="mapDialog">
|
|
<div class="corn" v-for="i in 4" :key="i"/>
|
|
<div ref="mapInfoWin"/>
|
|
</div>
|
|
<div v-if="data.showPingchangMapLegend" class="pingchangMapLegend"/>
|
|
</ai-map>
|
|
<ai-monitor :src="data.src" v-else-if="currentType === 'monitor'" :type="data.monitorType"/>
|
|
<ai-monitor-carousel :list="data.list" v-else-if="currentType === 'monitorCarousel'"/>
|
|
<img v-else-if="currentType=='img'" :src="data.src" alt="" style="width: 100%; height: 100%; object-fit: fill;"/>
|
|
<video style="width: 100%; height: 100%; object-fit: fill;" loop :src="data.src" autoplay
|
|
v-else-if="currentType === 'video'"/>
|
|
<AiDvPartyOrg style="width: 100%; height: 100%;" v-else-if="currentType === 'partyOrg'" :instance="instance"/>
|
|
<!-- <ai-sprite v-else-if="/building/.test(currentType)" v-bind="data" is3D @init="mods[currentType]"/> -->
|
|
<ai-dv-plot v-else-if="currentType=='plot'" :options="data.charts" :instance="instance"/>
|
|
<ai-assist v-else-if="currentType=='aiAssist'"/>
|
|
<ai-linkage-map v-else-if="currentType=='linkageMap'" :config="data" :instance="instance"/>
|
|
</ai-dv-panel>
|
|
</div>
|
|
</template>
|
|
|
|
<script>
|
|
import {scrollBoard} from '@jiaminghi/data-view'
|
|
import Vue from "vue"
|
|
import {mapState} from 'vuex'
|
|
import AiDvMap from "./AiDvMap";
|
|
import AiMonitor from "./AiMonitor/AiMonitor";
|
|
import AiSwiper from './AiSwiper'
|
|
import AiDvDisplay from "./layout/AiDvDisplay/AiDvDisplay";
|
|
import AiDvPanel from "./layout/AiDvPanel/AiDvPanel";
|
|
import AiDvSummary from "./layout/AiDvSummary/AiDvSummary";
|
|
import AiDvPlot from "./layout/AiDvPlot/AiDvPlot";
|
|
import AiAssist from "./AiAssist";
|
|
import AiMonitorCarousel from "./AiMonitorCarousel";
|
|
import AiLinkageMap from "./AiLinkageMap";
|
|
import AiDvTabs from "./AiDvTabs";
|
|
|
|
Vue.use(scrollBoard)
|
|
|
|
export default {
|
|
name: 'AiDvRender',
|
|
props: ['data', 'index', 'theme', 'instance'],
|
|
components: {
|
|
AiDvTabs,
|
|
AiLinkageMap,
|
|
AiMonitorCarousel,
|
|
AiAssist,
|
|
AiDvPlot,
|
|
// AiSprite,
|
|
AiDvSummary,
|
|
AiDvDisplay,
|
|
AiDvPanel,
|
|
AiMonitor,
|
|
AiSwiper,
|
|
AiDvMap
|
|
},
|
|
data() {
|
|
return {
|
|
// mods,
|
|
map: null,
|
|
lib: null,
|
|
timer: null,
|
|
mapDialog: false,
|
|
activeTab: '0'
|
|
}
|
|
},
|
|
computed: {
|
|
...mapState(['user']),
|
|
values: v => v.data?.[v.data?.dataType] || [],
|
|
currentType: v => v.data.type
|
|
},
|
|
watch: {
|
|
values: {
|
|
immediate: true,
|
|
deep: true, handler() {
|
|
if (this.currentType == 'map') {
|
|
this.renderMap()
|
|
}
|
|
}
|
|
}
|
|
},
|
|
methods: {
|
|
formatTable(data, isShowIndex, rowNum) {
|
|
const tableStyle = {
|
|
headerBGC: 'transparent',
|
|
evenRowBGC: 'transparent',
|
|
oddRowBGC: 'rgba(0, 133, 255, 0.2)',
|
|
headerHeight: 42,
|
|
align: 'center'
|
|
}
|
|
if (!data.length) {
|
|
return {
|
|
header: [],
|
|
data: []
|
|
}
|
|
}
|
|
if (this.data.tableConfig) {
|
|
const {x, y} = this.data.tableConfig, dataMap = {}
|
|
const header = [...new Set(Object.entries(data.find(e => e.row == x) || null)?.filter(e => e[0] != 'row').map(e => e[1]) || [])],
|
|
rows = [...new Set(Object.entries(data.find(e => e.row == y) || null)?.filter(e => e[0] != 'row').map(e => e[1]) || [])]
|
|
data.map(e => Object.keys(e).map(k => k != 'row' && (dataMap[k] = (dataMap[k] || "") + "#" + e[k])))
|
|
const tableData = Object.values(dataMap).map(e => e.split("#"))
|
|
return {
|
|
...tableStyle,
|
|
header: ["", ...header],
|
|
data: rows.map(y => [y, ...header.map(x => {
|
|
return tableData.find(m => m.includes(x) && m.includes(y)).at(-1)
|
|
})])
|
|
}
|
|
}
|
|
let rows = []
|
|
const header = data.map(v => {
|
|
return v[Object.keys(v)[0]]
|
|
})
|
|
Object.keys(data[0]).forEach((item, index) => {
|
|
if (index !== 0) {
|
|
rows.push(item)
|
|
}
|
|
})
|
|
return {
|
|
header: header,
|
|
data: rows.map(item => {
|
|
return data.map(v => {
|
|
return v[item]
|
|
})
|
|
}),
|
|
...tableStyle,
|
|
rowNum: rowNum || 7,
|
|
index: isShowIndex === '1',
|
|
waitTime: 8000,
|
|
carousel: 'page',
|
|
indexHeader: '排名',
|
|
align: ['center', 'center', 'center', 'center', 'center']
|
|
}
|
|
},
|
|
renderMap(count = 0) {
|
|
let {lib: AMap, map} = this
|
|
this.timer && clearInterval(this.timer)
|
|
if (AMap && map) {
|
|
map.clearMap()
|
|
const markers = Array.isArray(this.values) ? this.values : this.values.markers
|
|
const polylines = Array.isArray(this.values) ? [] : this.values.polylines || []
|
|
markers.map(e => ({lng: e['经度'], lat: e['纬度'], label: e['地区名称'], ...e})).filter(e => e.lng).map((e) => {
|
|
const {icon = "https://cdn.cunwuyun.cn/dvcp/h5/Location2.png"} = e
|
|
return new AMap.Marker({
|
|
map,
|
|
content: e.content || `<div class="marker ${this.data.alwaysShow ? 'showLabel' : ''}">
|
|
<img src="${icon}"/>
|
|
<span>${e.label}</span>
|
|
</div>`,
|
|
position: [e.lng, e.lat]
|
|
}).on('click', () => {
|
|
this.mapDialog = true
|
|
this.$nextTick(() => {
|
|
this.$refs.mapInfoWin.innerHTML = e.infoWindowHtml || [`<div class="infoWin">`, `<b>${e.label}</b>`, '</div>'].join('')
|
|
map.setZoomAndCenter(16, [e.lng, e.lat])
|
|
map.setPitch(60)
|
|
})
|
|
})
|
|
})
|
|
polylines.filter(e => e.path?.length > 0)?.map(e => new AMap.Polyline({
|
|
map, strokeColor: "#00FFAE", ...e, path: e.path.map(p => new AMap.LngLat(p[1], p[0]))
|
|
}))
|
|
map.setFitView()
|
|
const center = map.getCenter()
|
|
const zoom = map.getZoom()
|
|
map.on('click', () => {
|
|
map.setZoomAndCenter(zoom, center)
|
|
map.setPitch(0)
|
|
this.mapDialog = false
|
|
})
|
|
this.data.is3d > 0 && map.setPitch(65)
|
|
if (this.data.is3dAround == 1) {
|
|
this.timer = setInterval(() => map.setRotation(360, false, 16000))
|
|
}
|
|
} else if (count < 10) {
|
|
console.log("正在加载...%s", count)
|
|
setTimeout(() => this.renderMap(++count), 1000)
|
|
}
|
|
}
|
|
}
|
|
}
|
|
</script>
|
|
|
|
<style lang="scss" scoped>
|
|
.AiDvRender {
|
|
:deep(.dvScrollBoard1) {
|
|
|
|
.header {
|
|
background: rgba(0, 0, 0, 0.1) !important;
|
|
|
|
.header-item {
|
|
color: #FFBB73 !important;
|
|
font-size: 16px !important;
|
|
font-weight: 600;
|
|
}
|
|
}
|
|
|
|
|
|
.rows {
|
|
font-size: 16px;
|
|
font-weight: 600;
|
|
color: #FFFFFF;
|
|
line-height: 21px;
|
|
text-shadow: 0 2px 4px rgba(117, 9, 9, 0.5);
|
|
background: linear-gradient(180deg, #FFF6C7 0%, #FF9A02 100%);
|
|
-webkit-background-clip: text;
|
|
-webkit-text-fill-color: transparent;
|
|
|
|
& > div:nth-of-type(2n - 1) {
|
|
background-color: transparent !important;
|
|
}
|
|
|
|
& > div:nth-of-type(2n) {
|
|
background-color: rgba(0, 0, 0, 0.1) !important;
|
|
}
|
|
|
|
.index {
|
|
color: #fff;
|
|
text-shadow: none;
|
|
background: #BD4921 !important;
|
|
-webkit-background-clip: inherit;
|
|
-webkit-text-fill-color: #fff;
|
|
}
|
|
}
|
|
}
|
|
|
|
:deep(.marker) {
|
|
position: relative;
|
|
|
|
& > img {
|
|
width: 30px;
|
|
height: 30px;
|
|
}
|
|
|
|
& > span {
|
|
display: none;
|
|
}
|
|
|
|
&:hover > span, &.showLabel > span {
|
|
position: absolute;
|
|
left: 50%;
|
|
bottom: 0;
|
|
transform: translate(-50%, 100%);
|
|
display: block;
|
|
color: #fff;
|
|
font-size: 14px;
|
|
white-space: nowrap;
|
|
}
|
|
}
|
|
|
|
:deep(.mapInfoWin) {
|
|
$borderColor: #245D8E;
|
|
$borderCorn: url("https://cdn.cunwuyun.cn/dvcp/dv/mapDialogCorn.png");
|
|
position: absolute;
|
|
left: 50%;
|
|
top: 40%;
|
|
transform: translate(-50%, -50%);
|
|
padding: 16px 20px;
|
|
max-width: 800px;
|
|
background-color: rgba(#0A1B3E, 0.8);
|
|
backdrop-filter: blur(6px);
|
|
border: 1px solid $borderColor;
|
|
box-shadow: 10px 10px 10px inset rgba($borderColor, .8), -10px -10px 10px inset rgba($borderColor, .8);
|
|
border-radius: 4px;
|
|
color: white;
|
|
|
|
.corn {
|
|
$offset: -2px;
|
|
background-image: $borderCorn;
|
|
background-repeat: no-repeat;
|
|
position: absolute;
|
|
width: 14px;
|
|
height: 14px;
|
|
background-size: 100% 100%;
|
|
|
|
&:nth-of-type(1) {
|
|
left: $offset;
|
|
top: $offset;
|
|
transform: rotate(-90deg);
|
|
}
|
|
|
|
&:nth-of-type(2) {
|
|
right: $offset;
|
|
top: $offset;
|
|
transform: none;
|
|
}
|
|
|
|
&:nth-of-type(3) {
|
|
right: $offset;
|
|
bottom: $offset;
|
|
transform: rotate(90deg);
|
|
}
|
|
|
|
&:nth-of-type(4) {
|
|
left: $offset;
|
|
bottom: $offset;
|
|
transform: rotate(180deg);
|
|
}
|
|
}
|
|
}
|
|
|
|
.pingchangMapLegend {
|
|
width: 189px;
|
|
height: 95px;
|
|
background: url("https://cdn.cunwuyun.cn/pingchang/pingchangMapLegend.png");
|
|
background-size: 100% 100%;
|
|
position: absolute;
|
|
bottom: 32px;
|
|
right: 32px;
|
|
backdrop-filter: blur(10px);
|
|
}
|
|
}
|
|
</style>
|