houzhongjian
2024-07-23 8501060c4f921d1e744c477e4dc08eb47b52693c
提交 | 用户 | 时间
850106 1 <template>
H 2   <el-dialog :visible.sync="visible" :title="!dataForm.id ? $t('add') : $t('update')" :close-on-click-modal="false"
3              :close-on-press-escape="false" width="60%">
4     <el-form :model="dataForm" :rules="dataRule" ref="dataForm" @keyup.enter.native="dataFormSubmitHandle()"
5              label-width="120px">
6       <el-row>
7         <el-col :span="12">
8           <el-form-item prop="pointNo" :label="$t('point.pointNo')">
9             <el-input v-model="dataForm.pointNo" disabled></el-input>
10           </el-form-item>
11         </el-col>
12         <el-col :span="12">
13           <el-form-item prop="pointName" :label="$t('point.pointName')">
14             <el-input v-model="dataForm.pointName" :placeholder="$t('point.pointName')"></el-input>
15           </el-form-item>
16         </el-col>
17       </el-row>
18       <el-row>
19         <el-col :span="12">
20           <el-form-item prop="pointType" :label="$t('point.pointType')">
21             <dict-select-tag style="width: 100%;" v-model="dataForm.pointType" dictCode="point_type"
22                              :disabled="!!dataForm.id"
23                              placeholder="测点类型"></dict-select-tag>
24           </el-form-item>
25         </el-col>
26         <el-col :span="12">
27           <el-form-item prop="dataType" :label="$t('point.dataType')">
28             <dict-select-tag style="width: 100%;" v-model="dataForm.dataType" dictCode="data_type"
29                              placeholder="数据类型"></dict-select-tag>
30           </el-form-item>
31         </el-col>
32       </el-row>
33       <el-row>
34         <el-col :span="12">
35           <el-form-item prop="unit" :label="$t('point.unit')">
36             <el-input v-model="dataForm.unit" :placeholder="$t('point.unit')"></el-input>
37           </el-form-item>
38         </el-col>
39         <el-col :span="12">
40           <el-form-item prop="unittransfactor" :label="$t('point.unittransfactor')">
41             <el-input-number v-model="dataForm.unittransfactor"
42                              style="width: 100%"
43                              :controls="false"
44                              :placeholder="$t('point.unittransfactor')"></el-input-number>
45           </el-form-item>
46         </el-col>
47       </el-row>
48       <el-row>
49         <el-col :span="12">
50           <el-form-item prop="minfreqid" :label="$t('point.minfreqid')">
51             <dict-select-tag style="width: 100%;" v-model="dataForm.minfreqid" dictCode="minfreqid"
52                              :placeholder="$t('point.minfreqid')"></dict-select-tag>
53           </el-form-item>
54         </el-col>
55         <el-col :span="12">
56           <el-form-item prop="defaultValue" :label="$t('point.defaultValue')">
57             <el-input-number v-model="dataForm.defaultValue"
58                              style="width: 100%"
59                              :controls="false"
60                              :placeholder="$t('point.defaultValue')"></el-input-number>
61           </el-form-item>
62         </el-col>
63       </el-row>
64       <el-row>
65         <el-col :span="12">
66           <el-form-item prop="maxValue" :label="$t('point.maxValue')">
67             <el-input-number v-model="dataForm.maxValue"
68                              style="width: 100%"
69                              :controls="false"
70                              :placeholder="$t('point.maxValue')"></el-input-number>
71           </el-form-item>
72         </el-col>
73         <el-col :span="12">
74           <el-form-item prop="minValue" :label="$t('point.minValue')">
75             <el-input-number v-model="dataForm.minValue"
76                              style="width: 100%"
77                              :controls="false"
78                              :placeholder="$t('point.minValue')"></el-input-number>
79           </el-form-item>
80         </el-col>
81       </el-row>
82       <el-row>
83         <el-col :span="24">
84           <el-form-item prop="remark" :label="$t('point.remark')">
85             <el-input v-model="dataForm.remark" :placeholder="$t('point.remark')" type="textarea"></el-input>
86           </el-form-item>
87         </el-col>
88       </el-row>
89
90       <!--计量点-->
91       <el-row v-if="dataForm.pointType === 'MEASURE'">
92         <el-col :span="24">
93           <el-form-item prop="sourceOption" :label="$t('point.sourceOption')">
94             <el-cascader
95                 style="width: 100%;"
96                 v-model="dataForm.sourceOption"
97                 :options="sourceOptions"
98                 filterable></el-cascader>
99           </el-form-item>
100         </el-col>
101       </el-row>
102
103       <!--计算点-->
104       <el-row :gutter="20" v-if="dataForm.pointType === 'CALCULATE'">
105         <el-col :span="24">
106           <el-form-item label="表达式">
107             <el-table
108                 :data="expressionList"
109                 border
110                 style="width: 100%">
111               <el-table-column
112                   type="index"
113                   align="center"
114                   width="50"
115                   label="序号">
116               </el-table-column>
117               <el-table-column
118                   prop=""
119                   label="左括号"
120                   width="120"
121                   align="center">
122                 <template slot-scope="scope">
123                   <el-input
124                       size="mini"
125                       v-model="scope.row.parenthesesLeft"
126                       placeholder=""
127                       readonly
128                       maxlength="16">
129                     <el-button slot="prepend" @click="addParenthesesLeft(scope.$index, scope.row)">+</el-button>
130                     <el-button slot="append" @click="removeParenthesesLeft(scope.$index, scope.row)">-</el-button>
131                   </el-input>
132                 </template>
133               </el-table-column>
134               <el-table-column
135                   prop=""
136                   label="测点"
137                   align="center">
138                 <template slot-scope="scope">
139                   <el-select
140                       size="mini"
141                       v-model="scope.row.point"
142                       filterable
143                       placeholder="请选择">
144                     <el-option
145                         v-for="(item, index) in pointList"
146                         :key="index"
147                         :label="item.pointName"
148                         :value="item.pointNo">
149                     </el-option>
150                   </el-select>
151                 </template>
152               </el-table-column>
153               <el-table-column
154                   prop=""
155                   label="运算值"
156                   align="center">
157                 <template slot-scope="scope">
158                   <el-input
159                       size="mini"
160                       v-model="scope.row.point"
161                       placeholder="运算值"
162                       maxlength="16"
163                       clearable>
164                   </el-input>
165                 </template>
166               </el-table-column>
167               <el-table-column
168                   prop=""
169                   label="右括号"
170                   width="120"
171                   align="center">
172                 <template slot-scope="scope">
173                   <el-input
174                       size="mini"
175                       v-model="scope.row.parenthesesRight"
176                       placeholder=""
177                       readonly
178                       maxlength="16">
179                     <el-button slot="prepend" @click="addParenthesesRight(scope.$index, scope.row, ')')">+</el-button>
180                     <el-button slot="append" @click="removeParenthesesRight(scope.$index, scope.row)">-</el-button>
181                   </el-input>
182                 </template>
183               </el-table-column>
184               <el-table-column
185                   prop=""
186                   label="运算符"
187                   width="90"
188                   align="center">
189                 <template slot-scope="scope">
190                   <el-select size="mini" v-model="scope.row.operator" clearable placeholder="请选择"
191                              style="font-weight: 600;">
192                     <el-option
193                         v-for="item in operatorList"
194                         :key="item"
195                         :label="item"
196                         :value="item">
197                     </el-option>
198                   </el-select>
199                 </template>
200               </el-table-column>
201               <el-table-column
202                   prop=""
203                   label="操作"
204                   width="100"
205                   align="center">
206                 <template slot-scope="scope">
207                   <el-button
208                       @click.native.prevent="addExpressionRow(scope.$index, expressionList)"
209                       type="text"
210                       size="small">
211                     添加
212                   </el-button>
213                   <el-button
214                       @click.native.prevent="deleteExpressionRow(scope.$index, expressionList)"
215                       type="text"
216                       size="small">
217                     删除
218                   </el-button>
219                 </template>
220               </el-table-column>
221             </el-table>
222           </el-form-item>
223         </el-col>
224       </el-row>
225
226     </el-form>
227     <template slot="footer">
228       <el-button @click="visible = false">{{ $t('cancel') }}</el-button>
229       <el-button :loading="loading" type="primary" @click="dataFormSubmitHandle()">{{ $t('confirm') }}</el-button>
230     </template>
231   </el-dialog>
232 </template>
233 <script>
234   import debounce from 'lodash/debounce'
235   import DictSelectTag from "@/components/dict/dict-select-tag";
236
237   export default {
238     components: {
239       DictSelectTag
240     },
241     data() {
242       return {
243         loading: false,
244         visible: false,
245         deptList: [],
246         deptListVisible: false,
247         sourceOptions: [],
248         expressionList: [],
249         pointList: [],
250         pointMap: {},
251         operatorList: ['+', '-', '*', '/', '&', '|', '!', '>', '<'],
252         dataForm: {
253           id: '',
254           pointNo: '',
255           pointName: '',
256           pointType: '',
257           dataType: '',
258           unit: '',
259           unittransfactor: 1,
260           defaultValue: '',
261           maxValue: 1000000000000,
262           minValue: '',
263           sourceType: '',
264           sourceName: '',
265           tagNo: '',
266           minfreqid: '',
267           remark: '',
268           sourceOption: [],
269           mathPoint: {
270             id: '',
271             pointId: '',
272             expression: ''
273           },
274           measurePoint: {
275             id: '',
276             pointId: '',
277             sourceType: '',
278             sourceId: '',
279             tagNo: '',
280             dimension: '',
281           }
282         }
283       }
284     },
285     computed: {
286       dataRule() {
287         return {
288           pointName: [
289             {required: true, message: this.$t('validate.required'), trigger: 'blur'}
290           ],
291           pointType: [
292             {required: true, message: this.$t('validate.required'), trigger: 'blur'}
293           ],
294           dataType: [
295             {required: true, message: this.$t('validate.required'), trigger: 'blur'}
296           ],
297           unittransfactor: [
298             {required: true, message: this.$t('validate.required'), trigger: 'blur'}
299           ],
300           sourceArray: [
301             {required: true, message: this.$t('validate.required'), trigger: 'blur'}
302           ],
303           sourceType: [
304             {required: true, message: this.$t('validate.required'), trigger: 'blur'}
305           ],
306           sourceName: [
307             {required: true, message: this.$t('validate.required'), trigger: 'blur'}
308           ],
309           tagNo: [
310             {required: true, message: this.$t('validate.required'), trigger: 'blur'}
311           ],
312           minfreqid: [
313             {required: true, message: this.$t('validate.required'), trigger: 'blur'}
314           ],
315         }
316       }
317     },
318     methods: {
319       init() {
320         this.visible = true
321         this.$nextTick(() => {
322             this.$refs['dataForm'].resetFields()
323             this.dataForm.sourceArray = []
324             this.dataForm.sourceType = ''
325             this.dataForm.sourceName = ''
326             this.dataForm.tagNo = ''
327             this.dataForm['mathPoint'] = {}
328             this.dataForm.sourceOption = []
329             this.expressionList = [{
330               parenthesesLeft: '',
331               point: '',
332               parenthesesRight: '',
333               operator: ''
334             }]
335             Promise.all([
336               this.getSourceOption(),
337               this.getPointList()
338             ]).then(() => {
339               if (this.dataForm.id) {
340                 this.getInfo()
341               }
342             })
343
344           }
345         )
346       },
347       // 获取数据源选项
348       getSourceOption() {
349         return this.$http.get(`/data/channel/tag/tree`).then(({data: res}) => {
350           if (res.code !== 0) {
351             return this.$message.error(res.msg)
352           }
353           this.sourceOptions = res.data;
354         }).catch(() => {
355         })
356       },
357       getPointList() {
358         return this.$http.get(`/data/da/point/list`, {
359           params: {
360             pointType: "MEASURE"
361           }
362         }).then(({data: res}) => {
363           if (res.code !== 0) {
364             return this.$message.error(res.msg)
365           }
366           this.pointList = res.data;
367         }).catch(() => {
368         })
369       },
370       deleteExpressionRow(index, rows) {
371         if (!rows || rows.length === 1) {
372           this.$message({
373             message: '不能全部删除!',
374             type: 'error',
375             duration: 1500
376           })
377           return
378         }
379         rows.splice(index, 1)
380       },
381       addExpressionRow(index, rows) {
382         let row = JSON.parse(JSON.stringify(rows[index]))
383         rows.splice(index, 0, row)
384       },
385       addParenthesesLeft(index, row) {
386         if (row.parenthesesLeft) {
387           row.parenthesesLeft = row.parenthesesLeft + '('
388         } else {
389           row.parenthesesLeft = '('
390         }
391       },
392       removeParenthesesLeft(index, row) {
393         if (row.parenthesesLeft) {
394           row.parenthesesLeft = row.parenthesesLeft.substring(0, row.parenthesesLeft.length - 1)
395         } else {
396           row.parenthesesLeft = ''
397         }
398       },
399       addParenthesesRight(index, row) {
400         if (row.parenthesesRight) {
401           row.parenthesesRight = row.parenthesesRight + ')'
402         } else {
403           row.parenthesesRight = ')'
404         }
405       },
406       removeParenthesesRight(index, row) {
407         if (row.parenthesesRight) {
408           row.parenthesesRight = row.parenthesesRight.substring(0, row.parenthesesRight.length - 1)
409         } else {
410           row.parenthesesRight = ''
411         }
412       },
413       numAscSort(a, b) {
414         return a - b
415       },
416       resetFields(obj) {
417         for (let key in obj) {
418           if (key === 'pointtypename') {
419             continue
420           }
421           if (obj[key] instanceof Array) {
422             obj[key] = []
423           } else if (obj[key] instanceof Object) {
424             this.resetFields(obj[key])
425           } else {
426             obj[key] = ''
427           }
428         }
429       },
430       // 获取信息
431       getInfo() {
432         this.$http.get(`/data/da/point/${this.dataForm.id}`).then(({data: res}) => {
433           if (res.code !== 0) {
434             return this.$message.error(res.msg)
435           }
436           this.dataForm = {
437             ...this.dataForm,
438             ...res.data
439           }
440           this.expressionList = []
441           if (this.dataForm.pointType &&
442             this.dataForm.pointType === 'CALCULATE' &&
443             this.dataForm.mathPoint.expression) {
444             let expression = this.dataForm.mathPoint.expression
445             do {
446               let indexArray = [
447                 expression.indexOf('+'),
448                 expression.indexOf('-'),
449                 expression.indexOf('*'),
450                 expression.indexOf('/'),
451                 expression.indexOf('&'),
452                 expression.indexOf('|'),
453                 expression.indexOf('!'),
454                 expression.indexOf('>'),
455                 expression.indexOf('<')
456               ].sort(this.numAscSort)
457               if (indexArray[indexArray.length - 1] !== -1) {
458                 let endIndex = 0
459                 for (let key in indexArray) {
460                   if (indexArray[key] > -1) {
461                     endIndex = indexArray[key]
462                     break
463                   }
464                 }
465
466                 // 运算值
467                 let pointStr = expression.substring(0, endIndex)
468
469                 // 运算符
470                 let operator = expression.substr(endIndex, 1)
471                 let indexOfParenthesesLeft = pointStr.indexOf('(')
472                 let lastIndexOfParenthesesLeft = pointStr.lastIndexOf('(')
473
474                 // 左括号
475                 let parenthesesLeft = ''
476                 if (indexOfParenthesesLeft !== -1 && lastIndexOfParenthesesLeft !== -1) {
477                   parenthesesLeft = pointStr.substring(indexOfParenthesesLeft, lastIndexOfParenthesesLeft + 1)
478                   pointStr = pointStr.substring(lastIndexOfParenthesesLeft + 1)
479                 }
480
481                 let indexOfParenthesesRight = pointStr.indexOf(')')
482                 let lastIndexOfParenthesesRight = pointStr.lastIndexOf(')')
483
484                 // 右括号
485                 let parenthesesRight = ''
486                 if (indexOfParenthesesRight !== -1 && lastIndexOfParenthesesRight !== -1) {
487                   parenthesesRight = pointStr.substring(indexOfParenthesesRight, lastIndexOfParenthesesRight + 1)
488                   pointStr = pointStr.substring(0, indexOfParenthesesRight)
489                 }
490                 this.expressionList.push({
491                   parenthesesLeft: parenthesesLeft,
492                   point: pointStr,
493                   parenthesesRight: parenthesesRight,
494                   operator: operator
495                 })
496                 expression = expression.substring(endIndex + 1)
497               } else {
498                 let pointStr = expression
499                 let indexOfParenthesesLeft = pointStr.indexOf('(')
500                 let lastIndexOfParenthesesLeft = pointStr.lastIndexOf('(')
501                 let parenthesesLeft = ''
502                 if (indexOfParenthesesLeft !== -1 && lastIndexOfParenthesesLeft !== -1) {
503                   parenthesesLeft = pointStr.substring(indexOfParenthesesLeft, lastIndexOfParenthesesLeft + 1)
504                   pointStr = pointStr.substring(lastIndexOfParenthesesLeft + 1)
505                 }
506                 let indexOfParenthesesRight = pointStr.indexOf(')')
507                 let lastIndexOfParenthesesRight = pointStr.lastIndexOf(')')
508                 let parenthesesRight = ''
509                 if (indexOfParenthesesRight !== -1 && lastIndexOfParenthesesRight !== -1) {
510                   parenthesesRight = pointStr.substring(indexOfParenthesesRight, lastIndexOfParenthesesRight + 1)
511                   pointStr = pointStr.substring(0, indexOfParenthesesRight)
512                 }
513                 this.expressionList.push({
514                   parenthesesLeft: parenthesesLeft,
515                   point: pointStr,
516                   parenthesesRight: parenthesesRight,
517                   operator: ''
518                 })
519                 expression = ''
520               }
521             } while (expression && expression.length > 0)
522           }
523         }).catch(() => {
524         })
525       },
526       // 表单提交
527       dataFormSubmitHandle: debounce(function () {
528         this.$refs['dataForm'].validate((valid) => {
529           if (!valid) {
530             return false
531           }
532
533           if (this.dataForm.pointType === 'CALCULATE' &&
534             this.expressionList && this.expressionList.length > 0) {
535             let parenthesesLeftRex = /^[(]*$/
536             let parenthesesRightRex = /^[)]*$/
537             let expression = ''
538             for (let i = 0; i < this.expressionList.length; i++) {
539               let value = this.expressionList[i]
540               if (!parenthesesLeftRex.test(value.parenthesesLeft)) {
541                 this.$message({
542                   message: `第${i + 1}行左括号输入不正确!`,
543                   type: 'error',
544                   duration: 1500
545                 })
546                 return
547               }
548               if (!parenthesesRightRex.test(value.parenthesesRight)) {
549                 this.$message({
550                   message: `第${i + 1}行右括号输入不正确!`,
551                   type: 'error',
552                   duration: 1500
553                 })
554                 return
555               }
556               if (i !== (this.expressionList.length - 1) && !value.operator) {
557                 this.$message({
558                   message: `第${i + 1}行运算符不能为空!`,
559                   type: 'error',
560                   duration: 1500
561                 })
562                 return
563               }
564               expression = expression + value.parenthesesLeft + value.point + value.parenthesesRight + (i === (this.expressionList.length - 1) ? '' : value.operator)
565             }
566             this.dataForm['mathPoint']['expression'] = expression
567           } else {
568             this.dataForm['mathPoint'] = {}
569           }
570
571           this.loading = true
572           this.$http[!this.dataForm.id ? 'post' : 'put']('/data/da/point', {
573             ...this.dataForm
574           }).then(({data: res}) => {
575             this.loading = false
576             if (res.code !== 0) {
577               return this.$message.error(res.msg)
578             }
579             this.$message({
580               message: this.$t('prompt.success'),
581               type: 'success',
582               duration: 500,
583               onClose: () => {
584                 this.visible = false
585                 this.$emit('refreshDataList')
586               }
587             })
588           }).catch(() => {
589           })
590         })
591       }, 1000, {'leading': true, 'trailing': false})
592     }
593   }
594 </script>
595 <style>
596   .el-select {
597     width: 100%
598   }
599
600   .el-input-group__append {
601     padding: 0 5px 0 5px
602   }
603
604   .el-input-group__prepend {
605     padding: 0 5px 0 5px
606   }
607
608   .el-radio + .el-radio {
609     margin-left: 10px !important;
610   }
611 </style>