Merge remote-tracking branch 'origin/master'

main
hong.yang 1 year ago
commit 28a14968ab

@ -38,16 +38,17 @@ export default {
},
methods: {
//
// getDataByExpression (config) {
// if (this.config.expression) {
// // eslint-disable-next-line no-new-func
// const result = new Function('dataset', this.config.expression)
// config.customize.title = result(this.dataset)
// //
// this.updateDataset({ code: config.code, title: config.title, data: [{ title: config.customize.title }] })
// this.changeChartConfig(config)
// }
// },
getDataByExpression (config) {
//
if (this.config.expressionCodes && this.config.expressionCodes.length) {
// eslint-disable-next-line no-new-func
const result = new Function('dataset', 'computedDatas', this.config.expression)
config.customize.title = result(this.dataset, this.computedDatas)
//
this.updateComputedDatas({ code: config.code, title: config.title, data: config.customize.title })
// this.changeChartConfig(config)
}
},
dataFormatting (config, data) {
//
if (config.dataSource.businessKey) {

@ -21,7 +21,7 @@
prop="title"
>
<el-input
v-model="config.customize.title"
v-model="config.title"
placeholder="请输入标题"
clearable
/>

@ -23,6 +23,14 @@ export const settingConfig = {
label: '维度', // 维度/查询字段
enable: false,
multiple: true // 是否多选
},
text: { // 文本占位符
label: '文本内容', // 维度/查询字段
enable: true
},
expression: { // 文本占位符
label: '表达式', // 维度/查询字段
enable: true
}
}
}

@ -38,6 +38,25 @@
</template>
</data-set-select>
</el-form-item>
<el-form-item
v-if="config.option.displayOption.text && config.option.displayOption.text.enable"
label="文本内容"
>
<el-input
v-model="config.customize.title"
placeholder="请输入文本内容"
clearable
/>
</el-form-item>
<el-form-item
v-if="config.option.displayOption.expression && config.option.displayOption.expression.enable"
label="表达式"
>
<i
class="el-icon-edit expression"
@click="openExpression"
/>
</el-form-item>
</div>
</div>
<div
@ -575,6 +594,10 @@ data.forEach(item => {
:config="config"
:source-field-list="sourceFieldList"
/>
<expression-dialog
ref="expressionDialog"
:config="config"
/>
</div>
</el-form>
</div>
@ -589,13 +612,15 @@ import ComponentBinding from 'data-room-ui/BigScreenDesign/RightSetting/Componen
import dataSetSelect from 'data-room-ui/DataSetSetting/index.vue'
import { mapState } from 'vuex'
import { getDataSetDetails } from 'data-room-ui/js/api/bigScreenApi'
import ExpressionDialog from 'data-room-ui/BigScreenDesign/RightSetting/ExpressionDialog.vue'
export default {
name: 'DataSetting',
components: {
ComponentRelation,
ComponentBinding,
dataSetSelect,
ElDragSelect
ElDragSelect,
ExpressionDialog
},
data () {
return {
@ -720,6 +745,10 @@ export default {
}
},
methods: {
//
openExpression () {
this.$refs.expressionDialog.init()
},
//
serverPaginationChange (val) {
this.config.customize.webPagination = !val
@ -750,7 +779,7 @@ export default {
this.fieldsList = res.fields
//
if (type === 'initial') {
let deleteKeys = []
const deleteKeys = []
for (const key in this.config.dataSource.params) {
const param = res?.params?.find(field => field.name === key)
//
@ -925,6 +954,12 @@ export default {
justify-content: center;
}
}
//
.expression{
&:hover{
cursor: pointer;
}
}
//
.data-setting-box{
.data-setting-data-box{

@ -0,0 +1,221 @@
<template>
<el-dialog
:close-on-click-modal="false"
title="表达式"
width="60%"
:visible.sync="formVisible"
:append-to-body="false"
class="bs-dialog-wrap bs-el-dialog"
>
<div class="main-box">
<div class="left-box">
<el-tree
ref="tree"
:data="treeData"
:indent="0"
:props="{ label: 'label', children: 'children' }"
:default-expand-all="true"
:highlight-current="true"
:expand-on-click-node="false"
class="bs-el-tree tree-box"
@node-click="handleNodeClick"
/>
</div>
<div class="right-box">
<div class="codemirror-wrap">
<codemirror
ref="codemirrorRef"
v-model="currentConfig.expression"
class="codemirror-box"
:options="codemirrorOption"
@dragover.prevent
/>
<el-button
class="btn-box"
type="primary"
@click="executeScript"
>
运行脚本
</el-button>
</div>
<div class="script-content-box">
{{ scriptContent }}
</div>
</div>
</div>
<div
slot="footer"
class="dialog-footer"
>
<el-button
class="bs-el-button-default cancel"
@click="cancel"
>
取消
</el-button>
<el-button
type="primary"
@click="sure"
>
确定
</el-button>
</div>
</el-dialog>
</template>
<script>
import { codemirror } from 'vue-codemirror'
import 'codemirror/mode/javascript/javascript'
import 'codemirror/lib/codemirror.css'
import 'codemirror/theme/nord.css'
import { mapMutations, mapState } from 'vuex'
import cloneDeep from 'lodash/cloneDeep'
export default {
name: 'ExpressionDialog',
components: {
codemirror
},
props: {
config: {
type: Object,
default: () => {
}
}
},
data () {
return {
scriptContent: '', //
expression: '123',
formVisible: false,
codemirrorOption: {
mode: 'text/javascript',
lineNumbers: true,
lineWrapping: true,
theme: 'nord',
extraKey: { Ctrl: 'autocomplete' },
hintOptions: {
completeSingle: true
}
}
}
},
computed: {
...mapState({
dataset: state => state.bigScreen.dataset,
computedDatas: state => state.bigScreen.computedDatas
}),
//
treeData () {
const list = []
for (const item in this.dataset) {
const fields = Object.keys(this.dataset[item][0])
const children = fields.map((field) => {
return {
label: field,
code: item,
value: `dataset.${item}[0].${field}`
}
})
list.push({
label: item,
code: item,
value: `dataset.${item}`,
children
})
}
for (const item in this.computedDatas) {
list.push({
label: item,
code: item,
value: `computedDatas.${item}`
})
}
return list
},
currentConfig () {
return cloneDeep(this.config)
}
},
watch: {},
created () {},
mounted () {},
methods: {
...mapMutations({
changeChartConfig: 'bigScreen/changeChartConfig'
}),
init () {
this.formVisible = true
},
//
executeScript () {
// eslint-disable-next-line no-new-func
const result = new Function('dataset', 'computedDatas', this.currentConfig.expression)
this.scriptContent = result(this.dataset, this.computedDatas)
},
//
handleNodeClick (node, data, nodeObj) {
console.log(node, data, nodeObj)
const str = node.value
const code = node.code
this.$refs.codemirrorRef.codemirror.setValue(this.currentConfig.expression + ' + ' + str)
// expressionCodes
if (this.currentConfig.expressionCodes && Array.isArray(this.currentConfig.expressionCodes)) {
this.currentConfig.expressionCodes.push(code)
}
},
cancel () {
this.formVisible = false
},
sure () {
this.formVisible = false
this.changeChartConfig(this.currentConfig)
}
}
}
</script>
<style scoped lang="scss">
@import '../../assets/style/bsTheme.scss';
.bs-dialog-wrap{
::v-deep.el-dialog__body{
min-height: 500px;
}
}
.main-box{
width: 100%;
height: 500px;
display: flex;
.left-box{
flex: 1;
height: 100%;
.tree-box{
height: 100%;
overflow-y: auto;
}
}
.right-box{;
flex: 3 ;
height: 100%;
.codemirror-wrap{
height: 50%;
position: relative;
.btn-box{
position: absolute;
right: 10px;
bottom: 10px;
}
}
.codemirror-box {
height: 100% !important;
::v-deep .CodeMirror {
height: 100% !important;
font-family: Helvetica, Tahoma;
}
}
.script-content-box{
padding:10px
}
}
}
</style>

@ -284,7 +284,9 @@ export default {
'saveTimeLine',
'changeIframeDialog',
'changePageInfo',
'changeActiveItemConfig'
'changeActiveItemConfig',
'emptyDataset',
'emptyComputedDatas'
]),
//
permission () {
@ -426,6 +428,9 @@ export default {
})
.then(() => {
this.changeLayout([])
//
this.emptyDataset()
this.emptyComputedDatas()
this.resetPresetLine()
this.saveTimeLine('清空画布')
})

@ -19,12 +19,70 @@ export default {
dataLoading: false
}
},
watch: {
'config.expression': { // 表达式发生变化
handler (val) {
this.getDataByExpression(this.config)
}
},
currentDataset: { // 关联的数据发生变化
handler (val) {
if (val && Object.keys(val).length) {
this.getDataByExpression(this.config)
}
},
deep: true,
immediate: true
},
currentComputedDatas: { // 关联的数据发生变化
handler (val) {
if (val && Object.keys(val).length) {
this.getDataByExpression(this.config)
}
},
deep: true,
immediate: true
}
},
computed: {
...mapState({
pageCode: state => state.bigScreen.pageInfo.code,
customTheme: state => state.bigScreen.pageInfo.pageConfig.customTheme,
activeCode: state => state.bigScreen.activeCode
// dataset: state => state.bigScreen.dataset
}),
// 所有组件的数据集合
dataset () {
return this.$store.state.bigScreen.dataset
},
// 所有组件的数据集合
computedDatas () {
return this.$store.state.bigScreen.computedDatas
},
// 跟当前组件计算表达式关联的组件的数据集合
currentDataset () {
// ['RiTkJGDa','PEKwsHbf']this.config.expressionCodes
const newDataset = this.config.expressionCodes?.map(code => {
return this.dataset[code]
})
if (newDataset?.some(item => !item)) {
return null
} else {
return newDataset
}
},
// 跟当前组件计算表达式关联的组件的数据集合
currentComputedDatas () {
// ['RiTkJGDa','PEKwsHbf']this.config.expressionCodes
const newDataset = this.config.expressionCodes?.map(code => {
return this.computedDatas[code]
})
if (newDataset?.some(item => !item)) {
return null
} else {
return newDataset
}
},
// 组件数据加载时的背景颜色
loadingBackground () {
return this.customTheme === 'light' ? '#ffffff' : '#151A26'
@ -33,6 +91,7 @@ export default {
return (this.$route.path === window?.BS_CONFIG?.routers?.previewUrl) || (this.$route.path === '/big-screen/preview')
}
},
mounted () {
if (!['tables', 'flyMap', 'map'].includes(this.config.type)) {
this.chartInit()
@ -42,7 +101,9 @@ export default {
methods: {
...mapMutations({
changeChartConfig: 'bigScreen/changeChartConfig',
changeActiveItemConfig: 'bigScreen/changeActiveItemConfig'
changeActiveItemConfig: 'bigScreen/changeActiveItemConfig',
updateDataset: 'bigScreen/updateDataset',
updateComputedDatas: 'bigScreen/updateComputedDatas'
}),
/**
* 初始化组件
@ -110,6 +171,10 @@ export default {
}
}
}
// 将后端返回的数据保存
if (_res.success) {
this.updateDataset({ code: config.code, title: config.title, data: _res?.data })
}
config = this.dataFormatting(config, _res)
this.changeChartConfig(config)
}).catch((err) => {
@ -173,6 +238,10 @@ export default {
}
}
}
// 将后端返回的数据保存
if (_res.success) {
this.updateDataset({ code: config.code, title: config.title, data: _res?.data })
}
config = this.dataFormatting(config, _res)
if (this.chart) {
// 单指标组件和多指标组件的changeData传参不同
@ -209,6 +278,10 @@ export default {
newChart (option) {
// 覆盖
},
// 通过表达式计算获取组件的值
getDataByExpression (config) {
// 覆盖
},
changeStyle (config) {
config = { ...this.config, ...config }
// 样式改变时更新主题配置

@ -163,16 +163,18 @@ export default {
EventBus.$emit('deleteComponent', codes)
}
state.pageInfo.chartList = state.pageInfo.chartList.filter(chart => codes !== chart.code)
// 删除组件时,将该组件的缓存数据库中的数据也删除
deldataset(state, 'dataset', codes)
deldataset(state, 'computedDatas', codes)
}
// 存储删除后的状态
saveTimeLineFunc(state, '删除组件')
if (state.pageInfo.chartList.findIndex(item=>item.code===state.activeCode)==-1) {
if (state.pageInfo.chartList.findIndex(item => item.code === state.activeCode) == -1) {
state.activeItemConfig = null
state.activeCode = null
EventBus.$emit('closeRightPanel')
}
// 发送事件,关闭配置面板
},
changePageConfig (state, pageConfig) {
Vue.set(state.pageInfo, 'pageConfig', cloneDeep(pageConfig))
@ -367,6 +369,33 @@ export default {
})
// 将复制的组件添加到chartList中
state.pageInfo.chartList = [...copyCharts, ...state.pageInfo.chartList]
},
// 更新数据集库中的内容
updateDataset (state, res) {
Vue.set(state.dataset, res.title + res.code, res.data)
},
// 更新数据集库中的内容
updateComputedDatas (state, res) {
Vue.set(state.computedDatas, res.title + res.code, res.data)
},
// 清空数据集库
emptyDataset (state) {
state.dataset = {}
},
// 清空数据集库
emptyComputedDatas (state) {
state.computedDatas = {}
}
}
function deldataset (state, type, codes) {
const datasets = state[type]
for (const code of codes) {
for (const key in datasets) {
if (key.endsWith(code)) {
delete state[type][key]
break // 找到匹配的属性后,退出内层循环
}
}
}
}
function changeZIndexFuc (state, list) {

@ -64,7 +64,11 @@ export const defaultData = {
zoom: 100,
// 自适应下的缩放比例
fitZoom: 100,
iframeDialog: false
iframeDialog: false,
// 页面上所有组件的数据集的数据信息
dataset: {},
// 页面上所有组件的数据集的数据信息
computedDatas: {}
}
export default () => ({

Loading…
Cancel
Save