openatc-components 0.0.24 → 0.0.27

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (76) hide show
  1. package/config/index.js +1 -1
  2. package/package/kisscomps/components/ExpendConfig/ExpendConfig.vue +93 -0
  3. package/package/kisscomps/components/ExpendConfig/index.js +2 -0
  4. package/package/kisscomps/components/IntersectionMap/crossDirection/crossDiagram.vue +22 -0
  5. package/package/kisscomps/components/IntersectionMap/intersectionmap.vue +16 -12
  6. package/package/kisscomps/components/IntersectionWithInterface/IntersectionWithInterface.vue +244 -4
  7. package/package/kisscomps/components/KanBan/index.js +2 -0
  8. package/package/kisscomps/components/KanBan/kanban.vue +219 -0
  9. package/package/kisscomps/components/OverLap/OverLap.vue +11 -1
  10. package/package/kisscomps/components/PatternStatus/PatternStatus.vue +0 -1
  11. package/package/kisscomps/components/PhaseMarker/index.js +6 -0
  12. package/package/kisscomps/components/PhaseMarker/phasemarker.vue +215 -0
  13. package/package/kisscomps/components/PhaseMarker/svg/patternSvg.vue +121 -0
  14. package/package/kisscomps/components/PhaseMarker/svg/phase.vue +60 -0
  15. package/package/kisscomps/components/PhaseMarker/svg/phaseCount.vue +62 -0
  16. package/package/kisscomps/components/PhaseMarker/svg/phaseCountCycle.vue +62 -0
  17. package/package/kisscomps/components/PhaseMarker/svg/phaseSvg.vue +117 -0
  18. package/package/kisscomps/components/SchemeConfig/SchemeConfig.vue +30 -3
  19. package/package/kisscomps/components/SchemeConfig/manualControlModal/index.vue +21 -2
  20. package/package/kisscomps/components/SchemeConfig/realtimeStatusModal/index.vue +5 -47
  21. package/package/kisscomps/components/SchemeConfig/tentativeplancontrolmodal/index.vue +1304 -0
  22. package/package/kisscomps/components/StageBord/StageBord.vue +242 -0
  23. package/package/kisscomps/components/StageBord/index.js +2 -0
  24. package/package/kisscomps/components/StageStatus/StageStatus.vue +1 -1
  25. package/package/kisscomps/components/Stages/index.vue +86 -0
  26. package/package/kisscomps/components/overView/index.vue +656 -0
  27. package/package/kisscomps/components/patternList/patternList.vue +4 -0
  28. package/package/kisscomps/index.js +15 -1
  29. package/package/kissui.min.js +1 -1
  30. package/package.json +2 -2
  31. package/src/api/authapi.js +1 -1
  32. package/src/i18n/language/en.js +4 -1
  33. package/src/i18n/language/zh.js +4 -1
  34. package/src/icons/svg/tentativeplan.svg +33 -0
  35. package/src/kisscomps/components/ExpendConfig/ExpendConfig.vue +93 -0
  36. package/src/kisscomps/components/ExpendConfig/index.js +2 -0
  37. package/src/kisscomps/components/IntersectionMap/crossDirection/crossDiagram.vue +22 -0
  38. package/src/kisscomps/components/IntersectionMap/intersectionmap.vue +16 -12
  39. package/src/kisscomps/components/IntersectionWithInterface/IntersectionWithInterface.vue +244 -4
  40. package/src/kisscomps/components/KanBan/index.js +2 -0
  41. package/src/kisscomps/components/KanBan/kanban.vue +219 -0
  42. package/src/kisscomps/components/OverLap/OverLap.vue +11 -1
  43. package/src/kisscomps/components/PatternStatus/PatternStatus.vue +0 -1
  44. package/src/kisscomps/components/PhaseMarker/index.js +6 -0
  45. package/src/kisscomps/components/PhaseMarker/phasemarker.vue +215 -0
  46. package/src/kisscomps/components/PhaseMarker/svg/patternSvg.vue +121 -0
  47. package/src/kisscomps/components/PhaseMarker/svg/phase.vue +60 -0
  48. package/src/kisscomps/components/PhaseMarker/svg/phaseCount.vue +62 -0
  49. package/src/kisscomps/components/PhaseMarker/svg/phaseCountCycle.vue +62 -0
  50. package/src/kisscomps/components/PhaseMarker/svg/phaseSvg.vue +117 -0
  51. package/src/kisscomps/components/SchemeConfig/SchemeConfig.vue +30 -3
  52. package/src/kisscomps/components/SchemeConfig/manualControlModal/index.vue +21 -2
  53. package/src/kisscomps/components/SchemeConfig/realtimeStatusModal/index.vue +5 -47
  54. package/src/kisscomps/components/SchemeConfig/tentativeplancontrolmodal/index.vue +1304 -0
  55. package/src/kisscomps/components/StageBord/StageBord.vue +242 -0
  56. package/src/kisscomps/components/StageBord/index.js +2 -0
  57. package/src/kisscomps/components/StageStatus/StageStatus.vue +1 -1
  58. package/src/kisscomps/components/Stages/index.vue +86 -0
  59. package/src/kisscomps/components/overView/index.vue +656 -0
  60. package/src/kisscomps/components/patternList/patternList.vue +4 -0
  61. package/src/kisscomps/index.js +15 -1
  62. package/src/lib/publicjs/KissApi.js +2 -0
  63. package/src/main.js +2 -0
  64. package/src/router/index.js +15 -8
  65. package/src/utils/ControlFormat.js +68 -0
  66. package/src/utils/RingDataModel.js +1 -1
  67. package/src/utils/auth.js +8 -0
  68. package/src/views/home.vue +16 -1
  69. package/src/views/intersection.vue +188 -6
  70. package/src/views/overView.vue +33 -0
  71. package/src/views/schemeconfig.vue +6 -5
  72. package/static/styles/common.scss +2 -0
  73. package/static/styles/intersection.scss +18 -0
  74. package/static/styles/overview.scss +372 -0
  75. package/static/styles/schemeconfig.scss +99 -1
  76. package/static/styles/stages.scss +65 -0
