openatc-components 0.4.16 → 0.4.18

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.
@@ -0,0 +1,2 @@
1
+ import OptimizeKanban from './OptimizeKanban.vue'
2
+ export default OptimizeKanban
@@ -0,0 +1,369 @@
1
+ /**
2
+ * Copyright (c) 2020 kedacom
3
+ * OpenATC is licensed under Mulan PSL v2.
4
+ * You can use this software according to the terms and conditions of the Mulan PSL v2.
5
+ * You may obtain a copy of Mulan PSL v2 at:
6
+ * http://license.coscl.org.cn/MulanPSL2
7
+ * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
8
+ * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
9
+ * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
10
+ * See the Mulan PSL v2 for more details.
11
+ **/
12
+ <template>
13
+ <div class="kanbanOptimize">
14
+ <div v-if="this.nowNumber === 1" class="optimizetype">
15
+ <span>{{$t('openatccomponents.pattern.optimizetype')}}</span>
16
+ <el-select v-model="value" clearable :placeholder="$t('openatccomponents.common.select')">
17
+ <el-option
18
+ v-for="item in typeOptions"
19
+ :key="item.value"
20
+ :label="$t('openatccomponents.overview.type' + item.value)"
21
+ :value="item.value"
22
+ >
23
+ </el-option>
24
+ </el-select>
25
+ <span class="optimiNum">{{$t('openatccomponents.pattern.optimizecycle')}}</span>
26
+ <el-input v-model="optimizecycle" clearable :placeholder="$t('openatccomponents.common.enter')"></el-input>
27
+ <!-- <el-button type="primary" @click="onOptimizeClick()">{{$t('openatccomponents.pattern.inoptimize')}}</el-button> -->
28
+ </div>
29
+ <div class="common-board-column" :style="{marginTop:this.nowNumber === 1 ? 0 : '50px',marginLeft:this.nowNumber === 1 ? 0 : 0}">
30
+ <div class="common-board-column-header">
31
+ {{headerText}}
32
+ </div>
33
+ <div class="openatccomponents-board-table-header">
34
+ <el-row :gutter="13">
35
+ <el-col :span="4">{{this.$t('openatccomponents.overview.phase')}}
36
+ </el-col>
37
+ <el-col :span="10">{{this.$t('openatccomponents.overview.flow')}}
38
+ </el-col>
39
+ <el-col :span="10">{{this.$t('openatccomponents.overview.saturationflow')}}
40
+ </el-col>
41
+ </el-row>
42
+ </div>
43
+ <draggable
44
+ class="common-board-column-content"
45
+ :list="list"
46
+ :options="options">
47
+ <div class="common-board-item" v-for="element in list" :key="element.id">
48
+ <el-row :gutter="13">
49
+ <el-col :span="4">
50
+ <el-tooltip class="item" effect="dark" placement="left">
51
+ <div slot="content">{{element.name}}</div>
52
+ <div class="common-phase-description">
53
+ <xdrdirselector Width="70px" Height="70px" Widths="58px" Heights="58px" :Datas="styles" :Data="showStyle" :showlist="element.desc" :ISActiveMask="ISActiveMask" :MaskColor="MaskColor"></xdrdirselector>
54
+ </div>
55
+ </el-tooltip>
56
+ </el-col>
57
+ <el-col :span="10">
58
+ <el-input-number :controls="false" class="col-content" size="small" :step="1" v-model.number="element.flowperhour" ref="type" :disabled="element.mode === 7"></el-input-number>
59
+ </el-col>
60
+ <el-col :span="10">
61
+ <el-input-number :controls="false" class="col-content" size="small" :step="1" v-model.number="element.saturation" ref="types" :disabled="element.mode === 7"></el-input-number>
62
+ </el-col>
63
+ </el-row>
64
+ </div>
65
+ </draggable>
66
+ </div>
67
+ </div>
68
+ </template>
69
+ <script>
70
+ import draggable from 'vuedraggable'
71
+ import { getDuration } from '@/api/cross'
72
+ import xdrdirselector from '@/components/XRDDirSelector'
73
+
74
+ export default {
75
+ name: 'patternOptimize',
76
+ components: {
77
+ draggable,
78
+ xdrdirselector
79
+ },
80
+ data () {
81
+ return {
82
+ showStyle: {
83
+ left: '7px',
84
+ top: '0px'
85
+ },
86
+ styles: {
87
+ left: '7px',
88
+ top: '0px'
89
+ },
90
+ typeOptions: [{
91
+ value: 'flow-split-opt'
92
+ }, {
93
+ value: 'cycle-opt'
94
+ }],
95
+ value: 'flow-split-opt',
96
+ optimizecycle: 0
97
+ }
98
+ },
99
+ props: {
100
+ headerText: {
101
+ type: String,
102
+ default: 'Header'
103
+ },
104
+ id: {
105
+ type: Number
106
+ },
107
+ rings: {
108
+ type: Array
109
+ },
110
+ nowNumber: {
111
+ type: Number
112
+ },
113
+ phaseList: {
114
+ type: Array
115
+ },
116
+ options: {
117
+ type: Object,
118
+ default () {
119
+ return {}
120
+ }
121
+ },
122
+ list: {
123
+ type: Array,
124
+ default () {
125
+ return []
126
+ }
127
+ },
128
+ // index: {
129
+ // type: Number
130
+ // },
131
+ ISActiveMask: {
132
+ type: Boolean,
133
+ default: true
134
+ },
135
+ // 当phase的描述为空时,显示的图形颜色。
136
+ MaskColor: {
137
+ type: String,
138
+ default: '#000000'
139
+ }
140
+ },
141
+ created () {
142
+ // this.addMinSplit()
143
+ this.addMin()
144
+ },
145
+ computed () {
146
+
147
+ },
148
+ watch: {
149
+ list: {
150
+ handler: function () {
151
+ // let list = this.$refs.type
152
+ // let flow = this.$refs.types
153
+ // console.log(this.list, 'list')
154
+ // let cycle = 0
155
+ // let n = this.index
156
+ // for (let i = 0; i < list.length; i++) {
157
+ // cycle = cycle + Number(list[i].currentValue)
158
+ // }
159
+ // const globalParamModel = this.$store.getters.globalParamModel
160
+ // // let MaxCycle = globalParamModel.getParamsByType('patternList')[n].cycle
161
+ // let pattern = globalParamModel.getParamsByType('patternList')[n]
162
+ // globalParamModel.getParamsByType('patternList')[n].cycle = this.getMaxCycle(pattern)
163
+ // this.addMinSplit()
164
+ // this.$emit('handleSplit', n)
165
+ },
166
+ deep: true
167
+ }
168
+ },
169
+ methods: {
170
+ onOptimizeClick () {
171
+ let msg = this.$t('openatccomponents.pattern.algorithmEngineOptimization')
172
+ const loading = this.$loading({
173
+ lock: true,
174
+ text: msg,
175
+ spinner: 'el-icon-loading',
176
+ background: 'rgba(0, 0, 0, 0.7)'
177
+ })
178
+ setTimeout(() => {
179
+ loading.close()
180
+ this.handeleOptimizeClick()
181
+ }, 1000)
182
+ },
183
+ handeleOptimizeClick () {
184
+ let newPha = []
185
+ for (let i = 0; i < this.rings.length; i++) {
186
+ newPha.push(...this.rings[i])
187
+ }
188
+ let phaseData = newPha.map(item => {
189
+ return {
190
+ id: item.id,
191
+ flowperhour: item.flowperhour,
192
+ saturation: item.saturation
193
+ }
194
+ })
195
+ let patternList = this.$store.state.globalParam.tscParam.patternList
196
+ let pattern = patternList.filter((item) => item.id === this.id)[0]
197
+ let reqData = {
198
+ 'type': this.value,
199
+ 'optcycle': this.optimizecycle ? this.optimizecycle : 0,
200
+ 'phaseList': this.phaseList,
201
+ 'pattern': pattern,
202
+ 'phases': phaseData
203
+ }
204
+ let isValidata = []
205
+ for (let j = 0; j < newPha.length; j++) {
206
+ let comNum = (newPha[j].length / 4) * 1700 * 0.8
207
+ isValidata.push(newPha[j].flowperhour > comNum)
208
+ }
209
+ if (isValidata.includes(true)) {
210
+ this.$confirm(this.$t('openatccomponents.overview.maxFlow'),
211
+ this.$t('openatccomponents.common.alarm'), {
212
+ confirmButtonText: this.$t('eopenatccomponentsdge.common.confirm'),
213
+ cancelButtonText: this.$t('openatccomponents.common.cancel'),
214
+ type: 'warning'
215
+ }).then(() => {
216
+ getDuration(reqData).then(data => {
217
+ if (data.data.success) {
218
+ this.$message({
219
+ type: 'success',
220
+ message: this.$t('openatccomponents.pattern.success')
221
+ })
222
+ for (let i = 0; i < this.rings.length; i++) {
223
+ for (let j = 0; j < this.rings[i].length; j++) {
224
+ for (let h = 0; h < data.data.data.phase.length; h++) {
225
+ if (this.rings[i][j].id === data.data.data.phase[h].id) {
226
+ this.rings[i][j].value = data.data.data.phase[h].duration
227
+ // this.rings[i][j].cycle = data.data.data.phase[h].cycle
228
+ }
229
+ }
230
+ }
231
+ }
232
+ }
233
+ }).catch(error => {
234
+ console.log(error)
235
+ })
236
+ }).catch(() => {
237
+ })
238
+ } else {
239
+ getDuration(reqData).then(data => {
240
+ if (data.data.success) {
241
+ this.$message({
242
+ type: 'success',
243
+ message: this.$t('openatccomponents.pattern.success')
244
+ })
245
+ for (let i = 0; i < this.rings.length; i++) {
246
+ for (let j = 0; j < this.rings[i].length; j++) {
247
+ for (let h = 0; h < data.data.data.phase.length; h++) {
248
+ if (this.rings[i][j].id === data.data.data.phase[h].id) {
249
+ this.rings[i][j].value = data.data.data.phase[h].duration
250
+ // this.rings[i][j].cycle = data.data.data.phase[h].cycle
251
+ }
252
+ }
253
+ }
254
+ }
255
+ }
256
+ }).catch(error => {
257
+ console.log(error)
258
+ })
259
+ }
260
+ },
261
+ addMin () {
262
+ for (let i of this.list) {
263
+ if (!i.flowperhour || !i.saturation) {
264
+ i.length = this.list.length
265
+ i.flowperhour = 0
266
+ i.saturation = 1700
267
+ }
268
+ }
269
+ }
270
+ // addMinSplit () {
271
+ // const globalParamModel = this.$store.getters.globalParamModel
272
+ // let phaseList = globalParamModel.getParamsByType('phaseList')
273
+ // for (let ls of this.list) {
274
+ // let phase = phaseList.filter((item) => {
275
+ // return item.id === ls.id
276
+ // })[0]
277
+ // if (!phase.redyellow) {
278
+ // phase.redyellow = 0
279
+ // }
280
+ // if (!phase.yellow) {
281
+ // phase.yellow = 0
282
+ // }
283
+ // if (!phase.redclear) {
284
+ // phase.redclear = 0
285
+ // }
286
+ // if (!phase.flashgreen) {
287
+ // phase.flashgreen = 0
288
+ // }
289
+ // if (!phase.phasewalk) {
290
+ // phase.phasewalk = 0
291
+ // }
292
+ // if (!phase.pedclear) {
293
+ // phase.pedclear = 0
294
+ // }
295
+ // // let temp1 = phase.redyellow + phase.yellow + phase.redclear + phase.flashgreen // 绿信比的最小值要大于最小绿+黄灯+全红+绿闪
296
+ // // let temp2 = phase.phasewalk + phase.pedclear
297
+ // // if (temp1 > temp2) {
298
+ // // ls.minSplit = temp1
299
+ // // } else {
300
+ // // ls.minSplit = temp2
301
+ // // }
302
+ // // if (ls.mode !== 7 && ls.value < ls.minSplit) {
303
+ // // ls.value = ls.minSplit
304
+ // // }
305
+ // // let temp1 = phase.yellow + phase.redclear + phase.flashgreen // 绿信比的最小值要大于最小绿+黄灯+全红+绿闪
306
+ // let temp1 = phase.yellow + phase.redclear + phase.mingreen
307
+ // let temp2 = phase.yellow + phase.redclear + phase.phasewalk + phase.pedclear
308
+ // ls.minSplit = temp1 > temp2 ? temp1 : temp2
309
+ // if (ls.mode !== 7 && ls.value < ls.minSplit) {
310
+ // ls.value = ls.minSplit
311
+ // this.$message.error(this.$t('openatccomponents.pattern.splitCheckMsg'))
312
+ // }
313
+ // }
314
+ // },
315
+ // getMaxCycle (pattern) {
316
+ // let rings = pattern.rings
317
+ // let maxCycle = 0
318
+ // for (let ring of rings) {
319
+ // if (ring.length === 0) continue
320
+ // let cycle = 0
321
+ // for (let r of ring) {
322
+ // if (r.mode === 7) { // 忽略相位不计周期
323
+ // continue
324
+ // }
325
+ // cycle = cycle + r.value
326
+ // }
327
+ // if (cycle > maxCycle) {
328
+ // maxCycle = cycle
329
+ // }
330
+ // }
331
+ // return maxCycle
332
+ // },
333
+ // doChange (val) {
334
+ // // if (val.mode === 7) {
335
+ // // val.value = 0
336
+ // // } else {
337
+ // // val.value = 30
338
+ // // }
339
+ // }
340
+ }
341
+ }
342
+ </script>
343
+ <style lang="scss" scoped>
344
+ .col-content {
345
+ width: 100%;
346
+ }
347
+ .kanbanOptimize {
348
+ .common-board-column {
349
+ max-width: unset !important;
350
+ }
351
+ }
352
+ .optimizetype{
353
+ // float: left;
354
+ font-size: 14PX;
355
+ margin:0 0 10PX 0;
356
+ .el-input {
357
+ width: 80PX;
358
+ }
359
+ .el-select{
360
+ width: 145PX;
361
+ }
362
+ .el-button {
363
+ margin-left: 10PX;
364
+ }
365
+ .optimiNum {
366
+ padding-left: 10PX;
367
+ }
368
+ }
369
+ </style>
@@ -24,7 +24,7 @@
24
24
  </el-select>
