潘志宝
2025-02-28 4a859a6d69984c77fa8166255c65f5a94eb0bd71
提交 | 用户 | 时间
7462da 1 <template>
22bcd6 2   <Dialog v-model="dialogVisible" :title="dialogTitle" width="75%">
7462da 3     <el-form
L 4       ref="formRef"
5       v-loading="formLoading"
cd9f11 6       :model="dataForm"
7462da 7       :rules="formRules"
be4298 8       label-width="100px"
7462da 9     >
cd9f11 10       <el-divider content-position="left">基本信息</el-divider>
7462da 11       <el-row>
L 12         <el-col :span="12">
d3ee81 13           <el-form-item label="预测项名" prop="mmPredictItem.itemname">
14             <el-input v-model="dataForm.mmPredictItem.itemname" placeholder="预测项名"
15                       maxlength="50"/>
7462da 16           </el-form-item>
L 17         </el-col>
e1ff2d 18         <el-col :span="12">
d3ee81 19           <el-form-item label="编号" prop="mmPredictItem.itemno">
61c379 20             <el-input v-model="dataForm.mmPredictItem.itemno" placeholder="编号" maxlength="50"
21                       readonly/>
7462da 22           </el-form-item>
L 23         </el-col>
24       </el-row>
25       <el-row>
26         <el-col :span="12">
d3ee81 27           <el-form-item label="类型" prop="mmPredictItem.itemtypeid">
2caade 28             <el-select
L 29               v-model="dataForm.mmPredictItem.itemtypeid" @change="changeItemtype"
30               placeholder="请选择">
cd9f11 31               <el-option
L 32                 v-for="item in itemTypeList"
33                 :key="item.id"
34                 :label="item.itemtypename"
35                 :value="item.id"/>
36             </el-select>
7462da 37           </el-form-item>
L 38         </el-col>
39         <el-col :span="12">
e1ff2d 40           <el-form-item label="粒度" prop="mmPredictItem.granularity">
d3ee81 41             <el-select v-model="dataForm.mmPredictItem.granularity" placeholder="请选择">
42               <el-option
4c7918 43                 v-for="dict in getIntDictOptions(DICT_TYPE.PRED_GRANULARITY)"
d3ee81 44                 :key="dict.value"
45                 :label="dict.label"
46                 :value="dict.value"
47               />
48             </el-select>
7462da 49           </el-form-item>
L 50         </el-col>
51       </el-row>
52       <el-row>
53         <el-col :span="12">
e1ff2d 54           <el-form-item label="是否检查" prop="mmPredictItem.workchecked">
cd9f11 55             <el-select v-model="dataForm.mmPredictItem.workchecked" placeholder="请选择">
L 56               <el-option
d3ee81 57                 v-for="dict in getIntDictOptions(DICT_TYPE.COM_IS_INT)"
58                 :key="dict.value"
59                 :label="dict.label"
60                 :value="dict.value"
61               />
cd9f11 62             </el-select>
7462da 63           </el-form-item>
L 64         </el-col>
65         <el-col :span="12">
e1ff2d 66           <el-form-item label="是否启用" prop="mmPredictItem.status">
d3ee81 67             <el-select v-model="dataForm.mmPredictItem.status" placeholder="请选择">
cd9f11 68               <el-option
d3ee81 69                 v-for="dict in getIntDictOptions(DICT_TYPE.COM_IS_INT)"
70                 :key="dict.value"
71                 :label="dict.label"
72                 :value="dict.value"
73               />
cd9f11 74             </el-select>
7462da 75           </el-form-item>
L 76         </el-col>
77       </el-row>
78       <el-row>
79         <el-col :span="12">
e1ff2d 80           <el-form-item label="管网" prop="dmModuleItem.moduleid">
f5e3a1 81             <el-select v-model="dataForm.dmModuleItem.moduleid" placeholder="请选择" @change="clearExpressionList">
cd9f11 82               <el-option
L 83                 v-for="item in moduleList"
84                 :key="item.id"
85                 :label="item.modulename"
86                 :value="item.id"/>
87             </el-select>
7462da 88           </el-form-item>
L 89         </el-col>
90         <el-col :span="12">
2caade 91           <el-form-item label="类别">
83f63a 92             <el-input v-model="dataForm.dmModuleItem.categoryid" placeholder="类别" maxlength="64"/>
7462da 93           </el-form-item>
L 94         </el-col>
95       </el-row>
96       <el-row>
97         <el-col :span="12">
e1ff2d 98           <el-form-item label="排序" prop="dmModuleItem.itemorder">
d3ee81 99             <el-input-number v-model="dataForm.dmModuleItem.itemorder" :min="1" clearable
100                              controls-position="right"/>
7462da 101           </el-form-item>
L 102         </el-col>
103       </el-row>
22bcd6 104       <div v-if="dataForm.itemtypename === 'MergeItem'">
D 105         <el-row>
106           <el-col :span="12">
107             <el-form-item label="预测长度" prop="mmPredictItem.predictlength">
108               <el-input
109                 v-model="dataForm.mmPredictItem.predictlength" placeholder="预测长度"
110                 maxlength="5"/>
111             </el-form-item>
112           </el-col>
113           <el-col :span="12">
114             <el-form-item label="真实数据点">
115               <el-select
116                 v-model="dataForm.pointId"
117                 filterable
118                 clearable
119                 placeholder="请选择">
120                 <el-option
121                   v-for="item in pointList"
122                   :key="item.id"
123                   :label="item.pointName"
124                   :value="item.id"/>
125               </el-select>
126             </el-form-item>
127           </el-col>
128         </el-row>
129         <el-divider content-position="left">累计配置</el-divider>
130         <el-row>
131           <el-col :span="6">
132             <el-form-item label="是否累计" prop="iscumulant">
133               <el-select v-model="dataForm.iscumulant" placeholder="请选择" @change="(value) => iscumulantChange(dataForm)">
134                 <el-option
135                   v-for="dict in getIntDictOptions(DICT_TYPE.COM_IS_INT)"
136                   :key="dict.value"
137                   :label="dict.label"
138                   :value="dict.value"
139                 />
140               </el-select>
141             </el-form-item>
142           </el-col>
143           <el-col :span="6">
144             <el-form-item label="累计除数" prop="cumuldivisor">
145               <el-input-number v-model="dataForm.cumuldivisor" style="width: 100%" :disabled="dataForm.iscumulant !== 1"
146                 :min="1" :max="60"
147                 :controls="false"/>
148             </el-form-item>
149           </el-col>
150           <el-col :span="12">
151             <el-form-item label="累计测点">
152               <el-select
153                 v-model="dataForm.cumulpoint" :disabled="dataForm.iscumulant !== 1"
154                 filterable
155                 clearable
156                 placeholder="请选择">
157                 <el-option
158                   v-for="item in pointList.filter(e => e.pointType === 'CUMULATE')"
159                   :key="item.id"
160                   :label="item.pointName"
161                   :value="item.id"/>
162               </el-select>
163             </el-form-item>
164           </el-col>
165         </el-row>
166       </div>
cd9f11 167       <el-divider content-position="left" v-if="dataForm.itemtypename === 'NormalItem'">模型信息
L 168       </el-divider>
d3ee81 169       <el-row :gutter="8" v-if="dataForm.itemtypename === 'NormalItem'">
170         <el-col :span="12">
2caade 171           <el-form-item label="模型名称">
L 172             <el-input
173               v-model="dataForm.mmPredictModel.modelname" placeholder="模型名称"
174               maxlength="50"/>
cd9f11 175           </el-form-item>
L 176         </el-col>
7462da 177         <el-col :span="12">
d3ee81 178           <el-upload
179             class="upload-demo"
180             :limit="1"
181             :file-list="fileList"
182             :before-upload="beforeUpload"
183             :on-success="uploadModelSuccess"
184             :on-error="uploadModelError"
185             :action="uploadUrl"
4c7918 186             :show-file-list="false"
d3ee81 187             :http-request="httpRequest">
188             <el-button type="primary" @click="setReplaceModelOnly(false)">
189               <Icon icon="ep:upload"/>
190               上传模型
191             </el-button>
de0f62 192             <el-button type="primary" plain @click="setReplaceModelOnly(true)">
d3ee81 193               <Icon icon="ep:upload"/>
194               更新模型
195             </el-button>
196           </el-upload>
7462da 197         </el-col>
L 198       </el-row>
be4298 199       <el-row v-if="dataForm.itemtypename === 'NormalItem'">
d8e4be 200         <el-col :span="12">
22bece 201           <el-form-item label="关联项目" prop="mmPredictModel.mpkprojectid">
be4298 202             <el-select v-model="dataForm.mmPredictModel.mpkprojectid" placeholder="请选择">
D 203               <el-option
204                 v-for="item in mpkProjectList"
205                 :key="item.id"
206                 :label="item.projectName"
207                 :value="item.id"/>
208             </el-select>
209           </el-form-item>
210         </el-col>
d8e4be 211         <el-col :span="12">
e1ff2d 212           <el-form-item label="编号">
d3ee81 213             <el-input
e1ff2d 214               v-model="dataForm.mmPredictModel.modelno" placeholder="编号" maxlength="30" readonly
d3ee81 215               disabled/>
216           </el-form-item>
217         </el-col>
cd9f11 218       </el-row>
d3ee81 219       <el-row :gutter="8" v-if="dataForm.itemtypename === 'NormalItem'">
cd9f11 220         <el-col :span="24">
2caade 221           <el-form-item label="路径">
L 222             <el-input
223               v-model="dataForm.mmPredictModel.modelpath" placeholder="路径" maxlength="32"
224               disabled/>
cd9f11 225           </el-form-item>
L 226         </el-col>
227       </el-row>
d3ee81 228       <el-row :gutter="8" v-if="dataForm.itemtypename === 'NormalItem'">
cd9f11 229         <el-col :span="24">
2caade 230           <el-form-item label="类名">
L 231             <el-input
232               v-model="dataForm.mmPredictModel.classname" placeholder="类名" maxlength="32"
233               disabled/>
cd9f11 234           </el-form-item>
L 235         </el-col>
236       </el-row>
d3ee81 237       <el-row :gutter="8" v-if="dataForm.itemtypename === 'NormalItem'">
cd9f11 238         <el-col :span="12">
2caade 239           <el-form-item label="方法名">
L 240             <el-input
241               v-model="dataForm.mmPredictModel.methodname" placeholder="方法名"
242               maxlength="32" disabled/>
cd9f11 243           </el-form-item>
L 244         </el-col>
245         <el-col :span="12">
2caade 246           <el-form-item label="参数">
L 247             <el-input
248               v-model="dataForm.mmPredictModel.modelparamstructure" placeholder="参数"
249               maxlength="32" disabled/>
cd9f11 250           </el-form-item>
L 251         </el-col>
252       </el-row>
d8e4be 253       <el-divider content-position="left" v-if="dataForm.itemtypename === 'NormalItem'">模型输出
D 254       </el-divider>
255       <el-button
5c475d 256         v-if="dataForm.itemtypename === 'NormalItem'"
fcd59a 257         @click="addItemOutput()"
d8e4be 258         type="primary"
D 259         size="small">
260         添加
261       </el-button>
262       <el-table
263         v-if="dataForm.itemtypename === 'NormalItem'"
264         :data="dataForm.mmItemOutputList"
265         border
266         style="width: 100%; margin-top: 5px;">
61c379 267         <el-table-column prop="outputorder" label="排序" align="center" width="80px"/>
32396c 268         <el-table-column label="结果KEY" align="center" width="150px">
d8e4be 269           <template #default="scope">
D 270             <el-input v-model="scope.row.resultstr" placeholder="请输入"/>
271           </template>
272         </el-table-column>
32396c 273         <el-table-column label="结果类型" align="center" width="150px">
d8e4be 274           <template #default="scope">
D 275             <el-select
276               v-model="scope.row.resultType"
277               @change="(value) => resultTypeChange(value,scope.row)"
278               filterable
279               placeholder="请选择">
280               <el-option
281                 v-for="dict in getIntDictOptions(DICT_TYPE.MODEL_RESULT_TYPE)"
282                 :key="dict.value"
283                 :label="dict.label"
284                 :value="dict.value"/>
285             </el-select>
286           </template>
287         </el-table-column>
32396c 288         <el-table-column label="索引" align="center" width="100px">
d8e4be 289           <template #default="scope">
61c379 290             <el-input-number style="width:100%;hight:100%" :disabled="scope.row.resultType !== 2"
291                              v-model="scope.row.resultIndex" :min="0" step-strictly
292                              controls-position="right"/>
32396c 293           </template>
294         </el-table-column>
295         <el-table-column label="结果名称" align="center" width="150px">
296           <template #default="scope">
297             <el-input v-model="scope.row.resultName" placeholder="请输入"/>
d8e4be 298           </template>
D 299         </el-table-column>
300         <el-table-column label="数据点" align="center">
301           <template #default="scope">
302             <el-select
303               v-model="scope.row.pointid"
304               filterable
d7baa4 305               clearable
d8e4be 306               @change="(value) => changeOutputPoint(value,scope.row)"
D 307               placeholder="请选择">
308               <el-option
309                 v-for="item in pointList"
22bcd6 310                 :key="item.id"
D 311                 :label="item.pointName"
312                 :value="item.id"/>
313             </el-select>
314           </template>
315         </el-table-column>
316         <el-table-column label="是否累计" align="center" width="150px">
317           <template #default="scope">
318             <el-select v-model="scope.row.iscumulant" placeholder="请选择" @change="(value) => iscumulantChange(scope.row)">
319               <el-option
320                 v-for="dict in getIntDictOptions(DICT_TYPE.COM_IS_INT)"
321                 :key="dict.value"
322                 :label="dict.label"
323                 :value="dict.value"
324               />
325             </el-select>
326           </template>
327         </el-table-column>
328         <el-table-column label="累计除数" align="center" width="100px">
329           <template #default="scope">
330             <el-input-number v-model="scope.row.cumuldivisor" style="width: 100%"
331               :min="1" :max="60" :disabled="scope.row.iscumulant !== 1"
332               :controls="false"/>
333           </template>
334         </el-table-column>
335         <el-table-column label="累计数据点" align="center">
336           <template #default="scope">
337             <el-select
338               v-model="scope.row.cumulpoint"
339               :disabled="scope.row.iscumulant !== 1"
340               filterable
341               clearable
342               placeholder="请选择">
343               <el-option
344                 v-for="item in pointList.filter(e => e.pointType === 'CUMULATE')"
d8e4be 345                 :key="item.id"
D 346                 :label="item.pointName"
347                 :value="item.id"/>
348             </el-select>
349           </template>
350         </el-table-column>
351         <el-table-column prop="" label="操作" width="80" align="center">
352           <template #default="scope">
353             <el-button
354               @click="deleteItemOutput(scope.$index, dataForm.mmItemOutputList)"
355               type="text"
356               size="small">
357               删除
358             </el-button>
359           </template>
360         </el-table-column>
361       </el-table>
362       <el-divider content-position="left" v-if="dataForm.itemtypename === 'NormalItem'">模型设置参数
363       </el-divider>
cd9f11 364       <el-table
L 365         v-if="dataForm.itemtypename === 'NormalItem'"
366         :data="dataForm.mmModelArithSettingsList"
367         border
368         style="width: 100%; margin-top: 5px;">
7b1ce6 369         <el-table-column prop="key" label="键" align="center" min-width="150"/>
370         <el-table-column prop="name" label="名称" align="center" min-width="150"/>
371         <el-table-column prop="valuetype" label="类型" align="center" min-width="150"/>
32396c 372         <el-table-column prop="" label="值" align="center" min-width="200">
cd9f11 373           <template #default="scope">
932c3a 374             <el-input v-model="scope.row.value" maxlength="1000"
5c475d 375                       :disabled="scope.row.key === 'pyFile'"
d3ee81 376                       style="width:100%;height:100%"/>
cd9f11 377           </template>
L 378         </el-table-column>
379       </el-table>
d8e4be 380       <el-divider content-position="left" v-if="dataForm.itemtypename === 'NormalItem'">模型输入参数
cd9f11 381       </el-divider>
L 382       <el-table
2caade 383         v-if="dataForm.itemtypename === 'NormalItem'"
cd9f11 384         :data="dataForm.mmModelParamList"
L 385         border
386         style="width: 100%; margin-top: 5px;">
387         <el-table-column prop="modelparamportorder" label="端口" width="60" align="center"/>
388         <el-table-column prop="modelparamorder" label="序号" width="60" align="center"/>
389         <el-table-column prop="" label="类型" width="200" align="center">
390           <template #default="scope">
61c379 391             <el-select v-model="scope.row.modelparamtype"
392                        @change="changeModelparamtype(scope.row)"
393                        placeholder="请选择">
cd9f11 394               <el-option
d3ee81 395                 v-for="dict in getStrDictOptions(DICT_TYPE.MODEL_PARAM_TYPE)"
396                 :key="dict.value"
397                 :label="dict.label"
398                 :value="dict.value"
399               />
cd9f11 400             </el-select>
L 401           </template>
402         </el-table-column>
403         <el-table-column prop="" label="参数名称" align="center">
404           <template #default="scope">
5c475d 405             <el-select v-if="scope.row.modelparamtype === 'NormalItem'"
D 406               v-model="scope.row.modelparamid"
407               placeholder="请选择"
408               filterable
409               @change="changeModelparam(scope.row)"
410               style="width: 100%">
411               <el-option-group
412                 v-for="group in modelparamListMap['NormalItem']"
413                 :key="group.value"
414                 :label="group.label"
415               >
416                 <el-option
417                   v-for="item in group.children"
418                   :key="item.value"
419                   :label="item.label"
420                   :value="item.value"
421                 />
422               </el-option-group>
423             </el-select>
424             <el-select v-else
cd9f11 425               v-model="scope.row.modelparamid"
L 426               filterable
427               @change="changeModelparam(scope.row)"
428               placeholder="请选择">
429               <el-option
430                 v-for="(item, index) in modelparamListMap[scope.row.modelparamtype]"
431                 :key="index"
432                 :label="item.name"
433                 :value="item.id"/>
434             </el-select>
435           </template>
436         </el-table-column>
437         <el-table-column prop="" label="参数长度" width="120" align="center">
438           <template #default="scope">
e1ff2d 439             <el-input-number v-model="scope.row.datalength" :min="0" clearable
440                              controls-position="right"
441                              style="width:100%;hight:100%"/>
cd9f11 442           </template>
L 443         </el-table-column>
7b1ce6 444         <el-table-column prop="" label="操作" width="120" align="center">
cd9f11 445           <template #default="scope">
L 446             <el-button
447               @click="addRow(scope.$index, dataForm.mmModelParamList)"
932c3a 448               type="text">
cd9f11 449               添加
L 450             </el-button>
451             <el-button
22bece 452               @click="deleteRow(scope.$index, scope.row, dataForm.mmModelParamList)"
932c3a 453               type="text">
cd9f11 454               删除
L 455             </el-button>
456           </template>
457         </el-table-column>
458       </el-table>
459       <el-divider content-position="left" v-if="dataForm.itemtypename === 'MergeItem'">表达式
460       </el-divider>
461       <el-table
2caade 462         v-if="dataForm.itemtypename === 'MergeItem'"
cd9f11 463         :data="expressionList"
L 464         border
465         style="width: 100%; margin-top: 5px;">
466         <el-table-column
467           prop=""
5c475d 468           label="预测项(NormalItem)"
cd9f11 469           align="center">
L 470           <template #default="scope">
471             <el-select
472               v-model="scope.row.point"
5c475d 473               placeholder="请选择"
cd9f11 474               filterable
49e497 475               :no-data-text="'无数据(管网:' + moduleList.find(e => e.id === dataForm.dmModuleItem.moduleid)?.modulename + ')'"
fcd59a 476               @change="changeNormalItemSelect"
5c475d 477               style="width: 100%">
D 478               <el-option-group
49e497 479                 v-for="group in modelparamListMap['NormalItem'].filter(e => e.moduleid === dataForm.dmModuleItem.moduleid)"
5c475d 480                 :key="group.value"
D 481                 :label="group.label"
482               >
483                 <el-option
484                   v-for="item in group.children"
485                   :key="item.value"
486                   :label="item.label"
487                   :value="item.value"
488                 />
489               </el-option-group>
cd9f11 490             </el-select>
L 491           </template>
492         </el-table-column>
493         <el-table-column
494           prop="point"
495           label="编号"
496           align="center"/>
497         <el-table-column
498           prop=""
499           label="运算符"
500           align="center">
501           <template #default="scope">
7b1ce6 502             <el-select v-model="scope.row.operator" placeholder="请选择" clearable>
cd9f11 503               <el-option
L 504                 v-for="item in operatorList"
505                 :key="item"
506                 :label="item"
507                 :value="item"/>
508             </el-select>
509           </template>
510         </el-table-column>
511         <el-table-column
512           prop=""
513           label="操作"
2caade 514           width="140"
cd9f11 515           align="center">
L 516           <template #default="scope">
517             <el-button
518               @click="addExpressionRow(scope.$index, expressionList)"
519               type="text"
520               size="small">
521               添加
522             </el-button>
523             <el-button
524               @click="deleteExpressionRow(scope.$index, expressionList)"
525               type="text"
526               size="small">
527               删除
528             </el-button>
529           </template>
530         </el-table-column>
531       </el-table>
7462da 532     </el-form>
L 533     <template #footer>
534       <el-button :disabled="formLoading" type="primary" @click="submitForm">确 定</el-button>
535       <el-button @click="dialogVisible = false">取 消</el-button>
536     </template>
537   </Dialog>
538 </template>
539 <script lang="ts" setup>
d3ee81 540 import {DICT_TYPE, getIntDictOptions, getStrDictOptions} from '@/utils/dict'
7b1ce6 541 import * as MmPredictItem from '@/api/model/pre/item'
542 import * as MmItemType from '@/api/model/pre/type'
cd9f11 543 import * as DmModule from '@/api/model/pre/dm'
be4298 544 import * as ProjectApi from '@/api/model/mpk/project'
cd9f11 545 import * as DaPoint from '@/api/data/da/point'
7b1ce6 546 import {useUpload} from '@/api/model/pre/item'
e1ff2d 547 import * as ScheduleModelApi from '@/api/model/sche/model'
160af9 548 import {getPointSimpleList} from "@/api/data/da/point";
d3ee81 549
550 const {uploadUrl, httpRequest} = useUpload()
7462da 551
L 552 defineOptions({name: 'DataMmPredictItemForm'})
553
554 const {t} = useI18n() // 国际化
555 const message = useMessage() // 消息弹窗
556 const dialogVisible = ref(false) // 弹窗的是否展示
557 const dialogTitle = ref('') // 弹窗的标题
558 const formLoading = ref(false) // 表单的加载中:1)修改时的数据加载;2)提交的按钮禁用
559 const formType = ref('') // 表单的类型:create - 新增;update - 修改
cd9f11 560 const itemTypeList = ref([])
L 561 const itemTypeMap = ref({})
562 const moduleList = ref([])
be4298 563 const mpkProjectList = ref([])
2caade 564 const pointNoList = ref([])
cd9f11 565 const pointList = ref([])
L 566 const pointMap = ref({})
d3ee81 567 const modelparamListMap = ref({})
cd9f11 568 const modelparamMap = ref({})
L 569 const expressionList = ref([])
570 const fileList = ref([])
571 const operatorList = ['+', '-']
d3ee81 572 const replaceModelOnly = ref(false)
cd9f11 573 const queryParams = reactive({
L 574   pageNo: 1,
575   pageSize: 10,
576   pointNo: undefined,
577   pointName: undefined,
578 })
579 const dataForm = ref({
2caade 580   id: undefined,
e1ff2d 581   itemtypename: 'NormalItem',
cd9f11 582   mmPredictItem: {
2caade 583     id: undefined,
L 584     itemno: undefined,
585     itemname: undefined,
586     caltypeid: undefined,
587     itemtypeid: undefined,
588     predictlength: undefined,
d3ee81 589     granularity: 60,
2caade 590     status: undefined,
L 591     isfuse: undefined,
592     predictphase: undefined,
d3ee81 593     workchecked: 0,
2caade 594     unittransfactor: undefined,
160af9 595     saveindex: undefined,
cd9f11 596   },
L 597   dmModuleItem: {
2caade 598     id: undefined,
L 599     moduleid: undefined,
600     itemid: undefined,
d3ee81 601     itemorder: 1,
2caade 602     status: undefined,
L 603     categoryid: undefined
cd9f11 604   },
d8e4be 605   mmItemOutputList: [],
cd9f11 606   mmPredictModel: {
2caade 607     id: undefined,
L 608     modelno: undefined,
609     modelname: undefined,
610     itemid: undefined,
611     arithid: undefined,
612     trainsamplength: undefined,
613     predictsamplength: undefined,
614     isonlinetrain: undefined,
615     modelpath: undefined,
616     isnormal: undefined,
617     normalmax: undefined,
618     normalmin: undefined,
619     status: undefined,
620     classname: undefined,
621     methodname: undefined,
622     modelparamstructure: undefined,
623     resultstrid: undefined,
be4298 624     settingmap: undefined,
D 625     mpkprojectid: undefined
cd9f11 626   },
L 627   mmPredictMergeItem: {
2caade 628     id: undefined,
L 629     itemid: undefined,
630     expression: undefined,
631     num: undefined
cd9f11 632   },
L 633   mmModelArithSettingsList: [],
36885d 634   mmModelParamList: [],
22bcd6 635   pointId: undefined,
D 636   iscumulant: 0,
637   cumuldivisor: undefined,
638   cumulpoint: undefined,
7462da 639 })
L 640 const formRules = reactive({
d3ee81 641   'mmPredictItem.itemname': [{required: true, message: '预测项名不能为空', trigger: 'blur'}],
642   'mmPredictItem.itemtypeid': [{required: true, message: '类型不能为空', trigger: 'blur'}],
e1ff2d 643   'mmPredictItem.granularity': [{
d3ee81 644     required: true,
645     message: '粒度不能为空',
646     trigger: 'blur'
647   }],
e1ff2d 648   'mmPredictItem.workchecked': [{
d3ee81 649     required: true,
650     message: '是否检查不能为空',
651     trigger: 'blur'
652   }],
e1ff2d 653   'mmPredictItem.status': [{required: true, message: '是否启用不能为空', trigger: 'blur'}],
22bcd6 654   'iscumulant': [{required: true, message: '是否累计不能为空', trigger: 'blur'}],
e1ff2d 655   'dmModuleItem.moduleid': [{required: true, message: '管网不能为空', trigger: 'blur'}],
656   'dmModuleItem.itemorder': [{required: true, message: '排序不能为空', trigger: 'blur'}],
fcd59a 657   'mmPredictItem.predictlength': [{required: true, message: '预测长度不能为空', trigger: 'blur'}],
22bece 658   'mmPredictModel.mpkprojectid': [{required: true, message: '关联项目不能为空', trigger: 'blur'}],
d3ee81 659
7462da 660 })
L 661 const formRef = ref() // 表单 Ref
662
663 /** 打开弹窗 */
2caade 664 const open = async (type: string, id?: number, itemtypename?: string) => {
e1ff2d 665   formType.value = type
7462da 666   dialogVisible.value = true
L 667   dialogTitle.value = t('action.' + type)
2caade 668   dataForm.value.itemtypename = itemtypename || 'NormalItem'
e1ff2d 669   resetForm()
2caade 670   resetFields(dataForm.value)
83f63a 671   setDefaultFields()
e1ff2d 672
673   // 加载参数列表
5c475d 674   modelparamListMap.value = await ScheduleModelApi.getModelParamList(id)
e1ff2d 675
676   // 获取预测项类型列表
677   itemTypeList.value = await MmItemType.getItemTypeList()
678   itemTypeList.value.forEach(function (value) {
679     itemTypeMap[value.id] = value.itemtypename
680   })
681   if (!dataForm.value.id) {
682     dataForm.value.mmPredictItem.itemtypeid = itemTypeList.value[0].id
683   }
684
685   // 获取管网列表
686   moduleList.value = await DmModule.getModuleList()
687
be4298 688   // 获取mpk项目列表
D 689   mpkProjectList.value = await ProjectApi.list()
7b1ce6 690
e1ff2d 691   // 获取数据点列表
160af9 692   pointNoList.value = await DaPoint.getPointSimpleList(queryParams)
e1ff2d 693   if (pointNoList.value.length > 0) {
d8e4be 694     pointList.value = []
e1ff2d 695     pointNoList.value.forEach(function (value) {
696       pointList.value.push(value)
d8e4be 697       pointMap[value.id] = value.pointName
e1ff2d 698     })
699   }
700
7b1ce6 701   // 修改时,设置数据
702   if (id) {
703     formLoading.value = true
704     try {
705       getInfo(id)
706     } finally {
d8e4be 707       formLoading.value = false
7b1ce6 708     }
709   }
e1ff2d 710   formLoading.value = false
7462da 711 }
L 712 defineExpose({open}) // 提供 open 方法,用于打开弹窗
713
714 /** 提交表单 */
715 const emit = defineEmits(['success']) // 定义 success 事件,用于操作成功后的回调
716 const submitForm = async () => {
717   // 校验表单
718   if (!formRef) return
719   const valid = await formRef.value.validate()
720   if (!valid) return
22bcd6 721   //校验累计配置
D 722   if (dataForm.value.iscumulant === 1) {
723     if (dataForm.value.cumuldivisor == undefined) {
724       message.error("累计除数不为空")
725       return
726     }
727   }
d8e4be 728   //校验模型输出
fcd59a 729   if (dataForm.value.itemtypename === 'NormalItem') {
5c475d 730     if (dataForm.value.mmItemOutputList == undefined || dataForm.value.mmItemOutputList.length <= 0) {
D 731       message.error("模型输出不为空")
732       return
733     }
734
735     dataForm.value.mmItemOutputList.forEach(e => {
22bcd6 736       if (e.resultstr == undefined || e.resultstr === '' || e.resultType == undefined || e.resultType === ''
D 737         || (e.resultType === 2 && (e.resultIndex == undefined || e.resultIndex === ''))
738         || (e.iscumulant === 1 && e.cumuldivisor == undefined)
739       ) {
82c481 740         message.error("输出数据异常")
D 741         throw new Error('输出数据异常');
fcd59a 742       }
D 743     })
82c481 744
D 745     //校验模型输入
746     dataForm.value.mmModelParamList.forEach(e => {
747       if (e.modelparamid == undefined || e.modelparamid == '') {
748         message.error("输入数据异常")
749         throw new Error('输入数据异常');
750       }
751       // ind_ascii类型输出的序号必须是1,且所在端口序号最大为1(一个ind_ascii类型输入独占一个端口)
752       if (e.modelparamtype === 'IND_ASCII') {
753         if (e.modelparamorder != 1 || dataForm.value.mmModelParamList.filter(p => p.modelparamportorder === e.modelparamportorder).length != 1) {
754           message.error("输入数据异常:IND_ASCII类型输入独占一个端口")
755           throw new Error('输入数据异常:IND_ASCII类型输入独占一个端口');
756         }
757       }
758     })
fcd59a 759   }
D 760   if (dataForm.value.itemtypename === 'MergeItem') {
761     if (expressionList.value == undefined || expressionList.value.length <= 1) {
762       message.error("表达式长度低于2")
763       return
764     }
765
766     let flag = false
767     expressionList.value.forEach((e,index) => {
3affb8 768       if (e.point == undefined || e.point === '' || ((e.operator == undefined || e.operator === '') && index != expressionList.value.length - 1)) {
fcd59a 769         message.error("表达式数据异常")
5c475d 770         flag = true
D 771         return
772       }
773     })
774     if (flag) return
d8e4be 775   }
D 776
7462da 777   // 提交请求
L 778   formLoading.value = true
779   try {
cd9f11 780     const data = dataForm.value as unknown as MmPredictItem.MmPredictItemVO
b39d0b 781     if (expressionList.value && expressionList.value.length > 0) {
L 782       let expression = ''
783       for (let i = 0; i < expressionList.value.length; i++) {
784         let value = expressionList.value[i]
785         expression = expression + value.point + (i === (expressionList.value.length - 1) ? '' : value.operator)
786       }
787       dataForm.value.mmPredictMergeItem.expression = expression
788     } else {
789       dataForm.value.mmPredictMergeItem.expression = ''
790     }
791     if (dataForm.value.mmModelArithSettingsList) {
792       for (let item of dataForm.value.mmModelArithSettingsList) {
9b24e4 793         if (item.key === 'predictLength') {
b39d0b 794           dataForm.value.mmPredictItem.predictlength = item.value
L 795         }
796       }
797     }
7462da 798     if (formType.value === 'create') {
L 799       await MmPredictItem.createMmPredictItem(data)
800       message.success(t('common.createSuccess'))
801     } else {
802       await MmPredictItem.updateMmPredictItem(data)
803       message.success(t('common.updateSuccess'))
804     }
805     dialogVisible.value = false
806     // 发送操作成功的事件
807     emit('success')
808   } finally {
809     formLoading.value = false
810   }
811 }
83f63a 812
2caade 813 const resetFields = (obj) => {
L 814   for (let key in obj) {
815     if (key === 'itemtypename') {
816       continue
817     }
818     if (obj[key] instanceof Array) {
819       obj[key] = []
820     } else if (obj[key] instanceof Object) {
821       resetFields(obj[key])
822     } else {
823       obj[key] = ''
824     }
825   }
826 }
827
828 const getInfo = async (id) => {
829   dataForm.value = await MmPredictItem.getMmPredictItem(id)
7b1ce6 830   dataForm.value.itemtypename = itemTypeMap[dataForm.value.mmPredictItem.itemtypeid]
83f63a 831   expressionList.value = []
2caade 832   if (dataForm.value.mmPredictMergeItem && dataForm.value.mmPredictMergeItem.expression) {
L 833     let expression = dataForm.value.mmPredictMergeItem.expression
83f63a 834     do {
L 835       let indexPlus = expression.indexOf('+')
836       let indexSub = expression.indexOf('-')
837       if (indexPlus !== -1 || indexSub !== -1) {
838         let endIndex = (indexSub == -1 || (indexPlus < indexSub && indexPlus !== -1)) ? indexPlus : indexSub
839         expressionList.value.push({
840           point: expression.substring(0, endIndex),
5c475d 841           operator: expression.substring(endIndex, endIndex + 1)
83f63a 842         })
L 843         expression = expression.substring(endIndex + 1)
844       } else {
845         expressionList.value.push({
846           point: expression,
847           operator: ''
848         })
849         expression = ''
850       }
851     } while (expression && expression.length > 0)
852   }
853 }
854
855 function setReplaceModelOnly(value) {
cd9f11 856   replaceModelOnly.value = value
L 857 }
83f63a 858
L 859 function beforeUpload(file) {
cd9f11 860   let fileName = file.name
L 861   let first = fileName.lastIndexOf('.')
862   let nameLength = fileName.length
863   let fileSuffix = fileName.substring(first + 1, nameLength)
864   if (fileSuffix !== 'miail') {
865     message.error('只能上传miail类型文件')
866     return
867   }
868 }
83f63a 869
L 870 function uploadModelSuccess(response, file, fileList) {
cd9f11 871   if (response.code === 0) {
L 872     message.success(t('上传成功'))
873     dataForm.value.mmModelArithSettingsList = []
d3ee81 874     if (!replaceModelOnly.value) {
cd9f11 875       dataForm.value.mmModelParamList = []
L 876     }
877     dataForm.value.mmPredictModel.modelpath = ''
878     dataForm.value.mmPredictModel.modelparamstructure = ''
879     if (response.data.loadFieldSetList && response.data.loadFieldSetList[0].propertyList) {
83f63a 880       response.data.loadFieldSetList[0].propertyList.forEach(function (value) {
5c475d 881         //匹配  data数字
D 882         if (!/^data\d+$/.test(value.key)) {
cd9f11 883           dataForm.value.mmModelArithSettingsList.push({
L 884             key: value.key,
885             name: value.name,
886             valuetype: value.valueType,
887             value: value.value
888           })
889         }
2caade 890       })
cd9f11 891     }
d3ee81 892     dataForm.value.mmPredictModel.modelname = response.data.originalFilename
cd9f11 893     dataForm.value.mmPredictModel.classname = response.data.className
L 894     dataForm.value.mmPredictModel.methodname = response.data.methodName
895     if (response.data.paramPathList) {
896       dataForm.value.mmPredictModel.modelpath = response.data.paramPathList[0]
897     }
898     if (response.data.paramsArray) {
899       dataForm.value.mmPredictModel.modelparamstructure = response.data.paramsArray.join(',')
900     }
d3ee81 901     if (response.data.paramsCount && !replaceModelOnly.value) {
cd9f11 902       for (let i = 0; i < response.data.paramsCount; i++) {
L 903         dataForm.value.mmModelParamList.push({
904           modelparamportorder: (i + 1),
905           modelparamorder: (i + 1),
906           modelparamtype: '',
907           modelparamid: '',
908           modelparamname: '',
909           datalength: 0
910         })
911       }
912     }
913     if (response.data.settingConfigMap && response.data.settingConfigMap.settingMap) {
914       dataForm.value.mmPredictModel.settingmap = JSON.stringify(response.data.settingConfigMap.settingMap)
915     }
916   } else {
917     message.error('上传失败!' + response.msg)
918     return
919   }
920   fileList = []
921 }
83f63a 922
L 923 function uploadModelError(file, err, fileList) {
cd9f11 924 }
83f63a 925
L 926 function changeModelparam(row) {
cd9f11 927   row.modelparamname = modelparamMap[row.modelparamid]
L 928 }
83f63a 929
L 930 function changeItemtype(value) {
cd9f11 931   dataForm.value.itemtypename = itemTypeMap[value]
L 932 }
83f63a 933
61c379 934 function changeModelparamtype(row) {
cd9f11 935   row.modelparamid = ''
L 936 }
83f63a 937
61c379 938 function changeOutputPoint(value, row) {
d8e4be 939   row.tagname = pointMap[value]
cd9f11 940 }
83f63a 941
L 942 function deleteExpressionRow(index, rows) {
cd9f11 943   rows.splice(index, 1)
L 944 }
83f63a 945
L 946 function addExpressionRow(index, rows) {
cd9f11 947   let row = JSON.parse(JSON.stringify(rows[index]))
L 948   rows.splice(index, 0, row)
949 }
83f63a 950
22bece 951 function deleteRow(index, row, rows) {
D 952   if (!rows || rows.length === 1 || rows.filter(e => e.modelparamportorder === row.modelparamportorder).length === 1) {
953     message.error('不可删除!')
cd9f11 954     return
L 955   }
956   rows.splice(index, 1)
957   orderRow(rows)
958 }
83f63a 959
L 960 function addRow(index: string, rows) {
cd9f11 961   let row = JSON.parse(JSON.stringify(rows[index]))
L 962   rows.splice(index, 0, row)
963   orderRow(rows)
d8e4be 964 }
61c379 965
fcd59a 966 function addItemOutput() {
D 967   if (!dataForm.value.mmItemOutputList) {
968     dataForm.value.mmItemOutputList = []
969   }
970   dataForm.value.mmItemOutputList.push({})
971   orderItemOutput(dataForm.value.mmItemOutputList)
d8e4be 972 }
61c379 973
d8e4be 974 function deleteItemOutput(index: string, rows) {
D 975   if (!rows || rows.length === 1) {
976     message.error('不能全部删除!')
977     return
978   }
979   rows.splice(index, 1)
980   orderItemOutput(rows)
981 }
61c379 982
d8e4be 983 function orderItemOutput(list) {
D 984   list.sort((a, b) => a.outputorder - b.outputorder);
985   let outputorder = 1
986   list.forEach(function (value) {
987     value.outputorder = outputorder
988     outputorder++
989   })
990 }
991
992 function resultTypeChange(value, row) {
993   if (value === 1) {
994     row.resultIndex = undefined
61c379 995   } else if (value === 2) {
d8e4be 996     row.resultIndex = 0
D 997   }
cd9f11 998 }
22bcd6 999 function iscumulantChange(row) {
D 1000   row.cumuldivisor = undefined
1001   row.cumulpoint = undefined
1002 }
7462da 1003
83f63a 1004 function orderRow(rows) {
cd9f11 1005   let modelparamorder = 0
L 1006   let modelparamportorder = 0
1007   rows.forEach(function (value) {
1008     if (value.modelparamportorder !== modelparamportorder) {
1009       modelparamportorder = value.modelparamportorder
1010       modelparamorder = 1
1011     }
1012     value.modelparamorder = modelparamorder
1013     modelparamorder++
1014   })
1015 }
83f63a 1016
2caade 1017 const setDefaultFields = () => {
83f63a 1018   dataForm.value.mmPredictItem.workchecked = 0
L 1019   dataForm.value.mmPredictItem.status = 1
1020   dataForm.value.mmPredictItem.isfuse = 0
1021   dataForm.value.mmPredictItem.predictphase = 0
1022   dataForm.value.mmPredictItem.unittransfactor = 1
1023   dataForm.value.mmPredictItem.saveindex = '2'
1024   dataForm.value.dmModuleItem.status = 1
1025   dataForm.value.mmPredictModel.trainsamplength = 60
1026   dataForm.value.mmPredictModel.isonlinetrain = 0
1027   dataForm.value.mmPredictModel.status = 1
d8e4be 1028   dataForm.value.mmItemOutputList = []
83f63a 1029   expressionList.value = [{
L 1030     point: '',
1031     operator: ''
1032   }]
1033   fileList.value = []
1034 }
1035
f5e3a1 1036 const clearExpressionList = (value) => {
fcd59a 1037   expressionList.value = [{
D 1038     point: '',
1039     operator: ''
1040   }]
1041 }
1042
7462da 1043 /** 重置表单 */
d3ee81 1044 const resetForm = () => {
cd9f11 1045   dataForm.value = {
L 1046     mmModelArithSettingsList: [],
1047     mmModelParamList: [],
1048     id: '',
e1ff2d 1049     itemtypename: 'NormalItem',
cd9f11 1050     mmPredictItem: {
L 1051       id: '',
1052       itemno: '',
1053       itemname: '',
1054       caltypeid: '',
1055       itemtypeid: '',
1056       predictlength: '',
d3ee81 1057       granularity: 60,
cd9f11 1058       status: '',
L 1059       isfuse: '',
1060       predictphase: '',
d3ee81 1061       workchecked: 0,
cd9f11 1062       unittransfactor: '',
160af9 1063       saveindex: '',
cd9f11 1064     },
L 1065     dmModuleItem: {
1066       id: '',
1067       moduleid: '',
1068       itemid: '',
d3ee81 1069       itemorder: 1,
cd9f11 1070       status: 1,
L 1071       categoryid: ''
1072     },
d8e4be 1073     mmItemOutputList: [],
cd9f11 1074     mmPredictModel: {
L 1075       id: '',
1076       modelno: '',
1077       modelname: '',
1078       itemid: '',
1079       arithid: '',
1080       trainsamplength: '',
1081       predictsamplength: '',
1082       isonlinetrain: '',
1083       modelpath: '',
1084       isnormal: '',
1085       normalmax: '',
1086       normalmin: '',
1087       status: 1,
1088       classname: '',
1089       methodname: '',
1090       modelparamstructure: '',
1091       resultstrid: '',
1092       settingmap: ''
1093     },
1094     mmPredictMergeItem: {
1095       id: '',
1096       itemid: '',
1097       expression: '',
1098       num: ''
22bcd6 1099     },
D 1100     iscumulant: 0,
1101     cumuldivisor: undefined,
1102     cumulpoint: '',
7462da 1103   }
L 1104   formRef.value?.resetFields()
d3ee81 1105 }
cd9f11 1106
L 1107 onMounted(() => {
1108   init()
1109 })
1110
83f63a 1111 function init() {
cd9f11 1112 }
7462da 1113 </script>