Industrial-image-management.../src/views/enterprise-settings/data-migration/index.vue

383 lines
10 KiB
Vue

<template>
<GiPageLayout>
<div class="data-migration-container">
<!-- 数据迁移概览 -->
<a-card title="数据迁移概览" class="mb-6">
<a-row :gutter="16">
<a-col :span="6">
<a-statistic title="已迁移数据量" :value="migrationStats.migratedData" suffix="GB" />
</a-col>
<a-col :span="6">
<a-statistic title="待迁移数据量" :value="migrationStats.pendingData" suffix="GB" />
</a-col>
<a-col :span="6">
<a-statistic title="迁移任务数" :value="migrationStats.totalTasks" />
</a-col>
<a-col :span="6">
<a-statistic title="成功率" :value="migrationStats.successRate" suffix="%" />
</a-col>
</a-row>
</a-card>
<!-- 数据迁移任务 -->
<a-card title="数据迁移任务" class="mb-6">
<template #extra>
<a-space>
<a-button type="primary" @click="createMigrationTask">
<template #icon><icon-plus /></template>
创建迁移任务
</a-button>
<a-button @click="importMigrationPlan">
<template #icon><icon-import /></template>
导入迁移计划
</a-button>
</a-space>
</template>
<GiTable
row-key="id"
:data="migrationTasks"
:columns="taskColumns"
:pagination="taskPagination"
:loading="tasksLoading"
>
<!-- 任务状态 -->
<template #status="{ record }">
<a-tag :color="getTaskStatusColor(record.status)">
{{ getTaskStatusText(record.status) }}
</a-tag>
</template>
<!-- 进度条 -->
<template #progress="{ record }">
<a-progress
:percent="record.progress"
:color="getProgressColor(record.progress)"
size="small"
/>
</template>
<!-- 数据量 -->
<template #dataSize="{ record }">
<span class="font-medium">{{ record.dataSize }} GB</span>
</template>
<!-- 操作 -->
<template #action="{ record }">
<a-space>
<a-link @click="viewTaskDetail(record)">详情</a-link>
<a-link
v-if="record.status === 'pending'"
@click="startTask(record)"
>
开始
</a-link>
<a-link
v-if="record.status === 'running'"
@click="pauseTask(record)"
>
暂停
</a-link>
<a-link
v-if="record.status === 'paused'"
@click="resumeTask(record)"
>
继续
</a-link>
<a-link @click="deleteTask(record)">删除</a-link>
</a-space>
</template>
</GiTable>
</a-card>
<!-- 数据源配置 -->
<a-card title="数据源配置">
<template #extra>
<a-button @click="addDataSource">
<template #icon><icon-plus /></template>
新增数据源
</a-button>
</template>
<GiTable
row-key="id"
:data="dataSources"
:columns="sourceColumns"
:pagination="false"
>
<!-- 数据源类型 -->
<template #sourceType="{ record }">
<a-tag :color="getSourceTypeColor(record.sourceType)">
{{ record.sourceType }}
</a-tag>
</template>
<!-- 连接状态 -->
<template #connectionStatus="{ record }">
<a-space>
<div
:class="record.isConnected ? 'online-dot' : 'offline-dot'"
class="status-dot"
></div>
{{ record.isConnected ? '已连接' : '未连接' }}
</a-space>
</template>
<!-- 操作 -->
<template #sourceAction="{ record }">
<a-space>
<a-link @click="testConnection(record)">测试连接</a-link>
<a-link @click="editDataSource(record)">编辑</a-link>
<a-link @click="deleteDataSource(record)">删除</a-link>
</a-space>
</template>
</GiTable>
</a-card>
</div>
</GiPageLayout>
</template>
<script setup lang="ts">
import { reactive, ref } from 'vue'
import { Message } from '@arco-design/web-vue'
import type { TableColumnData } from '@arco-design/web-vue'
// 迁移统计信息
const migrationStats = reactive({
migratedData: 1256.8,
pendingData: 324.2,
totalTasks: 28,
successRate: 95.2,
})
// 迁移任务数据
const migrationTasks = ref([
{
id: 1,
taskName: '用户数据迁移',
sourceSystem: '旧版CRM系统',
targetSystem: '新版管理系统',
dataSize: 125.6,
progress: 100,
status: 'completed',
createTime: '2024-03-01 10:00:00',
startTime: '2024-03-01 10:30:00',
endTime: '2024-03-01 12:45:00',
operator: '张管理员',
},
{
id: 2,
taskName: '项目数据迁移',
sourceSystem: '旧版项目系统',
targetSystem: '新版管理系统',
dataSize: 256.3,
progress: 75,
status: 'running',
createTime: '2024-03-10 09:00:00',
startTime: '2024-03-10 09:30:00',
endTime: '',
operator: '李管理员',
},
{
id: 3,
taskName: '财务数据迁移',
sourceSystem: '旧版财务系统',
targetSystem: '新版管理系统',
dataSize: 189.4,
progress: 0,
status: 'pending',
createTime: '2024-03-15 14:00:00',
startTime: '',
endTime: '',
operator: '王管理员',
},
])
// 数据源配置
const dataSources = ref([
{
id: 1,
sourceName: '旧版CRM数据库',
sourceType: 'MySQL',
host: '192.168.1.100',
port: 3306,
database: 'old_crm',
username: 'admin',
isConnected: true,
createTime: '2024-02-15 10:00:00',
},
{
id: 2,
sourceName: '旧版项目数据库',
sourceType: 'PostgreSQL',
host: '192.168.1.101',
port: 5432,
database: 'old_project',
username: 'admin',
isConnected: true,
createTime: '2024-02-20 11:30:00',
},
{
id: 3,
sourceName: '文件存储系统',
sourceType: 'FTP',
host: '192.168.1.102',
port: 21,
database: '/data/files',
username: 'fileuser',
isConnected: false,
createTime: '2024-03-01 09:15:00',
},
])
// 任务表格列配置
const taskColumns: TableColumnData[] = [
{ title: '任务名称', dataIndex: 'taskName', width: 200 },
{ title: '源系统', dataIndex: 'sourceSystem', width: 150 },
{ title: '目标系统', dataIndex: 'targetSystem', width: 150 },
{ title: '数据量', dataIndex: 'dataSize', slotName: 'dataSize', width: 100 },
{ title: '进度', dataIndex: 'progress', slotName: 'progress', width: 150 },
{ title: '状态', dataIndex: 'status', slotName: 'status', width: 100 },
{ title: '创建时间', dataIndex: 'createTime', width: 160 },
{ title: '操作人员', dataIndex: 'operator', width: 100 },
{ title: '操作', slotName: 'action', width: 200 },
]
// 数据源表格列配置
const sourceColumns: TableColumnData[] = [
{ title: '数据源名称', dataIndex: 'sourceName', width: 200 },
{ title: '类型', dataIndex: 'sourceType', slotName: 'sourceType', width: 120 },
{ title: '主机地址', dataIndex: 'host', width: 150 },
{ title: '端口', dataIndex: 'port', width: 80 },
{ title: '数据库/路径', dataIndex: 'database', width: 200 },
{ title: '用户名', dataIndex: 'username', width: 120 },
{ title: '连接状态', dataIndex: 'connectionStatus', slotName: 'connectionStatus', width: 120 },
{ title: '创建时间', dataIndex: 'createTime', width: 160 },
{ title: '操作', slotName: 'sourceAction', width: 200 },
]
// 分页配置
const taskPagination = reactive({
current: 1,
pageSize: 10,
total: 3,
showTotal: true,
})
const tasksLoading = ref(false)
// 获取任务状态颜色
const getTaskStatusColor = (status: string) => {
const colorMap: Record<string, string> = {
pending: 'gray',
running: 'blue',
paused: 'orange',
completed: 'green',
failed: 'red',
}
return colorMap[status] || 'gray'
}
// 获取任务状态文本
const getTaskStatusText = (status: string) => {
const textMap: Record<string, string> = {
pending: '待开始',
running: '运行中',
paused: '已暂停',
completed: '已完成',
failed: '失败',
}
return textMap[status] || status
}
// 获取进度颜色
const getProgressColor = (progress: number) => {
if (progress >= 80) return '#52c41a'
if (progress >= 60) return '#1890ff'
if (progress >= 40) return '#faad14'
return '#ff4d4f'
}
// 获取数据源类型颜色
const getSourceTypeColor = (type: string) => {
const colorMap: Record<string, string> = {
MySQL: 'blue',
PostgreSQL: 'green',
Oracle: 'orange',
FTP: 'purple',
SFTP: 'cyan',
}
return colorMap[type] || 'gray'
}
// 操作方法
const createMigrationTask = () => {
Message.info('创建迁移任务功能开发中...')
}
const importMigrationPlan = () => {
Message.info('导入迁移计划功能开发中...')
}
const viewTaskDetail = (task: any) => {
Message.info(`查看任务详情: ${task.taskName}`)
}
const startTask = (task: any) => {
Message.info(`开始任务: ${task.taskName}`)
}
const pauseTask = (task: any) => {
Message.info(`暂停任务: ${task.taskName}`)
}
const resumeTask = (task: any) => {
Message.info(`继续任务: ${task.taskName}`)
}
const deleteTask = (task: any) => {
Message.info(`删除任务: ${task.taskName}`)
}
const addDataSource = () => {
Message.info('新增数据源功能开发中...')
}
const testConnection = (source: any) => {
Message.info(`测试连接: ${source.sourceName}`)
}
const editDataSource = (source: any) => {
Message.info(`编辑数据源: ${source.sourceName}`)
}
const deleteDataSource = (source: any) => {
Message.info(`删除数据源: ${source.sourceName}`)
}
</script>
<style scoped>
.data-migration-container {
padding: 16px;
}
.mb-6 {
margin-bottom: 24px;
}
.status-dot {
width: 8px;
height: 8px;
border-radius: 50%;
display: inline-block;
}
.online-dot {
background-color: #52c41a;
}
.offline-dot {
background-color: #d9d9d9;
}
</style>