25
25
  <span class="optimiNum">{{$t('openatccomponents.pattern.optimizecycle')}}</span>
26
26
  <el-input v-model="optimizecycle" clearable :placeholder="$t('openatccomponents.common.enter')"></el-input>
27
- <!-- <el-button type="primary" @click="optimize()">{{$t('openatccomponents.pattern.inoptimize')}}</el-button> -->
27
+ <el-button v-if="isTentative" type="primary" @click="optimize()">{{$t('openatccomponents.pattern.inoptimize')}}</el-button>
28
28
  </div>
29
29
  <el-table class="tb-edit" ref="singleTables" row-key="id" :data="tableRing" element-loading-text="Loading" :max-height="tableHeight" fit highlight-current-row id="footerBtn">
30
30
  <el-table-column prop="id" sortable align="center" :label="$t('openatccomponents.overview.id')">
@@ -40,11 +40,13 @@
40
40
  <el-table-column class="table-column" :label="$t('openatccomponents.overview.flow')" align="center">
41
41
  <template slot-scope="scope">
42
42
  <el-input-number :controls="false" class="col-content" size="small" :step="1" v-model.number="scope.row.flowperhour" ref="type"></el-input-number>
43
+ <!-- <span>{{scope.row.flowperhour}}</span> -->
43
44
  </template>
