Commit 7602dff5 authored by leon's avatar leon

Merge branch 'develop' into feature-retail

parents 0023edeb d8bfcee2
<template>
<view>
</view>
</template>
<script>
import echartElementData from '@/mixins/echartElementData.js'
export default {
name: 'Folder',
mixins: [echartElementData],
props: {
elementInfo: {
type: Object,
required: true
}
},
methods: {
initChart() {
uni.$emit(`folder_${this.elementInfo.id}`, this.elementData.dataList)
}
}
}
</script>
<style>
</style>
......@@ -130,10 +130,12 @@
}
if(chart) {
const option = chart.getOption()
if(option) {
option.series = dealSeries
// 重新setOption,使得设置的formatter生效
chart.setOption(option)
}
}
})
},
......
......@@ -132,6 +132,9 @@
},
methods: {
initChart() {
if(!this.elementData.dataList) {
return
}
this.tabsValue = this.elementInfo.option.tabs.defaultValue
if (this.elementData.dataList.defaultValue) {
this.tabsValue = this.elementData.dataList.defaultValue
......@@ -267,6 +270,8 @@
align-items: flex-start;
flex-wrap: wrap;
width: 100%;
justify-content: center;
align-items: center;
}
.tab-vertical {
display: flex !important;
......@@ -277,7 +282,7 @@
.tab-item {
width: var(--width);
margin: 1%;
margin: 3px;
font-size: var(--font-size);
color: var(--color);
border: var(--border-style);
......
......@@ -35,5 +35,7 @@ Vue.use(HTTPApi, app)
// 自定义方法
import common from './utils/common.js'
Vue.use(common, app)
import charts from './mixins/charts.js'
Vue.use(charts, app)
app.$mount()
const install = (Vue, vm) => {
/* 通用转换报表数据格式
@data: 传入的数据
@element: 图表的配置
*/
const parseChartData = (data, element) => {
const list = handleChartsList(handleChartData(data, element.data.dataConfig.data))
return convertChartsData(list, element)
}
/* 通用转换报表数据格式
@list: 数据列表
@dimension: 维度
@value: 数据
@condition:对应的条件配置
@type: 报表类型
*/
// dimension, value, conditions, type: string
const convertChartsData = (list, element) => {
if (!element.data.dataConfig.value.length) {
return
}
if (!list) {
return
}
const type = element.type
if (type === 'NormalBar' || type === 'HorizontalBar') {
return convertBarData(list, element)
}
if (type === 'NormalLine') {
return convertLineData(list, element)
}
if (type === 'LineMixBar') {
return convertLineMixBarData(list, element)
}
if (type === 'NormalPie') {
return convertPieData(list, element)
}
if (type === 'NormalRadar') {
return convertRadarData(list, element)
}
if (type === 'NormalGauge') {
return convertGuageData(list, element)
}
if (type === 'NormalTabs') {
return convertTabData(list, element)
}
if (type === 'NormalTable') {
return convertTableData(list, element)
}
if (type === 'NormalProgress') {
return convertProgressData(list, element)
}
if (type === 'CountTo' || type === 'CountTo' ) {
return convertNumberData(list, element)
}
if (type === 'BasicText') {
return convertTextData(list, element)
}
if (type === 'BarMixMap') {
return convertBarMixMapData(list, element)
}
if (type === 'ChinaMap') {
return convertChinaMapData(list, element)
}
}
/* 根据层级结构获取对应的数据
@obj: 传入的数据
@key: 对应的字段
*/
const filterChartData = (obj, key) => {
if (!key) {
return obj
}
for (const prop in obj) {
// eslint-disable-next-line no-prototype-builtins
if (obj.hasOwnProperty(prop)) {
if (prop === key) {
return obj[prop]
}
else if (obj.constructor === Object) {
const result = filterChartData(obj[prop], key)
if (result !== undefined) {
return result
}
}
else if (obj.constructor === Array) {
const result = filterChartData(obj[0], key)
if (result !== undefined) {
return result
}
}
}
}
}
/* item的数据格式:["string", "string"]
找到最外层的数据
*/
const handleChartData = (obj, item) => {
let result = obj
if (!item || !item.length) {
return result
}
item.forEach((child) => {
result = filterChartData(result, child)
})
return result
}
/* 处理图表类的数据
图表的数据,处理成数组格式
*/
const handleChartsList = (list) => {
if (list.constructor === String) {
return []
}
if (list.constructor === Object) {
const arr = []
arr.push(list)
return arr
}
return list
}
/* 解析条件判断
@condition:对应的条件配置
@data: 需要解析的数据
*/
const judgeConditions = (condition, data) => {
let number = 0
if (condition.length) {
condition.forEach((item) => {
let value = ''
value = handleChartData(data, item.field)
if (!value.length) {
number++
}
else {
const op = item.op
const val = item.value
if (op === 'GTR' && value > val) {
number++
}
if (op === 'GEQ' && value >= val) {
number++
}
if (op === 'EQU' && value === val) {
number++
}
if (op === 'LSS' && value < val) {
number++
}
if (op === 'LEQ' && value <= val) {
number++
}
if (op === 'NEQ' && value !== val) {
number++
}
if (op === 'CONT' && value.toString().includes(val)) {
number++
}
}
})
}
return condition.length === number
}
// 柱状图
const convertBarData = (list, element) => {
return convertBarOrLineData(list, element)
}
// 折线图
const convertLineData = (list, element) => {
return convertBarOrLineData(list, element)
}
// 柱状图或者折线图
const convertBarOrLineData = (list, element) => {
const categories = []
const series = []
const xAxis = element.data.dataConfig.dimension
const yAxis = element.data.dataConfig.value
const conditions = element.data.dataConfig.conditions
if (!xAxis.length) {
return
}
list.forEach((item) => {
// 数据判断,符合条件的数据
if (judgeConditions(conditions, item)) {
// 对应的维度加入categories
categories.push(handleChartData(item, xAxis))
// 对应的值加入series
yAxis.forEach((y, idx) => {
let obj = {name: '', data: []}
if (series.length > idx) {
obj = series[idx]
}
else {
series.push(obj)
}
obj.name = y[y.length - 1]
obj.data.push(handleChartData(item, y))
})
}
})
return {
categories: categories,
series: series
}
}
// 饼图
const convertPieData = (list, element) => {
const xAxis = element.data.dataConfig.dimension
const yAxis = element.data.dataConfig.value
const conditions = element.data.dataConfig.conditions
if (!xAxis.length) {
return
}
const series = []
list.forEach((item) => {
if (judgeConditions(conditions, item)) {
const obj = {
name: handleChartData(item, xAxis),
value: handleChartData(item, yAxis)
}
series.push(obj)
}
})
return { series }
}
// 折柱图
const convertLineMixBarData = (list, element) => {
const categories = []
const series = []
const xAxis = element.data.dataConfig.dimension
const yAxis = element.data.dataConfig.value
const conditions = element.data.dataConfig.conditions
if (!xAxis.length) {
return
}
const length = yAxis.length / 2
list.forEach((item) => {
// 数据判断,符合条件的数据
if (judgeConditions(conditions, item)) {
// 对应的维度加入categories
// categories.push(item[key])
categories.push(handleChartData(item, xAxis))
// 对应的值加入series
yAxis.forEach((y, idx) => {
let obj = {name: '', data: [], type: ''}
if (series.length > idx) {
obj = series[idx]
}
else {
series.push(obj)
}
if (idx < length) {
obj.type = 'bar'
}
else {
obj.type = 'line'
}
obj.name = y[y.length - 1]
obj.data.push(handleChartData(item, y))
})
}
})
return {
categories: categories,
series: series
}
}
// 雷达图
const convertRadarData = (list, element) => {
const series = []
const indicator = []
const xAxis = element.data.dataConfig.dimension
const yAxis = element.data.dataConfig.value
const conditions = element.data.dataConfig.conditions
if (!xAxis.length) {
return
}
list.forEach((item) => {
// 数据判断,符合条件的数据
if (judgeConditions(conditions, item)) {
// 对应的维度加入categories
indicator.push({
name: handleChartData(item, xAxis)
})
// 对应的值加入series
yAxis.forEach((y, idx) => {
let obj = {name: '', data: []}
if (series.length > idx) {
obj = series[idx]
}
else {
series.push(obj)
}
obj.name = y[y.length - 1]
obj.data.push(handleChartData(item, y))
})
}
})
return {
indicator: indicator,
series: series
}
}
// 选项卡
const convertTabData = (list, element) => {
const xAxis = element.data.dataConfig.dimension
const yAxis = element.data.dataConfig.value
const conditions = element.data.dataConfig.conditions
if (!xAxis.length) {
return
}
const series = []
list.forEach((item) => {
if (judgeConditions(conditions, item)) {
xAxis.forEach((x, idx) => {
const name = handleChartData(item, x)
let value = ''
if (yAxis.length >= xAxis.length ) {
value = handleChartData(item, yAxis[idx])
}
const obj = {
name: name,
value: value
}
series.push(obj)
})
}
})
return { series }
}
// 迁徙地图
const convertChinaMapData = (list, element) => {
const coordinate = element.data.dataConfig.coordinate
const xAxis = element.data.dataConfig.dimension
const yAxis = element.data.dataConfig.value
const conditions = element.data.dataConfig.conditions
if (!xAxis.length) {
return
}
const chinaMapAreas = []
list.forEach((item) => {
if (judgeConditions(conditions, item)) {
const arr = []
const name = handleChartData(item, coordinate)
const obj = {
name: handleChartData(item, xAxis),
value: handleChartData(item, yAxis)
}
arr.push({ name })
arr.push(obj)
chinaMapAreas.push(arr)
}
})
return { chinaMapAreas }
}
// 地图混合柱状图
const convertBarMixMapData = (list, element) => {
const xAxis = element.data.dataConfig.dimension
const yAxis = element.data.dataConfig.value
const conditions = element.data.dataConfig.conditions
if (!xAxis.length) {
return
}
const series = []
list.forEach((item) => {
if (judgeConditions(conditions, item)) {
const obj = {
name: handleChartData(item, xAxis),
value: handleChartData(item, yAxis)
}
series.push(obj)
}
})
return { series }
}
// 仪表盘
const convertGuageData = (list, element) => {
const xAxis = element.data.dataConfig.dimension
const yAxis = element.data.dataConfig.value
const conditions = element.data.dataConfig.conditions
if (!xAxis.length) {
return
}
const guageChart = []
list.forEach((item) => {
if (judgeConditions(conditions, item)) {
xAxis.forEach((x, idx) => {
const name = handleChartData(item, x)
let value = ''
if (yAxis.length >= xAxis.length ) {
value = handleChartData(item, yAxis[idx])
}
const obj = {
name: name,
value: value
}
guageChart.push(obj)
})
}
})
return { guageChart }
}
// 表格
const convertTableData = (list, element) => {
const yAxis = element.data.dataConfig.value
const conditions = element.data.dataConfig.conditions
const chartTables = []
list.forEach((item) => {
if (judgeConditions(conditions, item)) {
const obj = {}
yAxis.forEach((y, idx) => {
const key = y[y.length - 1]
const value = handleChartData(item, y)
obj[key] = value
})
chartTables.push(obj)
}
})
return { chartTables }
}
// 进度条
const convertProgressData = (list, element) => {
const yAxis = element.data.dataConfig.value
const conditions = element.data.dataConfig.conditions
let endVal = 0.0
list.forEach((item) => {
if (judgeConditions(conditions, item)) {
endVal = parseFloat(handleChartData(item, yAxis)).toFixed(2)
}
})
return { endVal }
}
// 数字
const convertNumberData = (list, element) => {
const yAxis = element.data.dataConfig.value
const conditions = element.data.dataConfig.conditions
let endVal = 0
list.forEach((item) => {
if (judgeConditions(conditions, item)) {
endVal = parseInt(handleChartData(item, yAxis))
}
})
return { endVal }
}
// 文本
const convertTextData = (list, element) => {
const yAxis = element.data.dataConfig.value
const conditions = element.data.dataConfig.conditions
let text = ''
list.forEach((item) => {
if (judgeConditions(conditions, item)) {
text = handleChartData(item, yAxis)
}
})
return { text }
}
vm.$u.charts = {
parseChartData,
}
}
export default {
install
}
\ No newline at end of file
......@@ -33,12 +33,21 @@ export default {
async handleDynamicData (value) {
const that = this
let { dataUrl, dataMethod, dataFormatter, dataProcessing, dataConfig } = { ...value }
if (!dataUrl.length) {
return
}
if(value.queryFormatter) dataFormatter = {...dataFormatter, ...value.queryFormatter}
dataUrl = dataUrl.replace(/^(\/(dashboardCharts|dashboardAPI))?/, '')
dataFormatter = that.$u.common.filterRequestParams({...dataFormatter})
let res = await that.$u.api[`${dataMethod.toLowerCase()}Http`](dataUrl, dataFormatter, {
custom: { loading: false }
})
// 文件夹类型的数据,直接拿接口返回数据
if (this.elementInfo.type === 'folder') {
that.elementData.dataList = res.data
return
}
if (dataProcessing) {
that.elementData.dataList = that.$u.common.converFunction(dataProcessing, res.data, value.queryFormatter)
} else if (dataConfig && dataConfig.value && dataConfig.value.length) {
......@@ -96,6 +105,24 @@ export default {
}
},
/** 文件数据 */
handleFolderData(value) {
const that = this
const { dataProcessing, dataConfig} = { ...value }
uni.$on(`folder_${that.elementInfo.folderId}`, data => {
if (!data) return
if (dataProcessing) {
that.elementData.dataList = that.$u.common.converFunction(dataProcessing, data)
return
}
if (dataConfig && dataConfig.value && dataConfig.value.length) {
that.elementData.dataList = that.$u.charts.parseChartData(data, that.elementInfo)
return
}
that.elementData.dataList = JSON.parse(JSON.stringify(data))
})
},
clearTimer() {
clearInterval(this.timer)
this.timer = null
......@@ -163,6 +190,15 @@ export default {
} else {
clearInterval(that.timer)
}
} else if (newVal.dataType === 'folder') {
that.handleFolderData(newVal)
if (newVal.dataPolling && newVal.dataPollingInterval > 0) {
that.timer = setInterval(() => {
that.handleFolderData(newVal)
}, newVal.dataPollingInterval * 1000)
} else {
clearInterval(that.timer)
}
}
},
deep: true,
......@@ -181,8 +217,8 @@ export default {
}
},
'elementData.dataList': {
handler(newVal) {
if (newVal) {
handler(newVal,oldVal) {
if (JSON.stringify(newVal) !== '{}' && JSON.stringify(newVal) !== JSON.stringify(oldVal) ) {
this.setStorageData()
this.initChart()
}
......
......@@ -55,6 +55,7 @@
<!-- 普通表格 -->
<NormalTable v-if="element.type == 'NormalTable'" :elementInfo="element"></NormalTable>
<!-- <Table v-if="element.type == 'NormalTable'" :elementInfo="element"></Table> -->
<Folder v-if="element.type == 'folder'" :elementInfo="element"></Folder>
</view>
</template>
<ModelData
......@@ -226,6 +227,8 @@
}, parseInt(info.dataPollingInterval) * 1000)
}
}
// 处理图层关系
res.data.Result.list = this.$u.common.elementFolderId(res.data.Result.list)
// 清除数据
if(uni.getStorageSync('reportInfo')) {
let cacheInfo = JSON.parse(uni.getStorageSync('reportInfo'))
......@@ -236,37 +239,11 @@
}
})
}
that.reportInfo = this.handleTabsLink(res.data.Result)
that.reportInfo = res.data.Result
uni.setStorageSync('reportInfo', JSON.stringify(res.data.Result))
that.getStickyTables()
}
},
/**
* tabs 组件处理关联关系
*/
handleTabsLink(data) {
data.list.forEach(item => {
if(item.type === 'NormalTabs' && (item.child.index.length || item.child.data.length)) {
if (item.child.index.length) {
item.child.index.forEach(child => {
const index = data.list.findIndex(i => i.id === child )
if(index != -1) {
data.list[index].linkTabsId = item.id
}
})
}
if (item.child.data.length) {
item.child.data.forEach(child => {
const index = data.list.findIndex(i => i.id === child.comp )
if(index != -1) {
data.list[index].linkTabsId = item.id
}
})
}
}
})
return data
},
/**
* 获取全局接口数据
*/
......
<template>
<view class="wrapper" :class="{'tabs-layout': showTabs}" :style="{width: `${theStyle.width - theStyle.left}px`, left:`${theStyle.left}px`}">
<!-- 普通选项卡 -->
<view v-if="showTabs"
style="position: fixed;top: 0;"
:style="{
width: `${parseInt(tabsElement.width * scale)}px`,
height: `${parseInt(tabsElement.height * (scale > 1 ? 1 : scale))}px`,
left: `${parseInt(tabsElement.left * scale)}px`,
zIndex: 10
}"
>
<NormalTabs
:elementInfo="tabsElement"
></NormalTabs>
</view>
<view :style="{'margin-top': `${tabsElement.height * (scale > 1 ? 1 : scale)}px`, height: `${theStyle.height}px`, width: `${theStyle.width - theStyle.left}px`, zIndex: 9}">
<view class="wrapper" :style="{width: `${theStyle.width - theStyle.left}px`, left:`${theStyle.left}px`}">
<view :style="{ height: `${theStyle.height}px`, width: `${theStyle.width - theStyle.left}px`, zIndex: 9}">
<!-- 普通柱状图 -->
<NormalBar v-if="element.type == 'NormalBar'" :elementInfo="element"></NormalBar>
<!-- 普通折线图 -->
......@@ -32,15 +19,10 @@
export default {
data() {
return {
element: {},
linkTabsId: '',
tabsElement: {}
element: {}
}
},
computed: {
showTabs() {
return this.linkTabsId && Object.keys(this.tabsElement).length
},
theStyle() {
const { windowWidth, windowHeight, screenHeight, safeArea } = uni.getSystemInfoSync()
const reduceBottom = screenHeight - safeArea.bottom
......@@ -50,71 +32,12 @@
left: safeArea.left
}
},
scale() {
let info = JSON.parse(uni.getStorageSync('reportInfo'))
if(JSON.stringify(info) == "{}") {
return
}
const { windowWidth } = uni.getSystemInfoSync()
const { width, height } = info.info
return windowWidth / width
}
},
onLoad(option) {
this.element = JSON.parse(decodeURIComponent(option.element))
this.linkTabsId = option.linkTabsId
if(this.linkTabsId && uni.getStorageSync('reportInfo')) {
let info = JSON.parse(uni.getStorageSync('reportInfo'))
const data = info.list.find(item => item.id === this.linkTabsId)
this.tabsElement = data
}
// 去掉全屏的定制按钮
const toolbox = {show: false}
this.element.option.toolbox = toolbox
},
onShow() {
/**
* 组件交互 - 组件
*/
uni.$on('handleLinkComp', ({ showData, hideData }) => {
let info = JSON.parse(uni.getStorageSync('reportInfo'))
const data = info.list.find(item => showData[0] === item.id)
data.hide = false
// 去掉全屏的定制按钮
data.option.toolbox = { show: false }
this.element = data
}),
/**
* 组件交互 - 参数
*/
uni.$on('handleLinkParams', ({index, paramName, value}) => {
let reportInfo = JSON.parse(uni.getStorageSync('reportInfo'))
if(index.length && paramName) {
const that = this
reportInfo.list = reportInfo.list.map(item => {
const flag = index.includes(item.id)
if(flag && item.type === 'BasicText' && item.data.dataType === 'static') {
that.$set(item.data.dataList, 'text', value)
}
if(flag && item.data.dataType === 'dynamic') {
if(!item.data.queryFormatter) item.data.queryFormatter = {}
that.$set(item.data.queryFormatter, paramName, value)
}
if(flag && item.data.dataType === 'dataSet') {
if(!item.data.dataSetInfo.queryFormatter) item.data.dataSetInfo.queryFormatter = {}
that.$set(item.data.dataSetInfo.queryFormatter, paramName, value)
}
if(flag && item.data.dataType === 'public') {
if(!item.data.queryFormatter) item.data.queryFormatter = {}
that.$set(item.data.queryFormatter, paramName, value)
}
return item
})
}
this.element = reportInfo.list.find(item => index[0] === item.id)
// 去掉全屏的定制按钮
this.element.option.toolbox = { show: false }
})
}
}
</script>
......@@ -134,11 +57,5 @@
padding-bottom: env(safe-area-inset-bottom); /*兼容 IOS>11.2*/
}
.tabs-layout {
display: flex;
align-items: center;
justify-content: space-between;
flex-direction: column;
}
</style>
......@@ -57,6 +57,7 @@
<!-- 普通表格 -->
<NormalTable v-if="element.type == 'NormalTable'" :elementInfo="element"></NormalTable>
<!-- <Table v-if="element.type == 'NormalTable'" :elementInfo="element"></Table> -->
<Folder v-if="element.type == 'folder'" :elementInfo="element"></Folder>
</view>
</template>
......@@ -123,9 +124,9 @@
// detail页面也会监听这两个事件,所有index页面需要在onShow里面增加监听,在onHide里面移除监听
onShow() {
const that = this
// if(uni.getStorageSync('reportInfo')) {
// this.reportInfo = JSON.parse(uni.getStorageSync('reportInfo'))
// }
if(Object.keys(that.reportInfo).length) {
uni.setStorageSync('reportInfo', JSON.stringify(that.reportInfo))
}
/**
* 组件交互 - 参数
*/
......@@ -246,12 +247,14 @@
if (Status === 'true') {
if(info.dataUrl) {
that.getGlobalData(info, list)
if(info.dataPollingInterval) {
if(info.dataPolling && info.dataPollingInterval > 0) {
that.timename = setInterval(() => {
that.getGlobalData(info, list)
}, parseInt(info.dataPollingInterval) * 1000)
}
}
// 处理图层关系
res.data.Result.list = this.$u.common.elementFolderId(res.data.Result.list)
// 清除数据
if(uni.getStorageSync('reportInfo')) {
let info = JSON.parse(uni.getStorageSync('reportInfo'))
......@@ -262,38 +265,11 @@
}
})
}
that.reportInfo = this.handleTabsLink(res.data.Result)
uni.setStorageSync('reportInfo', JSON.stringify(res.data.Result))
that.reportInfo = res.data.Result
uni.setStorageSync('reportInfo', JSON.stringify(that.reportInfo))
that.getStickyTables()
}
},
/**
* tabs 组件处理关联关系
*/
handleTabsLink(data) {
data.list.forEach(item => {
if(item.type === 'NormalTabs' && (item.child.index.length || item.child.data.length)) {
if (item.child.index.length) {
item.child.index.forEach(child => {
const index = data.list.findIndex(i => i.id === child )
if(index != -1) {
data.list[index].linkTabsId = item.id
}
})
}
if (item.child.data.length) {
item.child.data.forEach(child => {
const index = data.list.findIndex(i => i.id === child.comp )
if(index != -1) {
data.list[index].linkTabsId = item.id
}
})
}
}
})
return data
},
/**
* 获取全局接口数据
*/
......
......@@ -258,7 +258,7 @@ const install = (Vue, vm) => {
/**
*
* @param yAxis 表单的yAxis设置
* @param axis 表单的axis设置
*/
const dealAxisFormatter = (axis) => {
if (!axis) {
......@@ -278,7 +278,25 @@ const install = (Vue, vm) => {
return axis
}
/**
* 图层关系关联 子组件获取到folderId
* @param {elements}
*/
const elementFolderId = (elements) => {
elements.forEach(element => {
if (element.type === 'folder') {
element.child.data.forEach(item => {
const index = elements.findIndex(ele => ele.id === item)
if(index != -1) {
elements[index].folderId = element.id
elements[index].isChild = true
}
})
}
})
return elements
}
vm.$u.common = {
converFunction,
......@@ -291,7 +309,8 @@ const install = (Vue, vm) => {
getQueryFromString,
filterRequestParams,
dealTooltip,
dealAxisFormatter
dealAxisFormatter,
elementFolderId
}
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment