单独构建大屏ui库,避免引入混乱
This commit is contained in:
		
							
								
								
									
										369
									
								
								ui/dv/AiDvRender.vue
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										369
									
								
								ui/dv/AiDvRender.vue
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,369 @@ | ||||
| <template> | ||||
|   <div class="AiDvRender" style="width: 100%; height: 100%;"> | ||||
|     <ai-dv-display v-if="currentType === 'display'" :title="data.title" :list="values"/> | ||||
|     <ai-dv-panel | ||||
|         style="height: 100%; width: 100%;" | ||||
|         v-if="currentType !== 'display'" | ||||
|         :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="data.config" | ||||
|                     :ops="data.echartOps"/> | ||||
|       <AiDvTable | ||||
|           v-else-if="currentType === 'AiDvTable'" | ||||
|           :heigth="'100%'" | ||||
|           :stripe="data.stripe" | ||||
|           :theme="theme" | ||||
|           :isShowIndex="data.isShowIndex" | ||||
|           :config="dvTableConfig" | ||||
|           :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-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.vue' | ||||
| import AiDvDisplay from "./layout/AiDvDisplay/AiDvDisplay"; | ||||
| import AiDvPanel from "./layout/AiDvPanel/AiDvPanel"; | ||||
| import AiDvSummary from "./layout/AiDvSummary/AiDvSummary"; | ||||
| import AiDvPlot from "./layout/AiDvPlot/AiDvPlot.vue"; | ||||
| import AiAssist from "./AiAssist.vue"; | ||||
| import AiMonitorCarousel from "./AiMonitorCarousel.vue"; | ||||
|  | ||||
| Vue.use(scrollBoard) | ||||
|  | ||||
| export default { | ||||
|   name: 'AiDvRender', | ||||
|   props: ['data', 'index', 'theme', 'instance'], | ||||
|   components: { | ||||
|     AiMonitorCarousel, | ||||
|     AiAssist, | ||||
|     AiDvPlot, | ||||
|     // AiSprite, | ||||
|     AiDvSummary, | ||||
|     AiDvDisplay, | ||||
|     AiDvPanel, | ||||
|     AiMonitor, | ||||
|     AiSwiper, | ||||
|     AiDvMap | ||||
|   }, | ||||
|   data() { | ||||
|     return { | ||||
|       // mods, | ||||
|       map: null, | ||||
|       lib: null, | ||||
|       timer: null, | ||||
|       dvTableConfig: [], | ||||
|       mapDialog: false | ||||
|     } | ||||
|   }, | ||||
|   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() | ||||
|         } else if (this.currentType === 'AiDvTable') { | ||||
|           this.dvTableConfig = this.data[this.data.dataType].map((v, i) => { | ||||
|             return { | ||||
|               color: this.data.config[i] ? (this.data.config[i].color || '') : '', | ||||
|               width: this.data.config[i] ? (this.data.config[i].width || '') : '', | ||||
|               align: this.data.config[i] ? (this.data.config[i].align || '') : '' | ||||
|             } | ||||
|           }) | ||||
|           this.data.config = this.dvTableConfig | ||||
|         } | ||||
|       } | ||||
|     } | ||||
|   }, | ||||
|   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> | ||||
		Reference in New Issue
	
	Block a user