This commit is contained in:
liuye
2024-04-17 17:50:59 +08:00
14 changed files with 636 additions and 480 deletions

View File

@@ -7,7 +7,7 @@
<el-button v-else type="text">选择图表</el-button>
</template>
<div class="charts">
<div class="item pointer" v-for="tpl in tpls" :key="tpl.type" :class="{selected:selected==tpl.type}"
<div class="item pointer" v-for="(tpl,i) in tpls" :key="i" :class="{selected:selected==tpl.type}"
@click="selected=tpl.type">
<img :src="tpl.thumb"/>
<div v-text="tpl.label"/>
@@ -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

@@ -25,174 +25,7 @@
<div class="layout-right__content--wrapper">
<div class="layout-config__group">
<h2>组件设置</h2>
<config-item label="标题">
<el-input v-model="config.summaryTitle" size="mini" v-if="config.display === 'summary2'"/>
<el-input v-else v-model="config.title" size="mini"/>
</config-item>
<config-item label="边框" v-if="config.type !== 'display'">
<el-select size="mini" v-model="config.border" placeholder="请选择边框" clearable>
<el-option
v-for="(item, index) in borderList"
:key="index"
:label="item"
:value="item">
</el-option>
</el-select>
</config-item>
<template v-if="/(AiDvMap|linkageMap)/.test(config.type)">
<config-item label="地图数据(geoJSON)">
<el-input v-model="config.geoJson" size="mini" clearable placeholder="请输入geoJson的URL地址"/>
</config-item>
</template>
<template v-if="/linkageMap/.test(config.type)">
<config-item v-for="(item,i) in config.summaryConfigs" :key="i" :label="`统计${i+1}`">
<ai-select placeholder="请选择位置" v-model="item.pos" :select-list="positionList" size="mini"/>
<ai-select placeholder="请选择类型" v-model="item.display" :select-list="summaryOps" size="mini"/>
</config-item>
</template>
<template v-if="/Chart/.test(config.type)">
<config-item label="图表模板">
<chart-picker v-model="config.config" @input="v=>config.echartOps=$echartTpls[v]"/>
</config-item>
<config-item label="图表配置项" top-label>
<json-editor v-model="config.echartOps"/>
</config-item>
</template>
<config-item label="视频地址" v-if="config.type === 'video'">
<el-input v-model="config.src" size="mini"/>
</config-item>
<config-item label="图片URL" v-if="config.type=='img'">
<el-input v-model="config.src" size="mini" clearable placeholder="请输入图片URL"/>
</config-item>
<config-item label="视频类型" v-if="config.type === 'monitor'">
<ai-select size="mini" v-model="config.monitorType" :select-list="monitorTypes"/>
</config-item>
<config-item label="样式" v-if="config.type === 'AiRanking'">
<el-select size="mini" v-model="config.subType" placeholder="请选择样式" clearable>
<el-option label="样式1" value="Ranking1"></el-option>
<el-option label="样式2" value="Ranking2"></el-option>
<el-option label="样式3" value="Ranking3"></el-option>
</el-select>
</config-item>
<template v-if="config.type === 'table' || config.type === 'AiDvTable'">
<config-item label="显示排名">
<el-select size="mini" v-model="config.isShowIndex" placeholder="请选择" clearable>
<el-option
v-for="(item, index) in tableStatus"
:key="index"
:label="item.label"
:value="item.value">
</el-option>
</el-select>
</config-item>
<config-item label="斑马纹" v-if="config.type === 'AiDvTable'">
<el-select size="mini" v-model="config.stripe" placeholder="请选择" clearable>
<el-option
label="是"
value="1">
</el-option>
<el-option
label="否"
value="0">
</el-option>
</el-select>
</config-item>
<config-item label="简易样式" v-if="config.type === 'AiDvTable'">
<el-select size="mini" v-model="config.simple" placeholder="请选择" clearable>
<el-option
label="是"
value="1">
</el-option>
<el-option
label="否"
value="0">
</el-option>
</el-select>
</config-item>
<config-item label="表格行数" v-if="config.type !== 'AiDvTable'">
<el-input-number size="mini" style="width: 232px" :min="0" v-model="config.rowNum" controls-position="right"/>
</config-item>
<config-item v-if="config.type === 'AiDvTable'" v-for="(item, i) in config.config" :key="i" :label="`第${i+1}列`">
<el-select size="mini" style="width: 80px;" v-model="item.align" placeholder="请选择" clearable>
<el-option label="居中" value="center"></el-option>
<el-option label="居左" value="left"></el-option>
<el-option label="居右" value="right"></el-option>
</el-select>
<el-color-picker v-model="item.color" class="mar-h10" size="mini"/>
<el-input-number v-model="item.width" label="描述文字" controls-position="right" size="mini"/>
</config-item>
</template>
<template v-if="config.type === 'map'">
<div class="layout-config__item">
<label>遮罩层</label>
<div class="layout-config__item--right">
<el-select size="mini" v-model="config.mask" placeholder="请选择" clearable>
<el-option label="是" value="1"></el-option>
<el-option label="否" value="2"></el-option>
</el-select>
</div>
</div>
<div class="layout-config__item">
<label>地图图层</label>
<div class="layout-config__item--right">
<el-select size="mini" v-model="config.layers" placeholder="请选择" clearable>
<el-option label="地图" value="vector"/>
<el-option label="卫星" value="satellite"/>
</el-select>
</div>
</div>
<div class="layout-config__item">
<label>选择地区</label>
<div class="layout-config__item--right">
<AiAreaGet :instance="instance" :valueLevel="3" v-model="config.areaId" placeholder="地图展示的中心"/>
</div>
</div>
<div class="layout-config__item">
<label>限制地区</label>
<div class="layout-config__item--right">
<ai-select v-model="config.limitArea" :selectList="dict.getDict('yesOrNo')"/>
</div>
</div>
<div class="layout-config__item">
<label>显示标签</label>
<div class="layout-config__item--right">
<ai-select v-model="config.alwaysShow" :selectList="dict.getDict('yesOrNo')"/>
</div>
</div>
<div class="layout-config__item">
<label>展示光轨</label>
<div class="layout-config__item--right">
<ai-select v-model="config.pulseLines" :selectList="dict.getDict('yesOrNo')"/>
</div>
</div>
<div class="layout-config__item layout-config__item--input">
<label>地图样式</label>
<div class="layout-config__item--right">
<el-input size="mini" v-model="config.mapStyle" clearable placeholder="请输入地图样式ID,从UI处获取.."/>
</div>
</div>
<div class="layout-config__item layout-config__item--input">
<label>3D地图</label>
<div class="layout-config__item--right">
<ai-select v-model="config.is3d" :selectList="dict.getDict('yesOrNo')"/>
</div>
</div>
<div class="layout-config__item layout-config__item--input" v-if="config.is3d==1">
<label>3D环绕</label>
<div class="layout-config__item--right">
<ai-select v-model="config.is3dAround" :selectList="dict.getDict('yesOrNo')"/>
</div>
</div>
<div class="layout-config__item layout-config__item--input">
<label>显示图例</label>
<div class="layout-config__item--right">
<ai-select v-model="config.showPingchangMapLegend" :selectList="dict.getDict('yesOrNo')"/>
</div>
</div>
</template>
<config-item label="数据汇总" v-if="config.type === 'summary'">
<ai-select size="mini" v-model="config.display" placeholder="请选择类型" :select-list="summaryOps"/>
</config-item>
<config-extra v-model="config"/>
</div>
</div>
<div class="layout-right__content--wrapper">
@@ -212,43 +45,17 @@
</template>
<script>
import ConfigItem from "./configItem.vue";
import AiDialogBtn from "dui/packages/layout/AiDialogBtn";
import {monitorTypes} from "../config";
import JsonEditor from "./jsonEditor.vue";
import ChartPicker from "./chartPicker.vue";
import AiDvSummary from "@dui/dv/layout/AiDvSummary/AiDvSummary";
import ConfigItem from "./configItem";
import ConfigExtra from "./configExtra.vue";
export default {
name: 'componentConfig',
components: {ChartPicker, JsonEditor, AiDialogBtn, ConfigItem},
components: {ConfigExtra, ConfigItem},
props: {
config: {default: () => ({})},
instance: Function,
dict: Object,
},
data() {
return {
borderList: ['border0', 'border1', 'border2', 'border3', 'border4', 'border5', 'border6', 'border7', 'border8', 'border9', 'border10',
'border11', 'border12', 'border13', 'border14', 'border15'],//边框待选项
//是否显示排名
tableStatus: [
{label: '是', value: '1'},
{label: '否', value: '0'}
],
dialog: {},
monitorTypes,
positionList: [
{label: "左上", id: "lt"},
{label: "右上", id: "rt"},
{label: "左下", id: "lb"},
{label: "右下", id: "rb"}
]
}
},
computed: {
summaryOps: () => Object.keys(AiDvSummary.components).map(e => ({label: e, id: e})),
}
}
</script>

