提交一波,继续处理数据结构

This commit is contained in:
aixianling
2024-04-15 14:31:13 +08:00
parent e72f7c5e9f
commit fdfbaad6d8
9 changed files with 392 additions and 255 deletions

View File

@@ -17,7 +17,7 @@
</section>
</template>
<script>
import AiDialogBtn from "dui/packages/layout/AiDialogBtn.vue";
import AiDialogBtn from "dui/packages/layout/AiDialogBtn";
import {chartTpl} from "../config";
export default {
@@ -28,7 +28,8 @@ export default {
event: "input"
},
props: {
value: String
value: String,
tpls: {default: () => chartTpl.map(e => e.list).flat()}
},
data() {
return {
@@ -36,7 +37,6 @@ export default {
}
},
computed: {
tpls: () => chartTpl.map(e => e.list).flat(),
current: v => v.tpls.find(e => e.type == v.value) || {}
},
watch: {

View File

@@ -50,6 +50,13 @@
<ai-select placeholder="请选择类型" v-model="item.display" :select-list="summaryOps" size="mini"/>
</config-item>
</template>
<template v-if="/tabs/.test(config.type)">
<group-item v-for="(tab,i) in config.tabs" :key="i" :label="tab.label">
<config-item :label="comp.label" v-for="(comp,j) in tab.comps" :key="i+'_'+j">
<chart-picker v-model="comp.type" :tpls="layers"/>
</config-item>
</group-item>
</template>
<template v-if="/Chart/.test(config.type)">
<config-item label="图表模板">
<chart-picker v-model="config.config" @input="v=>config.echartOps=$echartTpls[v]"/>
@@ -212,16 +219,17 @@
</template>
<script>
import ConfigItem from "./configItem.vue";
import ConfigItem from "./configItem";
import AiDialogBtn from "dui/packages/layout/AiDialogBtn";
import {monitorTypes} from "../config";
import {layers, monitorTypes} from "../config";
import JsonEditor from "./jsonEditor.vue";
import ChartPicker from "./chartPicker.vue";
import AiDvSummary from "@dui/dv/layout/AiDvSummary/AiDvSummary";
import GroupItem from "./groupItem";
export default {
name: 'componentConfig',
components: {ChartPicker, JsonEditor, AiDialogBtn, ConfigItem},
components: {GroupItem, ChartPicker, JsonEditor, AiDialogBtn, ConfigItem},
props: {
config: {default: () => ({})},
instance: Function,
@@ -243,7 +251,8 @@ export default {
{label: "右上", id: "rt"},
{label: "左下", id: "lb"},
{label: "右下", id: "rb"}
]
],
layers
}
},
computed: {

View File

@@ -1,6 +1,6 @@
<template>
<section class="configItem" :class="{topLabel}">
<label v-text="label"/>
<label :class="{bold}" v-text="label"/>
<div class="content fill">
<slot v-if="$slots.default"/>
<div v-else-if="value" v-html="value"/>
@@ -13,7 +13,8 @@ export default {
props: {
label: String,
value: {default: null},
topLabel: Boolean
topLabel: Boolean,
bold: Boolean
},
}
</script>
@@ -35,6 +36,10 @@ export default {
color: #FFFFFF;
font-size: 12px;
text-align: right;
&.bold {
font-weight: bold;
}
}
.el-select .el-tag {

View File

@@ -0,0 +1,32 @@
<script>
export default {
name: "groupItem",
props: ['label']
}
</script>
<template>
<section class="groupItem">
<h2 v-text="label"/>
<slot/>
</section>
</template>
<style scoped lang="scss">
.groupItem {
padding: 10px 10px 20px;
border-bottom: 1px solid #000000;
&:last-child {
border: none;
}
& > h2 {
margin-bottom: 20px;
color: #FFFFFF;
font-size: 15px;
font-weight: 700;
}
}
</style>

View File

@@ -473,6 +473,241 @@ const customHtml = {
html: `<div style="width: 100%;height: 100%;background: #fff;text-align: center;line-height: 300px;font-size: 20px;color: #000;">自定义HTML</div>`
}]
}
const tables = [{
type: 'table',
label: '表格',
title: '表格',
border: 'border6',
width: 650,
height: 400,
zIndex: 1,
thumb: 'https://cdn.cunwuyun.cn/dvcp/dv/tpl/table.png',
dataX: '',
dataY: [],
rowNum: 7,
isShowIndex: '1',
sourceDataId: '',
api: '',
apiData: [],
dataType: 'staticData',
dynamicData: [],
staticData: [{name: '列1', v: 23, v2: 3}, {name: '列2', v: 12, v2: 4}, {name: '列2', v: 12, v2: 4}]
}, {
type: 'AiDvTable',
label: '新版表格',
title: '新版表格',
border: 'border6',
width: 650,
height: 400,
zIndex: 1,
thumb: 'https://cdn.cunwuyun.cn/dvcp/dv/tpl/table.png',
dataX: '',
dataY: [],
rowNum: 7,
stripe: '1',
isShowIndex: '1',
sourceDataId: '',
api: '',
config: [{
width: '', color: '', align: ''
}, {
width: '', color: '', align: ''
}, {
width: '', color: '', align: ''
}],
apiData: [],
dataType: 'staticData',
dynamicData: [],
staticData: [{name: '列1', v: 23, v2: 3}, {name: '列2', v: 12, v2: 4}, {name: '列2', v: 12, v2: 4}]
}, {
type: 'AiRanking',
label: '排行榜',
title: '排行榜',
border: 'border6',
width: 523,
height: 400,
zIndex: 1,
thumb: 'https://cdn.cunwuyun.cn/dvcp/dv/tpl/table.png',
dataX: '',
dataY: [],
rowNum: 7,
subType: 'Ranking1',
stripe: '1',
isShowIndex: '1',
sourceDataId: '',
api: '',
apiData: [],
dataType: 'staticData',
dynamicData: [],
staticData: [{name: '列1', value: 23}, {name: '列2', value: 12}, {name: '列2', value: 12}]
}]
const layouts = [
{
type: 'display',
label: '装饰',
display: 'display0',
width: 840,
height: 540,
isZoom: false,
zIndex: 1,
title: '标题',
thumb: 'https://cdn.cunwuyun.cn/dvcp/dv/tpl/display.png',
sourceDataId: '',
dataType: 'staticData',
staticData: [{
label: '个人服务办理', value: 247
}, {
label: '同比上月', value: 247
}]
}, {
type: 'panel',
label: '边框',
title: '边框',
border: 'border0',
width: 400,
height: 400,
isZoom: false,
zIndex: 1,
thumb: 'https://cdn.cunwuyun.cn/dvcp/dv/tpl/border.png'
}, {
type: 'summary',
label: '数据统计',
display: 'summary0',
width: 480,
height: 240,
zIndex: 1,
top: 0,
left: 0,
dataX: '',
dataY: [],
summaryTitle: '',
border: 'border3',
sourceDataId: '',
title: '数据统计',
dataType: 'staticData',
staticData: [{
key: '个人服务办理', value: 247
}, {
key: '同比上月', value: 247
}],
dynamicData: [],
thumb: 'https://cdn.cunwuyun.cn/dvcp/dv/tpl/total.png'
},
]
const others = [
{
label: "图片", list: [
{
label: "普通图片",
type: "img",
width: 500,
height: 400,
thumb: "https://cdn.cunwuyun.cn/dvcp/dv/img/display0-bg.png"
}
]
},
{
label: '党组织', type: 'partyOrg', list: [{
type: 'partyOrg',
label: '党组织',
width: 840,
height: 800,
zIndex: 1,
top: 0,
left: 0,
dataX: '',
dataY: [],
title: '党组织',
border: 'border3',
sourceDataId: '',
dataType: 'staticData',
staticData: [{
key: '个人服务办理', value: 247
}, {
key: '同比上月', value: 247
}],
dynamicData: [],
thumb: 'https://cdn.cunwuyun.cn/dvcp/dv/tpl/total.png'
}]
}, {
label: '轮播图', list: [{
type: 'swiper',
label: '轮播图',
width: 400,
height: 300,
zIndex: 1,
border: 'border2',
dataType: 'staticData',
staticData: [{
img: 'https://cdn.cunwuyun.cn/dvcp/dv/tpl/pie.png', title: '湖羊', content: `歙县众城湖羊养殖专业合作社
徐晓红 - 18273645627
歙县郑村镇唐跃村碉墅`
}],
thumb: 'https://cdn.cunwuyun.cn/dvcp/dv/tpl/swiper.png'
}, {
type: 'swiper',
label: '轮播图(点指示器)',
width: 800,
height: 358,
zIndex: 1,
border: 'border14',
dataType: 'staticData',
staticData: [{
content: `歙县众城湖羊养殖专业合作社
徐晓红 - 18273645627
歙县郑村镇唐跃村碉墅`
}, {
content: `歙县众城湖羊养殖专业合作社
徐晓红 - 18273645627
歙县郑村镇唐跃村碉墅`
},],
thumb: 'https://cdn.cunwuyun.cn/dvcp/dv/tpl/swiper.png',
dotIndicator: true
}]
}, {
label: '视频播放器', type: 'video', list: [{
type: 'video',
label: '视频播放器',
width: 400,
height: 300,
zIndex: 1,
src: '',
border: 'border2',
thumb: 'https://cdn.cunwuyun.cn/dvcp/dv/tpl/swiper.png'
}]
}, {
label: '视频监控', list: [
{
type: 'monitor',
label: '视频监控',
src: '',
width: 480,
height: 240,
zIndex: 1,
top: 0,
left: 0,
title: '',
moniterId: '',
monitorType: 'cmcc',
api: '/app/appzyvideoequipment/list2',
border: 'border2',
sourceDataId: '',
dataType: 'staticData',
staticData: '',
dynamicData: '',
thumb: 'https://cdn.cunwuyun.cn/dvcp/dv/tpl/video.png'
},
{
type: "monitorCarousel",
label: "视频轮播",
width: 480,
height: 480,
zIndex: 1,
title: "视频轮播",
thumb: "https://cdn.cunwuyun.cn/dvcp/dv/tpl/video.png"
}
]
}, customHtml]
const components = [{
label: '图表', list: [...chartTpl, {
label: "多维图", type: "plot", list: [{
@@ -498,130 +733,14 @@ const components = [{
}]
}]
}, {
label: '表格', list: [{
type: 'table',
label: '表格',
title: '表格',
border: 'border6',
width: 650,
height: 400,
zIndex: 1,
thumb: 'https://cdn.cunwuyun.cn/dvcp/dv/tpl/table.png',
dataX: '',
dataY: [],
rowNum: 7,
isShowIndex: '1',
sourceDataId: '',
api: '',
apiData: [],
dataType: 'staticData',
dynamicData: [],
staticData: [{name: '列1', v: 23, v2: 3}, {name: '列2', v: 12, v2: 4}, {name: '列2', v: 12, v2: 4}]
}, {
type: 'AiDvTable',
label: '新版表格',
title: '新版表格',
border: 'border6',
width: 650,
height: 400,
zIndex: 1,
thumb: 'https://cdn.cunwuyun.cn/dvcp/dv/tpl/table.png',
dataX: '',
dataY: [],
rowNum: 7,
stripe: '1',
isShowIndex: '1',
sourceDataId: '',
api: '',
config: [{
width: '', color: '', align: ''
}, {
width: '', color: '', align: ''
}, {
width: '', color: '', align: ''
}],
apiData: [],
dataType: 'staticData',
dynamicData: [],
staticData: [{name: '列1', v: 23, v2: 3}, {name: '列2', v: 12, v2: 4}, {name: '列2', v: 12, v2: 4}]
}, {
type: 'AiRanking',
label: '排行榜',
title: '排行榜',
border: 'border6',
width: 523,
height: 400,
zIndex: 1,
thumb: 'https://cdn.cunwuyun.cn/dvcp/dv/tpl/table.png',
dataX: '',
dataY: [],
rowNum: 7,
subType: 'Ranking1',
stripe: '1',
isShowIndex: '1',
sourceDataId: '',
api: '',
apiData: [],
dataType: 'staticData',
dynamicData: [],
staticData: [{name: '列1', value: 23}, {name: '列2', value: 12}, {name: '列2', value: 12}]
}]
},
{label: '表格', list: tables},
{
label: "样式", list: [
{
type: 'display',
label: '装饰',
display: 'display0',
width: 840,
height: 540,
isZoom: false,
zIndex: 1,
title: '标题',
thumb: 'https://cdn.cunwuyun.cn/dvcp/dv/tpl/display.png',
sourceDataId: '',
dataType: 'staticData',
staticData: [{
label: '个人服务办理', value: 247
}, {
label: '同比上月', value: 247
}]
}, {
type: 'panel',
label: '边框',
title: '边框',
border: 'border0',
width: 400,
height: 400,
isZoom: false,
zIndex: 1,
thumb: 'https://cdn.cunwuyun.cn/dvcp/dv/tpl/border.png'
}, {
type: 'summary',
label: '数据统计',
display: 'summary0',
width: 480,
height: 240,
zIndex: 1,
top: 0,
left: 0,
dataX: '',
dataY: [],
summaryTitle: '',
border: 'border3',
sourceDataId: '',
title: '数据统计',
dataType: 'staticData',
staticData: [{
key: '个人服务办理', value: 247
}, {
key: '同比上月', value: 247
}],
dynamicData: [],
thumb: 'https://cdn.cunwuyun.cn/dvcp/dv/tpl/total.png'
}
]
label: "样式", list: [...layouts, {
type: "tabs", label: "TAB页签", border: "border13", width: 480,
height: 240, thumb: 'https://cdn.cunwuyun.cn/dvcp/dv/tpl/tabs.png', top: 0, left: 0,
dataType: 'staticData', staticData: {}, title: "TAB页签"
}]
},
{label: '地图', list: maps}, {
type: 'ai3d', label: "3D", list: [{
@@ -646,122 +765,9 @@ const components = [{
thumb: "https://cdn.cunwuyun.cn/dvcp/dv/aiIcon.png"
}]
}, {
label: '其他', list: [
{
label: "图片", list: [
{
label: "普通图片",
type: "img",
width: 500,
height: 400,
thumb: "https://cdn.cunwuyun.cn/dvcp/dv/img/display0-bg.png"
}
]
},
{
label: '党组织', type: 'partyOrg', list: [{
type: 'partyOrg',
label: '党组织',
width: 840,
height: 800,
zIndex: 1,
top: 0,
left: 0,
dataX: '',
dataY: [],
title: '党组织',
border: 'border3',
sourceDataId: '',
dataType: 'staticData',
staticData: [{
key: '个人服务办理', value: 247
}, {
key: '同比上月', value: 247
}],
dynamicData: [],
thumb: 'https://cdn.cunwuyun.cn/dvcp/dv/tpl/total.png'
}]
}, {
label: '轮播图', list: [{
type: 'swiper',
label: '轮播图',
width: 400,
height: 300,
zIndex: 1,
border: 'border2',
dataType: 'staticData',
staticData: [{
img: 'https://cdn.cunwuyun.cn/dvcp/dv/tpl/pie.png', title: '湖羊', content: `歙县众城湖羊养殖专业合作社
徐晓红 - 18273645627
歙县郑村镇唐跃村碉墅`
}],
thumb: 'https://cdn.cunwuyun.cn/dvcp/dv/tpl/swiper.png'
}, {
type: 'swiper',
label: '轮播图(点指示器)',
width: 800,
height: 358,
zIndex: 1,
border: 'border14',
dataType: 'staticData',
staticData: [{
content: `歙县众城湖羊养殖专业合作社
徐晓红 - 18273645627
歙县郑村镇唐跃村碉墅`
}, {
content: `歙县众城湖羊养殖专业合作社
徐晓红 - 18273645627
歙县郑村镇唐跃村碉墅`
},],
thumb: 'https://cdn.cunwuyun.cn/dvcp/dv/tpl/swiper.png',
dotIndicator: true
}]
}, {
label: '视频播放器', type: 'video', list: [{
type: 'video',
label: '视频播放器',
width: 400,
height: 300,
zIndex: 1,
src: '',
border: 'border2',
thumb: 'https://cdn.cunwuyun.cn/dvcp/dv/tpl/swiper.png'
}]
}, {
label: '视频监控', list: [
{
type: 'monitor',
label: '视频监控',
src: '',
width: 480,
height: 240,
zIndex: 1,
top: 0,
left: 0,
title: '',
moniterId: '',
monitorType: 'cmcc',
api: '/app/appzyvideoequipment/list2',
border: 'border2',
sourceDataId: '',
dataType: 'staticData',
staticData: '',
dynamicData: '',
thumb: 'https://cdn.cunwuyun.cn/dvcp/dv/tpl/video.png'
},
{
type: "monitorCarousel",
label: "视频轮播",
width: 480,
height: 480,
zIndex: 1,
title: "视频轮播",
thumb: "https://cdn.cunwuyun.cn/dvcp/dv/tpl/video.png"
}
]
}, customHtml]
label: '其他', list: others
}]
export const layers = [...chartTpl.map(e => e.list), maps, tables, layouts, ...others.map(e => e.list)].flat()
export {components}
/**

View File

@@ -65,6 +65,12 @@
<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"/>
<template v-else-if="currentType=='tabs'">
<div slot="right" class="flex">
<div class="tabItem" v-for="(tab,i) in data.tabs" :key="i" v-text="tab.label" @click="activeTab=i" :class="{active:activeTab==i}"/>
</div>
<ai-dv-tabs v-model="activeTab" :config="data" :values="values"/>
</template>
</ai-dv-panel>
</div>
</template>
@@ -75,14 +81,15 @@ import Vue from "vue"
import {mapState} from 'vuex'
import AiDvMap from "./AiDvMap";
import AiMonitor from "./AiMonitor/AiMonitor";
import AiSwiper from './AiSwiper.vue'
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.vue";
import AiAssist from "./AiAssist.vue";
import AiMonitorCarousel from "./AiMonitorCarousel.vue";
import AiLinkageMap from "./AiLinkageMap.vue";
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)
@@ -90,6 +97,7 @@ export default {
name: 'AiDvRender',
props: ['data', 'index', 'theme', 'instance'],
components: {
AiDvTabs,
AiLinkageMap,
AiMonitorCarousel,
AiAssist,
@@ -110,6 +118,7 @@ export default {
timer: null,
dvTableConfig: [],
mapDialog: false,
activeTab: '0'
}
},
computed: {
@@ -123,6 +132,22 @@ export default {
deep: true, handler() {
if (this.currentType == 'map') {
this.renderMap()
} else if (this.currentType === 'tabs') {
//数据驱动内容生成,新增tab中的内容由设置的数据来生成
const meta = this.$copy(this.data.tabs)
this.data.tabs = Object.entries(this.values).map(([label, v]) => {
const tab = meta.find(e => e.label === label)
const comps = []
if (Array.isArray(v.data)) {
comps.push({label: "内容", ...tab})
} else {
Object.keys(v.data).map(name => {
const layer = tab.comps.find(e => e.label === name)
comps.push({label: name, ...layer})
})
}
return {label, comps}
})
} else if (this.currentType === 'AiDvTable') {
this.dvTableConfig = this.data[this.data.dataType].map((v, i) => {
return {
@@ -241,7 +266,7 @@ export default {
<style lang="scss" scoped>
.AiDvRender {
:deep(.dvScrollBoard1 ) {
:deep(.dvScrollBoard1) {
.header {
background: rgba(0, 0, 0, 0.1) !important;
@@ -282,7 +307,6 @@ export default {
}
}
:deep(.marker) {
position: relative;
@@ -368,5 +392,20 @@ export default {
right: 32px;
backdrop-filter: blur(10px);
}
.tabItem {
color: #1FBECC;
background: #1f9ecc29;
padding: 0 10px;
line-height: 20px;
margin-left: 4px;
font-size: 12px;
user-select: none;
&.active {
border: 1px solid #20B4C5;
color: #02FEFF;
}
}
}
</style>

38
ui/dv/AiDvTabs.vue Normal file
View File

@@ -0,0 +1,38 @@
<script>
import AiDvRender from "./AiDvRender";
export default {
name: "AiDvTabs",
model: {
prop: "active",
event: "input"
},
props: {
active: String,
config: Object,
values: Object
},
components: {AiDvRender},
computed: {
layers: v => {
const tab = v.config?.tabs[v.active]
const values = v.values[tab.label]
return tab.comps?.map(e => ({dataType: "staticData", ...e, staticData: values[e.label]}))?.filter(e => e.type) || []
}
}
}
</script>
<template>
<section class="AiDvTabs">
<ai-dv-render class="fill" v-for="(e,i) in layers" :key="i" :data="e"/>
</section>
</template>
<style scoped lang="scss">
.AiDvTabs {
display: flex;
flex-direction: column;
gap: 16px
}
</style>

View File

@@ -4,6 +4,9 @@
<template v-if="$slots.title" #title>
<slot name="title"/>
</template>
<template v-if="$slots.right" #right>
<slot name="right"/>
</template>
<div :style="{padding}" class="content">
<slot/>
</div>

View File

@@ -1,8 +1,9 @@
<template>
<section class="border13" :class="'border13-' + theme">
<div class="border13-title">
<div class="border13-title" :class="{right:!!$scopedSlots.right}">
<!-- <img src="../asset/ic-badge.png" v-if="theme === '1'" /> -->
<h2>{{ title }}</h2>
<h2 class="fill" v-text="title"/>
<slot name="right"/>
</div>
<div class="slot">
<slot/>
@@ -44,6 +45,10 @@ export default {
height: 28px;
margin-right: 8px;
}
&.right {
padding-right: 0;
}
}
&.border13-1 .border13-title {