<template>
|
<Dialog v-model="dialogVisible" :title="dialogTitle">
|
<el-form
|
class="-mb-15px"
|
:model="formData"
|
ref="formRef"
|
:inline="true"
|
:rules="formRules"
|
label-width="68px"
|
v-loading="formLoading"
|
>
|
<el-form-item style="width: 100%">
|
<el-divider content-position="left">模型信息</el-divider>
|
</el-form-item>
|
<el-form-item label="全类名" style="width: 90%" prop="className">
|
<el-input v-model="formData.className" placeholder=""/>
|
</el-form-item>
|
<el-form-item label="方法名" prop="methodName">
|
<el-select v-model="formData.methodName" @change="methodChange" style="width: 240px">
|
<el-option
|
v-for="item in methodList"
|
:key="item.id"
|
:label="item.methodName"
|
:value="item.methodName"
|
/>
|
</el-select>
|
</el-form-item>
|
<el-divider content-position="left">模型参数信息</el-divider>
|
<el-row :gutter="20">
|
<el-col :span="2" style="margin-bottom: 10px;margin-left: 20px">
|
<el-button tag="a" href="/template/模型参数导入模板.xlsx" download="模型参数导入模板.xlsx" style="text-decoration: none;" type="primary" size="small" link>模板下载</el-button>
|
</el-col>
|
<el-col :span="2" style="margin-bottom: 10px;">
|
<el-upload
|
ref="uploadRef"
|
v-model:file-list="fileList"
|
:show-file-list="false"
|
:action="importUrl"
|
:auto-upload="true"
|
:disabled="formLoading"
|
:before-upload="beforeUpload"
|
:headers="uploadHeaders"
|
:on-error="submitFormError"
|
:on-success="submitFormSuccess"
|
accept=".xlsx"
|
>
|
<el-button type="primary" size="small" link>参数导入</el-button>
|
</el-upload>
|
</el-col>
|
</el-row>
|
<el-row v-for="(item,index) in formData.datas" :key="index" :gutter="20">
|
<el-col :span="20">
|
<el-form-item :label="'参数_' + (index)" required style="width: 100%">
|
<el-input v-model="formData.datas[index]" placeholder="" />
|
</el-form-item>
|
</el-col>
|
</el-row>
|
<el-row v-if="hasModel" :gutter="20">
|
<el-col :span="20">
|
<el-form-item label="model" required style="width: 100%">
|
<el-input v-model="formData.model" placeholder="" />
|
</el-form-item>
|
</el-col>
|
</el-row>
|
<el-divider content-position="left">模型设置信息</el-divider>
|
<el-row :gutter="20">
|
<el-col :span="4">
|
<el-button type="primary" size="small" @click="addRow()">新增</el-button>
|
</el-col>
|
</el-row>
|
<el-table :data="formData.modelSettings" border>
|
<el-table-column
|
prop=""
|
label="参数key"
|
align="center">
|
<template #default="scope">
|
<el-input size="small" v-model="scope.row.settingKey" maxlength="50" clearable />
|
</template>
|
</el-table-column>
|
<el-table-column
|
prop=""
|
label="参数value"
|
align="center">
|
<template #default="scope">
|
<el-input size="small" v-model="scope.row.settingValue" maxlength="50" clearable />
|
</template>
|
</el-table-column>
|
<el-table-column label="操作" fixed="right" header-align="center" align="center" width="100">
|
<template #default="scope">
|
<el-button
|
@click="deleteRow(scope.$index)"
|
key="danger"
|
type="danger"
|
link
|
>删除</el-button>
|
</template>
|
</el-table-column>
|
</el-table>
|
<el-divider content-position="left">模型运行结果</el-divider>
|
<el-input v-model="modelRunResult" placeholder="" rows="4" type="textarea" />
|
<div style="display: flex;flex-direction: row;justify-content: end;margin-top: 16px">
|
<el-button :loading="modelRunloading" type="primary" @click="modelRun()">运行</el-button>
|
</div>
|
</el-form>
|
</Dialog>
|
</template>
|
<script lang="ts" setup>
|
import * as MpkApi from '@/api/model/mpk/mpk'
|
import {FormRules} from "element-plus";
|
import {getAccessToken, getTenantId} from "@/utils/auth";
|
|
const { t } = useI18n() // 国际化
|
const message = useMessage() // 消息弹窗
|
|
const dialogVisible = ref(false) // 弹窗的是否展示
|
const dialogTitle = ref('模型运行') // 弹窗的标题
|
|
const formData = reactive({
|
pyName: '',
|
className: '',
|
methodName: '',
|
datas: [],
|
modelSettings: [],
|
model: undefined
|
})
|
|
// 模型方法下拉列表
|
const methodList = ref([])
|
const hasModel = ref(false)
|
|
/** 打开弹窗 */
|
const open = async (row) => {
|
dialogVisible.value = true
|
formData.className = row.pkgName + '.impl.' + row.pyName + 'Impl';
|
formData.pyName = row.pyName;
|
const mpk = await MpkApi.getMpk(row.id)
|
methodList.value = mpk.modelMethods
|
formData.methodName = mpk.modelMethods[0].methodName
|
formData.datas = []
|
for (let i = 0 ; i < mpk.modelMethods[0].dataLength ; i++) {
|
formData.datas[i] = '[[]]'
|
}
|
hasModel.value = mpk.modelMethods[0].model === 1
|
|
// 回显参数
|
if (mpk.modelMethods[0].methodSettings && mpk.modelMethods[0].methodSettings.length > 0) {
|
formData.modelSettings = mpk.modelMethods[0].methodSettings.map(e => {
|
return {
|
settingKey: e.settingKey,
|
settingValue: e.value
|
}
|
})
|
}
|
}
|
defineExpose({ open }) // 提供 open 方法,用于打开弹窗
|
|
const formRules = reactive<FormRules>({
|
methodName: [
|
{required: true, message: '方法名不能为空', trigger: 'blur'}
|
],
|
className: [
|
{required: true, message: '全类名不能为空', trigger: 'blur'}
|
]
|
})
|
|
const addRow = function () {
|
formData.modelSettings.push({
|
settingKey: '',
|
settingValue: ''
|
})
|
}
|
const deleteRow = function (index) {
|
formData.modelSettings.splice(index, 1)
|
}
|
const methodChange = function (value) {
|
formData.datas = []
|
var method = methodList.value.find(e => e.methodName === value);
|
for (let i = 0 ; i < method?.dataLength ; i++) {
|
formData.datas[i] = '[[]]'
|
}
|
hasModel.value = method?.model === 1
|
// 回显参数
|
if (method.methodSettings && method.methodSettings.length > 0) {
|
formData.modelSettings = method.methodSettings.map(e => {
|
return {
|
settingKey: e.settingKey,
|
settingValue: e.value
|
}
|
})
|
}else {
|
formData.modelSettings = []
|
}
|
}
|
|
const fileList = ref([]) // 文件列表
|
const importUrl =
|
import.meta.env.VITE_BASE_URL + import.meta.env.VITE_API_URL + '/model/mpk/api/import'
|
const formLoading = ref(false) // 表单的加载中
|
const uploadHeaders = ref() // 上传 Header 头
|
/** 上传错误提示 */
|
const submitFormError = (): void => {
|
message.error('导入失败,请检查导入文件!')
|
formLoading.value = false
|
}
|
const submitFormSuccess = (response: any) => {
|
if (response.code !== 0) {
|
message.error(response.msg)
|
formLoading.value = false
|
return
|
}
|
const datas = response.data;
|
for (let i=0;i<formData.datas.length;i++) {
|
formData.datas[i] = datas[i]
|
}
|
message.success('导入成功')
|
formLoading.value = false
|
}
|
const beforeUpload = function (file) {
|
// 提交请求
|
uploadHeaders.value = {
|
Authorization: 'Bearer ' + getAccessToken(),
|
'tenant-id': getTenantId()
|
}
|
formLoading.value = true
|
return true;
|
}
|
|
// 模型运行结果
|
const modelRunResult = ref('')
|
// 模型运行loading
|
const modelRunloading = ref(false)
|
// 表单 Ref
|
const formRef = ref()
|
// 运行
|
const modelRun = async () => {
|
// 校验表单
|
if (!formRef) return
|
const valid = await formRef.value.validate()
|
if (!valid) return
|
// 提交请求
|
modelRunloading.value = true
|
try {
|
const data = {
|
...formData
|
}
|
|
//处理modelSettings
|
let settingsPredict = {};
|
data.modelSettings.forEach(e => {
|
settingsPredict[e.settingKey] = e.settingValue;
|
})
|
data.modelSettings = settingsPredict
|
data.hasModel = hasModel.value
|
if (data.hasModel && data.model) {
|
data.model = {model_path:data.model}
|
}else {
|
data.model = undefined
|
}
|
|
modelRunResult.value = await MpkApi.modelRun(data)
|
modelRunloading.value = false
|
message.success('运行成功')
|
} finally {
|
modelRunloading.value = false
|
}
|
}
|
</script>
|