3328350766
6 天以前 761eb03d6b3bebd0b197179564c84d89d3d12a0d
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
/*
 * @description: vuex mutations 事件
 * @Date: 2023-03-13 10:04:59
 * @Author: xing.heng
 * @LastEditors: xing.heng
 * @LastEditTime: 2023-06-08 15:24:01
 */
 
import Vue from 'vue'
// import _ from 'lodash'
import cloneDeep from 'lodash/cloneDeep'
import uniq from 'lodash/uniq'
import { defaultData } from './state'
import moment from 'moment'
import { randomString } from 'data-room-ui/js/utils'
import { EventBus } from 'data-room-ui/js/utils/eventBus'
import CloneDeep from 'lodash-es/cloneDeep'
export default {
  // 改变页面基本信息,后端请求的页面信息存储到此处
  changePageInfo (state, pageInfo) {
    state.pageInfo = pageInfo
  },
  // 改变组件列表
  changeLayout (state, layout) {
    state.pageInfo.chartList = layout
  },
  //
  changeIframeDialog  (state, dialogVisible) {
    state.iframeDialog = dialogVisible
  },
  // 改变当前选择组件id
  changeActiveCode (state, code) {
    state.activeCode = code
    state.hoverCode = code
    let activeItem = {}
    // let activeItem = cloneDeep(state.pageInfo.chartList?.find(
    //   item => item.code === code
    // ))
    for (const item of state.pageInfo.chartList) {
      // 检查当前项的 code 是否与 currentCode 匹配
      if (item.code === code) {
        activeItem = item
        break // 找到匹配的项后,退出循环
      }
      // 如果当前项的 type 为 'chartTab',则进一步检查其 tabList
      if (item.type === 'chartTab') {
        for (const tabItem of item.customize.tabList) {
          // 检查 tabList 中的每一项的 code 是否与 currentCode 匹配
          if (tabItem.chartCode === code) {
            activeItem = tabItem.chart
            break // 找到匹配的项后,退出循环
          }
        }
      }
    }
    changeGroup(code, state)
    state.activeItemConfig = cloneDeep(activeItem)
  },
  changeActiveCodes (state, codes) {
    // 传入codes,将codes中的组件的group改为tempGroup,不传入或者传入空数组,将所有组件的group改为'',即取消组合
    if (codes.length !== 0) {
      state.activeCodes = codes
      state.pageInfo.chartList = state.pageInfo.chartList?.map(chart => {
        return {
          ...chart,
          group: (codes.includes(chart.code) && !chart.group) ? 'tempGroup' : chart.group
        }
      })
    } else {
      state.activeCodes = codes
      state.pageInfo.chartList = state.pageInfo.chartList?.map(chart => {
        return {
          ...chart,
          // 确保取消高亮状态时不会使得原本设置过的组合被取消
          group: chart.group === 'tempGroup' ? '' : chart.group
        }
      })
    }
  },
  // 情况页面选中的组件
  clearActiveCodes (state) {
    state.activeCodes = []
  },
  // 改变当前hover组件id
  changeHoverCode (state, code) {
    state.hoverCode = code
  },
  // 改变当前选中组件id
  changePageLoading (state, booleanValue) {
    // 改变loading状态
    state.pageLoading = booleanValue
  },
  // 改变当前组件的加载状态
  changeChartLoading (state, itemConfig) {
    // 改变loading状态
    state.pageInfo.chartList.forEach((chart, index) => {
      if (chart.code === itemConfig.code) {
        chart.loading = itemConfig.loading
      }
    })
  },
  // 改变当前组件配置
  changeChartConfig (state, itemConfig) {
    // 如果存在parentCode的组件,则是tab中的组件
    if (itemConfig?.parentCode) {
      state.pageInfo.chartList.forEach((chart, index) => {
        if (chart.code === itemConfig.parentCode) {
          chart.customize.tabList.forEach((tabItem, i) => {
            if (tabItem.chartCode === itemConfig.code) {
              Vue.set(state.pageInfo.chartList[index].customize.tabList[i], 'chart', {
                ...state.pageInfo.chartList[index].customize.tabList[i].chart,
                ...itemConfig
              })
            }
          })
        }
      })
    } else {
      // 如果是一般的组件
      let index = null
      index = state.pageInfo.chartList.findIndex(
        item => item.code === itemConfig.code
      )
      Vue.set(state.pageInfo.chartList, index, {
        ...state.pageInfo.chartList[index],
        ...itemConfig
      })
      // 对比之前的config和当前的itemConfig的xywh,如果有变化,就改变卡尺对齐线
      const oldConfig = state.pageInfo.chartList[index]
      if (
        oldConfig.x !== itemConfig.x ||
        oldConfig.y !== itemConfig.y ||
        oldConfig.w !== itemConfig.w ||
        oldConfig.h !== itemConfig.h
      ) {
        // 改变当前组件的卡尺对齐线
        changePresetLine(state, itemConfig)
      }
    }
  },
  setPresetLine (state, { x, y, w, h }) {
    state.presetLine = [
      { type: 'h', site: y || 0 },
      { type: 'v', site: x || 0 }
    ]
  },
  changeActiveItemConfig (state, config) {
    state.activeItemConfig = cloneDeep(config)
  },
  // 新增一个组件
  addItem (state, itemConfig) {
    // 放到第一项
    state.pageInfo.chartList.unshift(itemConfig)
    changeZIndexFuc(state, state.pageInfo.chartList)
    saveTimeLineFunc(state, '新增组件' + itemConfig?.title)
  },
  // 删除组件/批量删除组件
  delItem (state, codes) {
    if (Array.isArray(codes)) {
      const delCharts = state.pageInfo.chartList.filter(chart => codes.includes(chart.code))
      // 如果删除的组件中有跑马灯,需要删除将跑马灯组件的音频实例销毁
      delCharts.some(item => { item.type === 'marquee' && EventBus.$emit('deleteComponent', item.code) })
      state.pageInfo.chartList = state.pageInfo.chartList.filter(chart => !codes.includes(chart.code))
    } else {
      // 如果删除的组件是跑马灯,需要删除将跑马灯组件的音频实例销毁
      const delChart = state.pageInfo.chartList.find(chart => codes === chart.code)
      if (delChart && delChart.type === 'marquee') {
        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) {
      state.activeItemConfig = null
      state.activeCode = null
      EventBus.$emit('closeRightPanel')
    }
    // 发送事件,关闭配置面板
  },
  changePageConfig (state, pageConfig) {
    Vue.set(state.pageInfo, 'pageConfig', cloneDeep(pageConfig))
    state.updateKey = new Date().getTime()
  },
  changeActiveItem (state, activeItem) {
    state.activeItem = cloneDeep(activeItem)
    state.activeId = activeItem.code
    // state.settingJson = cloneDeep(activeItem.settingConfig) || {}
  },
  // 改变当前组件的xywh
  changeActiveItemWH (state, chart) {
    if (chart.code === state.activeItemConfig.code) {
      state.activeItemConfig = {
        ...state.activeItemConfig,
        ...chart
      }
    }
  },
  // 清空卡尺对齐线
  resetPresetLine (state) {
    state.presetLine = []
  },
  // 改变组件的层级
  changeZIndex (state, list) {
    changeZIndexFuc(state, list)
  },
  // 改变锁定状态
  changeLocked (state, config) {
    // 如果是多选,则改变框选中的所有组件的锁定状态
    if (state.activeCodes && state.activeCodes.length > 1) {
      state.pageInfo.chartList = state.pageInfo.chartList?.map(chart => {
        return {
          ...chart,
          locked: state.activeCodes.includes(chart.code) ? !config.locked : chart.locked
        }
      })
      saveTimeLineFunc(state, config.locked ? '解锁选中组件' : '锁定选中组件')
    } else {
      // 如果不是多选,则只改变当前一个
      const index = state.pageInfo.chartList.findIndex(
        item => item.code === config.code
      )
      Vue.set(state.pageInfo.chartList[index], 'locked', !config.locked)
      saveTimeLineFunc(state, !config.locked ? `解锁${config?.title}` : `锁定${config?.title}`)
    }
  },
  // 改变网格显示状态
  changeGridShow (state, isShow) {
    state.hasGrid = isShow
  },
  // 改变组件的key
  changeChartKey (state, code) {
    const index = state.pageInfo.chartList.findIndex(
      item => item.code === code
    )
    if (index < 0) {
      return
    }
    const config = state.pageInfo.chartList[index]
    Vue.set(config, 'key', config.code + new Date().getTime())
  },
  // 改变缓存数据集中的字段列表
  changeCacheDataFields (state, { dataSetId, data }) {
    // 将 state.pageInfo.pageConfig.cacheDataSets 中的 dataSetId 对应fields字段数据替换为 data
    const index = state.pageInfo.pageConfig.cacheDataSets.findIndex(cacheData => cacheData.dataSetId === dataSetId)
    if (index < 0) {
      return
    }
    Vue.set(state.pageInfo.pageConfig.cacheDataSets[index], 'fields', data?.fields || [])
  },
  // 改变缓存数据集中的数据参数
  changeCacheDataParams (state, { dataSetId, data }) {
    // 将 state.pageInfo.pageConfig.cacheDataSets 中的 dataSetId 对应fields字段数据替换为 data
    const index = state.pageInfo.pageConfig.cacheDataSets.findIndex(cacheData => cacheData.dataSetId === dataSetId)
    if (index < 0) {
      return
    }
    Vue.set(state.pageInfo.pageConfig.cacheDataSets[index], 'params', data?.params || [])
  },
  // 改变缓存数据集中的数据
  changeCacheDataSetData (state, { dataSetId, data }) {
    const index = state.pageInfo.pageConfig.cacheDataSets.findIndex(cacheData => cacheData.dataSetId === dataSetId)
    if (index < 0) {
      return
    }
    state.pageInfo.pageConfig.cacheDataSets[index].data = data || []
  },
  // 改变shift是否被按下
  changeCtrlOrCommandDown (state, isDown) {
    state.shiftKeyDown = isDown
  },
  // 初始化store中的数据,防止污染
  resetStoreData (state) {
    for (const stateKey in state) {
      state[stateKey] = cloneDeep(defaultData[stateKey])
    }
  },
  changeZoom (state, zoom) {
    state.zoom = zoom
  },
  changeFitZoom (state, zoom) {
    state.fitZoom = zoom
  },
  changeActivePos (state, { diffX, diffY }) {
    const activeCodes = state.activeCodes
    activeCodes?.forEach(code => {
      const chart = state.pageInfo.chartList.find(item => item.code === code)
      if (chart) {
        chart.x += diffX
        chart.y += diffY
      }
      const index = state.pageInfo.chartList.findIndex(
        item => item.code === chart.code
      )
      if (index < 0) {
        return
      }
      Vue.set(state.pageInfo.chartList, index, {
        ...state.pageInfo.chartList[index],
        ...chart
      })
      changePresetLine(state, chart)
    })
  },
  // 保存当前状态
  saveTimeLine (state, title) {
    const date = new Date()
    const time = moment(date).format('HH:mm:ss')
    // title默认获取当前时间,时分秒
    if (!title) {
      const date = new Date()
      title = `${date.getHours()}:${date.getMinutes()}:${date.getSeconds()}`
    }
    saveTimeLineFunc(state, title, time)
  },
  // 撤回/反撤回当前事件线 (undo和redo放到一个函数中,用isUndo区分)
  undoTimeLine (state, isUndo = true) {
    let currentStore = {}
    // 撤回
    if (isUndo) {
      if (state.timelineStore.length > 0 && state.currentTimeLine > 1) {
        // 时间线往前推一个
        state.currentTimeLine = state.currentTimeLine - 1
        currentStore = state.timelineStore[state.currentTimeLine - 1]
        if (currentStore?.chartList) {
          state.pageInfo.chartList = cloneDeep(currentStore?.chartList)
          state.activeItemConfig = cloneDeep(currentStore?.chartList?.find(item => item.code === state.activeCode) || {})
          EventBus.$emit('operationRollback', true)
        }
      }
    }
    // 反撤回 redo
    if (!isUndo) {
      if (state.currentTimeLine < state.timelineStore.length) {
        // 时间线往后推一个
        state.currentTimeLine = state.currentTimeLine + 1
        currentStore = state.timelineStore[state.currentTimeLine - 1]
        state.pageInfo.chartList = cloneDeep(currentStore?.chartList || [])
      }
    }
    state.pageInfo.chartList = state.pageInfo.chartList.map(chart => {
      return {
        ...chart,
        key: chart.code + new Date().getTime()
      }
    })
  },
  clearTimeline (state) {
    // 最后一个状态
    const lastStore = state.timelineStore[state.timelineStore.length - 1]
    // 将最后一个状态作为初始状态,否则下次拖拽后无法回到之前
    state.timelineStore = [
      {
        ...lastStore,
        timelineTitle: '初始状态',
        updateTime: moment(new Date()).format('HH:mm:ss')
      }
    ]
    state.currentTimeLine = 1
  },
  // 回退到指定时间线
  rollbackTimeline (state, index) {
    state.pageInfo.chartList = cloneDeep(state.timelineStore[index]?.chartList || [])
    state.currentTimeLine = index + 1
  },
  // 复制组件
  copyCharts (state) {
    state.copyChartCodes = cloneDeep(state.activeCodes)
  },
  // 粘贴组件
  pasteCharts (state) {
    const copyChartCodes = state.copyChartCodes
    const chartList = state.pageInfo.chartList
    // 将选中的组件复制一份, code加上 随机后缀, key 也加上随机后缀, x, y 各增加50
    const additionCode = randomString(5)
    const copyCharts = copyChartCodes.map(code => {
      const chart = chartList.find(item => item.code === code)
      const copyChart = cloneDeep(chart)
      copyChart.code = `${copyChart.code}_${additionCode}`
      copyChart.key = `${copyChart.key}_${additionCode}`
      copyChart.group = (copyChart.group && copyChart.group !== 'tempGroup') ? `${copyChart.group}_${additionCode}` : ''
      copyChart.x += 50
      copyChart.y += 50
      return copyChart
    })
    // 将复制的组件添加到chartList中
    state.pageInfo.chartList = [...copyCharts, ...state.pageInfo.chartList]
  },
  // 更新数据集库中的内容
  updateDataset (state, res) {
    // 如果只是更新了组件的标题
    if (res.isChangeTitle) {
      if (state.dataset.hasOwnProperty(res.oldTitle + '_' + res.code)) {
        const _dataset = CloneDeep(state.dataset)
        _dataset[res.title + '_' + res.code] = _dataset[res.oldTitle + '_' + res.code]
        delete _dataset[res.oldTitle + '_' + res.code]
        state.dataset = CloneDeep(_dataset)
      }
    } else {
      Vue.set(state.dataset, res.title + '_' + res.code, res.data)
    }
  },
  // 更新数据集库中的内容
  updateComputedDatas (state, res) {
    // 如果只是更新了组件的标题
    if (res.isChangeTitle) {
      if ((!res.isExpression) && state.computedDatas.hasOwnProperty(res.oldTitle + '_' + res.code)) {
        const _computedDatas = CloneDeep(state.computedDatas)
        _computedDatas[res.title + '_' + res.code] = _computedDatas[res.oldTitle + '_' + res.code]
        delete _computedDatas[res.oldTitle + '_' + res.code]
        state.computedDatas = CloneDeep(_computedDatas)
      }
    } else {
      Vue.set(state.computedDatas, res.title + '_' + res.code, res.data)
    }
  },
  // 清空数据集库
  emptyDataset (state) {
    state.dataset = {}
  },
  // 清空数据集库
  emptyComputedDatas (state) {
    state.computedDatas = {}
  },
  // 修改磁吸状态
  snapChange (state, snap) {
    state.snapTolerance = snap
  }
}
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) {
  const len = list?.length - 1 || 0
  list.forEach((item, i) => {
    const index = state.pageInfo.chartList.findIndex(
      _item => _item.code === item.code
    )
    Vue.set(state.pageInfo.chartList[len - index], 'z', i)
  })
}
 
