458 lines
12 KiB
Vue
458 lines
12 KiB
Vue
<template>
|
|
<div class="layout-config__group--wrapper">
|
|
<ai-dialog
|
|
append-to-body
|
|
:visible.sync="isShowEditor"
|
|
width="1000px"
|
|
class="layout-config__edit"
|
|
title="编辑器"
|
|
@onConfirm="onConfirm">
|
|
<div>
|
|
<b-code-editor v-model="json" lint="dracula" auto-format height="440px"></b-code-editor>
|
|
</div>
|
|
</ai-dialog>
|
|
<div class="layout-config__group" v-if="options.monitorType !== 'hik' && options.monitorType !== 'dahua'">
|
|
<h2>基础设置</h2>
|
|
<div class="layout-config__item">
|
|
<label>数据类型</label>
|
|
<div class="layout-config__item--right">
|
|
<el-select size="mini" v-model="options.dataType" placeholder="请选择数据类型">
|
|
<el-option
|
|
v-for="item in dataTypes"
|
|
:key="item.value"
|
|
:label="item.label"
|
|
:value="item.value">
|
|
</el-option>
|
|
</el-select>
|
|
</div>
|
|
</div>
|
|
<div class="layout-config__code" v-if="options.dataType === 'staticData'">
|
|
<el-button @click="showEditor" class="layout-config__code--btn" title="编辑" type="text" icon="iconfont iconjdq_led_edit"></el-button>
|
|
<vue-json-editor
|
|
:value="options.staticData"
|
|
:show-btns="false"
|
|
mode="view"
|
|
lang="zh">
|
|
</vue-json-editor>
|
|
</div>
|
|
<template v-else-if="options.dataType === 'dynamicData'">
|
|
<div class="layout-config__item">
|
|
<label>数据源</label>
|
|
<div class="layout-config__item--right">
|
|
<el-select size="mini" v-model="options.sourceDataId" placeholder="请选择数据源" @change="onDataChange">
|
|
<el-option
|
|
v-for="item in sourceData"
|
|
:key="item.id"
|
|
:label="item.description"
|
|
:value="item.id">
|
|
</el-option>
|
|
</el-select>
|
|
</div>
|
|
</div>
|
|
</template>
|
|
<template v-else>
|
|
<div class="layout-config__item">
|
|
<label>接口地址</label>
|
|
<div class="layout-config__item--right">
|
|
<el-input size="mini" v-model="options.api" @blur="onApiChange"></el-input>
|
|
</div>
|
|
</div>
|
|
</template>
|
|
</div>
|
|
<div class="layout-config__group" v-if="options.monitorType === 'hik' || options.monitorType === 'dahua'">
|
|
<h2>基础设置</h2>
|
|
<div class="layout-config__item">
|
|
<label>视频地址</label>
|
|
<div class="layout-config__item--right">
|
|
<el-input size="mini" v-model="options.src"></el-input>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div class="layout-config__group" v-if="options.dataType !== 'staticData' && options.type === 'monitor' && options.monitorType === 'cmcc'">
|
|
<h2>字段设置</h2>
|
|
<div class="layout-config__item">
|
|
<label>监控视频</label>
|
|
<div class="layout-config__item--right">
|
|
<el-select size="mini" v-model="options.moniterId" placeholder="请选择监控视频" @change="onMoniterId">
|
|
<el-option
|
|
v-for="(item, index) in monitorList"
|
|
:key="index"
|
|
:label="item.name"
|
|
:value="item.id">
|
|
</el-option>
|
|
</el-select>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div class="layout-config__group" v-if="options.dataType !== 'staticData' && options.type !== 'monitor' && keys.length && options.type !== 'table'">
|
|
<h2>字段设置</h2>
|
|
<div class="layout-config__item">
|
|
<label>X轴设置</label>
|
|
<div class="layout-config__item--right">
|
|
<el-select size="mini" v-model="options.dataX" placeholder="请选择X轴" @change="onChooseChange">
|
|
<el-option
|
|
v-for="(item, index) in keys"
|
|
:key="index"
|
|
:label="item"
|
|
:value="item">
|
|
</el-option>
|
|
</el-select>
|
|
</div>
|
|
</div>
|
|
<div class="layout-config__item">
|
|
<label>Y轴设置</label>
|
|
<div class="layout-config__item--right">
|
|
<el-select size="mini" multiple :multiple-limit="options.type.indexOf('pie') > -1 ? 1 : 100" v-model="options.dataY" collapse-tags placeholder="请选择Y轴" @change="onChooseChange">
|
|
<el-option
|
|
v-for="(item, index) in keys"
|
|
:key="index"
|
|
:label="item"
|
|
:value="item">
|
|
</el-option>
|
|
</el-select>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</template>
|
|
|
|
<script>
|
|
import Vue from 'vue'
|
|
import vueJsonEditor from 'vue-json-editor'
|
|
import CodeEditor from 'bin-code-editor'
|
|
import 'bin-code-editor/lib/styles/index.css'
|
|
|
|
Vue.use(CodeEditor)
|
|
|
|
export default {
|
|
name: 'dataCofing',
|
|
|
|
props: {
|
|
options: Object,
|
|
instance: Function,
|
|
dict: Object,
|
|
params: Object,
|
|
urlPrefix: String
|
|
},
|
|
|
|
data () {
|
|
return {
|
|
dataTypes: [
|
|
{
|
|
value: 'staticData',
|
|
label: '静态数据'
|
|
},
|
|
{
|
|
value: 'dynamicData',
|
|
label: '动态数据'
|
|
},
|
|
{
|
|
value: 'apiData',
|
|
label: '接口'
|
|
}
|
|
],
|
|
isShowEditor: false,
|
|
json: {},
|
|
sourceDataId: '',
|
|
sourceData: [],
|
|
keys: [],
|
|
monitorList: [],
|
|
list: [],
|
|
jsonData: `{"title":"测试json数据","children":[{"name":"子项名称", "desc":"子项说明" },{"name":"子项名称1", "desc":"子项说明1" }]}`
|
|
}
|
|
},
|
|
|
|
components: {
|
|
vueJsonEditor
|
|
},
|
|
|
|
mounted () {
|
|
this.getDataList()
|
|
|
|
if ((this.options.dataY && this.options.dataY.length && this.options.dataX) || this.options.type === 'monitor') {
|
|
const api = this.options.dataType === 'apiData' ? this.options.api : `${this.urlPrefix}/appdiylargescreen/statisticsByLsid?id=${this.options.sourceDataId}`
|
|
this.instance.post(api).then(res => {
|
|
if (res.code == 0) {
|
|
if (res.data.length && this.options.type !== 'monitor') {
|
|
this.list = res.data
|
|
this.keys = Object.keys(res.data[0])
|
|
|
|
this.$nextTick(() => {
|
|
this.onChooseChange()
|
|
})
|
|
} else if (this.options.type === 'monitor') {
|
|
this.monitorList = res.data
|
|
|
|
if (this.options.src) {
|
|
const obj = res.data.filter(v => this.options.title === v.name)
|
|
|
|
if (obj.length) {
|
|
this.options.src = obj[0].url
|
|
}
|
|
}
|
|
}
|
|
}
|
|
})
|
|
}
|
|
},
|
|
|
|
methods: {
|
|
showEditor () {
|
|
this.json = JSON.stringify(this.options.staticData)
|
|
this.isShowEditor = true
|
|
},
|
|
|
|
onMoniterId (e) {
|
|
this.instance.post(`${this.urlPrefix}/appzyvideoequipment/getWebSdkUrl?deviceId=${e}`).then(res => {
|
|
if (res.code == 0) {
|
|
this.options.src = JSON.parse(res.data).url
|
|
}
|
|
})
|
|
},
|
|
|
|
getDataList () {
|
|
this.instance.post(`${this.urlPrefix}/appdiylargescreen/allDatasourceByPage`, null, {
|
|
params: {
|
|
current: 1,
|
|
size: 10000
|
|
}
|
|
}).then(res => {
|
|
if (res.code == 0) {
|
|
this.sourceData = res.data.records
|
|
}
|
|
})
|
|
},
|
|
|
|
onApiChange () {
|
|
this.options.dataX = ''
|
|
this.options.dataY = []
|
|
this.instance.post(this.options.api).then(res => {
|
|
if (res.code == 0) {
|
|
if (res.data.length) {
|
|
if (this.options.type === 'table') {
|
|
const keys = Object.keys(res.data[0])
|
|
const list = res.data
|
|
this.options.apiData = keys.map(v => {
|
|
let obj = {}
|
|
list.forEach((item, index) => {
|
|
obj[`v${index}`] = item[v]
|
|
})
|
|
|
|
return {
|
|
row: v,
|
|
...obj
|
|
}
|
|
})
|
|
} else if (this.options.type === 'summary') {
|
|
this.options.apiData = Object.keys(res.data[0]).map(item => {
|
|
return {
|
|
key: item,
|
|
value: res.data[0][item]
|
|
}
|
|
})
|
|
} else if (this.options.type === 'monitor') {
|
|
this.monitorList = res.data
|
|
} else {
|
|
this.list = res.data
|
|
this.keys = Object.keys(res.data[0])
|
|
}
|
|
}
|
|
}
|
|
})
|
|
},
|
|
|
|
onChooseChange () {
|
|
let arr = []
|
|
if (this.options.dataX && this.options.dataY.length) {
|
|
this.list.forEach(item => {
|
|
let obj = {}
|
|
this.options.dataY.forEach(v => {
|
|
obj[v] = item[v]
|
|
})
|
|
arr.push({
|
|
[this.options.dataX]: item[this.options.dataX],
|
|
...obj
|
|
})
|
|
})
|
|
|
|
this.options[this.options.dataType] = arr
|
|
}
|
|
},
|
|
|
|
onDataChange (e) {
|
|
this.options.dataX = ''
|
|
this.options.dataY = []
|
|
this.instance.post(`${this.urlPrefix}/appdiylargescreen/statisticsByLsid?id=${e}`).then(res => {
|
|
if (res.code == 0) {
|
|
if (res.data.length) {
|
|
if (this.options.type === 'table') {
|
|
const keys = Object.keys(res.data[0])
|
|
const list = res.data
|
|
this.options.dynamicData = keys.map(v => {
|
|
let obj = {}
|
|
list.forEach((item, index) => {
|
|
obj[`v${index}`] = item[v]
|
|
})
|
|
|
|
return {
|
|
row: v,
|
|
...obj
|
|
}
|
|
})
|
|
} else if (this.options.type === 'summary') {
|
|
this.options.dynamicData = Object.keys(res.data[0]).map(item => {
|
|
return {
|
|
key: item,
|
|
value: res.data[0][item]
|
|
}
|
|
})
|
|
} else {
|
|
this.list = res.data
|
|
this.keys = Object.keys(res.data[0])
|
|
}
|
|
}
|
|
}
|
|
})
|
|
},
|
|
|
|
onConfirm () {
|
|
this.$set(this.options, 'staticData', JSON.parse(this.json))
|
|
this.isShowEditor = false
|
|
this.$emit('change')
|
|
}
|
|
}
|
|
}
|
|
</script>
|
|
|
|
<style lang="scss">
|
|
.el-dialog__body {
|
|
.jsoneditor-vue {
|
|
height: 480px;
|
|
|
|
.jsoneditor-poweredBy {
|
|
display: none;
|
|
}
|
|
}
|
|
}
|
|
.layout-config__group--wrapper {
|
|
.layout-config__code .jsoneditor-vue {
|
|
.jsoneditor-menu {
|
|
display: none;
|
|
}
|
|
|
|
.jsoneditor {
|
|
border: 1px solid #030411;
|
|
background: #0e1013;
|
|
}
|
|
|
|
.jsoneditor-field {
|
|
color: gray;
|
|
}
|
|
|
|
.jsoneditor-tree button:focus {
|
|
background-color: transparent;
|
|
outline: none;
|
|
}
|
|
}
|
|
|
|
.layout-config__group {
|
|
padding: 10px 10px 20px;
|
|
border-bottom: 1px solid #000000;
|
|
|
|
&:last-child {
|
|
border: none;
|
|
}
|
|
|
|
.layout-config__code {
|
|
position: relative;
|
|
padding-left: 10px;
|
|
|
|
.layout-config__code--btn {
|
|
position: absolute;
|
|
right: 0;
|
|
top: 0;
|
|
color: gray;
|
|
z-index: 1;
|
|
|
|
&:hover {
|
|
opacity: 0.8 ;
|
|
}
|
|
}
|
|
}
|
|
|
|
& > h2 {
|
|
margin-bottom: 20px;
|
|
color: #FFFFFF;
|
|
font-size: 15px;
|
|
font-weight: 700;
|
|
}
|
|
}
|
|
|
|
.layout-config__item {
|
|
display: flex;
|
|
align-items: center;
|
|
justify-content: space-between;
|
|
margin-bottom: 10px;
|
|
|
|
&:last-child {
|
|
margin-bottom: 0;
|
|
}
|
|
|
|
label {
|
|
flex-shrink: 0;
|
|
width: 60px;
|
|
color: #FFFFFF;
|
|
font-size: 12px;
|
|
text-align: right;
|
|
}
|
|
|
|
.layout-config__item--right {
|
|
display: flex;
|
|
align-items: center;
|
|
justify-content: flex-end;
|
|
width: 200px;
|
|
text-align: right;
|
|
}
|
|
|
|
.el-select .el-tag {
|
|
color: #fff;
|
|
background: transparent;
|
|
}
|
|
|
|
input {
|
|
background: #262C33;
|
|
font-size: 12px;
|
|
color: #fff;
|
|
border: 1px solid #030411;
|
|
}
|
|
|
|
.el-input__icon {
|
|
color: #fff;
|
|
}
|
|
|
|
.el-switch__label {
|
|
color: #fff;
|
|
}
|
|
|
|
.el-select {
|
|
width: 100%;
|
|
|
|
&:last-child {
|
|
margin-right: 0;
|
|
}
|
|
|
|
input {
|
|
background: #262C33;
|
|
font-size: 12px;
|
|
color: #fff;
|
|
border: 1px solid #030411;
|
|
}
|
|
|
|
.el-input__icon {
|
|
color: #fff;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
</style>
|