Merge branch 'develop-business-css' of http://121.37.111.42:3000/ThbTech/JavaProjectRepo into development-business-css

This commit is contained in:
wanxiaoli 2026-03-11 18:18:04 +08:00
commit b1fa56a7f3
3 changed files with 227 additions and 66 deletions

View File

@ -0,0 +1,47 @@
import request from '@/utils/request';
//获取所有项目列表
export function searchAlgorithmsPage(queryParams:any){
return request({
url: '/train/list' ,
method: 'get',
params:queryParams
});
}
//新增项目
export function addAlgorithms(data:any){
return request({
url:'/train/submit' ,
method: 'Post',
data: data
});
}
//更新项目信息
export function updateAlgorithms (queryParams:any){
return request({
url:'/list' ,
method: 'PUT',
data: queryParams
});
}
//单个删除项目
export function deleteAlgorithms (queryParams:any){
return request({
url:'/list/'+queryParams.id ,
method: 'delete'
// params: queryParams
});
}
//多选删除项目
export function deleteBatchAlgorithms (queryParams:any){
return request({
url:'/list',
method: 'delete',
data: queryParams
});
}

View File

@ -6,17 +6,18 @@ import { useUserStoreHook } from '@/store/modules/user';
// 创建 axios 实例 // 创建 axios 实例
const service = axios.create({ const service = axios.create({
baseURL: import.meta.env.VITE_APP_BASE_API, baseURL: import.meta.env.VITE_APP_BASE_API,
timeout: 50000, timeout: 50000
headers: { 'Content-Type': 'application/json;charset=utf-8' }
}); });
// 请求拦截器 // 请求拦截器
service.interceptors.request.use( service.interceptors.request.use(
(config: AxiosRequestConfig) => { (config: any) => {
if (!config.headers) { if (!config.headers) {
throw new Error( config.headers = {};
`Expected 'config' and 'config.headers' not to be undefined` }
); // Only set Content-Type if data is not FormData
if (!(config.data instanceof FormData)) {
config.headers['Content-Type'] = 'application/json;charset=utf-8';
} }
const user = useUserStoreHook(); const user = useUserStoreHook();
if (user.Token) { if (user.Token) {
@ -31,7 +32,7 @@ service.interceptors.request.use(
// 响应拦截器 // 响应拦截器
service.interceptors.response.use( service.interceptors.response.use(
(response: AxiosResponse) => { (response: any) => {
const { status, msg } = response; const { status, msg } = response;
if (status === 200) { if (status === 200) {
if (response.data.code == 401) { if (response.data.code == 401) {

View File

@ -5,39 +5,49 @@ export default {
</script> </script>
<script setup lang="ts"> <script setup lang="ts">
import { onMounted, ref, nextTick } from "vue"; import { onMounted, ref, nextTick,reactive } from "vue";
import { ElForm, ElMessage, ElMessageBox } from "element-plus"; import { ElForm, ElMessage, ElMessageBox,FormRules } from "element-plus";
import { searchAlgorithmsPage,addAlgorithms,updateAlgorithms,deleteAlgorithms,deleteBatchAlgorithms} from "@/api/business/algorithm"; import { searchAlgorithmsPage,addAlgorithms,updateAlgorithms,deleteAlgorithms,deleteBatchAlgorithms} from "@/api/algorithm";
import { getDictItemById } from '@/api/dict'; import { getDictItemById } from '@/api/dict';
import Page from '@/components/Pagination/page.vue' import Page from '@/components/Pagination/page.vue'
const apiUrl = import.meta.env.VITE_APP_BASE_API; // const apiUrl = import.meta.env.VITE_APP_BASE_API; //
const fileList:any = ref([])
const isSwitch = ref(false);
// //
const queryParams = ref({ const queryParams:any = ref({
current: 1, current: 1,
size: 10, size: 10,
querystr: '' total: 0,
title: '',
algorithmType: '',
deviceType: '',
state: '',
}); });
//
const rules = reactive<FormRules>({
name: [{ required: true, message: "请输入训练任务名称", trigger: "blur" }],
algorithmType: [{ required: true, message: "请选择算法类型", trigger: "change" }]
});
// //
const total = ref() const total = ref()
// //
const tableData: any = ref([]); const tableData= ref([]);
// //
const loading = ref(false) const loading = ref(false)
function gettableData() { function gettableData() {
let params = { const params = {
name: input.value, current: queryParams.value.current,
pageNum: queryParams.value.current, size: queryParams.value.size,
pageSize: queryParams.value.size, title: queryParams.value.title
}; };
loading.value = true;
searchAlgorithmsPage(params).then((result:any) => { searchAlgorithmsPage(params).then((res:any) => {
tableData.value = result.records; tableData.value = res.data.records;
total.value = result.total; queryParams.value.total = res.data.total;
loading.value = false;
}).catch((err) => { })
loading.value = false;
});
} }
const algorithmData: any = ref([]); const algorithmData: any = ref([]);
@ -47,10 +57,11 @@ function getAlgorithmList() { // 获取算法列表
pageNum: 1, pageNum: 1,
pageSize: 999, pageSize: 999,
}; };
loading.value = true; loading.value = false;
searchAlgorithmsPage(params).then((result:any) => { searchAlgorithmsPage(params).then((result:any) => {
algorithmData.value = result.records; algorithmData.value = result.data.records;
}).catch((err) => {
}).catch((err:any) => {
}); });
} }
@ -67,6 +78,19 @@ function menuInit() { // 获取算法类型字典项
}).catch((err: any) => { }).catch((err: any) => {
}); });
} }
const statusData:any = ref([]);
function statusInit() { //
let params = {
dictId: '9b25718a0998f66cada0893121551447',
size:99,
current:1
}
getDictItemById(params).then((result: any) => {
statusData.value = result.data.records;
gettableData()
}).catch((err: any) => {
});
}
const infoForm = ref(); const infoForm = ref();
// //
@ -111,39 +135,46 @@ function addClick() {
function confirmClick(formEl: any) { function confirmClick(formEl: any) {
formEl.validate((valid: any) => { formEl.validate((valid: any) => {
if (valid) { if (valid) {
const params = { if(isSwitch.value == true){
algorithmType: info.value.algorithmType, return
name: info.value.name,
description: info.value.description,
version: info.value.version,
principle: info.value.principle,
inputParams: info.value.inputParams,
outputParams: info.value.outputParams,
inferBaseUrl: info.value.inferBaseUrl,
trainBaseUrl: info.value.trainBaseUrl,
supportedDeviceTypes: info.value.supportedDeviceTypes,
defaultHyperParams: info.value.defaultHyperParams,
status: info.value.status,
} }
addAlgorithms(params).then((res) => { isSwitch.value = true
gettableData(); // const data:any = {
// taskJson: JSON.stringify(info.value),
// }
const data = new FormData()
info.value.trainParams = JSON.stringify(trainParamsData.value)
data.append('task', JSON.stringify(info.value))
// Add file if exists
if (fileList.value.length > 0) {
data.append('file', fileList.value[0].raw)
}
dialogVisible.value = false
addAlgorithms(data).then((res: any) => {
dialogVisible.value = false; dialogVisible.value = false;
}); ElMessage({
message: "新增成功",
type: "success",
})
gettableData();
}).catch(() => {
dialogVisible.value = false;
isSwitch.value = false;
})
}else{
isSwitch.value = false;
} }
}); })
} }
//- //-
function handleClose() { function handleClose() {
dialogVisible.value = false; dialogVisible.value = false;
dialogViewVisible.value = false; dialogViewVisible.value = false;
if (infoForm.value != null) infoForm.value.resetFields(); if (infoForm.value != null) infoForm.value.resetFields();
} }
//
const rules = ref({
name: [{ required: true, message: "请输入训练任务名称", trigger: "blur" }],
algorithmType: [{ required: true, message: "请选择算法类型", trigger: "change" }]
});
// //
function viewClick(row: any) { function viewClick(row: any) {
title.value = "查看详情"; title.value = "查看详情";
@ -206,9 +237,12 @@ function dateFormat(row: any) {
} }
} }
onMounted(() => { onMounted(() => {
getAlgorithmList() //
menuInit() // menuInit() //
statusInit()
getAlgorithmList() //
gettableData(); gettableData();
}); });
function changeStatus(row: any) { function changeStatus(row: any) {
// let params = { // let params = {
@ -238,6 +272,47 @@ function changeShowResult(isShow:boolean){ // 切换显示结果模型
} }
const dialogViewVisible = ref(false) // const dialogViewVisible = ref(false) //
function handlefilechange(file:any){
fileList.value = []
fileList.value.push(file)
}
function handlefileremove(){
fileList.value = []
}
function statusName(code:any){
let name = ''
console.log(statusData.value)
for(let i = 0;i<statusData.value.length;i++){
if(statusData.value[i].itemCode == code){
name = statusData.value[i].dictName
}
}
return name
}
const trainParamsData:any = ref([])
function addTrainParams(){
trainParamsData.value.push({
key:"",
value:" "
})
}
function delTrainParams(index:any){
trainParamsData.value.splice(index,1)
}
function resetClick(){
queryParams.value = {
current: 1,
size: 10,
total: 0,
title: '',
algorithmType: '',
deviceType: '',
state: '',
}
gettableData()
}
</script> </script>
<template> <template>
@ -247,22 +322,35 @@ const dialogViewVisible = ref(false) // 模型详情弹窗
style="display: flex;display: -webkit-flex; justify-content: space-between; -webkit-justify-content: space-between;margin-bottom: 10px"> style="display: flex;display: -webkit-flex; justify-content: space-between; -webkit-justify-content: space-between;margin-bottom: 10px">
<div style="display: flex;display: -webkit-flex;"> <div style="display: flex;display: -webkit-flex;">
<el-input v-model="input" placeholder="请输入训练任务名称" @keyup.enter="gettableData" style="width: 200px" clearable /> <el-input v-model="input" placeholder="请输入训练任务名称" @keyup.enter="gettableData" style="width: 200px" clearable />
<el-select style="width: 200px;margin-left: 10px;" clearable v-model="queryParams.algorithmType" placeholder="请选择算法类型">
<el-option v-for="item in algorithmData" :key="item.algorithmType" :label="item.algorithmType" :value="item.algorithmType" ></el-option>
</el-select>
<el-select style="width: 200px;margin-left: 10px;" clearable v-model="queryParams.deviceType" placeholder="请选择设备类型">
<el-option v-for="item in menuData" :key="item.itemCode" :label="item.dictName" :value="item.itemCode" ></el-option>
</el-select>
<el-select style="width: 200px;margin-left: 10px;" clearable v-model="queryParams.state" placeholder="请选择状态">
<el-option v-for="item in statusData" :key="item.itemCode" :label="item.dictName" :value="item.itemCode" ></el-option>
</el-select>
<el-button type="primary" style="margin-left: 10px" @click="gettableData">搜索</el-button> <el-button type="primary" style="margin-left: 10px" @click="gettableData">搜索</el-button>
</div> </div>
<div style="display: flex;display: -webkit-flex;"> <div style="display: flex;display: -webkit-flex;">
<el-button type="primary" @click="addClick"> <el-button type="primary" @click="resetClick">重置</el-button>
新增</el-button> <el-button type="primary" @click="addClick">新建训练任务</el-button>
</div> </div>
</div> </div>
<el-table v-loading="loading" :data="tableData" style="width: 100%; height: calc(100vh - 260px);margin-bottom: 10px;" border <el-table v-loading="loading" :data="tableData" style="width: 100%; height: calc(100vh - 260px);margin-bottom: 10px;" border
:header-cell-style="{ background: 'rgb(250 250 250)', color: '#383838', height: '50px' }"> :header-cell-style="{ background: 'rgb(250 250 250)', color: '#383838', height: '50px' }">
<el-table-column type="selection" width="50" align="center"></el-table-column> <el-table-column type="selection" width="50" align="center" prop="id"></el-table-column>
<el-table-column type="index" label="序号" width="70" align="center"></el-table-column> <el-table-column type="index" label="序号" width="70" align="center" prop="taskId"></el-table-column>
<el-table-column prop="name" label="任务名称" width="180"></el-table-column> <el-table-column prop="taskName" label="任务名称" width="180" ></el-table-column>
<el-table-column prop="version" label="算法类型" width="100"></el-table-column> <el-table-column prop="algorithmType" label="算法类型" width="100" ></el-table-column>
<el-table-column prop="description" label="设备类型" min-width="100"></el-table-column> <el-table-column prop="deviceType" label="设备类型" min-width="100" ></el-table-column>
<el-table-column prop="description" label="任务状态" min-width="100"></el-table-column> <el-table-column prop="status" label="任务状态" min-width="100">
<template #default="scope">
{{statusName(scope.row.status)}}
</template>
</el-table-column>
<el-table-column prop="updatedAt" label="创建时间" width="200"> <el-table-column prop="updatedAt" label="创建时间" width="200">
<template #default="scope"> <template #default="scope">
@ -289,20 +377,45 @@ const dialogViewVisible = ref(false) // 模型详情弹窗
<Page :total="total" v-model:size="queryParams.size" v-model:current="queryParams.current" @pagination="gettableData()" ></Page> <Page :total="total" v-model:size="queryParams.size" v-model:current="queryParams.current" @pagination="gettableData()" ></Page>
</div> </div>
<el-dialog v-model="dialogVisible" :close-on-click-modal="false" <el-dialog v-model="dialogVisible" :close-on-click-modal="false"
:modal="false" draggable :before-close="handleClose" :title="title" :modal="false" draggable :before-close="handleClose" :title="title"
append-to-body width="1145px" height="600px"> append-to-body width="1145px" height="600px">
<el-form ref="infoForm" :model="info" :rules="rules" label-width="100px" <el-form ref="infoForm" :model="info" :rules="rules" label-width="100px"
style="margin-top: 20px;"> style="margin-top: 20px;">
<el-form-item label="训练名称名称" prop="name" style="width: 100%;" > <el-form-item label="训练名称" prop="name" style="width: 100%;" >
<el-input v-model="info.task_name" style="width: 100%" placeholder="输入算法名称"></el-input> <el-input v-model="info.name" style="width: 100%" placeholder="输入算法名称"></el-input>
</el-form-item> </el-form-item>
<el-form-item label="设备类型" prop="deviceType" style="width: 100%;" >
<el-select v-model="info.deviceType">
<el-option v-for="item in menuData" :key="item.itemCode" :label="item.dictName" :value="item.itemCode" ></el-option>
</el-select>
</el-form-item>
<el-form-item label="算法类型" prop="algorithmType" style="width: 100%;" >
<el-select v-model="info.algorithmType">
<el-option v-for="item in algorithmData" :key="item.algorithmType" :label="item.name" :value="item.algorithmType" ></el-option>
</el-select v-model="info.algorithmType">
</el-form-item>
<el-form-item label="数据源类型" style="width: 100%;" >
<el-upload accept=".xlsx" ref="upload" class="upload-demo" action="" :on-change="handlefilechange" :on-remove="handlefileremove" :auto-upload="false" :file-list="fileList" style="width: calc(100% - 70px);position:relative">
<template #trigger>
<el-button type="primary">点击上传</el-button>
</template>
</el-upload>
</el-form-item>
<el-form-item label="数据源类型" style="width: 100%;" >
<div style="display: flex;justify-content:space-between;">
<el-button type="primary" @click="addTrainParams">添加</el-button>
<div style="display: flex;" v-for="(item,index) in trainParamsData" :key="index">
<el-input v-model="item.key" style="width: 100%" placeholder="输入算法名称"></el-input>
<el-input v-model="item.value" style="width: 100%" placeholder="输入算法名称"></el-input>
<el-button type="primary" @click="delTrainParams(index)">删除</el-button>
</div>
</div>
</el-form-item>
<span class="dialog-footer" <span class="dialog-footer"
style="display: flex;display: -webkit-flex; justify-content: flex-end;-webkit-justify-content: flex-end;"> style="display: flex;display: -webkit-flex; justify-content: flex-end;-webkit-justify-content: flex-end;">
<el-button @click="handleClose"> </el-button> <el-button @click="handleClose"> </el-button>
<el-button type="primary" @click="confirmClick(infoForm)"> </el-button> <el-button type="primary" @click="confirmClick(infoForm)">提交训练</el-button>
</span> </span>
</el-form> </el-form>
</el-dialog> </el-dialog>