/* * @description: bigScreen公共方法 * @Date: 2023-03-24 17:10:43 * @Author: xing.heng */ // import _ from 'lodash' import { mapMutations, mapState } from 'vuex' import { EventBus } from 'data-room-ui/js/utils/eventBus' import { getChatInfo, getUpdateChartInfo } from '../api/bigScreenApi' import axiosFormatting from '../../js/utils/httpParamsFormatting' import { settingToTheme } from 'data-room-ui/js/utils/themeFormatting' import cloneDeep from 'lodash/cloneDeep' import mqtt from 'mqtt' export default { data() { return { filterList: [], treeParentId: 0, dataLoading: false } }, watch: { 'config.expression': { // 表达式发生变化 handler(val) { this.getDataByExpression(this.config) } }, // 标题发生变化时需要及时更新表达式中的数据集库的字段名 'config.title': { handler(val, oldVal) { this.updateDataset({ code: this.config.code, title: val, data: [], oldTitle: oldVal, isChangeTitle: true }) this.updateComputedDatas({ code: this.config.code, title: val, data: [], oldTitle: oldVal, isChangeTitle: true }) } }, currentDataset: { // 关联的数据发生变化 handler(val, old) { if (val && Object.keys(val).length && JSON.stringify(val) !== JSON.stringify(old)) { this.getDataByExpression(this.config) } }, deep: true, immediate: true }, currentComputedDatas: { // 关联的数据发生变化 handler(val, old) { if (val && Object.keys(val).length && JSON.stringify(val) !== JSON.stringify(old)) { 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() { const newDataset = {} this.config.expressionCodes?.forEach(item => { const code = item.split('_')[1] for (const key in this.dataset) { const objCode = key.split('_')[1] if (objCode === code) { newDataset[code] = this.dataset[key] } } }) return newDataset }, // 跟当前组件计算表达式关联的组件的数据集合 currentComputedDatas() { const newDataset = {} this.config.expressionCodes?.forEach(item => { const code = item.split('_')[1] for (const key in this.computedDatas) { const objCode = key.split('_')[1] if (objCode === code) { newDataset[code] = this.computedDatas[key] } } }) return newDataset }, isPreview() { 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() } this.watchCacheData() }, methods: { ...mapMutations({ changeChartConfig: 'bigScreen/changeChartConfig', changeActiveItemConfig: 'bigScreen/changeActiveItemConfig', updateDataset: 'bigScreen/updateDataset', updateComputedDatas: 'bigScreen/updateComputedDatas' }), /** * 初始化组件 */ chartInit() { let config = this.config console.log('this.config: ', this.config); // key和code相等,说明是一进来刷新,调用list接口 if (this.isPreview) { // 改变样式 config = this.changeStyle(config) ? this.changeStyle(config) : config // 改变数据 config = this.changeDataByCode(config) } else { // 否则说明是更新,这里的更新只指更新数据(改变样式时是直接调取changeStyle方法),因为更新数据会改变key,调用chart接口 // eslint-disable-next-line no-unused-vars config = this.changeData(config) } }, /** * 初始化组件时获取后端返回的数据, 返回数据和当前组件的配置_list * @param settingConfig 设置时的配置。不传则为当前组件的配置 * @returns {Promise} */ changeDataByCode(config) { let currentPage = 1 let size = 10 if (config?.option?.pagination) { currentPage = config.option.pagination.currentPage size = config.option.pagination.pageSize } return new Promise((resolve, reject) => { config.loading = true getChatInfo({ // innerChartCode: this.pageCode ? config.code : undefined, chartCode: config.code, current: currentPage, pageCode: this.pageCode, size: size, type: config.type }).then(async (res) => { config.loading = false let _res = cloneDeep(res) //--------------------MQTT数据集执行前置条件------------------------------------------------------------ if (res.data && res.data.datasetType && res.data.datasetType === 'mqtt') { res.executionByFrontend = true } //--------------------MQTT数据集执行前置条件------------------------------------------------------------ // 如果是http数据集的前端代理,则需要调封装的axios请求 if (res.executionByFrontend) { if (res.data.datasetType === 'mqtt') { //2025-2-1屏蔽掉mqtt功能 // // _res = this.httpDataFormatting(res, [{"data":new Date().toLocaleString()}]) // let clientId = "SW-VIEWS" + new Date().getTime(); // let client = mqtt.connect('ws://broker.emqx.io:8083/mqtt', { // clientId: clientId, // username: 'admin', // password: '123456' // }) // let produceTopic = "STime"; // client.on('connect', () => { // console.log('mqtt 已经连接成功'); // client.subscribe(produceTopic, (data) => { // console.log("mqtt " + produceTopic + " 订阅成功"); // }) // }); // client.on('message', (topic, data) => { // console.log("mqtt 收到" + topic + "的消息"); // // console.log(data.toString()); // if (topic === produceTopic) { // // 处理指定主题下的消息 // let JsonData = JSON.parse(data.toString()); // // console.log(JsonData); // _res = this.httpDataFormatting(res, [{ "data": JsonData.time }]) // console.log('mqtt_res: ', _res); // config = this.dataFormatting(config, _res) // } // }) // client.on('reconnect', () => { // console.log("mqtt reconnect"); // }) // client.on('offline', () => { // console.log("mqtt offline"); // }) // client.on('error', (error) => { // console.log("mqtt error"); // console.log(error); // }) } if (res.data.datasetType === 'http') { _res = await axiosFormatting(res.data) _res = this.httpDataFormatting(res, _res) } if (res.data.datasetType === 'js') { try { const scriptAfterReplacement = res.data.script.replace(/\${(.*?)}/g, (match, p) => { const value = this.config.dataSource?.params[p] if (value === null || value === undefined || value === '') { return "''" } else if (!isNaN(value)) { return value || p } else { return `'${value}' || '${p}'` } }) // eslint-disable-next-line no-new-func const scriptMethod = new Function(scriptAfterReplacement) _res.data = scriptMethod() } catch (error) { console.info('JS数据集脚本执行失败', error) } } } // 将后端返回的数据保存 if (_res.success) { this.updateDataset({ code: config.code, title: config.title, data: _res?.data }) } config = this.dataFormatting(config, _res) this.changeChartConfig(config) }).catch((err) => { console.info(err) }).finally(() => { resolve(config) }) }) }, /** * @description: 更新chart * @param {Object} config * @param {Array} filterList */ changeData(config, filterList) { const list = config?.paramsList?.map((item) => { if (item.value === '${level}') { return { ...item, value: config.customize.level } } else if (item.value === '${name}') { return { ...item, value: config.customize.scope } } else { return item } }) const params = { chart: { ...config, paramsList: list ? [...list] : [], option: undefined }, current: 1, pageCode: this.pageCode, type: config.type, filterList: filterList || this.filterList } return new Promise((resolve, reject) => { config.loading = true getUpdateChartInfo(params).then(async (res) => { console.log('getUpdateChartInfo-res: ', res); config.loading = false let _res = cloneDeep(res) //--------------------MQTT数据集执行前置条件------------------------------------------------------------ if (res.data && res.data.datasetType && res.data.datasetType === 'mqtt') { res.executionByFrontend = true } //--------------------MQTT数据集执行前置条件------------------------------------------------------------ // 如果是http数据集的前端代理,则需要调封装的axios请求 if (res.executionByFrontend) { if (res.data.datasetType === 'mqtt') { //2025-2-1 停掉mqtt功能 // // _res = this.httpDataFormatting(res, [{"data":new Date().toLocaleString()}]) // let clientId = "SW-VIEWS" + new Date().getTime(); // this.client = mqtt.connect('ws://broker.emqx.io:8083/mqtt', { // clientId: clientId, // username: 'admin', // password: '123456' // }) // let produceTopic = "STime"; // this.client.on('connect', () => { // console.log('mqtt 已经连接成功'); // this.client.subscribe(produceTopic, (data) => { // console.log("mqtt " + produceTopic + " 订阅成功"); // }) // }); // this.client.on('message', (topic, data) => { // console.log("mqtt 收到" + topic + "的消息"); // // console.log(data.toString()); // if (topic === produceTopic) { // // 处理指定主题下的消息 // let JsonData = JSON.parse(data.toString()); // // console.log(JsonData); // _res = this.httpDataFormatting(res, [{ "data": JsonData.time }]) // console.log('mqtt_res: ', _res); // config = this.dataFormatting(config, _res) // } // }) // this.client.on('reconnect', () => { // console.log("mqtt reconnect"); // }) // this.client.on('offline', () => { // console.log("mqtt offline"); // }) // this.client.on('error', (error) => { // console.log("mqtt error"); // console.log(error); // }) // console.log('this.httpDataFormatting(res, _res): ', _res); } if (res.data.datasetType === 'http') { _res = await axiosFormatting(res.data) console.log('await axiosFormatting_res: ', _res); _res = this.httpDataFormatting(res, _res) } if (res.data.datasetType === 'js') { try { params.filterList.forEach(item => { this.config.dataSource.params[item.column] = item.value }) const scriptAfterReplacement = res.data.script.replace(/\${(.*?)}/g, (match, p) => { const value = this.config.dataSource?.params[p] if (value === null || value === undefined || value === '') { return "''" } else if (!isNaN(value)) { return value || p } else { return `'${value}' || '${p}'` } }) // eslint-disable-next-line no-new-func const scriptMethod = new Function(scriptAfterReplacement) _res.data = scriptMethod() } catch (error) { console.info('JS数据集脚本执行失败', error) } } } // 将后端返回的数据保存 if (_res.success) { console.log('_res.success: ', _res.success); this.updateDataset({ code: config.code, title: config.title, data: _res?.data }) } config = this.dataFormatting(config, _res) if (this.chart) { // 单指标组件和多指标组件的changeData传参不同 if (['Liquid', 'Gauge', 'RingProgress', 'Progress'].includes(config.chartType)) { this.chart.changeData(config.option.percent) } else { this.chart.changeData(config.option.data) } } if (this.config.type === 'candlestick' && this.charts) { this.updateChartData(config, _res) } else if (this.charts) { // 地图组件的被联动更新 this.changeMapData(config.option.data) } }).catch(err => { console.info(err) }).finally(() => { if (config) { config.loading = false } console.log('last-config: ', config); resolve(config) }) }) }, // 更新图表数据 updateChartData() { }, // http前台代理需要对返回的数据进行重新组装 httpDataFormatting(chartRes, httpRes) { let result = {} result = { columnData: chartRes.columnData, data: httpRes, success: chartRes.success } return result }, dataFormatting(config, data) { // 覆盖 }, newChart(option) { // 覆盖 }, // 通过表达式计算获取组件的值 getDataByExpression(config) { // 覆盖 }, changeStyle(config) { config = { ...this.config, ...config } // 样式改变时更新主题配置 config.theme = settingToTheme(cloneDeep(config), this.customTheme) this.changeChartConfig(config) if (config.code === this.activeCode) { this.changeActiveItemConfig(config) } }, // 缓存组件数据监听 watchCacheData() { EventBus.$on('cacheDataInit', (data, dataSetId) => { // 如果是缓存数据集 // 且当前组件的businessKey和缓存的dataSetId相等时,更新组件 if ( this.config.dataSource.dataSetType === '2' && this.config.dataSource.businessKey === dataSetId ) { const config = this.dataFormatting(this.config, data) config.key = new Date().getTime() this.changeChartConfig(config) this.newChart(config.option) } }) } }, beforeDestroy() { //2025-2-1屏蔽掉mqtt功能 // this.client.on('close', () => { // console.log("mqtt close"); // }) // this.client.end() }, }