44
45
  </el-table-column>
45
46
  <el-table-column align="center" :label="$t('openatccomponents.overview.saturationflow')">
46
47
  <template slot-scope="scope">
47
48
  <el-input-number :controls="false" class="col-content" size="small" :step="1" v-model.number="scope.row.saturation" ref="types"></el-input-number>
49
+ <!-- <span>{{scope.row.saturation}}</span> -->
48
50
  </template>
49
51
  </el-table-column>
50
52
  </el-table>
@@ -96,7 +98,7 @@
96
98
  <script>
97
99
  import draggable from 'vuedraggable'
98
100
  import { getDuration } from '../../../api/cross'
99
- import xdrdirselector from '../XRDDirSelector/XRDDirSelector'
101
+ import xdrdirselector from '../XRDDirSelector/XRDDirSelector.vue'
100
102
 
101
103
  export default {
102
104
  name: 'patternOptimize',
@@ -129,6 +131,10 @@ export default {
129
131
  type: String,
130
132
  default: 'Header'
131
133
  },
134
+ isTentative: {
135
+ type: Boolean,
136
+ default: false
137
+ },
132
138
  tableRing: {
133
139
  type: Array
134
140
  },
@@ -177,7 +183,7 @@ export default {
177
183
  },
178
184
  created () {
179
185
  // this.addMinSplit()
180
- this.addMin()
186
+ // this.addMin()
181
187
  },
182
188
  watch: {
183
189
  list: {
@@ -294,23 +294,20 @@
294
294
  name="patternOptimize"
295
295
  >
296
296
  <pattern-optimize
297
- v-for="n in optimizes"
298
- :key="n"
299
297
  class="expendkanban"
300
- :list="
301
- patternOne.length === 0
302
- ? planPattern.rings[n - 1]
303
- : patternOne[0].rings[n - 1]
304
- "
305
298
  :rings="patternOne.length === 0 ? planPattern : patternOne[0]"
306
299
  :phaseList="phaseList"
307
- :options="options"
308
- :header-text="$t('openatccomponents.pattern.ring') + n"
309
- :index="n"
310
- :nowNumber="n"
300
+ :tableRing="tableRing"
301
+ :showStyle="showStyle"
302
+ :styles="styles"
303
+ :isTentative="true"
311
304
  @handleSplit="handleSplit"
312
305
  >
313
306
  </pattern-optimize>
307
+ <!-- ref="patternOptimize"
308
+ :tableRing="tableRing"
309
+ :id="selectedRow.id"
310
+ @optimizesucess="optimizesucess" -->
314
311
  </el-tab-pane>
315
312
  </el-tabs>
316
313
  </el-row>
@@ -325,7 +322,8 @@
325
322
 
326
323
  <script>
327
324
  import { hasPermission } from '../../../../utils/auth'
328
-
325
+ import PhaseDataModel from '../../IntersectionMap/crossDirection/utils.js'
326
+ import CrossDiagramMgr from '../../../../EdgeMgr/controller/crossDiagramMgr.js'
329
327
  export default {
330
328
  name: 'tentativeplancontrol',
331
329
  props: {
@@ -398,7 +396,16 @@ export default {
398
396
  options: {
399
397
  group: 'pattern'
400
398
  },
399
+ styles: {
400
+ left: '2px',
401
+ top: 0
402
+ },
403
+ showStyle: {
404
+ left: '2px',
405
+ top: 0
406
+ },
401
407
  max: '',
408
+ tableRing: [],
402
409
  contrloType: '',
403
410
  patternCycleEqual: true,
404
411
  // activeList: 'ring',
@@ -422,6 +429,8 @@ export default {
422
429
  }
423
430
  },
424
431
  created () {
432
+ this.PhaseDataModel = new PhaseDataModel()
433
+ this.CrossDiagramMgr = new CrossDiagramMgr()
425
434
  this.patternPlan()
426
435
  this.getCycle()
427
436
  if (this.patternOne.length === 0) {
@@ -759,7 +768,7 @@ export default {
759
768
  for (let phase of this.phaseList) {
760
769
  let ring = {}
761
770
  ring.name = 'Phase ' + phase.id
762
- ring.desc = this.getPhaseDescription(phase.direction)
771
+ ring.desc = this.getPhaseDescription(phase)
763
772
  ring.id = phase.id
764
773
  ring.value = 30
765
774
  ring.mode = 2
@@ -779,6 +788,15 @@ export default {
779
788
  let barrier = this.handleCurrentChange(newPattern.rings)
780
789
  newPattern.barriers = barrier
781
790
  this.planPattern = newPattern
791
+ const flatArray = this.planPattern.rings.flat().filter(item => item !== null)
792
+ this.tableRing = flatArray.map(item => {
793
+ return {
794
+ id: item.id,
795
+ desc: item.desc,
796
+ flowperhour: item.flowperhour ? item.flowperhour : 0,
797
+ saturation: item.saturation ? item.saturation : 0
798
+ }
799
+ })
782
800
  },
783
801
  getCycle () {
784
802
  for (let rings of this.planPattern.rings) {
@@ -817,12 +835,71 @@ export default {
817
835
  }
818
836
  }
819
837
  },
838
+ // getPhaseDescription (phaseList) {
839
+ // if (!phaseList) return
840
+ // let list = []
841
+ // for (let id of phaseList) {
842
+ // let obj = {}
843
+ // obj.id = id
844
+ // obj.color = '#454545'
845
+ // list.push(obj)
846
+ // }
847
+ // return list
848
+ // },
849
+ getPedPhasePos () {
850
+ // 行人相位信息
851
+ this.sidewalkPhaseData = []
852
+ // let phaseList = this.globalParamModel.getParamsByType('phaseList')
853
+ this.phaseList.forEach((ele, i) => {
854
+ if (ele.peddirection) {
855
+ ele.peddirection.forEach((dir, index) => {
856
+ // 行人相位
857
+ if (this.PhaseDataModel.getSidePos(dir)) {
858
+ this.sidewalkPhaseData.push({
859
+ key: this.CrossDiagramMgr.getUniqueKey('pedphase'),
860
+ phaseid: ele.id, // 相位id,用于对应相位状态
861
+ id: dir,
862
+ name: this.PhaseDataModel.getSidePos(dir).name
863
+ })
864
+ }
865
+ })
866
+ }
867
+ })
868
+ return this.sidewalkPhaseData
869
+ },
820
870
  getPhaseDescription (phaseList) {
821
- if (!phaseList) return
822
871
  let list = []
823
- for (let id of phaseList) {
872
+ let peddirections = []
873
+ let sidewalkPhaseData = this.getPedPhasePos()
874
+ for (let walk of sidewalkPhaseData) {
875
+ if (phaseList.peddirection) {
876
+ for (let ped of phaseList.peddirection) {
877
+ // if (stg === walk.phaseid) {
878
+ let obj = {}
879
+ obj.name = walk.name
880
+ obj.id = walk.id
881
+ if (ped === walk.id) {
882
+ peddirections.push(obj)
883
+ peddirections = Array.from(new Set(peddirections))
884
+ }
885
+ // }
886
+ }
887
+ } else {
888
+ peddirections = []
889
+ }
890
+ }
891
+ if (phaseList.direction.length > 0) {
892
+ for (let id of phaseList.direction) {
893
+ let obj = {}
894
+ obj.id = id
895
+ obj.peddirection = peddirections
896
+ obj.color = '#454545'
897
+ list.push(obj)
898
+ }
899
+ } else {
824
900
  let obj = {}
825
- obj.id = id
901
+ obj.id = ''
902
+ obj.peddirection = peddirections
826
903
  obj.color = '#454545'
827
904
  list.push(obj)
828
905
  }
@@ -906,6 +983,15 @@ export default {
906
983
  // if (this.patternOne[0].contrloType === 'stage') {
907
984
  // this.changeStage()
908
985
  // }
986
+ const flatArray = this.patternOne[0].rings.flat().filter(item => item !== null)
987
+ this.tableRing = flatArray.map(item => {
988
+ return {
989
+ id: item.id,
990
+ desc: item.desc,
991
+ flowperhour: item.flowperhour ? item.flowperhour : 0,
992
+ saturation: item.saturation ? item.saturation : 0
993
+ }
994
+ })
909
995
  this.manualInfo.offset = this.offset
910
996
  for (let rings of this.patternOne[0].rings) {
911
997
  if (rings.length === 0) continue