TrainingPlatform_VUE/src/components/ModelCard.vue
2025-06-03 16:28:46 +08:00

224 lines
7.4 KiB
Vue

<template>
<div class="page-body">
<div class="container-xl">
<div class="row row-deck row-cards">
<div class="col-12">
<div class="card">
<div class="card-header">
<h3 class="card-title">训练记录</h3>
</div>
<div class="card-body border-bottom py-3">
</div>
<div class="table-responsive">
<table class="table card-table table-vcenter text-nowrap datatable">
<thead>
<tr>
<th class="w-1 text-center"><input class="form-check-input m-0 align-middle" type="checkbox"
aria-label="Select all invoices"></th>
<th class="w-1 text-center">训练编号
<svg xmlns="http://www.w3.org/2000/svg" class="icon icon-sm icon-thick" width="24" height="24"
viewBox="0 0 24 24" stroke-width="2" stroke="currentColor" fill="none" stroke-linecap="round"
stroke-linejoin="round">
<path stroke="none" d="M0 0h24v24H0z" fill="none" />
<path d="M6 15l6 -6l6 6" />
</svg>
</th>
<th class="text-center">创建时间</th>
<th class="text-center">预训练模型</th>
<th class="text-center">数据集名称</th>
<th class="text-center">任务类型</th>
<th class="text-center">mAP</th>
<th class="text-center">precision</th>
<th class="text-center">当前状态</th>
<th class="text-center">action</th>
</tr>
</thead>
<tbody>
<tr v-for="task in project_training_tasks">
<td class="text-center"><input class="form-check-input m-0 align-middle" type="checkbox"
aria-label="Select invoice"></td>
<td class="text-center"><span class="text-secondary">{{ task.id }}</span></td>
<td class="text-center"><a href="invoice.html" class="text-reset" tabindex="-1"></a>{{
formatCreateTime(task.create_time) }}</td>
<td class="text-center">
<span class="flag flag-xs flag-country-us me-2"></span>
{{ task.pre_model_name }}
</td>
<td class="text-center">
{{ task.dataset_name }}
</td>
<td class="text-center">
{{ task.task_type === 'Detect' ? '目标检测' : task.task_type === 'Classify' ? '图像分类' : task.task_type
}}
</td>
<td class="text-center">
{{ task.epochData }}
</td>
<td class="text-center">{{ task.precision }}</td>
<td class="text-center">
<span class="badge me-1" :class="{
'bg-warning': task.status === '初始化',
'bg-info': task.status === '训练中',
'bg-success': task.status === '训练完成',
'bg-danger': task.status === '训练异常'
}">
</span>
{{ task.status }}
</td>
<td class="text-end">
<span>
<button class="btn dropdown-toggle align-text-top" data-bs-boundary="viewport"
data-bs-toggle="dropdown">操作</button>
<div class="dropdown-menu dropdown-menu-end">
<router-link class="dropdown-item"
:to="{ path: '/train-detail', query: { task_id: task.id } }">
查看详细
</router-link>
<a class="dropdown-item" href="#">
编辑
</a>
<a class="dropdown-item" href="#"
@click="deleteTask(task.id, task.user, task.project_name, task.dataset_name)">
删除
</a>
</div>
</span>
</td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
</div>
</div>
</div>
</template>
<script setup lang="ts" name="ModelCard">
import axios from 'axios'
import { get } from 'http';
import { API_URL } from '@/config/config'
import { ref, onMounted } from 'vue';
// 定义任务的类型
interface Task {
id: number;
user: string;
project_name: string;
pre_model_name: string;
dataset_name: string;
task_type: string;
status: string;
epoch: number;
batch_size: number;
image_size: number;
create_time: string;
model_size: string;
epochData: number;
precision: number;
}
let props = defineProps({
project_training_tasks: {
type: Array as () => Task[], // 指定类型为 Task 数组
default: () => [{
id: 0,
user: '',
project_name: '',
pre_model_name: '',
dataset_name: '',
task_type: '',
status: '',
epoch: 0,
batch_size: 0,
image_size: 0,
create_time: '',
model_size: '',
epochData: 0.0,
precision: 0.0,
}]
}
})
let mAP = ref<number>(0.0)
async function get_curr_epoch_data(training_id: number) {
try {
let response = await axios.get(`${API_URL}/training/get_curr_epoch_data/`, {
params: {
training_id: training_id
}
});
// 返回一个对象,包含 mAP95 和 precision
return {
mAP95: response.data.data.mAP95,
precision: response.data.data.precision
};
} catch (error) {
console.log(error);
return { mAP95: 0, precision: 0 }; // 返回默认值
}
}
async function deleteTask(id: number, user: string, projectName: string, datasetName: string) {
let response1 = await axios.get(`${API_URL}/training/delete_project_training_task/`, {
params: {
id: id,
user: user,
projectName: projectName
}
})
if (response1.data.success) {
alert('删除成功')
window.location.reload()
} else {
alert('删除失败')
}
}
// 在 onMounted 中获取每个任务的 epoch 数据
onMounted(async () => {
for (let task of props.project_training_tasks) {
const { mAP95, precision } = await get_curr_epoch_data(task.id);
task.epochData = mAP95; // 或者根据需要存储 precision
task.precision = precision;
}
});
// 功能函数
function formatCreateTime(dateString: string) {
if (!dateString) { // 检查 dateString 是否有效
return '无效的日期'; // 返回一个默认值或错误提示
}
const date = new Date(dateString);
if (isNaN(date.getTime())) { // 检查日期是否有效
return '无效的日期'; // 返回一个默认值或错误提示
}
return date.toISOString().slice(0, 19).replace('T', ' '); // 格式化为 YYYY-MM-DD HH:mm:ss
}
</script>
<style>
.card-link {
border: 1px solid transparent;
/* 默认边框 */
transition: border 0.3s;
/* 添加过渡效果 */
}
.card-link:hover {
border: 2px solid rgb(242, 238, 238);
/* 悬停时的边框效果 */
}
</style>