View File

@@ -0,0 +1,239 @@
<script>
import GroupItem from "./groupItem";
import ConfigItem from "./configItem";
import ChartPicker from "./chartPicker";
import JsonEditor from "./jsonEditor";
import {layers, monitorTypes} from "../config";
import AiDvSummary from "@dui/dv/layout/AiDvSummary/AiDvSummary";
export default {
name: "configExtra",
components: {JsonEditor, ChartPicker, ConfigItem, GroupItem},
props: ['config'],
model: {
prop: 'config',
event: 'input'
},
data() {
return {
borderList: ['border0', 'border1', 'border2', 'border3', 'border4', 'border5', 'border6', 'border7', 'border8', 'border9', 'border10',
'border11', 'border12', 'border13', 'border14', 'border15'],//边框待选项
layers, monitorTypes,
tableStatus: [
{label: '是', value: '1'},
{label: '否', value: '0'}
],
positionList: [
{label: "左上", id: "lt"},
{label: "右上", id: "rt"},
{label: "左下", id: "lb"},
{label: "右下", id: "rb"}
],
}
},
computed: {
summaryOps: () => Object.keys(AiDvSummary.components).map(e => ({label: e, id: e})),
values: v => v.config?.[v.config?.dataType] || v.config.data
},
watch: {
values: {
immediate: true, deep: true,
handler() {
if (this.config.type === 'AiDvTable') {
this.config.config = this.values?.map((v, i) => {
return {
color: this.config.config?.[i]?.color || '',
width: this.config.config?.[i]?.width || '',
align: this.config.config?.[i]?.align || '',
}
})
}
}
}
},
}
</script>
<template>
<section class="configExtra">
<config-item label="标题">
<el-input v-model="config.summaryTitle" size="mini" v-if="config.display === 'summary2'" placeholder="请输入标题"/>
<el-input v-else v-model="config.title" size="mini" placeholder="请输入标题"/>
</config-item>
<config-item label="边框" v-if="config.type !== 'display'">
<el-select size="mini" v-model="config.border" placeholder="请选择边框" clearable>
<el-option
v-for="(item, index) in borderList"
:key="index"
:label="item"
:value="item">
</el-option>
</el-select>
</config-item>
<config-item label="图表模板">
<chart-picker v-model="config.type" :tpls="layers" @input="v=>config.echartOps=$echartTpls[v]"/>
</config-item>
<template v-if="/(AiDvMap|linkageMap)/.test(config.type)">
<config-item label="地图数据(geoJSON)">
<el-input v-model="config.geoJson" size="mini" clearable placeholder="请输入geoJson的URL地址"/>
</config-item>
</template>
<template v-if="/linkageMap/.test(config.type)">
<config-item v-for="(item,i) in config.summaryConfigs" :key="i" :label="`统计${i+1}`">
<ai-select placeholder="请选择位置" v-model="item.pos" :select-list="positionList" size="mini"/>
<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 values" :key="i" :label="i">
<group-item v-for="(comp,j) in tab" :key="j" :label="comp.name">
<config-extra v-model="tab[j]"/>
</group-item>
</group-item>
</template>
<template v-if="/Chart/.test(config.type)">
<config-item label="图表配置项" top-label>
<json-editor v-model="config.echartOps"/>
</config-item>
</template>
<config-item label="视频地址" v-if="config.type === 'video'">
<el-input v-model="config.src" size="mini"/>
</config-item>
<config-item label="图片URL" v-if="config.type=='img'">
<el-input v-model="config.src" size="mini" clearable placeholder="请输入图片URL"/>
</config-item>
<config-item label="视频类型" v-if="config.type === 'monitor'">
<ai-select size="mini" v-model="config.monitorType" :select-list="monitorTypes"/>
</config-item>
<config-item label="样式" v-if="config.type === 'AiRanking'">
<el-select size="mini" v-model="config.subType" placeholder="请选择样式" clearable>
<el-option label="样式1" value="Ranking1"></el-option>
<el-option label="样式2" value="Ranking2"></el-option>
<el-option label="样式3" value="Ranking3"></el-option>
</el-select>
</config-item>
<template v-if="config.type === 'table' || config.type === 'AiDvTable'">
<config-item label="显示排名">
<el-select size="mini" v-model="config.isShowIndex" placeholder="请选择" clearable>
<el-option
v-for="(item, index) in tableStatus"
:key="index"
:label="item.label"
:value="item.value">
</el-option>
</el-select>
</config-item>
<config-item label="斑马纹" v-if="config.type === 'AiDvTable'">
<el-select size="mini" v-model="config.stripe" placeholder="请选择" clearable>
<el-option
label="是"
value="1">
</el-option>
<el-option
label="否"
value="0">
</el-option>
</el-select>
</config-item>
<config-item label="简易样式" v-if="config.type === 'AiDvTable'">
<el-select size="mini" v-model="config.simple" placeholder="请选择" clearable>
<el-option
label="是"
value="1">
</el-option>
<el-option
label="否"
value="0">
</el-option>
</el-select>
</config-item>
<config-item label="表格行数" v-if="config.type !== 'AiDvTable'">
<el-input-number size="mini" style="width: 232px" :min="0" v-model="config.rowNum" controls-position="right"/>
</config-item>
<config-item v-if="config.type === 'AiDvTable'" v-for="(item, i) in config.config" :key="i" :label="`第${i+1}列`">
<el-select size="mini" style="width: 80px;" v-model="item.align" placeholder="请选择" clearable>
<el-option label="居中" value="center"></el-option>
<el-option label="居左" value="left"></el-option>
<el-option label="居右" value="right"></el-option>
</el-select>
<el-color-picker v-model="item.color" class="mar-h10" size="mini"/>
<el-input-number v-model="item.width" label="描述文字" controls-position="right" size="mini"/>
</config-item>
</template>
<template v-if="config.type === 'map'">
<div class="layout-config__item">
<label>遮罩层</label>
<div class="layout-config__item--right">
<el-select size="mini" v-model="config.mask" placeholder="请选择" clearable>
<el-option label="是" value="1"></el-option>
<el-option label="否" value="2"></el-option>
</el-select>
</div>
</div>
<div class="layout-config__item">
<label>地图图层</label>
<div class="layout-config__item--right">
<el-select size="mini" v-model="config.layers" placeholder="请选择" clearable>
<el-option label="地图" value="vector"/>
<el-option label="卫星" value="satellite"/>
</el-select>
</div>
</div>
<div class="layout-config__item">
<label>选择地区</label>
<div class="layout-config__item--right">
<AiAreaGet :instance="instance" :valueLevel="3" v-model="config.areaId" placeholder="地图展示的中心"/>
</div>
</div>
<div class="layout-config__item">
<label>限制地区</label>
<div class="layout-config__item--right">
<ai-select v-model="config.limitArea" :selectList="dict.getDict('yesOrNo')"/>
</div>
</div>
<div class="layout-config__item">
<label>显示标签</label>
<div class="layout-config__item--right">
<ai-select v-model="config.alwaysShow" :selectList="dict.getDict('yesOrNo')"/>
</div>
</div>
<div class="layout-config__item">
<label>展示光轨</label>
<div class="layout-config__item--right">
<ai-select v-model="config.pulseLines" :selectList="dict.getDict('yesOrNo')"/>
</div>
</div>
<div class="layout-config__item layout-config__item--input">
<label>地图样式</label>
<div class="layout-config__item--right">
<el-input size="mini" v-model="config.mapStyle" clearable placeholder="请输入地图样式ID,从UI处获取.."/>
</div>
</div>
<div class="layout-config__item layout-config__item--input">
<label>3D地图</label>
<div class="layout-config__item--right">
<ai-select v-model="config.is3d" :selectList="dict.getDict('yesOrNo')"/>
</div>
</div>
<div class="layout-config__item layout-config__item--input" v-if="config.is3d==1">
<label>3D环绕</label>
<div class="layout-config__item--right">
<ai-select v-model="config.is3dAround" :selectList="dict.getDict('yesOrNo')"/>
</div>
</div>
<div class="layout-config__item layout-config__item--input">
<label>显示图例</label>
<div class="layout-config__item--right">
<ai-select v-model="config.showPingchangMapLegend" :selectList="dict.getDict('yesOrNo')"/>
</div>
</div>
</template>
<config-item label="数据汇总" v-if="config.type === 'summary'">
<ai-select size="mini" v-model="config.display" placeholder="请选择类型" :select-list="summaryOps"/>
</config-item>
</section>
</template>
<style scoped lang="scss">
</style>

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-if="label" 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

