Industrial-image-management.../src/views/construction-operation-plat.../implementation-workflow/data-processing/data-preprocessing/index.vue

532 lines
13 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<template>
<GiPageLayout>
<div class="data-preprocessing-container">
<!-- 步骤指示器 -->
<div class="steps-container">
<a-steps :current="currentStep" size="small" class="preprocessing-steps">
<a-step title="选择数据" />
<a-step title="预处理设置" />
<a-step title="执行预处理" />
<a-step title="完成" />
</a-steps>
</div>
<!-- 步骤内容 -->
<div class="step-content">
<!-- 第一步选择数据 -->
<div v-if="currentStep === 0" class="step-panel">
<div class="step-header">
<h3>选择要预处理的数据</h3>
</div>
<div class="data-selection">
<!-- 项目选择 -->
<div class="project-select">
<a-select
v-model="selectedProject"
placeholder="请选择项目"
allow-clear
style="width: 300px"
>
<a-option
v-for="project in projectList"
:key="project.id"
:value="project.id"
>
{{ project.name }}
</a-option>
</a-select>
</div>
<!-- 文件列表 -->
<div class="file-list">
<a-table
:data="fileList"
:columns="fileColumns"
:row-selection="{ type: 'checkbox' }"
@select="handleFileSelect"
@select-all="handleFileSelectAll"
row-key="id"
:pagination="false"
:scroll="{ y: 400 }"
>
<template #fileName="{ record }">
<div class="file-item">
<a-checkbox :checked="selectedFiles.includes(record.id)" />
<span class="file-name">{{ record.fileName }}</span>
</div>
</template>
<template #fileType="{ record }">
<a-tag :color="getFileTypeColor(record.fileType)">
{{ record.fileType }}
</a-tag>
</template>
<template #fileSize="{ record }">
<span>{{ record.fileSize }}</span>
</template>
<template #uploadTime="{ record }">
<span>{{ record.uploadTime }}</span>
</template>
</a-table>
</div>
</div>
<div class="step-actions">
<a-button
type="primary"
@click="nextStep"
:disabled="selectedFiles.length === 0"
>
下一步
</a-button>
</div>
</div>
<!-- 第二步:预处理设置 -->
<div v-if="currentStep === 1" class="step-panel">
<div class="step-header">
<h3>预处理设置</h3>
</div>
<div class="preprocessing-settings">
<!-- 图像处理选项 -->
<div class="setting-group">
<h4>图像处理</h4>
<div class="setting-options">
<a-checkbox v-model="settings.image.denoise">去噪</a-checkbox>
<a-checkbox v-model="settings.image.enhance">增强</a-checkbox>
<a-checkbox v-model="settings.image.crop">裁剪</a-checkbox>
<a-checkbox v-model="settings.image.rotate">旋转校正</a-checkbox>
</div>
</div>
<!-- 视频处理选项 -->
<div class="setting-group">
<h4>视频处理</h4>
<div class="setting-options">
<a-checkbox v-model="settings.video.keyFrameExtraction">关键帧提取</a-checkbox>
<a-checkbox v-model="settings.video.stabilization">稳定化</a-checkbox>
<a-checkbox v-model="settings.video.split">分辨率调整</a-checkbox>
</div>
</div>
<!-- 输出格式设置 -->
<div class="setting-group">
<h4>输出格式</h4>
<a-form-item label="输出格式">
<a-select v-model="settings.output.format" style="width: 200px">
<a-option value="JPG">JPG</a-option>
<a-option value="PNG">PNG</a-option>
<a-option value="TIFF">TIFF</a-option>
<a-option value="MP4">MP4</a-option>
</a-select>
</a-form-item>
<a-form-item label="输出目录">
<a-input v-model="settings.output.directory" style="width: 300px" />
</a-form-item>
</div>
</div>
<div class="step-actions">
<a-button @click="prevStep">上一步</a-button>
<a-button type="primary" @click="nextStep">下一步</a-button>
</div>
</div>
<!-- 第三步:执行预处理 -->
<div v-if="currentStep === 2" class="step-panel">
<div class="step-header">
<h3>执行预处理</h3>
</div>
<div class="processing-section">
<div class="processing-status">
<div class="status-text">
<span v-if="!isProcessing">准备预处理...</span>
<span v-else>正在处理中...</span>
</div>
<div class="progress-container">
<a-progress
:percent="processingProgress"
:status="isProcessing ? 'normal' : 'warning'"
/>
<span class="progress-text">{{ processingProgress }}%</span>
</div>
</div>
</div>
<div class="step-actions">
<a-button @click="prevStep" :disabled="isProcessing">上一步</a-button>
<a-button
v-if="!isProcessing"
type="primary"
@click="startProcessing"
>
开始预处理
</a-button>
<a-button
v-else
type="primary"
@click="nextStep"
:disabled="processingProgress < 100"
>
下一步
</a-button>
</div>
</div>
<!-- 第四步:完成 -->
<div v-if="currentStep === 3" class="step-panel">
<div class="step-header">
<h3>完成</h3>
</div>
<div class="completion-section">
<div class="completion-icon">
<div class="success-icon">
<GiSvgIcon name="check-circle" size="48" />
</div>
</div>
<div class="completion-text">
<h4>预处理完成</h4>
<p>数据预处理已成功完成,共处理了 {{ selectedFiles.length }} 个文件</p>
</div>
</div>
<div class="step-actions">
<a-button @click="viewResults">查看结果</a-button>
<a-button type="primary" @click="continueProcessing">继续处理</a-button>
</div>
</div>
</div>
</div>
</GiPageLayout>
</template>
<script setup lang="ts">
import { ref, reactive, onMounted } from 'vue'
import { Message } from '@arco-design/web-vue'
import type { TableColumnData } from '@arco-design/web-vue/es/table/interface'
defineOptions({ name: 'DataPreprocessing' })
// 当前步骤
const currentStep = ref(0)
const isProcessing = ref(false)
const processingProgress = ref(0)
// 项目列表
const projectList = ref([
{ id: 1, name: 'A风场2023年检查' },
{ id: 2, name: 'B风场维修项目' },
{ id: 3, name: 'C风场建设项目' }
])
const selectedProject = ref<number>()
const selectedFiles = ref<number[]>([])
// 文件列表
const fileList = ref([
{
id: 1,
fileName: 'IMG_20231105_1430.jpg',
fileType: 'image',
fileSize: '3.2MB',
uploadTime: '2023-11-05 14:32'
},
{
id: 2,
fileName: 'VID_20231106_0915.mp4',
fileType: 'video',
fileSize: '45.6MB',
uploadTime: '2023-11-06 09:18'
}
])
// 文件表格列配置
const fileColumns: TableColumnData[] = [
{
title: '文件名',
dataIndex: 'fileName',
width: 300,
ellipsis: true,
tooltip: true
},
{
title: '类型',
dataIndex: 'fileType',
slotName: 'fileType',
width: 100,
align: 'center'
},
{
title: '大小',
dataIndex: 'fileSize',
slotName: 'fileSize',
width: 100,
align: 'center'
},
{
title: '上传时间',
dataIndex: 'uploadTime',
slotName: 'uploadTime',
width: 150,
align: 'center'
}
]
// 预处理设置
const settings = reactive({
image: {
denoise: false,
enhance: false,
crop: false,
rotate: false
},
video: {
keyFrameExtraction: false,
stabilization: false,
split: false
},
output: {
format: 'JPG',
directory: '/output/processed'
}
})
// 获取文件类型颜色
const getFileTypeColor = (type: string) => {
switch (type) {
case 'image':
return 'blue'
case 'video':
return 'green'
case 'audio':
return 'orange'
case 'document':
return 'purple'
default:
return 'gray'
}
}
// 文件选择处理
const handleFileSelect = (selectedRowKeys: number[]) => {
selectedFiles.value = selectedRowKeys
}
const handleFileSelectAll = (checked: boolean) => {
if (checked) {
selectedFiles.value = fileList.value.map(file => file.id)
} else {
selectedFiles.value = []
}
}
// 步骤导航
const nextStep = () => {
if (currentStep.value < 3) {
currentStep.value++
}
}
const prevStep = () => {
if (currentStep.value > 0) {
currentStep.value--
}
}
// 开始处理
const startProcessing = () => {
isProcessing.value = true
processingProgress.value = 0
// 模拟处理进度
const timer = setInterval(() => {
processingProgress.value += 10
if (processingProgress.value >= 100) {
clearInterval(timer)
isProcessing.value = false
Message.success('预处理完成!')
}
}, 500)
}
// 查看结果
const viewResults = () => {
Message.info('跳转到结果页面')
}
// 继续处理
const continueProcessing = () => {
currentStep.value = 0
selectedFiles.value = []
selectedProject.value = undefined
processingProgress.value = 0
isProcessing.value = false
Message.info('开始新的预处理任务')
}
onMounted(() => {
// 初始化数据
})
</script>
<style scoped lang="less">
.data-preprocessing-container {
padding: 20px;
}
.steps-container {
margin-bottom: 40px;
.preprocessing-steps {
max-width: 600px;
margin: 0 auto;
}
}
.step-content {
min-height: 500px;
}
.step-panel {
background: #fff;
border-radius: 8px;
padding: 24px;
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
}
.step-header {
margin-bottom: 24px;
border-bottom: 1px solid #e8e8e8;
padding-bottom: 16px;
h3 {
margin: 0;
color: #333;
font-size: 18px;
font-weight: 600;
}
}
.data-selection {
.project-select {
margin-bottom: 20px;
}
.file-list {
margin-bottom: 20px;
}
}
.file-item {
display: flex;
align-items: center;
gap: 8px;
.file-name {
color: #333;
}
}
.preprocessing-settings {
.setting-group {
margin-bottom: 32px;
h4 {
margin-bottom: 16px;
color: #333;
font-size: 16px;
font-weight: 600;
}
.setting-options {
display: flex;
gap: 16px;
flex-wrap: wrap;
margin-bottom: 16px;
}
}
}
.processing-section {
text-align: center;
padding: 40px;
.processing-status {
.status-text {
font-size: 16px;
color: #666;
margin-bottom: 24px;
}
.progress-container {
display: flex;
align-items: center;
gap: 16px;
max-width: 400px;
margin: 0 auto;
.progress-text {
font-weight: 600;
color: #333;
}
}
}
}
.completion-section {
text-align: center;
padding: 40px;
.completion-icon {
margin-bottom: 24px;
.success-icon {
display: inline-block;
color: #52c41a;
}
}
.completion-text {
h4 {
margin-bottom: 12px;
color: #333;
font-size: 20px;
font-weight: 600;
}
p {
color: #666;
font-size: 14px;
}
}
}
.step-actions {
display: flex;
justify-content: flex-end;
gap: 12px;
margin-top: 40px;
padding-top: 24px;
border-top: 1px solid #e8e8e8;
}
:deep(.arco-steps-item-title) {
font-size: 14px;
font-weight: 500;
}
:deep(.arco-table-cell) {
padding: 8px 16px;
}
:deep(.arco-form-item) {
margin-bottom: 16px;
}
:deep(.arco-form-item-label) {
font-weight: 500;
}
</style>