提交 | 用户 | 时间
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">
442724 302             <el-select-v2
d8e4be 303               v-model="scope.row.pointid"
442724 304               :options="pointList || []"
D 305               placeholder="请选择"
306               :props="{value:'id',label:'pointName'}"
d7baa4 307               clearable
442724 308               filterable
d8e4be 309               @change="(value) => changeOutputPoint(value,scope.row)"
442724 310               :fit-input-width="false"
D 311             />
22bcd6 312           </template>
D 313         </el-table-column>
314         <el-table-column label="是否累计" align="center" width="150px">
315           <template #default="scope">
316             <el-select v-model="scope.row.iscumulant" placeholder="请选择" @change="(value) => iscumulantChange(scope.row)">
317               <el-option
318                 v-for="dict in getIntDictOptions(DICT_TYPE.COM_IS_INT)"
319                 :key="dict.value"
320                 :label="dict.label"
321                 :value="dict.value"
322               />
323             </el-select>
324           </template>
325         </el-table-column>
326         <el-table-column label="累计除数" align="center" width="100px">
327           <template #default="scope">
328             <el-input-number v-model="scope.row.cumuldivisor" style="width: 100%"
329               :min="1" :max="60" :disabled="scope.row.iscumulant !== 1"
330               :controls="false"/>
331           </template>
332         </el-table-column>
333         <el-table-column label="累计数据点" align="center">
334           <template #default="scope">
442724 335             <el-select-v2
22bcd6 336               v-model="scope.row.cumulpoint"
442724 337               :options="pointList.filter(e => e.pointType === 'CUMULATE') || []"
D 338               placeholder="请选择"
339               :props="{value:'id',label:'pointName'}"
22bcd6 340               clearable
442724 341               filterable
D 342               :fit-input-width="false"
343               :disabled="scope.row.iscumulant !== 1"
344             />
d8e4be 345           </template>
D 346         </el-table-column>
347         <el-table-column prop="" label="操作" width="80" align="center">
348           <template #default="scope">
349             <el-button
350               @click="deleteItemOutput(scope.$index, dataForm.mmItemOutputList)"
351               type="text"
352               size="small">
353               删除
354             </el-button>
355           </template>
356         </el-table-column>
357       </el-table>
358       <el-divider content-position="left" v-if="dataForm.itemtypename === 'NormalItem'">模型设置参数
359       </el-divider>
cd9f11 360       <el-table
L 361         v-if="dataForm.itemtypename === 'NormalItem'"
362         :data="dataForm.mmModelArithSettingsList"
363         border
364         style="width: 100%; margin-top: 5px;">
7b1ce6 365         <el-table-column prop="key" label="键" align="center" min-width="150"/>
366         <el-table-column prop="name" label="名称" align="center" min-width="150"/>
367         <el-table-column prop="valuetype" label="类型" align="center" min-width="150"/>
32396c 368         <el-table-column prop="" label="值" align="center" min-width="200">
cd9f11 369           <template #default="scope">
932c3a 370             <el-input v-model="scope.row.value" maxlength="1000"
5c475d 371                       :disabled="scope.row.key === 'pyFile'"
d3ee81 372                       style="width:100%;height:100%"/>
cd9f11 373           </template>
L 374         </el-table-column>
375       </el-table>
d8e4be 376       <el-divider content-position="left" v-if="dataForm.itemtypename === 'NormalItem'">模型输入参数
cd9f11 377       </el-divider>
L 378       <el-table
2caade 379         v-if="dataForm.itemtypename === 'NormalItem'"
cd9f11 380         :data="dataForm.mmModelParamList"
L 381         border
382         style="width: 100%; margin-top: 5px;">
383         <el-table-column prop="modelparamportorder" label="端口" width="60" align="center"/>
384         <el-table-column prop="modelparamorder" label="序号" width="60" align="center"/>
385         <el-table-column prop="" label="类型" width="200" align="center">
386           <template #default="scope">
61c379 387             <el-select v-model="scope.row.modelparamtype"
388                        @change="changeModelparamtype(scope.row)"
389                        placeholder="请选择">
cd9f11 390               <el-option
d3ee81 391                 v-for="dict in getStrDictOptions(DICT_TYPE.MODEL_PARAM_TYPE)"
392                 :key="dict.value"
393                 :label="dict.label"
394                 :value="dict.value"
395               />
cd9f11 396             </el-select>
L 397           </template>
398         </el-table-column>
399         <el-table-column prop="" label="参数名称" align="center">
400           <template #default="scope">
442724 401             <el-select-v2 v-if="scope.row.modelparamtype === 'NormalItem'"
5c475d 402               v-model="scope.row.modelparamid"
442724 403               :options="modelparamListMap['NormalItem'] || []"
5c475d 404               placeholder="请选择"
442724 405               :props="{value:'value',label:'label',options:'children'}"
D 406               clearable
5c475d 407               filterable
442724 408               :fit-input-width="false"
D 409             />
410             <el-select-v2 v-else
cd9f11 411               v-model="scope.row.modelparamid"
442724 412               :options="modelparamListMap[scope.row.modelparamtype] || []"
D 413               placeholder="请选择"
414               :props="{value:'id',label:'name'}"
415               clearable
cd9f11 416               filterable
442724 417               :fit-input-width="false"
D 418             />
cd9f11 419           </template>
L 420         </el-table-column>
421         <el-table-column prop="" label="参数长度" width="120" align="center">
422           <template #default="scope">
e1ff2d 423             <el-input-number v-model="scope.row.datalength" :min="0" clearable
424                              controls-position="right"
425                              style="width:100%;hight:100%"/>
cd9f11 426           </template>
L 427         </el-table-column>
7b1ce6 428         <el-table-column prop="" label="操作" width="120" align="center">
cd9f11 429           <template #default="scope">
L 430             <el-button
431               @click="addRow(scope.$index, dataForm.mmModelParamList)"
932c3a 432               type="text">
cd9f11 433               添加
L 434             </el-button>
435             <el-button
22bece 436               @click="deleteRow(scope.$index, scope.row, dataForm.mmModelParamList)"
932c3a 437               type="text">
cd9f11 438               删除
L 439             </el-button>
440           </template>
441         </el-table-column>
442       </el-table>
443       <el-divider content-position="left" v-if="dataForm.itemtypename === 'MergeItem'">表达式
444       </el-divider>
445       <el-table
2caade 446         v-if="dataForm.itemtypename === 'MergeItem'"
cd9f11 447         :data="expressionList"
L 448         border
449         style="width: 100%; margin-top: 5px;">
450         <el-table-column
451           prop=""
5c475d 452           label="预测项(NormalItem)"
cd9f11 453           align="center">
L 454           <template #default="scope">
455             <el-select
456               v-model="scope.row.point"
5c475d 457               placeholder="请选择"
cd9f11 458               filterable
49e497 459               :no-data-text="'无数据(管网:' + moduleList.find(e => e.id === dataForm.dmModuleItem.moduleid)?.modulename + ')'"
fcd59a 460               @change="changeNormalItemSelect"
5c475d 461               style="width: 100%">
D 462               <el-option-group
49e497 463                 v-for="group in modelparamListMap['NormalItem'].filter(e => e.moduleid === dataForm.dmModuleItem.moduleid)"
5c475d 464                 :key="group.value"
D 465                 :label="group.label"
466               >
467                 <el-option
468                   v-for="item in group.children"
469                   :key="item.value"
470                   :label="item.label"
471                   :value="item.value"
472                 />
473               </el-option-group>
cd9f11 474             </el-select>
L 475           </template>
476         </el-table-column>
477         <el-table-column
478           prop="point"
479           label="编号"
480           align="center"/>
481         <el-table-column
482           prop=""
483           label="运算符"
484           align="center">
485           <template #default="scope">
7b1ce6 486             <el-select v-model="scope.row.operator" placeholder="请选择" clearable>
cd9f11 487               <el-option
L 488                 v-for="item in operatorList"
489                 :key="item"
490                 :label="item"
491                 :value="item"/>
492             </el-select>
493           </template>
494         </el-table-column>
495         <el-table-column
496           prop=""
497           label="操作"
2caade 498           width="140"
cd9f11 499           align="center">
L 500           <template #default="scope">
501             <el-button
502               @click="addExpressionRow(scope.$index, expressionList)"
503               type="text"
504               size="small">
505               添加
506             </el-button>
507             <el-button
508               @click="deleteExpressionRow(scope.$index, expressionList)"
509               type="text"
510               size="small">
511               删除
512             </el-button>
513           </template>
514         </el-table-column>
515       </el-table>
7462da 516     </el-form>
L 517     <template #footer>
518       <el-button :disabled="formLoading" type="primary" @click="submitForm">确 定</el-button>
519       <el-button @click="dialogVisible = false">取 消</el-button>
520     </template>
521   </Dialog>
522 </template>
523 <script lang="ts" setup>
d3ee81 524 import {DICT_TYPE, getIntDictOptions, getStrDictOptions} from '@/utils/dict'
7b1ce6 525 import * as MmPredictItem from '@/api/model/pre/item'
526 import * as MmItemType from '@/api/model/pre/type'
cd9f11 527 import * as DmModule from '@/api/model/pre/dm'
be4298 528 import * as ProjectApi from '@/api/model/mpk/project'
cd9f11 529 import * as DaPoint from '@/api/data/da/point'
7b1ce6 530 import {useUpload} from '@/api/model/pre/item'
e1ff2d 531 import * as ScheduleModelApi from '@/api/model/sche/model'
160af9 532 import {getPointSimpleList} from "@/api/data/da/point";
d3ee81 533
534 const {uploadUrl, httpRequest} = useUpload()
7462da 535
L 536 defineOptions({name: 'DataMmPredictItemForm'})
537
538 const {t} = useI18n() // 国际化
539 const message = useMessage() // 消息弹窗
540 const dialogVisible = ref(false) // 弹窗的是否展示
541 const dialogTitle = ref('') // 弹窗的标题
542 const formLoading = ref(false) // 表单的加载中:1)修改时的数据加载;2)提交的按钮禁用
543 const formType = ref('') // 表单的类型:create - 新增;update - 修改
cd9f11 544 const itemTypeList = ref([])
L 545 const itemTypeMap = ref({})
546 const moduleList = ref([])
be4298 547 const mpkProjectList = ref([])
2caade 548 const pointNoList = ref([])
cd9f11 549 const pointList = ref([])
L 550 const pointMap = ref({})
d3ee81 551 const modelparamListMap = ref({})
cd9f11 552 const expressionList = ref([])
L 553 const fileList = ref([])
554 const operatorList = ['+', '-']
d3ee81 555 const replaceModelOnly = ref(false)
cd9f11 556 const queryParams = reactive({
L 557   pageNo: 1,
558   pageSize: 10,
559   pointNo: undefined,
560   pointName: undefined,
561 })
562 const dataForm = ref({
2caade 563   id: undefined,
e1ff2d 564   itemtypename: 'NormalItem',
cd9f11 565   mmPredictItem: {
2caade 566     id: undefined,
L 567     itemno: undefined,
568     itemname: undefined,
569     caltypeid: undefined,
570     itemtypeid: undefined,
571     predictlength: undefined,
d3ee81 572     granularity: 60,
2caade 573     status: undefined,
L 574     isfuse: undefined,
575     predictphase: undefined,
d3ee81 576     workchecked: 0,
2caade 577     unittransfactor: undefined,
160af9 578     saveindex: undefined,
cd9f11 579   },
L 580   dmModuleItem: {
2caade 581     id: undefined,
L 582     moduleid: undefined,
583     itemid: undefined,
d3ee81 584     itemorder: 1,
2caade 585     status: undefined,
L 586     categoryid: undefined
cd9f11 587   },
d8e4be 588   mmItemOutputList: [],
cd9f11 589   mmPredictModel: {
2caade 590     id: undefined,
L 591     modelno: undefined,
592     modelname: undefined,
593     itemid: undefined,
594     arithid: undefined,
595     trainsamplength: undefined,
596     predictsamplength: undefined,
597     isonlinetrain: undefined,
598     modelpath: undefined,
599     isnormal: undefined,
600     normalmax: undefined,
601     normalmin: undefined,
602     status: undefined,
603     classname: undefined,
604     methodname: undefined,
605     modelparamstructure: undefined,
606     resultstrid: undefined,
be4298 607     settingmap: undefined,
D 608     mpkprojectid: undefined
cd9f11 609   },
L 610   mmPredictMergeItem: {
2caade 611     id: undefined,
L 612     itemid: undefined,
613     expression: undefined,
614     num: undefined
cd9f11 615   },
L 616   mmModelArithSettingsList: [],
36885d 617   mmModelParamList: [],
22bcd6 618   pointId: undefined,
D 619   iscumulant: 0,
620   cumuldivisor: undefined,
621   cumulpoint: undefined,
7462da 622 })
L 623 const formRules = reactive({
d3ee81 624   'mmPredictItem.itemname': [{required: true, message: '预测项名不能为空', trigger: 'blur'}],
625   'mmPredictItem.itemtypeid': [{required: true, message: '类型不能为空', trigger: 'blur'}],
e1ff2d 626   'mmPredictItem.granularity': [{
d3ee81 627     required: true,
628     message: '粒度不能为空',
629     trigger: 'blur'
630   }],
e1ff2d 631   'mmPredictItem.workchecked': [{
d3ee81 632     required: true,
633     message: '是否检查不能为空',
634     trigger: 'blur'
635   }],
e1ff2d 636   'mmPredictItem.status': [{required: true, message: '是否启用不能为空', trigger: 'blur'}],
22bcd6 637   'iscumulant': [{required: true, message: '是否累计不能为空', trigger: 'blur'}],
e1ff2d 638   'dmModuleItem.moduleid': [{required: true, message: '管网不能为空', trigger: 'blur'}],
639   'dmModuleItem.itemorder': [{required: true, message: '排序不能为空', trigger: 'blur'}],
fcd59a 640   'mmPredictItem.predictlength': [{required: true, message: '预测长度不能为空', trigger: 'blur'}],
22bece 641   'mmPredictModel.mpkprojectid': [{required: true, message: '关联项目不能为空', trigger: 'blur'}],
d3ee81 642
7462da 643 })
L 644 const formRef = ref() // 表单 Ref
645
646 /** 打开弹窗 */
2caade 647 const open = async (type: string, id?: number, itemtypename?: string) => {
e1ff2d 648   formType.value = type
7462da 649   dialogVisible.value = true
L 650   dialogTitle.value = t('action.' + type)
2caade 651   dataForm.value.itemtypename = itemtypename || 'NormalItem'
e1ff2d 652   resetForm()
2caade 653   resetFields(dataForm.value)
83f63a 654   setDefaultFields()
e1ff2d 655
656   // 加载参数列表
5c475d 657   modelparamListMap.value = await ScheduleModelApi.getModelParamList(id)
e1ff2d 658
659   // 获取预测项类型列表
660   itemTypeList.value = await MmItemType.getItemTypeList()
661   itemTypeList.value.forEach(function (value) {
662     itemTypeMap[value.id] = value.itemtypename
663   })
664   if (!dataForm.value.id) {
665     dataForm.value.mmPredictItem.itemtypeid = itemTypeList.value[0].id
666   }
667
668   // 获取管网列表
669   moduleList.value = await DmModule.getModuleList()
670
be4298 671   // 获取mpk项目列表
D 672   mpkProjectList.value = await ProjectApi.list()
7b1ce6 673
e1ff2d 674   // 获取数据点列表
160af9 675   pointNoList.value = await DaPoint.getPointSimpleList(queryParams)
e1ff2d 676   if (pointNoList.value.length > 0) {
d8e4be 677     pointList.value = []
e1ff2d 678     pointNoList.value.forEach(function (value) {
679       pointList.value.push(value)
d8e4be 680       pointMap[value.id] = value.pointName
e1ff2d 681     })
682   }
683
7b1ce6 684   // 修改时,设置数据
685   if (id) {
686     formLoading.value = true
687     try {
688       getInfo(id)
689     } finally {
d8e4be 690       formLoading.value = false
7b1ce6 691     }
692   }
e1ff2d 693   formLoading.value = false
7462da 694 }
L 695 defineExpose({open}) // 提供 open 方法,用于打开弹窗
696
697 /** 提交表单 */
698 const emit = defineEmits(['success']) // 定义 success 事件,用于操作成功后的回调
699 const submitForm = async () => {
700   // 校验表单
701   if (!formRef) return
702   const valid = await formRef.value.validate()
703   if (!valid) return
22bcd6 704   //校验累计配置
D 705   if (dataForm.value.iscumulant === 1) {
706     if (dataForm.value.cumuldivisor == undefined) {
707       message.error("累计除数不为空")
708       return
709     }
710   }
d8e4be 711   //校验模型输出
fcd59a 712   if (dataForm.value.itemtypename === 'NormalItem') {
5c475d 713     if (dataForm.value.mmItemOutputList == undefined || dataForm.value.mmItemOutputList.length <= 0) {
D 714       message.error("模型输出不为空")
715       return
716     }
717
718     dataForm.value.mmItemOutputList.forEach(e => {
22bcd6 719       if (e.resultstr == undefined || e.resultstr === '' || e.resultType == undefined || e.resultType === ''
D 720         || (e.resultType === 2 && (e.resultIndex == undefined || e.resultIndex === ''))
721         || (e.iscumulant === 1 && e.cumuldivisor == undefined)
722       ) {
82c481 723         message.error("输出数据异常")
D 724         throw new Error('输出数据异常');
fcd59a 725       }
D 726     })
82c481 727
D 728     //校验模型输入
729     dataForm.value.mmModelParamList.forEach(e => {
730       if (e.modelparamid == undefined || e.modelparamid == '') {
731         message.error("输入数据异常")
732         throw new Error('输入数据异常');
733       }
734       // ind_ascii类型输出的序号必须是1,且所在端口序号最大为1(一个ind_ascii类型输入独占一个端口)
735       if (e.modelparamtype === 'IND_ASCII') {
736         if (e.modelparamorder != 1 || dataForm.value.mmModelParamList.filter(p => p.modelparamportorder === e.modelparamportorder).length != 1) {
737           message.error("输入数据异常:IND_ASCII类型输入独占一个端口")
738           throw new Error('输入数据异常:IND_ASCII类型输入独占一个端口');
739         }
740       }
741     })
fcd59a 742   }
D 743   if (dataForm.value.itemtypename === 'MergeItem') {
744     if (expressionList.value == undefined || expressionList.value.length <= 1) {
745       message.error("表达式长度低于2")
746       return
747     }
748
749     let flag = false
750     expressionList.value.forEach((e,index) => {
3affb8 751       if (e.point == undefined || e.point === '' || ((e.operator == undefined || e.operator === '') && index != expressionList.value.length - 1)) {
fcd59a 752         message.error("表达式数据异常")
5c475d 753         flag = true
D 754         return
755       }
756     })
757     if (flag) return
d8e4be 758   }
D 759
7462da 760   // 提交请求
L 761   formLoading.value = true
762   try {
cd9f11 763     const data = dataForm.value as unknown as MmPredictItem.MmPredictItemVO
b39d0b 764     if (expressionList.value && expressionList.value.length > 0) {
L 765       let expression = ''
766       for (let i = 0; i < expressionList.value.length; i++) {
767         let value = expressionList.value[i]
768         expression = expression + value.point + (i === (expressionList.value.length - 1) ? '' : value.operator)
769       }
770       dataForm.value.mmPredictMergeItem.expression = expression
771     } else {
772       dataForm.value.mmPredictMergeItem.expression = ''
773     }
774     if (dataForm.value.mmModelArithSettingsList) {
775       for (let item of dataForm.value.mmModelArithSettingsList) {
9b24e4 776         if (item.key === 'predictLength') {
b39d0b 777           dataForm.value.mmPredictItem.predictlength = item.value
L 778         }
779       }
780     }
7462da 781     if (formType.value === 'create') {
L 782       await MmPredictItem.createMmPredictItem(data)
783       message.success(t('common.createSuccess'))
784     } else {
785       await MmPredictItem.updateMmPredictItem(data)
786       message.success(t('common.updateSuccess'))
787     }
788     dialogVisible.value = false
789     // 发送操作成功的事件
790     emit('success')
791   } finally {
792     formLoading.value = false
793   }
794 }
83f63a 795
2caade 796 const resetFields = (obj) => {
L 797   for (let key in obj) {
798     if (key === 'itemtypename') {
799       continue
800     }
801     if (obj[key] instanceof Array) {
802       obj[key] = []
803     } else if (obj[key] instanceof Object) {
804       resetFields(obj[key])
805     } else {
806       obj[key] = ''
807     }
808   }
809 }
810
811 const getInfo = async (id) => {
812   dataForm.value = await MmPredictItem.getMmPredictItem(id)
7b1ce6 813   dataForm.value.itemtypename = itemTypeMap[dataForm.value.mmPredictItem.itemtypeid]
83f63a 814   expressionList.value = []
2caade 815   if (dataForm.value.mmPredictMergeItem && dataForm.value.mmPredictMergeItem.expression) {
L 816     let expression = dataForm.value.mmPredictMergeItem.expression
83f63a 817     do {
L 818       let indexPlus = expression.indexOf('+')
819       let indexSub = expression.indexOf('-')
820       if (indexPlus !== -1 || indexSub !== -1) {
821         let endIndex = (indexSub == -1 || (indexPlus < indexSub && indexPlus !== -1)) ? indexPlus : indexSub
822         expressionList.value.push({
823           point: expression.substring(0, endIndex),
5c475d 824           operator: expression.substring(endIndex, endIndex + 1)
83f63a 825         })
L 826         expression = expression.substring(endIndex + 1)
827       } else {
828         expressionList.value.push({
829           point: expression,
830           operator: ''
831         })
832         expression = ''
833       }
834     } while (expression && expression.length > 0)
835   }
836 }
837
838 function setReplaceModelOnly(value) {
cd9f11 839   replaceModelOnly.value = value
L 840 }
83f63a 841
L 842 function beforeUpload(file) {
cd9f11 843   let fileName = file.name
L 844   let first = fileName.lastIndexOf('.')
845   let nameLength = fileName.length
846   let fileSuffix = fileName.substring(first + 1, nameLength)
847   if (fileSuffix !== 'miail') {
848     message.error('只能上传miail类型文件')
849     return
850   }
851 }
83f63a 852
L 853 function uploadModelSuccess(response, file, fileList) {
cd9f11 854   if (response.code === 0) {
L 855     message.success(t('上传成功'))
856     dataForm.value.mmModelArithSettingsList = []
d3ee81 857     if (!replaceModelOnly.value) {
cd9f11 858       dataForm.value.mmModelParamList = []
L 859     }
860     dataForm.value.mmPredictModel.modelpath = ''
861     dataForm.value.mmPredictModel.modelparamstructure = ''
862     if (response.data.loadFieldSetList && response.data.loadFieldSetList[0].propertyList) {
83f63a 863       response.data.loadFieldSetList[0].propertyList.forEach(function (value) {
5c475d 864         //匹配  data数字
D 865         if (!/^data\d+$/.test(value.key)) {
cd9f11 866           dataForm.value.mmModelArithSettingsList.push({
L 867             key: value.key,
868             name: value.name,
869             valuetype: value.valueType,
870             value: value.value
871           })
872         }
2caade 873       })
cd9f11 874     }
d3ee81 875     dataForm.value.mmPredictModel.modelname = response.data.originalFilename
cd9f11 876     dataForm.value.mmPredictModel.classname = response.data.className
L 877     dataForm.value.mmPredictModel.methodname = response.data.methodName
878     if (response.data.paramPathList) {
879       dataForm.value.mmPredictModel.modelpath = response.data.paramPathList[0]
880     }
881     if (response.data.paramsArray) {
882       dataForm.value.mmPredictModel.modelparamstructure = response.data.paramsArray.join(',')
883     }
d3ee81 884     if (response.data.paramsCount && !replaceModelOnly.value) {
cd9f11 885       for (let i = 0; i < response.data.paramsCount; i++) {
L 886         dataForm.value.mmModelParamList.push({
887           modelparamportorder: (i + 1),
888           modelparamorder: (i + 1),
889           modelparamtype: '',
890           modelparamid: '',
891           modelparamname: '',
892           datalength: 0
893         })
894       }
895     }
896     if (response.data.settingConfigMap && response.data.settingConfigMap.settingMap) {
897       dataForm.value.mmPredictModel.settingmap = JSON.stringify(response.data.settingConfigMap.settingMap)
898     }
899   } else {
900     message.error('上传失败!' + response.msg)
901     return
902   }
903   fileList = []
904 }
83f63a 905
L 906 function uploadModelError(file, err, fileList) {
cd9f11 907 }
83f63a 908
L 909 function changeItemtype(value) {
cd9f11 910   dataForm.value.itemtypename = itemTypeMap[value]
L 911 }
83f63a 912
61c379 913 function changeModelparamtype(row) {
cd9f11 914   row.modelparamid = ''
L 915 }
83f63a 916
61c379 917 function changeOutputPoint(value, row) {
d8e4be 918   row.tagname = pointMap[value]
cd9f11 919 }
83f63a 920
L 921 function deleteExpressionRow(index, rows) {
cd9f11 922   rows.splice(index, 1)
L 923 }
83f63a 924
L 925 function addExpressionRow(index, rows) {
cd9f11 926   let row = JSON.parse(JSON.stringify(rows[index]))
L 927   rows.splice(index, 0, row)
928 }
83f63a 929
22bece 930 function deleteRow(index, row, rows) {
D 931   if (!rows || rows.length === 1 || rows.filter(e => e.modelparamportorder === row.modelparamportorder).length === 1) {
932     message.error('不可删除!')
cd9f11 933     return
L 934   }
935   rows.splice(index, 1)
936   orderRow(rows)
937 }
83f63a 938
L 939 function addRow(index: string, rows) {
cd9f11 940   let row = JSON.parse(JSON.stringify(rows[index]))
L 941   rows.splice(index, 0, row)
942   orderRow(rows)
d8e4be 943 }
61c379 944
fcd59a 945 function addItemOutput() {
D 946   if (!dataForm.value.mmItemOutputList) {
947     dataForm.value.mmItemOutputList = []
948   }
949   dataForm.value.mmItemOutputList.push({})
950   orderItemOutput(dataForm.value.mmItemOutputList)
d8e4be 951 }
61c379 952
d8e4be 953 function deleteItemOutput(index: string, rows) {
D 954   if (!rows || rows.length === 1) {
955     message.error('不能全部删除!')
956     return
957   }
958   rows.splice(index, 1)
959   orderItemOutput(rows)
960 }
61c379 961
d8e4be 962 function orderItemOutput(list) {
D 963   list.sort((a, b) => a.outputorder - b.outputorder);
964   let outputorder = 1
965   list.forEach(function (value) {
966     value.outputorder = outputorder
967     outputorder++
968   })
969 }
970
971 function resultTypeChange(value, row) {
972   if (value === 1) {
973     row.resultIndex = undefined
61c379 974   } else if (value === 2) {
d8e4be 975     row.resultIndex = 0
D 976   }
cd9f11 977 }
22bcd6 978 function iscumulantChange(row) {
D 979   row.cumuldivisor = undefined
980   row.cumulpoint = undefined
981 }
7462da 982
83f63a 983 function orderRow(rows) {
cd9f11 984   let modelparamorder = 0
L 985   let modelparamportorder = 0
986   rows.forEach(function (value) {
987     if (value.modelparamportorder !== modelparamportorder) {
988       modelparamportorder = value.modelparamportorder
989       modelparamorder = 1
990     }
991     value.modelparamorder = modelparamorder
992     modelparamorder++
993   })
994 }
83f63a 995
2caade 996 const setDefaultFields = () => {
83f63a 997   dataForm.value.mmPredictItem.workchecked = 0
L 998   dataForm.value.mmPredictItem.status = 1
999   dataForm.value.mmPredictItem.isfuse = 0
1000   dataForm.value.mmPredictItem.predictphase = 0
1001   dataForm.value.mmPredictItem.unittransfactor = 1
1002   dataForm.value.mmPredictItem.saveindex = '2'
1003   dataForm.value.dmModuleItem.status = 1
1004   dataForm.value.mmPredictModel.trainsamplength = 60
1005   dataForm.value.mmPredictModel.isonlinetrain = 0
1006   dataForm.value.mmPredictModel.status = 1
d8e4be 1007   dataForm.value.mmItemOutputList = []
83f63a 1008   expressionList.value = [{
L 1009     point: '',
1010     operator: ''
1011   }]
1012   fileList.value = []
1013 }
1014
f5e3a1 1015 const clearExpressionList = (value) => {
fcd59a 1016   expressionList.value = [{
D 1017     point: '',
1018     operator: ''
1019   }]
1020 }
1021
7462da 1022 /** 重置表单 */
d3ee81 1023 const resetForm = () => {
cd9f11 1024   dataForm.value = {
L 1025     mmModelArithSettingsList: [],
1026     mmModelParamList: [],
1027     id: '',
e1ff2d 1028     itemtypename: 'NormalItem',
cd9f11 1029     mmPredictItem: {
L 1030       id: '',
1031       itemno: '',
1032       itemname: '',
1033       caltypeid: '',
1034       itemtypeid: '',
1035       predictlength: '',
d3ee81 1036       granularity: 60,
cd9f11 1037       status: '',
L 1038       isfuse: '',
1039       predictphase: '',
d3ee81 1040       workchecked: 0,
cd9f11 1041       unittransfactor: '',
160af9 1042       saveindex: '',
cd9f11 1043     },
L 1044     dmModuleItem: {
1045       id: '',
1046       moduleid: '',
1047       itemid: '',
d3ee81 1048       itemorder: 1,
cd9f11 1049       status: 1,
L 1050       categoryid: ''
1051     },
d8e4be 1052     mmItemOutputList: [],
cd9f11 1053     mmPredictModel: {
L 1054       id: '',
1055       modelno: '',
1056       modelname: '',
1057       itemid: '',
1058       arithid: '',
1059       trainsamplength: '',
1060       predictsamplength: '',
1061       isonlinetrain: '',
1062       modelpath: '',
1063       isnormal: '',
1064       normalmax: '',
1065       normalmin: '',
1066       status: 1,
1067       classname: '',
1068       methodname: '',
1069       modelparamstructure: '',
1070       resultstrid: '',
1071       settingmap: ''
1072     },
1073     mmPredictMergeItem: {
1074       id: '',
1075       itemid: '',
1076       expression: '',
1077       num: ''
22bcd6 1078     },
D 1079     iscumulant: 0,
1080     cumuldivisor: undefined,
1081     cumulpoint: '',
7462da 1082   }
L 1083   formRef.value?.resetFields()
d3ee81 1084 }
cd9f11 1085
L 1086 onMounted(() => {
1087   init()
1088 })
1089
83f63a 1090 function init() {
cd9f11 1091 }
7462da 1092 </script>