456 lines
		
	
	
		
			12 KiB
		
	
	
	
		
			Vue
		
	
	
	
	
	
			
		
		
	
	
			456 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 style="height: 500px;">
 | |
|         <vue-json-editor
 | |
|           v-model="json" 
 | |
|           :show-btns="false"
 | |
|           mode="code"
 | |
|           lang="zh">
 | |
|         </vue-json-editor>
 | |
|       </div>
 | |
|     </ai-dialog>
 | |
|     <div class="layout-config__group" v-if="options.monitorType !== 'hik'">
 | |
|       <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'">
 | |
|       <h2>基础设置</h2>
 | |
|       <div class="layout-config__item">
 | |
|         <label>视频ID</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 vueJsonEditor from 'vue-json-editor'
 | |
|   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: []
 | |
|       }
 | |
|     },
 | |
| 
 | |
|     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.parse(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(JSON.stringify(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>
 |