ADD: 修改数据合并逻辑,新增 event-source-polyfill包,实现长连接通信,展示合并进度
This commit is contained in:
@@ -1,33 +1,48 @@
|
||||
<template>
|
||||
<el-dialog v-model="dialogVisible" :title="parameter.title" :destroy-on-close="true" width="450px" draggable>
|
||||
<el-form class="drawer-multiColumn-form" label-width="100px">
|
||||
<el-form-item label="">
|
||||
<el-upload
|
||||
ref="uploadRef"
|
||||
action="#"
|
||||
class="upload"
|
||||
:http-request="uploadZip"
|
||||
accept=".zip"
|
||||
:auto-upload="!parameter.confirmMessage"
|
||||
:on-change="handleChange"
|
||||
:on-remove="handleRemove"
|
||||
>
|
||||
<slot name="empty">
|
||||
<el-icon class="el-icon--upload">
|
||||
<upload-filled />
|
||||
</el-icon>
|
||||
<div class="el-upload__text">
|
||||
<spam>点击上传</spam>
|
||||
</div>
|
||||
</slot>
|
||||
<template #tip>
|
||||
<slot name="tip">
|
||||
<div class="el-upload__tip">请上传 .zip 标准格式文件</div>
|
||||
</slot>
|
||||
</template>
|
||||
</el-upload>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<el-dialog
|
||||
v-model="dialogVisible"
|
||||
:title="parameter.title"
|
||||
:destroy-on-close="true"
|
||||
width="450px"
|
||||
:close-on-click-modal="!parameter.progressBar"
|
||||
draggable
|
||||
>
|
||||
<el-upload
|
||||
ref="uploadRef"
|
||||
action="#"
|
||||
class="upload"
|
||||
:limit="1"
|
||||
:http-request="uploadZip"
|
||||
accept=".zip"
|
||||
:auto-upload="!parameter.confirmMessage"
|
||||
:on-change="handleChange"
|
||||
:on-remove="handleRemove"
|
||||
:disabled="fileDisabled"
|
||||
>
|
||||
<slot name="empty">
|
||||
<el-button type="primary" icon="Upload">点击上传</el-button>
|
||||
</slot>
|
||||
<template #tip>
|
||||
<slot name="tip">
|
||||
<div class="el-upload__tip">请上传 .zip 标准格式文件</div>
|
||||
</slot>
|
||||
</template>
|
||||
</el-upload>
|
||||
<el-progress
|
||||
v-if="parameter.progressBar"
|
||||
:status="progressData.status"
|
||||
:percentage="progressData.percentage"
|
||||
></el-progress>
|
||||
<el-text v-if="parameter.progressBar && progressData.status === 'exception'" size="small" type="danger">
|
||||
{{ progressData.message }}
|
||||
</el-text>
|
||||
<el-text v-if="parameter.progressBar && progressData.status === 'success'" size="small" type="success">
|
||||
{{ progressData.message }}
|
||||
</el-text>
|
||||
<el-text v-if="parameter.progressBar && progressData.status === ''" size="small" type="info">
|
||||
{{ progressData.message }}
|
||||
</el-text>
|
||||
|
||||
<template #footer v-if="parameter.confirmMessage">
|
||||
<el-button :disabled="disable" type="primary" @click="uploadSubmit">开始导入</el-button>
|
||||
</template>
|
||||
@@ -37,16 +52,20 @@
|
||||
<script setup lang="ts" name="ImportZip">
|
||||
import { ref } from 'vue'
|
||||
import type { UploadInstance, UploadProps, UploadRequestOptions } from 'element-plus'
|
||||
import http from '@/api'
|
||||
|
||||
export interface ZipParameterProps {
|
||||
title: string // 标题
|
||||
patternId?: string // 模式ID
|
||||
planId?: string // 计划ID
|
||||
importApi?: (params: any) => Promise<any> // 批量导入的Api
|
||||
confirmMessage?: string // 提示信息
|
||||
progressBar?: boolean // 进度条
|
||||
}
|
||||
// dialog状态
|
||||
const dialogVisible = ref(false)
|
||||
const disable = ref(true)
|
||||
const fileDisabled = ref(false)
|
||||
const uploadRef = ref<UploadInstance>()
|
||||
|
||||
// 父组件传过来的参数
|
||||
@@ -63,44 +82,141 @@ const acceptParams = (params: ZipParameterProps) => {
|
||||
}
|
||||
|
||||
// 文件上传
|
||||
const uploadZip = async (param: UploadRequestOptions) => {
|
||||
const uploadZip = (param: UploadRequestOptions) => {
|
||||
let zipFormData = new FormData()
|
||||
zipFormData.append('file', param.file)
|
||||
if (parameter.value.patternId) {
|
||||
zipFormData.append('patternId', parameter.value.patternId)
|
||||
}
|
||||
await parameter.value.importApi!(zipFormData).then(res => handleImportResponse(res))
|
||||
if (parameter.value.planId) {
|
||||
zipFormData.append('planId', parameter.value.planId)
|
||||
}
|
||||
if (parameter.value.progressBar) {
|
||||
initSSE()
|
||||
}
|
||||
|
||||
setTimeout(() => {
|
||||
parameter.value.importApi!(zipFormData).then(res => handleImportResponse(res))
|
||||
}, 1000)
|
||||
}
|
||||
|
||||
const handleImportResponse = (res: any) => {
|
||||
if (res.code === 'A0000') {
|
||||
ElMessage.success('导入成功')
|
||||
if (!parameter.value.progressBar) {
|
||||
if (res.code === 'A0000') {
|
||||
ElMessage.success('导入成功')
|
||||
} else {
|
||||
ElMessage.error(res.message)
|
||||
}
|
||||
dialogVisible.value = false
|
||||
emit('result', res.data)
|
||||
} else {
|
||||
ElMessage.error(res.message)
|
||||
//
|
||||
}
|
||||
dialogVisible.value = false
|
||||
emit('result', res.data)
|
||||
}
|
||||
|
||||
const uploadSubmit = () => {
|
||||
if (!uploadRef.value) {
|
||||
return ElMessage.warning('请选择文件!')
|
||||
}
|
||||
progressData.value = {
|
||||
percentage: 0,
|
||||
status: '',
|
||||
message: ''
|
||||
}
|
||||
ElMessageBox.confirm(parameter.value.confirmMessage, '温馨提示', {
|
||||
confirmButtonText: '确定',
|
||||
cancelButtonText: '取消',
|
||||
type: 'warning'
|
||||
})
|
||||
.then(() => {
|
||||
disable.value = true
|
||||
fileDisabled.value = true
|
||||
uploadRef.value?.submit()
|
||||
})
|
||||
.catch(() => {})
|
||||
.catch(() => {
|
||||
disable.value = false
|
||||
fileDisabled.value = false
|
||||
})
|
||||
}
|
||||
const handleChange: UploadProps['onChange'] = (uploadFile, uploadFiles) => {
|
||||
disable.value = uploadFiles.length === 0
|
||||
progressData.value = {
|
||||
percentage: 0,
|
||||
status: '',
|
||||
message: ''
|
||||
}
|
||||
}
|
||||
const handleRemove: UploadProps['onRemove'] = (uploadFile, uploadFiles) => {
|
||||
disable.value = uploadFiles.length === 0
|
||||
progressData.value = {
|
||||
percentage: 0,
|
||||
status: '',
|
||||
message: ''
|
||||
}
|
||||
}
|
||||
|
||||
const progressData = ref({
|
||||
percentage: 0,
|
||||
status: '',
|
||||
message: ''
|
||||
})
|
||||
const eventSource = ref<EventSource | null>(null)
|
||||
|
||||
const initSSE = () => {
|
||||
eventSource.value = http.sse('/sse/createSse')
|
||||
|
||||
eventSource.value.onmessage = event => {
|
||||
console.log('收到消息内容是:', event.data)
|
||||
const res = JSON.parse(event.data)
|
||||
progressData.value.percentage = res.data
|
||||
progressData.value.message = res.message
|
||||
if (res.code === 'A0002') {
|
||||
fileDisabled.value = false
|
||||
disable.value = false
|
||||
progressData.value.status = 'exception'
|
||||
ElMessage.error(res.message)
|
||||
}
|
||||
if (progressData.value.percentage === 100) {
|
||||
progressData.value.status = 'success'
|
||||
eventSource.value!.close()
|
||||
ElMessage.success('导入成功')
|
||||
dialogVisible.value = false
|
||||
emit('result', true)
|
||||
}
|
||||
}
|
||||
|
||||
eventSource.value.onerror = error => {
|
||||
console.warn('SSE 连接出错:', error)
|
||||
eventSource.value!.close()
|
||||
}
|
||||
}
|
||||
// 添加一个手动关闭EventSource的函数
|
||||
const closeEventSource = () => {
|
||||
if (eventSource.value) {
|
||||
eventSource.value.close()
|
||||
eventSource.value = null
|
||||
console.log('SSE连接已关闭')
|
||||
}
|
||||
}
|
||||
// 监听 dialogVisible 的变化,确保在对话框关闭时清理资源
|
||||
watch(dialogVisible, newVal => {
|
||||
if (!newVal) {
|
||||
// 延迟执行,确保在组件完全关闭后清理
|
||||
setTimeout(() => {
|
||||
closeEventSource()
|
||||
fileDisabled.value = false
|
||||
disable.value = false
|
||||
progressData.value = {
|
||||
percentage: 0,
|
||||
status: '',
|
||||
message: ''
|
||||
}
|
||||
}, 100)
|
||||
}
|
||||
})
|
||||
onUnmounted(() => {
|
||||
closeEventSource()
|
||||
})
|
||||
defineExpose({
|
||||
acceptParams
|
||||
})
|
||||
|
||||
Reference in New Issue
Block a user