// 改变当前组件的卡尺对齐线
function changePresetLine (state, { x, y, w, h }) {
  state.presetLine = [
    { type: 'h', site: y || 0 },
    { type: 'v', site: x || 0 }
  ]
}
 
function changeGroup (code, state) {
  if (code) {
    // 找到和此组件group相同的组件,并添加到activeCodes中
    const group = state.pageInfo.chartList?.find(item => item.code === code)?.group
    if (group) {
      state.activeCodes = state.pageInfo.chartList?.filter(chart => chart.group === group && chart.group).map(item => item.code)
    }
    if (state.shiftKeyDown) {
      state.activeCodes = uniq([...state.activeCodes, code])
      // eslint-disable-next-line no-unused-expressions
      state.pageInfo.chartList?.forEach(chart => {
        if (state.activeCodes.includes(chart.code)) {
          chart.group = 'tempGroup'
        }
      })
    } else {
      if (!group) {
        state.activeCodes = [code]
      }
    }
  } else {
    state.activeCodes = []
    state.pageInfo.chartList = state.pageInfo.chartList?.map(chart => ({
      ...chart,
      group: chart.group === 'tempGroup' ? '' : chart.group
    }))
  }
}
 
function saveTimeLineFunc (state, title, time) {
  // 最多保存10个状态
  const MAX_TIME_LINE = 10
  const stateCopy = cloneDeep(state.pageInfo)
  const date = new Date()
  time = time || moment(date).format('HH:mm:ss')
  stateCopy.timelineTitle = title
  stateCopy.updateTime = time
 
  if (!Array.isArray(state.timelineStore)) {
    state.timelineStore = []
  }
  if (!Number.isInteger(state.currentTimeLine)) {
    state.currentTimeLine = 0
  }
  if (state.timelineStore.length >= MAX_TIME_LINE) {
    // 去掉最早的一个
    state.timelineStore.shift()
  }
  state.timelineStore?.push(stateCopy)
  state.currentTimeLine = state.timelineStore?.length
}