package/config/index.js CHANGED
@@ -15,7 +15,7 @@ module.exports = {
15
15
  // target: 'http://192.168.13.103:8012/openatc',//'http://172.16.239.139:8080/',//设置你调用的接口域名和端口号
16
16
  // target: 'http://192.168.14.2:8012/openatc',//'http://172.16.239.139:8080/',//设置你调用的接口域名和端口号
17
17
  // target: 'https://dolphin-test.kedacom.com/openatc',
18
- target: 'http://192.168.13.105:11003',
18
+ target: 'http://192.168.13.105:11003/openatc',
19
19
  // target: 'http://192.168.13.103:10003/openatc',
20
20
  // target: 'http://192.168.13.103:9999',//'http://172.16.239.139:8080/',//设置你调用的接口域名和端口号
21
21
  // target: 'http://192.168.13.103:9999/kissapi',//'http://172.16.239.139:8080/',//设置你调用的接口域名和端口号
@@ -0,0 +1,93 @@
1
+ <template>
2
+ <div>
3
+ <div class="common-board-column">
4
+ <div class="common-board-column-header">
5
+ {{headerText}}
6
+ </div>
7
+ <div class="common-board-table-header">
8
+ <el-row :gutter="13">
9
+ <el-col :span="8">{{this.$t('openatccomponents.pattern.property')}}
10
+ </el-col>
11
+ <el-col :span="8">{{this.$t('openatccomponents.pattern.delaystart')}}
12
+ </el-col>
13
+ <el-col :span="8">{{this.$t('openatccomponents.pattern.advanceend')}}
14
+ </el-col>
15
+ </el-row>
16
+ </div>
17
+ <draggable
18
+ class="common-board-column-content"
19
+ :list="list"
20
+ :options="options">
21
+ <div class="common-board-item" v-for="element in list" :key="element.id">
22
+ <el-row :gutter="13" >
23
+ <el-col :span="8">
24
+ <el-select v-model="element.options" size="small" multiple collapse-tags :placeholder="$t('openatccomponents.common.select')">
25
+ <el-option
26
+ v-for="item in coordphaseOption"
27
+ :key="item.value"
28
+ :label="$t('openatccomponents.pattern.coordphaseOption' + item.value)"
29
+ :value="item.value">
30
+ </el-option>
31
+ </el-select>
32
+ </el-col>
33
+ <el-col :span="8">
34
+ <el-input-number :controls="false" size="small" :min="0" :max="255" :step="1" v-model.number="element.delaystart" ref="type"></el-input-number>
35
+ </el-col>
36
+ <el-col :span="8">
37
+ <el-input-number :controls="false" size="small" :min="0" :max="255" :step="1" v-model.number="element.advanceend" ref="type"></el-input-number>
38
+ </el-col>
39
+ </el-row>
40
+ </div>
41
+ </draggable>
42
+ </div>
43
+ </div>
44
+ </template>
45
+
46
+ <script>
47
+ import draggable from 'vuedraggable'
48
+ export default {
49
+ name: 'expend-config',
50
+ components: {
51
+ draggable
52
+ },
53
+ data () {
54
+ return {
55
+ coordphaseOption: [{
56
+ value: 1
57
+ }, {
58
+ value: 2
59
+ }, {
60
+ value: 4
61
+ }]
62
+ }
63
+ },
64
+ props: {
65
+ headerText: {
66
+ type: String,
67
+ default: 'Header'
68
+ },
69
+ list: {
70
+ type: Array,
71
+ default () {
72
+ return []
73
+ }
74
+ },
75
+ index: {
76
+ type: Number
77
+ },
78
+ options: {
79
+ type: Object,
80
+ default () {
81
+ return {}
82
+ }
83
+ }
84
+ }
85
+
86
+ }
87
+ </script>
88
+
89
+ <style lang="scss" scoped>
90
+ .el-input-number--small {
91
+ width: 94px;
92
+ }
93
+ </style>
@@ -0,0 +1,2 @@
1
+ import ExpendConfig from './ExpendConfig.vue'
2
+ export default ExpendConfig
@@ -11,6 +11,16 @@
11
11
  **/
12
12
  <template>
13
13
  <div class="crossImg">
14
+ <div v-show="isShowMode">
15
+ <div class="controlText">
16
+ <div style="border:0px solid red;float:right;">
17
+ {{controlName }}
18
+ </div>
19
+ </div>
20
+ <div class="modeText">
21
+ {{modeName }}
22
+ </div>
23
+ </div>
14
24
  <!-- 右行道路 B-->
15
25
  <div class="right-dir-road" v-if="roadDir === 'right'">
16
26
  <div class="centerText" v-if="crossType !== 'Customroads' && isHasPhase">
@@ -193,6 +203,18 @@ export default {
193
203
  },
194
204
  roadDirection: {
195
205
  type: String
206
+ },
207
+ isShowMode: {
208
+ type: Boolean,
209
+ devault: false
210
+ },
211
+ modeName: {
212
+ type: String,
213
+ default: ''
214
+ },
215
+ controlName: {
216
+ type: String,
217
+ default: ''
196
218
  }
197
219
  },
