commonMixins.js 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321
  1. /*
  2. * @description: bigScreen公共方法
  3. * @Date: 2023-03-24 17:10:43
  4. * @Author: xing.heng
  5. */
  6. // import _ from 'lodash'
  7. import { mapMutations, mapState } from 'vuex'
  8. import { EventBus } from 'data-room-ui/js/utils/eventBus'
  9. import { getChatInfo, getUpdateChartInfo } from '../api/bigScreenApi'
  10. import axiosFormatting from '../../js/utils/httpParamsFormatting'
  11. import { settingToTheme } from 'data-room-ui/js/utils/themeFormatting'
  12. import cloneDeep from 'lodash/cloneDeep'
  13. export default {
  14. data () {
  15. return {
  16. filterList: [],
  17. treeParentId: 0,
  18. dataLoading: false
  19. }
  20. },
  21. watch: {
  22. 'config.expression': { // 表达式发生变化
  23. handler (val) {
  24. this.getDataByExpression(this.config)
  25. }
  26. },
  27. currentDataset: { // 关联的数据发生变化
  28. handler (val, old) {
  29. if (val && Object.keys(val).length && JSON.stringify(val) !== JSON.stringify(old)) {
  30. this.getDataByExpression(this.config)
  31. }
  32. },
  33. deep: true,
  34. immediate: true
  35. },
  36. currentComputedDatas: { // 关联的数据发生变化
  37. handler (val, old) {
  38. if (val && Object.keys(val).length && JSON.stringify(val) !== JSON.stringify(old)) {
  39. this.getDataByExpression(this.config)
  40. }
  41. },
  42. deep: true,
  43. immediate: true
  44. }
  45. },
  46. computed: {
  47. ...mapState({
  48. pageCode: state => state.bigScreen.pageInfo.code,
  49. customTheme: state => state.bigScreen.pageInfo.pageConfig.customTheme,
  50. activeCode: state => state.bigScreen.activeCode
  51. // dataset: state => state.bigScreen.dataset
  52. }),
  53. // 所有组件的数据集合
  54. dataset () {
  55. return this.$store.state.bigScreen.dataset
  56. },
  57. // 所有组件的数据集合
  58. computedDatas () {
  59. return this.$store.state.bigScreen.computedDatas
  60. },
  61. // 跟当前组件计算表达式关联的组件的数据集合
  62. currentDataset () {
  63. const newDataset = {}
  64. this.config.expressionCodes?.forEach(item => {
  65. const code = item.split('_')[1]
  66. for (const key in this.dataset) {
  67. const objCode = key.split('_')[1]
  68. if (objCode === code) {
  69. newDataset[code] = this.dataset[key]
  70. }
  71. }
  72. })
  73. return newDataset
  74. },
  75. // 跟当前组件计算表达式关联的组件的数据集合
  76. currentComputedDatas () {
  77. const newDataset = {}
  78. this.config.expressionCodes?.forEach(item => {
  79. const code = item.split('_')[1]
  80. for (const key in this.computedDatas) {
  81. const objCode = key.split('_')[1]
  82. if (objCode === code) {
  83. newDataset[code] = this.computedDatas[key]
  84. }
  85. }
  86. })
  87. return newDataset
  88. },
  89. // 组件数据加载时的背景颜色
  90. loadingBackground () {
  91. return this.customTheme === 'light' ? '#ffffff' : '#151A26'
  92. },
  93. isPreview () {
  94. return (this.$route.path === window?.BS_CONFIG?.routers?.previewUrl) || (this.$route.path === '/big-screen/preview')
  95. }
  96. },
  97. mounted () {
  98. if (!['tables', 'flyMap', 'map'].includes(this.config.type)) {
  99. this.chartInit()
  100. }
  101. this.watchCacheData()
  102. },
  103. methods: {
  104. ...mapMutations({
  105. changeChartConfig: 'bigScreen/changeChartConfig',
  106. changeActiveItemConfig: 'bigScreen/changeActiveItemConfig',
  107. updateDataset: 'bigScreen/updateDataset',
  108. updateComputedDatas: 'bigScreen/updateComputedDatas'
  109. }),
  110. /**
  111. * 初始化组件
  112. */
  113. chartInit () {
  114. let config = this.config
  115. // key和code相等,说明是一进来刷新,调用list接口
  116. if (this.isPreview) {
  117. // 改变样式
  118. config = this.changeStyle(config) ? this.changeStyle(config) : config
  119. // 改变数据
  120. config = this.changeDataByCode(config)
  121. } else {
  122. // 否则说明是更新,这里的更新只指更新数据(改变样式时是直接调取changeStyle方法),因为更新数据会改变key,调用chart接口
  123. // eslint-disable-next-line no-unused-vars
  124. config = this.changeData(config)
  125. }
  126. },
  127. /**
  128. * 初始化组件时获取后端返回的数据, 返回数据和当前组件的配置_list
  129. * @param settingConfig 设置时的配置。不传则为当前组件的配置
  130. * @returns {Promise<unknown>}
  131. */
  132. changeDataByCode (config) {
  133. let currentPage = 1
  134. let size = 10
  135. if (config?.option?.pagination) {
  136. currentPage = config.option.pagination.currentPage
  137. size = config.option.pagination.pageSize
  138. }
  139. return new Promise((resolve, reject) => {
  140. config.loading = true
  141. getChatInfo({
  142. // innerChartCode: this.pageCode ? config.code : undefined,
  143. chartCode: config.code,
  144. current: currentPage,
  145. pageCode: this.pageCode,
  146. size: size,
  147. type: config.type
  148. }).then(async (res) => {
  149. config.loading = false
  150. let _res = cloneDeep(res)
  151. // 如果是http数据集的前端代理,则需要调封装的axios请求
  152. if (res.executionByFrontend) {
  153. if (res.data.datasetType === 'http') {
  154. _res = await axiosFormatting(res.data)
  155. _res = this.httpDataFormatting(res, _res)
  156. }
  157. if (res.data.datasetType === 'js') {
  158. try {
  159. const scriptAfterReplacement = res.data.script.replace(/\${(.*?)}/g, (match, p) => {
  160. const value = this.config.dataSource?.params[p]
  161. if (value === null || value === undefined || value === '') {
  162. return "''"
  163. } else if (!isNaN(value)) {
  164. return value || p
  165. } else {
  166. return `'${value}' || '${p}'`
  167. }
  168. })
  169. // eslint-disable-next-line no-new-func
  170. const scriptMethod = new Function(scriptAfterReplacement)
  171. _res.data = scriptMethod()
  172. } catch (error) {
  173. console.info('JS数据集脚本执行失败', error)
  174. }
  175. }
  176. }
  177. // 将后端返回的数据保存
  178. if (_res.success) {
  179. this.updateDataset({ code: config.code, title: config.title, data: _res?.data })
  180. }
  181. config = this.dataFormatting(config, _res)
  182. this.changeChartConfig(config)
  183. }).catch((err) => {
  184. console.info(err)
  185. }).finally(() => {
  186. resolve(config)
  187. })
  188. })
  189. },
  190. /**
  191. * @description: 更新chart
  192. * @param {Object} config
  193. */
  194. changeData (config, filterList) {
  195. const list = config?.paramsList?.map((item) => {
  196. if (item.value === '${level}') {
  197. return { ...item, value: config.customize.level }
  198. } else if (item.value === '${name}') {
  199. return { ...item, value: config.customize.scope }
  200. } else {
  201. return item
  202. }
  203. })
  204. const params = {
  205. chart: {
  206. ...config,
  207. paramsList: list ? [...list] : [],
  208. option: undefined
  209. },
  210. current: 1,
  211. pageCode: this.pageCode,
  212. type: config.type,
  213. filterList: filterList || this.filterList
  214. }
  215. return new Promise((resolve, reject) => {
  216. config.loading = true
  217. getUpdateChartInfo(params).then(async (res) => {
  218. config.loading = false
  219. let _res = cloneDeep(res)
  220. // 如果是http数据集的前端代理,则需要调封装的axios请求
  221. if (res.executionByFrontend) {
  222. if (res.data.datasetType === 'http') {
  223. _res = await axiosFormatting(res.data)
  224. _res = this.httpDataFormatting(res, _res)
  225. }
  226. if (res.data.datasetType === 'js') {
  227. try {
  228. params.filterList.forEach(item => {
  229. this.config.dataSource.params[item.column] = item.value
  230. })
  231. const scriptAfterReplacement = res.data.script.replace(/\${(.*?)}/g, (match, p) => {
  232. const value = this.config.dataSource?.params[p]
  233. if (value === null || value === undefined || value === '') {
  234. return "''"
  235. } else if (!isNaN(value)) {
  236. return value || p
  237. } else {
  238. return `'${value}' || '${p}'`
  239. }
  240. })
  241. // eslint-disable-next-line no-new-func
  242. const scriptMethod = new Function(scriptAfterReplacement)
  243. _res.data = scriptMethod()
  244. } catch (error) {
  245. console.info('JS数据集脚本执行失败', error)
  246. }
  247. }
  248. }
  249. // 将后端返回的数据保存
  250. if (_res.success) {
  251. this.updateDataset({ code: config.code, title: config.title, data: _res?.data })
  252. }
  253. config = this.dataFormatting(config, _res)
  254. if (this.chart) {
  255. // 单指标组件和多指标组件的changeData传参不同
  256. if (['Liquid', 'Gauge', 'RingProgress'].includes(config.chartType)) {
  257. this.chart.changeData(config.option.percent)
  258. } else {
  259. this.chart.changeData(config.option.data)
  260. }
  261. }
  262. }).catch(err => {
  263. console.info(err)
  264. }).finally(() => {
  265. if (config) {
  266. config.loading = false
  267. }
  268. resolve(config)
  269. })
  270. })
  271. },
  272. // http前台代理需要对返回的数据进行重新组装
  273. httpDataFormatting (chartRes, httpRes) {
  274. let result = {}
  275. result = {
  276. columnData: chartRes.columnData,
  277. data: httpRes,
  278. success: chartRes.success
  279. }
  280. return result
  281. },
  282. dataFormatting (config, data) {
  283. // 覆盖
  284. },
  285. newChart (option) {
  286. // 覆盖
  287. },
  288. // 通过表达式计算获取组件的值
  289. getDataByExpression (config) {
  290. // 覆盖
  291. },
  292. changeStyle (config) {
  293. config = { ...this.config, ...config }
  294. // 样式改变时更新主题配置
  295. config.theme = settingToTheme(cloneDeep(config), this.customTheme)
  296. this.changeChartConfig(config)
  297. if (config.code === this.activeCode) {
  298. this.changeActiveItemConfig(config)
  299. }
  300. },
  301. // 缓存组件数据监听
  302. watchCacheData () {
  303. EventBus.$on('cacheDataInit', (data, dataSetId) => {
  304. // 如果是缓存数据集
  305. // 且当前组件的businessKey和缓存的dataSetId相等时,更新组件
  306. if (
  307. this.config.dataSource.dataSetType === '2' &&
  308. this.config.dataSource.businessKey === dataSetId
  309. ) {
  310. const config = this.dataFormatting(this.config, data)
  311. config.key = new Date().getTime()
  312. this.changeChartConfig(config)
  313. this.newChart(config.option)
  314. }
  315. })
  316. }
  317. }
  318. }