liriming
2025-03-03 8bb7160c9c4fd7ce5893ee673647b13cc35410ae
提交 | 用户 | 时间
3933d8 1 <template>
D 2   <Dialog v-model="dialogVisible" :title="dialogTitle">
3     <el-form
4       class="-mb-15px"
5       :model="formData"
6       ref="formRef"
7       :inline="true"
8       :rules="formRules"
9       label-width="68px"
10       v-loading="formLoading"
11     >
12       <el-form-item style="width: 100%">
13         <el-divider content-position="left">模型信息</el-divider>
14       </el-form-item>
15       <el-row>
16         <el-col :span="24">
17           <el-form-item label="全类名" style="width: 100%" prop="className">
18             <el-input disabled v-model="formData.className" placeholder=""/>
19           </el-form-item>
20         </el-col>
21       </el-row>
22       <el-row>
23         <el-col :span="24">
24           <el-form-item label="方法名" prop="methodName">
25             <el-select v-model="formData.methodId" @change="methodChange" style="width: 240px">
26               <el-option
27                 v-for="item in methodList"
28                 :key="item.id"
29                 :label="item.className + '.' + item.methodName + '()'"
30                 :value="item.id"
31               />
32             </el-select>
33           </el-form-item>
34         </el-col>
35       </el-row>
36       <el-divider content-position="left">模型参数信息</el-divider>
37       <div style="display:flex;flex-direction: row;align-items: center;margin-bottom: 6px">
38         <el-button tag="a" :href="staticDir + '/template/模型参数导入模板.xlsx'" download="模型参数导入模板.xlsx" style="text-decoration: none;" type="primary" size="small" link>模板下载</el-button>
39         <el-upload
40           ref="uploadRef"
41           v-model:file-list="fileList"
42           :show-file-list="false"
43           :action="importUrl"
44           :auto-upload="true"
45           :disabled="formLoading"
46           :before-upload="beforeUpload"
47           :headers="uploadHeaders"
48           :on-error="submitFormError"
49           :on-success="submitFormSuccess"
50           accept=".xlsx"
51         >
52           <el-button type="primary" size="small" link>参数导入</el-button>
53         </el-upload>
54       </div>
55       <el-row v-for="(item,index) in datas" :key="index" :gutter="20">
56         <el-col :span="24">
57           <el-form-item :label="'参数_' + (index)" required style="width: 100%">
58             <el-input type="textarea" :disabled="true" :rows="3" v-model="datas[index]" placeholder="" />
59           </el-form-item>
60         </el-col>
61       </el-row>
62       <el-divider content-position="left">模型设置信息</el-divider>
63 <!--      <el-row :gutter="20">-->
64 <!--        <el-col :span="4">-->
65 <!--          <el-button type="primary" size="small" @click="addRow()">新增</el-button>-->
66 <!--        </el-col>-->
67 <!--      </el-row>-->
68       <el-table :data="formData.modelSettings" border>
69         <el-table-column
70           prop=""
71           label="参数key"
72           align="center">
73           <template #default="scope">
74             <el-input size="small" v-model="scope.row.settingKey" :disabled="true" maxlength="50" clearable />
75           </template>
76         </el-table-column>
77         <el-table-column
78           prop=""
79           label="参数名称"
80           align="center">
81           <template #default="scope">
82             <el-input size="small" v-model="scope.row.name" :disabled="true" maxlength="50" clearable />
83           </template>
84         </el-table-column>
85         <el-table-column
86           prop=""
87           label="参数value"
88           align="center">
89           <template #default="scope">
90             <el-input size="small" v-model="scope.row.settingValue" :disabled="scope.row.settingKey === 'pyFile'" maxlength="50" clearable />
91           </template>
92         </el-table-column>
93 <!--        <el-table-column label="操作" fixed="right" header-align="center" align="center" width="100">-->
94 <!--          <template #default="scope">-->
95 <!--            <el-button-->
96 <!--              @click="deleteRow(scope.$index)"-->
97 <!--              key="danger"-->
98 <!--              type="danger"-->
99 <!--              :disabled="scope.row.settingKey === 'pyFile'"-->
100 <!--              link-->
101 <!--            >删除</el-button>-->
102 <!--          </template>-->
103 <!--        </el-table-column>-->
104       </el-table>
105       <el-divider content-position="left">模型运行结果</el-divider>
106       <el-input v-model="modelRunResult" placeholder="" rows="4" type="textarea" />
107       <div style="display: flex;flex-direction: row;justify-content: end;margin-top: 16px">
108         <el-button :loading="modelRunloading" type="primary" @click="modelRun()">运行</el-button>
109       </div>
110     </el-form>
111   </Dialog>
112 </template>
113 <script lang="ts" setup>
114   import * as MlModelApi from '@/api/model/matlab/mlModel'
115   import {FormRules} from "element-plus";
116   import {getAccessToken, getTenantId} from "@/utils/auth";
117   import download from "@/utils/download";
118   const staticDir = ref(import.meta.env.VITE_STATIC_DIR)
119
120   const { t } = useI18n() // 国际化
121   const message = useMessage() // 消息弹窗
122
123   const dialogVisible = ref(false) // 弹窗的是否展示
124   const dialogTitle = ref('模型运行') // 弹窗的标题
125
126   const formData = reactive({
127     modelFileName: '',
128     className: '',
129     methodName: '',
130     methodId: '',
131     uuids: [],
132     modelSettings: [],
133     outLength: 1
134   })
135
136   const datas = ref([])
137
138   // 模型方法下拉列表
139   const methodList = ref([])
140
141   /** 打开弹窗 */
142   const open = async (row) => {
143     dialogVisible.value = true
144     formData.modelFileName = row.modelFileName
145     const matlabModel = await MlModelApi.get(row.id)
146     methodList.value = matlabModel.modelMethods
147     formData.className = matlabModel.modelMethods[0].className
148     formData.methodId = matlabModel.modelMethods[0].id
149     formData.methodName = matlabModel.modelMethods[0].methodName
150     formData.outLength = matlabModel.modelMethods[0].outLength
151     datas.value = []
152     formData.uuids = [];
153     for (let i = 0 ; i < matlabModel.modelMethods[0].dataLength ; i++) {
154      datas.value[i] = '[[]]';
155      formData.uuids[i] = '';
156     }
157
158     // 回显参数
159     if (matlabModel.modelMethods[0].methodSettings && matlabModel.modelMethods[0].methodSettings.length > 0) {
160       formData.modelSettings = matlabModel.modelMethods[0].methodSettings
161     }
162
163   }
164   defineExpose({ open }) // 提供 open 方法,用于打开弹窗
165
166   const formRules = reactive<FormRules>({
167     methodName: [
168       {required: true, message: '方法名不能为空', trigger: 'blur'}
169     ],
170     className: [
171       {required: true, message: '全类名不能为空', trigger: 'blur'}
172     ]
173   })
174
175   const addRow = function () {
176     formData.modelSettings.push({
177       settingKey: '',
178       settingValue: ''
179     })
180   }
181   const deleteRow = function (index) {
182     formData.modelSettings.splice(index, 1)
183   }
184   const methodChange = function (value) {
185     datas.value = []
186     formData.uuids = [];
187     var method = methodList.value.find(e => e.id === value);
188     formData.methodName = method.methodName
189     formData.className = method.className
190     for (let i = 0 ; i < method?.dataLength ; i++) {
191       datas.value[i] = '[[]]';
192       formData.uuids[i] = '';
193     }
194     // 回显参数
195     if (method.methodSettings && method.methodSettings.length > 0) {
196       formData.modelSettings = method.methodSettings
197     }else {
198       formData.modelSettings = []
199     }
200   }
201
202   const fileList = ref([]) // 文件列表
203   const importUrl =
204     import.meta.env.VITE_BASE_URL + import.meta.env.VITE_API_URL + '/model/matlab/model/importData'
205   const formLoading = ref(false) // 表单的加载中
206   const uploadHeaders = ref() // 上传 Header 头
207   /** 上传错误提示 */
208   const submitFormError = (): void => {
209     message.error('导入失败,请检查导入文件!')
210     formLoading.value = false
211   }
212   const submitFormSuccess = (response: any) => {
213     try {
214       if (response.code !== 0) {
215         message.error(response.msg)
216         return
217       }
218       const data = response.data;
219       if (datas.value.length > data.length) {
220         message.error("导入数据长度为" + data.length + ",应≥" + datas.value.length)
221         return
222       }
223       for (let i = 0; i < datas.value.length; i++) {
224         datas.value[i] = data[i].data
225         formData.uuids[i] = data[i].uuid;
226       }
227       message.success('导入成功')
228     } finally {
229       formLoading.value = false
230     }
231   }
232   const beforeUpload = function (file) {
233     // 提交请求
234     uploadHeaders.value = {
235       Authorization: 'Bearer ' + getAccessToken(),
236       'tenant-id': getTenantId()
237     }
238     formLoading.value = true
239     return true;
240   }
241
242   // 模型运行结果
243   const modelRunResult = ref('')
244   // 模型运行loading
245   const modelRunloading = ref(false)
246   // 表单 Ref
247   const formRef = ref()
248   // 运行
249   const modelRun = async () => {
250     modelRunResult.value = ''
251   // 校验表单
252     if (!formRef) return
253     const valid = await formRef.value.validate()
254     if (!valid) return
255
256
257     // 提交请求
258     modelRunloading.value = true
259     try {
260       const data = {
261         ...formData
262       }
263
264       //处理modelSettings
265       // let settingsPredict = {};
266       // data.modelSettings.forEach(e => {
267       //   settingsPredict[e.settingKey] = e.settingValue;
268       // })
269       // data.modelSettings = settingsPredict
270
271       let result = await MlModelApi.test(data)
272
273       modelRunResult.value = result;
274       message.success('运行成功')
275     } finally {
276       modelRunloading.value = false
277     }
278   }
279 </script>