openatc-components 0.4.16 → 0.4.17

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>
@@ -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',
@@ -294,23 +294,19 @@
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"
311
303
  @handleSplit="handleSplit"
312
304
  >
313
305
  </pattern-optimize>
306
+ <!-- ref="patternOptimize"
307
+ :tableRing="tableRing"
308
+ :id="selectedRow.id"
309
+ @optimizesucess="optimizesucess" -->
314
310
  </el-tab-pane>
315
311
  </el-tabs>
316
312
  </el-row>
@@ -325,7 +321,8 @@
325
321
 
326
322
  <script>
327
323
  import { hasPermission } from '../../../../utils/auth'
328
-
324
+ import PhaseDataModel from '../../IntersectionMap/crossDirection/utils.js'
325
+ import CrossDiagramMgr from '../../../../EdgeMgr/controller/crossDiagramMgr.js'
329
326
  export default {
330
327
  name: 'tentativeplancontrol',
331
328
  props: {
@@ -398,7 +395,16 @@ export default {
398
395
  options: {
399
396
  group: 'pattern'
400
397
  },
398
+ styles: {
399
+ left: '2px',
400
+ top: 0
401
+ },
402
+ showStyle: {
403
+ left: '2px',
404
+ top: 0
405
+ },
401
406
  max: '',
407
+ tableRing: [],
402
408
  contrloType: '',
403
409
  patternCycleEqual: true,
404
410
  // activeList: 'ring',
@@ -422,6 +428,8 @@ export default {
422
428
  }
423
429
  },
424
430
  created () {
431
+ this.PhaseDataModel = new PhaseDataModel()
432
+ this.CrossDiagramMgr = new CrossDiagramMgr()
425
433
  this.patternPlan()
426
434
  this.getCycle()
427
435
  if (this.patternOne.length === 0) {
@@ -759,7 +767,7 @@ export default {
759
767
  for (let phase of this.phaseList) {
760
768
  let ring = {}
761
769
  ring.name = 'Phase ' + phase.id
762
- ring.desc = this.getPhaseDescription(phase.direction)
770
+ ring.desc = this.getPhaseDescription(phase)
763
771
  ring.id = phase.id
764
772
  ring.value = 30
765
773
  ring.mode = 2
@@ -779,6 +787,15 @@ export default {
779
787
  let barrier = this.handleCurrentChange(newPattern.rings)
780
788
  newPattern.barriers = barrier
781
789
  this.planPattern = newPattern
790
+ const flatArray = this.planPattern.rings.flat().filter(item => item !== null)
791
+ this.tableRing = flatArray.map(item => {
792
+ return {
793
+ id: item.id,
794
+ desc: item.desc,
795
+ flowperhour: item.flowperhour ? item.flowperhour : 0,
796
+ saturation: item.saturation ? item.saturation : 0
797
+ }
798
+ })
782
799
  },
783
800
  getCycle () {
784
801
  for (let rings of this.planPattern.rings) {
@@ -817,12 +834,71 @@ export default {
817
834
  }
818
835
  }
819
836
  },
837
+ // getPhaseDescription (phaseList) {
838
+ // if (!phaseList) return
839
+ // let list = []
840
+ // for (let id of phaseList) {
841
+ // let obj = {}
842
+ // obj.id = id
843
+ // obj.color = '#454545'
844
+ // list.push(obj)
845
+ // }
846
+ // return list
847
+ // },
848
+ getPedPhasePos () {
849
+ // 行人相位信息
850
+ this.sidewalkPhaseData = []
851
+ // let phaseList = this.globalParamModel.getParamsByType('phaseList')
852
+ this.phaseList.forEach((ele, i) => {
853
+ if (ele.peddirection) {
854
+ ele.peddirection.forEach((dir, index) => {
855
+ // 行人相位
856
+ if (this.PhaseDataModel.getSidePos(dir)) {
857
+ this.sidewalkPhaseData.push({
858
+ key: this.CrossDiagramMgr.getUniqueKey('pedphase'),
859
+ phaseid: ele.id, // 相位id,用于对应相位状态
860
+ id: dir,
861
+ name: this.PhaseDataModel.getSidePos(dir).name
862
+ })
863
+ }
864
+ })
865
+ }
866
+ })
867
+ return this.sidewalkPhaseData
868
+ },
820
869
  getPhaseDescription (phaseList) {
821
- if (!phaseList) return
822
870
  let list = []
823
- for (let id of phaseList) {
871
+ let peddirections = []
872
+ let sidewalkPhaseData = this.getPedPhasePos()
873
+ for (let walk of sidewalkPhaseData) {
874
+ if (phaseList.peddirection) {
875
+ for (let ped of phaseList.peddirection) {
876
+ // if (stg === walk.phaseid) {
877
+ let obj = {}
878
+ obj.name = walk.name
879
+ obj.id = walk.id
880
+ if (ped === walk.id) {
881
+ peddirections.push(obj)
882
+ peddirections = Array.from(new Set(peddirections))
883
+ }
884
+ // }
885
+ }
886
+ } else {
887
+ peddirections = []
888
+ }
889
+ }
890
+ if (phaseList.direction.length > 0) {
891
+ for (let id of phaseList.direction) {
892
+ let obj = {}
893
+ obj.id = id
894
+ obj.peddirection = peddirections
895
+ obj.color = '#454545'
896
+ list.push(obj)
897
+ }
898
+ } else {
824
899
  let obj = {}
825
- obj.id = id
900
+ obj.id = ''
901
+ obj.peddirection = peddirections
826
902
  obj.color = '#454545'
827
903
  list.push(obj)
828
904
  }
@@ -906,6 +982,15 @@ export default {
906
982
  // if (this.patternOne[0].contrloType === 'stage') {
907
983
  // this.changeStage()
908
984
  // }
985
+ const flatArray = this.patternOne[0].rings.flat().filter(item => item !== null)
986
+ this.tableRing = flatArray.map(item => {
987
+ return {
988
+ id: item.id,
989
+ desc: item.desc,
990
+ flowperhour: item.flowperhour ? item.flowperhour : 0,
991
+ saturation: item.saturation ? item.saturation : 0
992
+ }
993
+ })
909
994
  this.manualInfo.offset = this.offset
910
995
  for (let rings of this.patternOne[0].rings) {
911
996
  if (rings.length === 0) continue
@@ -10,7 +10,7 @@
10
10
  * See the Mulan PSL v2 for more details.
11
11
  **/
12
12
  <template>
13
- <div :style="{position: 'relative'}">
13
+ <div :style="{position: 'relative',height: '40px'}">
14
14
  <div :style="{position: 'absolute', left: Data?Data.left:0, top: Data?Data.top:0}">
15
15
  <svg
16
16
  version="1.1"