import { computed, defineComponent, Fragment, ref } from 'vue'
|
import styles from './ImportProcessDialog.module.scss'
|
import BaseDialog from '@/components/BaseDialog/BaseDialog'
|
import { ElMessage } from 'element-plus'
|
import { _t, Language } from '@/libs/Language/Language'
|
import IconButton from '../IconButton/IconButton'
|
import { Socket } from '@/libs/Socket/index'
|
import dayjs from 'dayjs'
|
import { ConfirmBox } from '@/components/ConfirmBox/ConfirmBox'
|
const ReceiveProgress = 'ReceiveProgress'
|
const Cancel = 'Cancel'
|
export default defineComponent({
|
name: 'ImportProcessDialog',
|
props: {
|
visible: {
|
type: Boolean,
|
default: false,
|
},
|
elapsedTime: {
|
type: String,
|
default: '00:00:00',
|
},
|
remainingTime: {
|
type: String,
|
default: '00:00:00',
|
},
|
IsInspectionPointTask: {
|
type: Boolean,
|
default: false,
|
},
|
},
|
setup(props, { emit }) {
|
const timeText = computed(() => _t('计算中...'))
|
const visible = ref(false)
|
const connectionId = ref('')
|
const dtoJson = ref('')
|
const progress = ref(0)
|
const remainingTime = ref('00:00:00')
|
const elapsedTime = ref(timeText.value)
|
const clearTime = ref(null)
|
const startTime = ref<dayjs.Dayjs>()
|
const isCancel = ref(false)
|
let socket: Socket | null = null
|
const handleClose = () => {
|
visible.value = false
|
clearTime.value && clearTime.value()
|
}
|
/**
|
* 头部配置
|
*/
|
const headers = computed(() => {
|
return {
|
Authorization: `Bearer ${sessionStorage.getItem('Token')}`,
|
'X-Project': sessionStorage.getItem('X-Project'),
|
'Accept-Language': Language.getLangReqHeader(),
|
}
|
})
|
/**
|
* 上传成功
|
*/
|
const onSuccess = () => {
|
if (!isCancel.value) {
|
ElMessage.success(_t('导入成功'))
|
handleClose()
|
}
|
}
|
/**
|
* 失败
|
* @param err
|
*/
|
const onError = (err: any) => {
|
try {
|
const message = JSON.parse(err.message)
|
ElMessage.error(message.msg)
|
} catch (error) {
|
ElMessage.error(_t('导入失败'))
|
}
|
handleClose()
|
}
|
|
const initSocket = () => {
|
return new Promise((resolve, reject) => {
|
socket = new Socket({
|
url: '/hubs/v1/traceImportProgress',
|
name: '追溯导入进度',
|
})
|
|
socket?.connection?.start().then((data: any) => {
|
if (socket) {
|
connectionId.value = socket!.connection!.connectionId
|
dtoJson.value = JSON.stringify({
|
key: connectionId.value,
|
IsInspectionPointTask: props.IsInspectionPointTask,
|
})
|
socket.on(ReceiveProgress, onReceiveProgress)
|
resolve(true)
|
} else {
|
reject(false)
|
}
|
})
|
})
|
}
|
|
const onReceiveProgress = (data: any) => {
|
progress.value = data
|
if (progress.value === 0) {
|
remainingTime.value = timeText.value
|
} else if (progress.value > 0 && progress.value < 100) {
|
const elapsed = dayjs().diff(startTime.value, 'second')
|
const totalEstimatedSeconds = Math.ceil(
|
(elapsed * 100) / progress.value
|
)
|
const remainingSeconds = Math.max(totalEstimatedSeconds - elapsed, 0)
|
|
remainingTime.value = dayjs()
|
.startOf('day')
|
.add(remainingSeconds, 'second')
|
.format('HH:mm:ss')
|
} else if (progress.value >= 100) {
|
remainingTime.value = '00:00:00'
|
clearTime.value && clearTime.value()
|
}
|
}
|
/**
|
* 上传钩子
|
*/
|
const onBeforeUpload = async (file: File) => {
|
const result = await initSocket()
|
if (!result) {
|
return false
|
}
|
const format = ['xlsx', 'xls', 'csv']
|
if (!format.includes(file.name.split('.')[1])) {
|
ElMessage.error(
|
_t('导入文件格式不正确,请导入.xlsx/.xls与.csv格式的文件')
|
)
|
return false
|
}
|
|
visible.value = true
|
clearTime.value = updateTime()
|
return true
|
}
|
|
const updateTime = () => {
|
startTime.value = dayjs()
|
const t = setInterval(() => {
|
elapsedTime.value = dayjs()
|
.startOf('day')
|
.add(dayjs().diff(startTime.value, 'second'), 'second')
|
.format('HH:mm:ss')
|
}, 1000)
|
return () => clearInterval(t)
|
}
|
|
const onOpen = () => {
|
elapsedTime.value = '00:00:00'
|
remainingTime.value = timeText.value
|
progress.value = 0
|
}
|
|
const onCancelImport = async () => {
|
try {
|
await ConfirmBox(_t('是否取消导入'))
|
isCancel.value = true
|
socket?.call(Cancel, connectionId.value).then((res: any) => {
|
visible.value = false
|
clearTime.value && clearTime.value()
|
elapsedTime.value = '00:00:00'
|
remainingTime.value = timeText.value
|
ElMessage.success(_t('取消导入成功'))
|
})
|
} catch (error) {
|
isCancel.value = false
|
}
|
}
|
|
return () => (
|
<Fragment>
|
<el-upload
|
name="file"
|
accept=".xlsx,.xls,.csv"
|
show-file-list={false}
|
data={{ dtoJson: dtoJson.value }}
|
onError={onError}
|
onSuccess={onSuccess}
|
before-upload={onBeforeUpload}
|
headers={headers.value}
|
action="/api/v1/tracemanagement/trace/import"
|
>
|
<IconButton icon="in"></IconButton>
|
</el-upload>
|
<BaseDialog
|
v-model={visible.value}
|
title={_t('导入进度')}
|
onOpen={onOpen}
|
onClose={handleClose}
|
hideClose={true}
|
showFooter={false}
|
v-slots={{
|
footer: () => (
|
<el-button onClick={onCancelImport}>{_t('取消导入')}</el-button>
|
),
|
}}
|
>
|
<div class={styles.processContent}>
|
<div class={styles.processTitle}>{_t('导入进度')}</div>
|
<div class={styles.processItem}>
|
<div
|
class={styles.process}
|
style={{ width: `${progress.value}%` }}
|
></div>
|
</div>
|
</div>
|
<div class={styles.content}>
|
<div class={styles.timeItem}>
|
<span class={styles.label}>{_t('已用时间')}</span>
|
<span class={styles.time}>{elapsedTime.value}</span>
|
</div>
|
<div class={styles.timeItem}>
|
<span class={styles.label}>{_t('剩余时间')}</span>
|
<span class={styles.time}>{remainingTime.value}</span>
|
</div>
|
</div>
|
</BaseDialog>
|
</Fragment>
|
)
|
},
|
})
|