houzhongjian
3 天以前 d5207d8eaff6188ae0d79c07de17d0b8dbaed65a
提交 | 用户 | 时间
2f0aa4 1 <template>
6badb7 2   <Dialog v-model="dialogVisible" :title="dialogTitle" width="60%">
2f0aa4 3     <el-form
4       ref="formRef"
5       v-loading="formLoading"
6       :model="formData"
7       :rules="formRules"
8       label-width="120px"
9     >
22bece 10       <el-divider content-position="left">基本信息</el-divider>
2f0aa4 11       <el-row>
12         <el-col :span="12">
13           <el-form-item label="模型编号" prop="modelCode">
14             <el-input v-model="formData.modelCode" placeholder="请输入模型编号" />
15           </el-form-item>
16         </el-col>
17       </el-row>
18       <el-row>
19         <el-col :span="12">
20           <el-form-item label="模型类型" prop="modelType">
6badb7 21             <el-select v-model="formData.modelType" placeholder="请选择">
22               <el-option
8ea580 23                 v-for="dict in getStrDictOptions(DICT_TYPE.SCHE_MODEL_TYPE)"
6badb7 24                 :key="dict.value"
25                 :label="dict.label"
26                 :value="dict.value"
27               />
28             </el-select>
2f0aa4 29           </el-form-item>
30         </el-col>
31         <el-col :span="12">
32           <el-form-item label="调用方式" prop="invocation">
6badb7 33             <el-select v-model="formData.invocation" placeholder="请选择">
34               <el-option
8ea580 35                 v-for="dict in getStrDictOptions(DICT_TYPE.SCHE_MODEL_INVOCATION)"
6badb7 36                 :key="dict.value"
37                 :label="dict.label"
38                 :value="dict.value"
39               />
40             </el-select>
2f0aa4 41           </el-form-item>
42         </el-col>
43       </el-row>
22bece 44       <el-divider content-position="left">模型信息</el-divider>
D 45       <div style="width: 120px;text-align: right;margin-bottom: 8px">
e4de9b 46         <el-popover placement="right" :width="300" trigger="click" ref="modelPopover" @before-enter="model = undefined">
22bece 47           <template #reference>
D 48             <span style="color: #409eff;cursor: pointer">关联模型信息</span>
49           </template>
50           <template #default>
51             <div style="display:flex;flex-direction: row;align-items: center;">
52               <el-cascader style="width: 100%" v-model="model" placeholder="选择模型" :teleported="false" @change="changeModel" :options="scheduleModelList"/>
53             </div>
54           </template>
55         </el-popover>
56       </div>
2f0aa4 57       <el-row>
22bece 58         <el-col :span="12">
D 59           <el-form-item label="模型名称" prop="modelName">
091c7e 60             <el-input v-model="formData.modelName" placeholder="请输入模型名称"/>
22bece 61           </el-form-item>
D 62         </el-col>
63         <el-col :span="12">
2f0aa4 64           <el-form-item label="类名" prop="className">
22bece 65             <el-input v-model="formData.className" placeholder="请输入类名" :disabled="true" />
2f0aa4 66           </el-form-item>
67         </el-col>
68       </el-row>
69       <el-row>
70         <el-col :span="12">
71           <el-form-item label="方法名" prop="methodName">
22bece 72             <el-input v-model="formData.methodName" placeholder="请输入方法名" :disabled="true" />
2f0aa4 73           </el-form-item>
74         </el-col>
75         <el-col :span="12">
76           <el-form-item label="参数数量" prop="portLength">
22bece 77             <el-input-number v-model="formData.portLength" :min="0" controls-position="right" :disabled="true" />
2f0aa4 78           </el-form-item>
79         </el-col>
80       </el-row>
81       <el-row>
82         <el-col :span="24">
83           <el-form-item label="参数构造" prop="paramStructure">
22bece 84             <el-input v-model="formData.paramStructure" placeholder="请输入参数构造" :disabled="true" />
2f0aa4 85           </el-form-item>
86         </el-col>
87       </el-row>
88       <el-row>
89         <el-col :span="24">
90           <el-form-item label="模型路径" prop="modelPath">
22bece 91             <el-input v-model="formData.modelPath" placeholder="模型路径" :disabled="true" />
2f0aa4 92           </el-form-item>
93         </el-col>
94       </el-row>
95       <el-divider content-position="left">输入参数</el-divider>
96       <el-table
97         :data="formData.paramList"
98         border
99         style="width: 100%; margin-top: 5px;">
100         <el-table-column
101           prop=""
102           label="端口"
103           width="100"
104           align="center">
6badb7 105           <template #default="scope">
22bece 106             <el-input v-model="scope.row.modelparamportorder" maxlength="5" clearable :disabled="true"
6badb7 107                       style="width:100%; hight:100%"/>
2f0aa4 108           </template>
109         </el-table-column>
110         <el-table-column
111           prop=""
112           label="序号"
113           width="100"
114           align="center">
6badb7 115           <template #default="scope">
22bece 116             <el-input v-model="scope.row.modelparamorder" maxlength="5" clearable
6badb7 117                       style="width:100%;hight:100%"/>
2f0aa4 118           </template>
119         </el-table-column>
120         <el-table-column
121           prop=""
122           label="类型"
123           width="150"
124           align="center">
6badb7 125           <template #default="scope">
22bece 126             <el-select v-model="scope.row.modelparamtype" placeholder="请选择" @change="changeModelparamtype(scope.row)">
2f0aa4 127               <el-option
8ea580 128                 v-for="dict in getStrDictOptions(DICT_TYPE.MODEL_PARAM_TYPE)"
2f0aa4 129                 :key="dict.value"
130                 :label="dict.label"
131                 :value="dict.value"
132               />
133             </el-select>
134           </template>
135         </el-table-column>
8ea580 136         <el-table-column
2f0aa4 137           prop=""
138           label="参数名称"
139           align="center">
6badb7 140           <template #default="scope">
22bece 141             <el-select v-if="scope.row.modelparamtype === 'NormalItem'"
D 142               v-model="scope.row.modelparamid"
143               placeholder="请选择"
144               filterable
145               style="width: 100%">
146               <el-option-group
147                 v-for="group in modelparamListMap['NormalItem']"
148                 :key="group.value"
149                 :label="group.label"
150               >
151                 <el-option
152                   v-for="item in group.children"
153                   :key="item.value"
154                   :label="item.label"
155                   :value="item.value"
156                 />
157               </el-option-group>
158             </el-select>
159             <el-select v-else
2f0aa4 160               v-model="scope.row.modelparamid"
161               filterable
162               placeholder="请选择">
163               <el-option
d3ee81 164                 v-for="(item, index) in modelparamListMap[scope.row.modelparamtype]"
2f0aa4 165                 :key="index"
166                 :label="item.name"
d3ee81 167                 :value="item.id"/>
2f0aa4 168             </el-select>
169           </template>
8ea580 170         </el-table-column>
2f0aa4 171         <el-table-column
172           prop=""
173           label="参数长度"
d3ee81 174           width="160"
2f0aa4 175           align="center">
6badb7 176           <template #default="scope">
d3ee81 177             <el-input-number v-model="scope.row.datalength" :min="0" clearable controls-position="right"
178                              style="width:100%;hight:100%"/>
2f0aa4 179           </template>
180         </el-table-column>
181         <el-table-column
182           prop=""
183           label="操作"
184           width="100"
185           align="center">
6badb7 186           <template #default="scope">
2f0aa4 187             <el-button
6badb7 188               link
189               @click.prevent="addRow(scope.$index, formData.paramList)"
190               type="primary"
2f0aa4 191               size="small">
192               添加
193             </el-button>
194             <el-button
6badb7 195               link
22bece 196               @click.prevent="deleteRow(scope.$index, scope.row, formData.paramList)"
6badb7 197               type="primary"
2f0aa4 198               size="small">
199               删除
200             </el-button>
201           </template>
202         </el-table-column>
203       </el-table>
204
205       <el-divider content-position="left">设置参数</el-divider>
206       <el-table
6badb7 207         :data="formData.settingList"
2f0aa4 208         border
209         style="width: 100%; margin-top: 5px;">
210         <el-table-column
211           prop=""
212           label="键"
213           align="center">
6badb7 214           <template #default="scope">
22bece 215             <el-input v-model="scope.row.key" maxlength="20" clearable :disabled="true"
6badb7 216                       style="width:100%;hight:100%"/>
2f0aa4 217           </template>
218         </el-table-column>
219         <el-table-column
220           prop=""
221           label="名称"
222           align="center">
6badb7 223           <template #default="scope">
22bece 224             <el-input v-model="scope.row.name" maxlength="20" clearable :disabled="true"
6badb7 225                       style="width:100%;hight:100%"/>
2f0aa4 226           </template>
227         </el-table-column>
228         <el-table-column
229           prop=""
230           label="类型"
231           align="center">
6badb7 232           <template #default="scope">
22bece 233             <el-select v-model="scope.row.valuetype" placeholder="请选择" :disabled="true">
d3ee81 234               <el-option
235                 v-for="dict in getStrDictOptions(DICT_TYPE.MODEL_METHOD_SETTING_VALUE_TYPE)"
236                 :key="dict.value"
237                 :label="dict.label"
238                 :value="dict.value"
239               />
240             </el-select>
2f0aa4 241           </template>
242         </el-table-column>
243         <el-table-column
244           prop=""
245           label="值"
246           align="center">
6badb7 247           <template #default="scope">
22bece 248             <el-input v-model="scope.row.value" maxlength="256" clearable  :disabled="scope.row.key === 'pyFile'"
6badb7 249                       style="width:100%;hight:100%"/>
2f0aa4 250           </template>
251         </el-table-column>
22bece 252 <!--        <el-table-column-->
D 253 <!--          prop=""-->
254 <!--          label="操作"-->
255 <!--          width="100"-->
256 <!--          align="center">-->
257 <!--          <template #default="scope">-->
258 <!--            <el-button-->
259 <!--              @click.prevent="addRow(scope.$index, formData.settingList)"-->
260 <!--              link-->
261 <!--              type="primary"-->
262 <!--              size="small">-->
263 <!--              添加-->
264 <!--            </el-button>-->
265 <!--            <el-button-->
266 <!--              @click.prevent="deleteRow(scope.$index, formData.settingList)"-->
267 <!--              link-->
268 <!--              type="primary"-->
269 <!--              size="small">-->
270 <!--              删除-->
271 <!--            </el-button>-->
272 <!--          </template>-->
273 <!--        </el-table-column>-->
2f0aa4 274       </el-table>
23c8b8 275       <el-divider content-position="left">模型下发配置</el-divider>
D 276       <el-row :gutter="20">
277         <el-col :span="4">
278           <el-button type="primary" size="small" @click="addRowOut()" >新增</el-button>
279         </el-col>
280       </el-row>
281       <el-table
282         :data="formData.modelOut"
283         border
284         style="width: 100%; margin-top: 5px;">
fa3d25 285         <el-table-column prop="resultKey" label="输出key" align="center" min-width="100">
23c8b8 286           <template #default="scope">
D 287             <el-input size="mini" v-model="scope.row.resultKey" style="width:100%;height:100%"/>
288           </template>
289         </el-table-column>
fa3d25 290         <el-table-column prop="resultType" label="数据类型" align="center" min-width="150">
23c8b8 291           <template #default="scope">
fa3d25 292             <el-select v-model="scope.row.resultType" placeholder="请选择">
D 293               <el-option
294                 v-for="dict in getStrDictOptions(DICT_TYPE.RESULT_TYPE)"
295                 :key="dict.value"
296                 :label="dict.label"
297                 :value="dict.value"
298               />
299             </el-select>
23c8b8 300           </template>
D 301         </el-table-column>
302         <el-table-column prop="resultPort" label="角标1" align="center" min-width="100">
303           <template #default="scope">
304             <el-input-number :min="0" clearable controls-position="right" size="mini" v-model="scope.row.resultPort" style="width:100%;height:100%"/>
305           </template>
306         </el-table-column>
307         <el-table-column prop="resultIndex" label="角标2" align="center" min-width="100">
308           <template #default="scope">
309             <el-input-number :min="0" clearable controls-position="right" size="mini" v-model="scope.row.resultIndex" style="width:100%;height:100%"/>
310           </template>
311         </el-table-column>
312         <el-table-column prop="isWrite" label="是否下发" align="center" min-width="100">
313           <template #default="scope">
314             <el-switch size="small" v-model="scope.row.isWrite" :active-value="1"
315                        :inactive-value="0"/>
316           </template>
317         </el-table-column>
318         <el-table-column
319           prop=""
320           label="测点名称"
321           align="center" min-width="200">
322           <template #default="scope">
323             <el-select v-model="scope.row.pointNo"
324                        filterable
325                        placeholder="请选择">
326               <el-option
327                 v-for="(item, index) in modelparamListMap['DATAPOINT']"
328                 :key="index"
329                 :label="item.name"
330                 :value="item.itemNo"/>
331             </el-select>
332           </template>
333         </el-table-column>
334         <el-table-column prop="disturbancePointNo’" label="无扰切换点位" align="center" min-width="200">
335           <template #default="scope">
336             <el-select v-model="scope.row.disturbancePointNo"
4d3aa7 337                        clearable
23c8b8 338                        filterable
D 339                        placeholder="请选择">
340               <el-option
341                 v-for="(item, index) in modelparamListMap['DATAPOINT']"
342                 :key="index"
343                 :label="item.name"
344                 :value="item.itemNo"/>
345             </el-select>
346           </template>
347         </el-table-column>
348         <el-table-column label="操作" fixed="right" header-align="center" align="center" width="100">
349           <template #default="scope">
350             <el-button
351               @click="deleteModelOutRow(scope.$index)"
352               key="danger"
353               type="danger"
354               link
355             >删除
356             </el-button>
357           </template>
358         </el-table-column>
359       </el-table>
2f0aa4 360     </el-form>
361     <template #footer>
362       <el-button :disabled="formLoading" type="primary" @click="submitForm">确 定</el-button>
363       <el-button @click="dialogVisible = false">取 消</el-button>
364     </template>
365   </Dialog>
366 </template>
367 <script lang="ts" setup>
8ea580 368   import { DICT_TYPE, getStrDictOptions } from '@/utils/dict'
2f0aa4 369   import * as ScheduleModelApi from '@/api/model/sche/model'
370   import { CommonStatusEnum } from '@/utils/constants'
22bece 371   import * as MpkApi from "@/api/model/mpk/mpk";
23c8b8 372   import {generateUUID} from "@/utils";
2f0aa4 373
374   defineOptions({ name: 'ScheduleModelForm' })
375
376   const { t } = useI18n() // 国际化
377   const message = useMessage() // 消息弹窗
378   const dialogVisible = ref(false) // 弹窗的是否展示
379   const dialogTitle = ref('') // 弹窗的标题
380   const formLoading = ref(false) // 表单的加载中:1)修改时的数据加载;2)提交的按钮禁用
381   const formType = ref('') // 表单的类型:create - 新增;update - 修改
382   const formData = ref({
383     id: undefined,
384     modelCode: undefined,
385     modelName: undefined,
386     modelType: undefined,
387     className: undefined,
388     methodName: undefined,
389     portLength: undefined,
390     paramStructure: undefined,
391     modelPath: undefined,
392     resultStrId: undefined,
393     invocation: undefined,
8ea580 394     status: CommonStatusEnum.ENABLE,
22bece 395     paramList: [],
23c8b8 396     settingList: [],
D 397     modelOut: []
2f0aa4 398   })
399   const formRules = reactive({
400     modelCode: [{ required: true, message: '模型编号不能为空', trigger: 'blur' }],
401     modelName: [{ required: true, message: '模型名称不能为空', trigger: 'blur' }],
402     modelType: [{ required: true, message: '模型类型不能为空', trigger: 'blur' }]
403   })
404   const formRef = ref() // 表单 Ref
6badb7 405   const modelparamListMap = ref({})
22bece 406   // 调度模型列表
D 407   const scheduleModelList = ref([])
408   const model = ref()
409   const modelPopover = ref()
2f0aa4 410
411   const addRow = function (index, rows) {
412     let row = JSON.parse(JSON.stringify(rows[index]))
413     rows.splice(index, 0, row)
414     this.orderRow(rows)
415   }
416
22bece 417   const deleteRow = function (index, row, rows) {
D 418     if (!rows || rows.length === 1 || rows.filter(e => e.modelparamportorder === row.modelparamportorder).length === 1) {
419       message.error('不可删除!')
2f0aa4 420       return
421     }
422     rows.splice(index, 1)
423     this.orderRow(rows)
424   }
425
426   const orderRow = function (rows) {
427     let modelparamorder = 0
428     let modelparamportorder = 0
429     rows.forEach(function (value) {
430       if (value.modelparamportorder !== modelparamportorder) {
431         modelparamportorder = value.modelparamportorder
432         modelparamorder = 1
433       }
434       value.modelparamorder = modelparamorder
435       modelparamorder++
436     })
437   }
438
439   /** 打开弹窗 */
440   const open = async (type: string, id?: number) => {
441     dialogVisible.value = true
442     dialogTitle.value = t('action.' + type)
443     formType.value = type
444     resetForm()
445     // 修改时,设置数据
446     if (id) {
447       formLoading.value = true
448       try {
449         formData.value = await ScheduleModelApi.getScheduleModel(id)
450       } finally {
451         formLoading.value = false
452       }
453     }
d3ee81 454     // 加载参数列表
455     modelparamListMap.value = await ScheduleModelApi.getModelParamList()
22bece 456     // 加载调度模型列表
D 457     getScheduleModelList()
2f0aa4 458   }
459   defineExpose({ open }) // 提供 open 方法,用于打开弹窗
460
461   /** 提交表单 */
462   const emit = defineEmits(['success']) // 定义 success 事件,用于操作成功后的回调
463   const submitForm = async () => {
464     // 校验表单
465     if (!formRef) return
466     const valid = await formRef.value.validate()
467     if (!valid) return
468     // 提交请求
469     formLoading.value = true
470     try {
471       const data = formData.value as unknown as ScheduleModelApi.ScheduleModelVO
472       if (formType.value === 'create') {
473         await ScheduleModelApi.createScheduleModel(data)
474         message.success(t('common.createSuccess'))
475       } else {
476         await ScheduleModelApi.updateScheduleModel(data)
477         message.success(t('common.updateSuccess'))
478       }
479       dialogVisible.value = false
480       // 发送操作成功的事件
481       emit('success')
482     } finally {
483       formLoading.value = false
484     }
485   }
486
487   /** 重置表单 */
488   const resetForm = () => {
489     formData.value = {
490       id: undefined,
491       modelCode: undefined,
492       modelName: undefined,
493       modelType: undefined,
494       className: undefined,
495       methodName: undefined,
496       portLength: undefined,
497       paramStructure: undefined,
498       modelPath: undefined,
499       resultStrId: undefined,
500       invocation: undefined,
6badb7 501       status: CommonStatusEnum.ENABLE,
22bece 502       paramList: [],
23c8b8 503       settingList: [],
D 504       modelOut: []
2f0aa4 505     }
506     formRef.value?.resetFields()
507   }
22bece 508
D 509   const getScheduleModelList = async () => {
510     let list = await MpkApi.list({pyType: 'schedul'})
511     if (list && list.length > 0) {
512       scheduleModelList.value = list.map(e => {
513         return {
514           label: e.pyChineseName,
515           value: e,
516           children: e.modelMethods.map(m => {
517             return {
518               label: m.methodName,
519               value: m
520             }
521           })
522         }
523       })
524     }
525   }
526
527   // 选择调度模型
528   const changeModel = async () => {
529     // 校验
530     if (model.value && model.value.length > 0) {
531       const modelInfo = model.value[0]
532       const methodInfo = model.value[1]
533       formData.value.modelName = modelInfo.pyChineseName
534       formData.value.className = modelInfo.pkgName + '.impl.' + modelInfo.pyName + 'Impl';
535       formData.value.methodName = methodInfo.methodName
536       formData.value.portLength = methodInfo.dataLength
537       // 参数构造
538       let paramStructure = []
539       for (let i = 0; i < methodInfo.dataLength; i++) {
540         paramStructure.push('[[D')
541       }
542       if (methodInfo.model === 1) {
543         paramStructure.push('java.util.HashMap')
544       }
545       paramStructure.push('java.util.HashMap')
546       formData.value.paramStructure = paramStructure.join(',')
547       formData.value.modelPath = modelInfo.pyModule
548       // 输入参数
549       let paramList = []
550       for (let i = 0; i < methodInfo.dataLength; i++) {
551         paramList.push({
552           modelparamportorder: i+1 + '',
553           modelparamorder: '1',
554           modelparamtype: '',
555           modelparamid: '',
556           datalength: 0
557         })
558       }
559
560       formData.value.paramList = paramList
561       // 设置参数
562       let settingList = []
563       methodInfo.methodSettings.forEach(e => {
564         settingList.push({
565           key: e.settingKey,
566           value: e.value,
567           valuetype: e.valueType,
568           name: e.name
569         })
570       })
571       formData.value.settingList = settingList
572       modelPopover.value.hide()
573     }else {
574       message.error("请先选择模型")
575     }
576   }
577
578   function changeModelparamtype(row) {
579     row.modelparamid = ''
580   }
23c8b8 581   const addRowOut= function () {
D 582     if(formData.value.modelOut===undefined) {
583       formData.value.modelOut = []
584     }
585     formData.value.modelOut.push({
586       id: generateUUID(),
587       resultKey: undefined,
588       resultType: "double[][]",
589       port: 0,
590       index: 0,
591       isWrite: 1,
592       pointNo:undefined,
593       sort:undefined,
594       disturbancePointNo:undefined,
595     })
596   }
597   const deleteModelOutRow = function (index) {
598     formData.value.modelOut.splice(index, 1)
599   }
2f0aa4 600 </script>