@@ -172,7 +172,7 @@ export const chartTpl = [{
thumb: 'https://cdn.cunwuyun.cn/dvcp/dv/tpl/bar10.png',
height: 300,
dataType: 'staticData',
staticData: [{name: '阿斯达', v1: 23}, {name: '水电费', v1: 12}, {name: '凡哥', v1: 67}, {name: '党费', v1: 98}],
staticData: [{name: '阿斯达', v1: 23}, {name: '水电费', v1: 12}],
config: 'barChart10'
},
]
@@ -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

@@ -130,7 +130,7 @@ export default {
fontSize: 22
},
itemStyle: {
borderColor: "rgba(2, 198, 220, 1)",
borderColor: "rgba(2, 198, 220, 0)",
borderWidth: 2,
areaColor: "#02bcff29",
shadowBlur: 120,

View File

@@ -1,9 +1,10 @@
<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-if="currentType !== 'display'"
v-else
:padding="data.padding"
:title="data.title"
:theme="theme"
@@ -25,7 +26,7 @@
:key="`chart-${index}`"
:theme="theme"
:data="values"
:tpl="data.config"
:tpl="currentType"
:ops="data.echartOps"/>
<AiDvTable
v-else-if="currentType === 'AiDvTable'"
@@ -33,7 +34,7 @@
:stripe="data.stripe"
:theme="theme"
:isShowIndex="data.isShowIndex"
:config="dvTableConfig"
:config="data.config"
:data="values" :simple="data.simple==1">
</AiDvTable>
<AiRanking
@@ -75,14 +76,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 +92,7 @@ export default {
name: 'AiDvRender',
props: ['data', 'index', 'theme', 'instance'],
components: {
AiDvTabs,
AiLinkageMap,
AiMonitorCarousel,
AiAssist,
@@ -108,8 +111,8 @@ export default {
map: null,
lib: null,
timer: null,
dvTableConfig: [],
mapDialog: false,
activeTab: '0'
}
},
computed: {
@@ -123,15 +126,6 @@ export default {
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
}
}
}
@@ -241,7 +235,7 @@ export default {
<style lang="scss" scoped>
.AiDvRender {
:deep(.dvScrollBoard1 ) {
:deep(.dvScrollBoard1) {
.header {
background: rgba(0, 0, 0, 0.1) !important;
@@ -282,7 +276,6 @@ export default {
}
}
:deep(.marker) {
position: relative;

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

@@ -0,0 +1,67 @@
<script>
import AiDvPanel from "./layout/AiDvPanel/AiDvPanel.vue";
export default {
name: "AiDvTabs",
components: {AiDvPanel},
props: {
config: Object,
},
data() {
return {activeTab: '0'}
},
computed: {
values: v => v.config?.[v.config?.dataType] || {},
tabs: v => Object.keys(v.values),
layers() {
return this.values[this.activeTab].map(e => ({dataType: "staticData", ...e, staticData: e.data})) || []
}
},
watch: {
tabs: {
immediate: true, deep: true,
handler(v) {
this.activeTab = v[0]
}
}
}
}
</script>
<template>
<section class="AiDvTabs">
<ai-dv-panel :padding="config.padding" :title="config.title" :theme="$attrs.theme" :border="config.border || ''">
<div slot="right" class="flex">
<div class="tabItem" v-for="(tab,i) in tabs" :key="i" v-text="tab" @click="activeTab=tab" :class="{active:activeTab==tab}"/>
</div>
<ai-dv-render class="fill" v-for="(e,i) in layers" :key="i" :data="layers[i]" :index="i"/>
</ai-dv-panel>
</section>
</template>
<style scoped lang="scss">
.AiDvTabs {
height: 100%;
:deep(.content) {
display: flex;
flex-direction: column;
gap: 16px;
}
.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>

View File

@@ -21,24 +21,23 @@ export default {
min: 0,
max: 8000,
maxOpen: true,
itemWidth: 14,
itemHeight: 14,
align: 'left',
itemSymbol: 'circle',
inRange: {
color: [
"#25EDF4",
"rgba(12,222,233,0.9)",
"rgba(11,208,218,0.81)",
"rgba(11,193,213,0.72)",
"rgba(11,172,193,0.63)",
"rgba(9,147,174,0.54)",
"rgba(7,108,136,0.45)",
"rgba(6,78,107,0.36)",
"rgba(5,66,97,0.27)"].reverse()
"#25b3f866", "#73DCFC66", "#35FDFC66", "#37FBB980", "#05FA8280",
"#D8F98A80", "#F3C83F80", "#FD900480", "#FB374480"
],
},
inverse: true,
outOfRange: {color: "#25EDF4"},
textStyle: {
color: "#fff"
color: "#9BB7D4FF"
},
calculable: true
},
geo: []
},
dialog: false,
detail: [],
@@ -56,7 +55,7 @@ export default {
},
computed: {
sta: v => v.config.summaryConfigs || [],
mapData: v => v.geoData.map(e => ({name: e.name.replace(/([市县区])/g, ""), value: parseInt(e.低风险纠纷) + parseInt(e.中风险纠纷) + parseInt(e.高风险纠纷)}))
mapData: v => v.geoData.map(e => ({name: e.name.replace(/([市县区])/g, ""), value: parseInt(e.排查受理总数)}))
},
methods: {
getData(type = "530300000000") {
@@ -65,7 +64,6 @@ export default {
if (type == "530300000000") {
this.geoData = json.map
this.$refs.map.chart?.setOption({series: {data: this.mapData}})
console.log(this.$refs.map.chart?.getOption()?.series)
}
this.config.summaryConfigs = json.sta?.map((e, i) => ({pos: ["rt", "lb", 'lt', 'rb'][i % 4], display: "summary20", ...e})) || []
})
@@ -89,6 +87,7 @@ export default {
高风险纠纷: "#FF6868",
中风险纠纷: "#FFAB68",
低风险纠纷: "#7FE89E",
排查受理总数: "#25EDF4"
}[k]
})
}

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 {

View File

@@ -118,7 +118,7 @@ export default {
columns: v => v.header.map((e, i) => {
let item = {}
Object.values(e).forEach(label => {
const {align, width, color} = v.config[i]
const {align, width, color} = (v.config[i] || {})
item.align = align
item.prop = `col${i}`
item.label = label
@@ -233,7 +233,7 @@ export default {
}
.body {
height: calc(100% - 40px);
height: calc(100% - 32px);
padding: 10px 0;
overflow-y: auto;
box-sizing: border-box;

View File

@@ -129,7 +129,7 @@ export default {
theme() {
this.refresh()
},
tpl(v) {
type(v) {
v && this.refresh()
}
},