198
220
  // computed: {
@@ -23,10 +23,13 @@
23
23
  'transMiddleCrossImg3': bodyDomWidth <= 300 && bodyDomWidth > 260,
24
24
  'transMiniCrossImg': bodyDomWidth <= 260,
25
25
  'changePaddingBottom': graphicMode }">
26
- <CrossDiagram v-if="reset"
26
+ <CrossDiagram ref = "crossDiagram" v-if="reset"
27
27
  :crossStatusData="crossStatusData"
28
28
  :agentId="agentId"
29
29
  :isShowInterval="isShowInterval"
30
+ :isShowMode="isShowMode"
31
+ :modeName="modeName"
32
+ :controlName="controlName"
30
33
  :devStatus="devStatus"
31
34
  :roadDirection="roadDirection" />
32
35
  </div>
@@ -72,14 +75,21 @@ export default {
72
75
  type: Boolean,
73
76
  default: true
74
77
  },
75
- Token: {
76
- handler: function (val) {
77
- this.setPropsToken(val)
78
- }
79
- },
80
78
  roadDirection: {
81
79
  type: String,
82
80
  default: 'right'
81
+ },
82
+ isShowMode: {
83
+ type: Boolean,
84
+ default: false
85
+ },
86
+ modeName: {
87
+ type: String,
88
+ default: ''
89
+ },
90
+ controlName: {
91
+ type: String,
92
+ default: ''
83
93
  }
84
94
  },
85
95
  watch: {
@@ -91,11 +101,6 @@ export default {
91
101
  },
92
102
  // 深度观察监听
93
103
  deep: true
94
- },
95
- Token: {
96
- handler: function (val) {
97
- this.setPropsToken(val)
98
- }
99
104
  }
100
105
  },
101
106
  created () {
@@ -105,7 +110,6 @@ export default {
105
110
  },
106
111
  mounted () {
107
112
  this.getParentSize()
108
- this.setPropsToken(this.Token)
109
113
  },
110
114
  updated () {
111
115
  },
@@ -18,15 +18,21 @@
18
18
  :devStatus="devStatus"
19
19
  :agentId="agentId"
20
20
  :graphicMode="true"
21
- :roadDirection="roadDirection" />
21
+ :roadDirection="roadDirection"
22
+ :modeName="modeName !== '' ? modeName : controlData.mode"
23
+ :controlName="controlName !== '' ? controlName : controlData.control"
24
+ :isShowMode="isShowMode"
25
+ :isShowInterval="isShowInterval"
26
+ @onSelectStages="onSelectStages"/>
22
27
  </div>
23
28
  </template>
24
29
  <script>
25
30
  import IntersectionMap from '../IntersectionMap'
26
31
  import { getMessageByCode } from '../../../utils/responseMessage'
27
- import { getTscControl, queryDevice } from '../../../api/control.js'
28
- import { registerMessage } from '../../../api/param'
29
- import { getIframdevid, setIframdevid, setToken } from '../../../utils/auth.js'
32
+ import { getTscControl, queryDevice, putTscControl } from '../../../api/control.js'
33
+ import { registerMessage, uploadSingleTscParam } from '../../../api/param'
34
+ import { getIframdevid, setIframdevid, setToken, setHost } from '../../../utils/auth.js'
35
+ import ControlFormat from '../../../utils/ControlFormat.js'
30
36
  export default {
31
37
  name: 'intersection-with-interface',
32
38
  components: {
@@ -34,6 +40,7 @@ export default {
34
40
  },
35
41
  data () {
36
42
  return {
43
+ controlData: {},
37
44
  boxVisible: false,
38
45
  dialogWidth: '100%',
39
46
  crossStatusData: {}, // 路口状态数据
@@ -45,6 +52,10 @@ export default {
45
52
  }
46
53
  },
47
54
  props: {
55
+ reqUrl: {
56
+ type: String,
57
+ default: 'http://192.168.13.105:11003/openatc'
58
+ },
48
59
  AgentId: {
49
60
  type: String,
50
61
  default: '0'
@@ -56,6 +67,22 @@ export default {
56
67
  roadDirection: {
57
68
  type: String,
58
69
  default: 'right'
70
+ },
71
+ isShowInterval: {
72
+ type: Boolean,
73
+ default: true
74
+ },
75
+ isShowMode: {
76
+ type: Boolean,
77
+ default: false
78
+ },
79
+ modeName: {
80
+ type: String,
81
+ default: ''
82
+ },
83
+ controlName: {
84
+ type: String,
85
+ default: ''
59
86
  }
60
87
  },
61
88
  watch: {
@@ -114,6 +141,7 @@ export default {
114
141
  }
115
142
  return
116
143
  }
144
+ this.$emit('registerMessage', data)
117
145
  this.devStatus = 3
118
146
  this.clearPatternInterval() // 清除其他定时器
119
147
  this.phaseControlTimer = setInterval(() => {
@@ -180,6 +208,10 @@ export default {
180
208
  return
181
209
  }
182
210
  this.crossStatusData = JSON.parse(JSON.stringify(data.data.data.data))
211
+ let param = JSON.parse(JSON.stringify(data.data.data.data))
212
+ // this.controlData = this.handleGetData(param)
213
+ this.controlData = this.controlFormat.handleGetData(param)
214
+ this.$emit('getTscControl', data)
183
215
  }).catch(error => {
184
216
  this.$message.error(error)
185
217
  console.log(error)
@@ -206,6 +238,7 @@ export default {
206
238
  _this.platform = res.data.data.platform
207
239
  _this.$refs.intersectionMap.resetCrossDiagram()
208
240
  _this.registerMessage() // 注册消息
241
+ _this.$emit('queryDevice', res)
209
242
  })
210
243
  },
211
244
  firstInit () {
@@ -227,11 +260,218 @@ export default {
227
260
  if (token && token !== '') {
228
261
  setToken(token)
229
262
  }
263
+ },
264
+ setHost (host) {
265
+ // 获取组件外传入的token,便于独立组件调用接口
266
+ if (host && host !== '') {
267
+ setHost(host)
268
+ }
269
+ },
270
+ async doPatternCommit (control) {
271
+ let that = this
272
+ let resData
273
+ await putTscControl(control, this.agentId).then(data => {
274
+ resData = data
275
+ let success = 0
276
+ if (!data.data.success) {
277
+ that.$message.error(getMessageByCode(data.data.code, that.$i18n.locale))
278
+ return
279
+ }
280
+ if (data.data.data && data.data.data.data) {
281
+ success = data.data.data.data.success
282
+ if (success !== 0) {
283
+ let errormsg = 'openatccomponents.overview.putTscControlError' + success
284
+ that.$message.error(this.$t(errormsg))
285
+ return
286
+ }
287
+ }
288
+ // this.closeManualModal()
289
+ if ((that.currModel === 5 || that.currModel === 6 || that.currModel === 10 || that.currModel === 12) && (that.preselectModel === 6 || that.preselectModel === 10 || that.preselectModel === 12)) {
290
+ that.$message.success(this.$t('openatccomponents.overview.nextcycleeffic'))
291
+ return
292
+ }
293
+ if (that.preselectModel === 4) {
294
+ that.$message.success(this.$t('openatccomponents.overview.transitioneffic'))
295
+ return
296
+ }
297
+ if (success === 0) {
298
+ that.$message.success(this.$t('openatccomponents.common.download'))
299
+ }
300
+ }).catch(error => {
301
+ that.$message.error(error)
302
+ console.log(error)
303
+ })
304
+ return resData
305
+ },
306
+ async getTscControlInfo () {
307
+ await getTscControl(this.agentId).then((data) => {
308
+ let res = data
309
+ this.controlInfo = {
310
+ tscData: null,
311
+ stageData: null,
312
+ controlData: null
313
+ }
314
+ if (!data.data.success) {
315
+ if (data.data.code === '4003') {
316
+ this.$message.error(getMessageByCode(data.data.code, this.$i18n.locale))
317
+ return
318
+ }
319
+ let parrenterror = getMessageByCode(data.data.code, this.$i18n.locale)
320
+ if (data.data.data) {
321
+ // 子类型错误
322
+ let childErrorCode = data.data.data.errorCode
323
+ if (childErrorCode) {
324
+ let childerror = getMessageByCode(data.data.data.errorCode, this.$i18n.locale)
325
+ this.$message.error(parrenterror + ',' + childerror)
326
+ }
327
+ } else {
328
+ this.$message.error(parrenterror)
329
+ }
330
+ return
331
+ }
332
+ let tscData = JSON.parse(JSON.stringify(res.data.data))
333
+ let stageData = []
334
+ // stageData = this.handleStageData(tscData) // 处理阶段(驻留)stage数据
335
+ let controlData = {}
336
+ let param = Object.assign({}, tscData)
337
+ controlData = this.controlFormat.handleGetData(param)
338
+ this.controlData = controlData
339
+ this.controlInfo = {
340
+ tscData: tscData,
341
+ stageData: stageData,
342
+ controlData: controlData
343
+ }
344
+ }).catch(error => {
345
+ this.$message.error(error)
346
+ console.log(error)
347
+ })
348
+ },
349
+ async getPhase () {
350
+ await uploadSingleTscParam('phase', this.agentId).then(data => {
351
+ let res = data.data
352
+ if (!res.success) {
353
+ if (res.code === '4003') {
354
+ this.$message.error(this.$t('openatccomponents.errorTip.devicenotonline'))
355
+ return
356
+ }
357
+ this.$message.error(getMessageByCode(data.data.code, this.$i18n.locale))
358
+ return
359
+ }
360
+ this.phaseList = res.data.data.phaseList
361
+ })
362
+ },
363
+ async getPhaseInfo () {
364
+ await this.getPhase()
365
+ let res = [...this.phaseList]
366
+ return res
367
+ },
368
+ async getControlInfo () {
369
+ await this.getTscControlInfo()
370
+ // let res = this.controlInfo.controlData
371
+ let res = this.controlInfo.tscData
372
+ return res
373
+ },
374
+ clearInterVals () {
375
+ this.clearPatternInterval() // 清除定时器
376
+ this.clearRegisterMessageTimer() // 清除定时器
377
+ },
378
+ onSelectStages (value) {
379
+ this.currentStage = value
380
+ this.$emit('onSelectStages', value)
381
+ },
382
+ async lockPhase (reqData) {
383
+ let res = await this.doPatternCommit(reqData)
384
+ return res
385
+ },
386
+ async unlockPhase (reqData) {
387
+ let res = await this.doPatternCommit(reqData)
388
+ return res
389
+ },
390
+ async changeControlPattern (reqData) {
391
+ let res = await this.doPatternCommit(reqData)
392
+ return res
393
+ },
394
+ getBusPos () {
395
+ // 公交相位信息
396
+ this.busPhaseData = []
397
+ this.phaseList.forEach((ele, i) => {
398
+ if (ele.controltype >= 3 && ele.controltype <= 5) {
399
+ ele.direction.forEach((dir, index) => {
400
+ // 车道相位
401
+ this.busPhaseData.push({
402
+ // key: this.CrossDiagramMgr.getUniqueKey('busphase'),
403
+ phaseid: ele.id, // 相位id,用于对应相位状态
404
+ id: dir, // 接口返回的dir字段,对应前端定义的相位方向id,唯一标识
405
+ name: this.PhaseDataModel.getBusPhasePos(dir).name,
406
+ controltype: ele.controltype
407
+ })
408
+ })
409
+ }
410
+ })
411
+ let result = []
412
+ let obj = {}
413
+ for (var i = 0; i < this.busPhaseData.length; i++) {
414
+ if (!obj[this.busPhaseData[i].phaseid]) {
415
+ result.push(this.busPhaseData[i])
416
+ obj[this.busPhaseData[i].phaseid] = true
417
+ }
418
+ }
419
+ this.busPhaseData = result
420
+ },
421
+ handleStageData (data) {
422
+ this.getBusPos()
423
+ this.stagesList = []
424
+ let busPhaseData = this.busPhaseData
425
+ let stages = data.stages
426
+ if (!stages) return
427
+ let stagesTemp = []
428
+ for (let stage of stages) {
429
+ let tempList = []
430
+ let directionList = []
431
+ let stageControType = 0
432
+ let peddirections = []
433
+ for (let stg of stage) {
434
+ let currPhase = this.phaseList.filter((item) => {
435
+ return item.id === stg
436
+ })[0]
437
+ if (currPhase !== undefined) {
438
+ directionList = [...currPhase.direction, ...directionList]
439
+ }
440
+ for (let walk of this.sidewalkPhaseData) {
441
+ if (stg === walk.phaseid) {
442
+ peddirections.push(...currPhase.peddirection)
443
+ peddirections = Array.from(new Set(peddirections))
444
+ }
445
+ }
446
+ for (let busPhase of busPhaseData) {
447
+ if (stg === busPhase.phaseid) {
448
+ stageControType = busPhase.controltype
449
+ }
450
+ }
451
+ }
452
+ directionList = [...new Set(directionList)]
453
+ if (directionList.length === 0) return
454
+ tempList = directionList.map(dir => ({
455
+ id: dir,
456
+ color: '#606266',
457
+ controltype: stageControType,
458
+ peddirection: peddirections
459
+ }))
460
+ stagesTemp.push(tempList)
461
+ }
462
+ this.stagesList = JSON.parse(JSON.stringify(stagesTemp))
463
+ // 相位变化时触发回调
464
+ if (this.currentStage !== data.current_stage) {
465
+ this.$emit('onPhaseChange', this.stagesList, data.current_stage)
466
+ }
467
+ this.currentStage = data.current_stage
230
468
  }
231
469
  },
232
470
  created () {
233
471
  this.agentId = this.AgentId
234
472
  this.setDialogWidth()
473
+ this.setHost(this.reqUrl)
474
+ this.controlFormat = new ControlFormat()
235
475
  },
236
476
  mounted () {
237
477
  setIframdevid(this.AgentId)
@@ -0,0 +1,2 @@
1
+ import KanBan from './KanBan.vue'
2
+ export default KanBan