Commit a224ea9d by 焦子成

1

parent 01ebec5a
......@@ -533,6 +533,11 @@ export const useDownloadStore = defineStore('download', () => {
download.status = 'paused'
activeDownloadCount.value--
saveToStorage()
http.post(config.downLoadStatus,{
detailId: download.id,
fileStatus: 2, //下载状态 0:等待中 1:下载中 2:已暂停 3:已完成 4:失败
}).then(res=>{
})
// 只有在非批量下载且非单个下载模式下才自动启动下一个等待中的下载
if (!isBatchDownloading.value && !isSingleDownloading.value) {
startNextPendingDownload()
......
......@@ -14,8 +14,7 @@
<el-icon>
<User />
</el-icon>
<!-- {{ authStore.user?.userName }} -->
{{ userName }}
{{ userName }}
<el-icon>
<ArrowDown />
</el-icon>
......@@ -127,7 +126,7 @@
</div>
</template>
</el-alert>
</div>
</div>
</div>
</div>
......@@ -235,7 +234,7 @@
<div class="download-actions">
<!-- 状态筛选 -->
<!-- <el-select v-model="statusFilter" placeholder="按状态筛选" clearable style="width: 150px; margin-right: 10px;"
<el-select v-model="statusFilter" placeholder="按状态筛选" clearable style="width: 150px; margin-right: 10px;"
@change="handleStatusFilterChange">
<el-option label="全部" value="" />
<el-option label="等待中" value="pending" />
......@@ -243,15 +242,6 @@
<el-option label="已暂停" value="paused" />
<el-option label="已完成" value="completed" />
<el-option label="失败" value="error" />
</el-select> -->
<el-select v-model="fileStatus" placeholder="按状态筛选" clearable
style="width: 150px; margin-right: 10px;" @change="handleStatusFilterChange">
<el-option label="全部" value="" />
<el-option label="等待中" :value="0" />
<el-option label="下载中" :value="1" />
<el-option label="已暂停" :value="2" />
<el-option label="已完成" :value="3" />
<el-option label="失败" :value="4" />
</el-select>
<!-- 页面级别操作 -->
......@@ -262,15 +252,9 @@
暂停当前页
</el-button>
<el-divider direction="vertical" />
<!-- <el-button @click="downloadStore.clearCompleted" size="small">
清除已完成
</el-button> -->
<el-button @click="clearCompleted" size="small">
清除已完成
</el-button>
<!-- <el-button @click="downloadStore.clearAll" type="danger" size="small">
清除所有
</el-button> -->
<el-button @click="clearAll" type="danger" size="small">
清除所有
</el-button>
......@@ -363,7 +347,7 @@
<template #default="{ row }">
<span v-if="row.status == 'pending'">-</span>
<span v-else class="size-info">
{{ row.fileSize }}
{{ row.fileSize }}
</span>
</template>
</el-table-column>
......@@ -381,19 +365,15 @@
暂停
</el-button> -->
<!-- <el-button v-if="row.status === 'paused'" @click="resumeSingleDownload(row.id)" type="success"
<el-button v-if="row.status === 'paused'" @click="resumeSingleDownload(row.id)" type="success"
size="small">
继续
</el-button> -->
</el-button>
<el-button v-if="row.status === 'error'" @click="startSingleDownload(row.id)" type="warning"
size="small">
重试
</el-button>
<!-- <el-button @click="downloadStore.cancelDownload(row.id)" type="danger" size="small">
删除
</el-button> -->
<el-button @click="deleteRow(row)" type="danger" size="small">
删除
</el-button>
......@@ -427,7 +407,22 @@ import config from '@/api/api.js';
import axios from "axios";
import { el, ro } from 'element-plus/es/locales.mjs'
const statusMap = {
0: 'pending',
1: 'downloading',
2: 'paused',
3: 'completed',
4: 'error'
}
const statusMap1 = {
'pending': 0,
'downloading': 1,
'paused': 2,
'completed': 3,
'error': 4
}
const userName = ref('')
const router = useRouter()
const authStore = useAuthStore()
const downloadStore = useDownloadStore()
......@@ -446,7 +441,6 @@ const activeCollapse = ref(['upload']) // 默认展开配置区域
// 分页相关
const currentPage = ref(1)
const pageSize = ref(10)
const fileStatus = ref('')
// 已上传文件列表
let upQuery = ref({
current: 1,
......@@ -455,12 +449,6 @@ let upQuery = ref({
let upTableData = reactive([])
let upTotal = ref(0)
// 下载任务管理列表
// let deQuery = ref({
// current: 1,
// pageSize: 10,
// fileStatus: ''
// })
let deTableData = reactive([])
let deTotal = ref(0)
let columnMapping = ref({
......@@ -479,25 +467,10 @@ const canParse = computed(() => {
previewData.value.length > 0
})
// 已上传 Excel 文件列表数据加载
const loadUpTableData = () => {
http.post(config.uploadBatchList, upQuery.value).then(res => {
if (res.code === 200) {
for (let element of res.data.rows) {
element.createTime = element.createTime ? element.createTime.substring(0, 10) : ''
}
upTableData = res.data.rows
upTotal.value = res.data.total
} else {
ElMessage.error(res.message)
}
})
}
// 计算分页后的下载列表
const paginatedDownloads = computed(() => {
const start = (currentPage.value - 1) * pageSize.value
const end = start + pageSize.value
// const start = (currentPage.value - 1) * pageSize.value
// const end = start + pageSize.value
// return filteredDownloads.value.slice(start, end)
return filteredDownloads.value.slice(0)
})
......@@ -549,6 +522,7 @@ const selectExcelFile = async (fileId) => {
ElMessage.error('文件信息不存在')
return
}
downloadStore.setCurrentExcelFile(fileId)
selectedFile.value = {
name: res.data.uploadName,
}
......@@ -562,7 +536,9 @@ const selectExcelFile = async (fileId) => {
url: element.fileUrl
})
}
// 总数据
rawExcelData.value = list || []
// 生成预览数据
if (list.length > 5) {
previewData.value = list.slice(0, 5)
} else {
......@@ -583,21 +559,22 @@ const deleteExcelFile = async (fileId) => {
return
}
// try {
// await downloadStore.deleteExcelFile(fileId)
// ElMessage.success('Excel文件已删除')
// } catch (error) {
// console.error('删除Excel文件失败:', error)
// ElMessage.error('删除Excel文件失败: ' + (error.message || '未知错误'))
// }
http.post(config.uploadBatchDelete, { batchId: fileId }).then(res => {
if (res.code === 200) {
ElMessage.success('Excel文件已删除')
loadUpTableData()
} else {
ElMessage.error(res.message)
}
})
try {
await downloadStore.deleteExcelFile(fileId)
ElMessage.success('Excel文件已删除')
http.post(config.uploadBatchDelete, { batchId: fileId }).then(res => {
if (res.code === 200) {
loadUpTableData()
} else {
ElMessage.error(res.message)
}
})
} catch (error) {
console.error('删除Excel文件失败:', error)
ElMessage.error('删除Excel文件失败: ' + (error.message || '未知错误'))
}
}
// 处理文件选择
......@@ -785,7 +762,6 @@ const getFileExtensionFromUrl = (url) => {
return extension
}
}
// 如果没有找到有效的扩展名,返回.tmp
return '.tmp'
} catch (error) {
......@@ -795,20 +771,20 @@ const getFileExtensionFromUrl = (url) => {
}
// 选择下载路径
// const selectDownloadPath = () => {
// ElMessageBox.prompt('请输入自定义子文件夹名称', '设置下载子文件夹', {
// confirmButtonText: '确定',
// cancelButtonText: '取消',
// inputValue: customSubFolder.value,
// inputPlaceholder: '例如: vue-downloader-files (留空则直接下载到默认路径)'
// }).then(({ value }) => {
// customSubFolder.value = value
// updateDownloadPath()
// ElMessage.success('下载路径已设置')
// }).catch(() => {
// // 用户取消
// })
// }
const selectDownloadPath = () => {
ElMessageBox.prompt('请输入自定义子文件夹名称', '设置下载子文件夹', {
confirmButtonText: '确定',
cancelButtonText: '取消',
inputValue: customSubFolder.value,
inputPlaceholder: '例如: vue-downloader-files (留空则直接下载到默认路径)'
}).then(({ value }) => {
customSubFolder.value = value
updateDownloadPath()
ElMessage.success('下载路径已设置')
}).catch(() => {
// 用户取消
})
}
// 清空文件名前缀
const clearFileNamePrefix = () => {
......@@ -828,7 +804,7 @@ const updateDownloadPath = () => {
// 更新store中的文件名前缀
downloadStore.setCustomSubFolder(customSubFolder.value)
}
const userName = ref('')
// 组件挂载时初始化
onMounted(() => {
// 先初始化下载store
......@@ -841,20 +817,28 @@ onMounted(() => {
detectBrowserDownloadPath()
loadUpTableData()
loadDetailTableData()
})
const statusMap = {
0: 'pending',
1: 'downloading',
2: 'paused',
3: 'completed',
4: 'error'
// 已上传 Excel 文件列表数据加载
const loadUpTableData = () => {
http.post(config.uploadBatchList, upQuery.value).then(res => {
if (res.code === 200) {
for (let element of res.data.rows) {
element.createTime = element.createTime ? element.createTime.substring(0, 10) : ''
}
upTableData = res.data.rows
upTotal.value = res.data.total
} else {
ElMessage.error(res.message)
}
})
}
function loadDetailTableData() {
http.post(config.uploadDetailList, {
current: currentPage.value,
size: pageSize.value,
fileStatus: fileStatus.value
fileStatus: statusMap1[statusFilter.value]
}).then(res => {
if (res.code === 200) {
var list = []
......@@ -882,16 +866,16 @@ function loadDetailTableData() {
})
}
// console.log('--lsit:',list)
// deTableData = res.data.rows
downloadStore.downloads = list
downloadStore.setCustomSubFolder(filePrefix)
deTotal.value = res.data.total
customSubFolder.value = filePrefix
loadUploadDetailTotalNum()
} else {
ElMessage.error(res.message)
}
})
}
let totalNumObj = ref({
countNum: 0,
fileLength: '',
......@@ -916,12 +900,12 @@ function loadUploadDetailTotalNum() {
// 清除已完成
function clearCompleted() {
downloadStore.clearCompleted()
http.post(config.uploadDetailDeleteAll, {
type: 0
}).then(res => {
if (res.code === 200) {
ElMessage.success(res.message)
// deQuery.value.current = 1
currentPage.value = 1
// loadUploadDetailList()
loadDetailTableData()
......@@ -932,6 +916,7 @@ function clearCompleted() {
}
// 清除所有
function clearAll() {
downloadStore.clearAll()
http.post(config.uploadDetailDeleteAll, {
type: 1
}).then(res => {
......@@ -947,14 +932,13 @@ function clearAll() {
}
// 删除单行
function deleteRow(row) {
downloadStore.cancelDownload(row.id)
http.post(config.uploadDetailDelete, {
detailId: row.detailId
}).then(res => {
if (res.code === 200) {
ElMessage.success(res.message)
// deQuery.value.current = 1
currentPage.value = 1
// loadUploadDetailList()
loadDetailTableData()
} else {
ElMessage.error(res.message)
......@@ -972,6 +956,7 @@ const parseExcelFile = async () => {
ElMessage.warning('请先选择Excel文件并配置列映射')
return
}
// 数据预览列表 URL 列必须是有效的 HTTP/HTTPS URL
const url = previewData.value[0]?.url
if (!url || !/^https?:\/\//i.test(url)) {
ElMessage.warning('预览数据中的URL格式不正确,请检查列映射')
......@@ -1030,7 +1015,8 @@ const parseExcelFile = async () => {
ElMessage.warning('Excel文件中没有找到有效数据')
return
}
// 保存文件到本地之前先删除本地所有文件
downloadStore.clearAll()
// 保存Excel文件到本地存储
processingProgress.value = 30
processingMessage.value = '正在保存Excel文件到本地...'
......@@ -1147,8 +1133,10 @@ function getDetailList() {
return preview
}
var upDetailId = ''
let detailList = reactive([])
function uploadDetails() {
detailList = getDetailList()
http.post(config.uploadBatchFileUpload, {
......@@ -1163,7 +1151,6 @@ function uploadDetails() {
// details: detailList
}).then(res => {
if (res.code === 200) {
// loadDetailTableData()
upDetailId = res.data
uploadDetailsFile()
} else {
......@@ -1181,7 +1168,6 @@ function uploadDetailsFile() {
uplist = detailList
detailList = []
}
// console.log('list-->', detailList.length)
http.post(config.fileUploadDetail, {
batchId: upDetailId,
details: uplist
......@@ -1201,7 +1187,6 @@ function uploadDetailsFile() {
// 下载当前页所有任务
const downloadCurrentPage = async () => {
const currentPageItems = paginatedDownloads.value
// const currentPageItems = deTableData
if (currentPageItems.length === 0) {
ElMessage.warning('当前页没有下载任务')
return
......@@ -1211,16 +1196,12 @@ const downloadCurrentPage = async () => {
const startableItems = currentPageItems.filter(item =>
['pending', 'paused', 'error'].includes(item.status)
)
// const startableItems = currentPageItems.filter(item =>
// [0, 2, 4].includes(item.fileStatus)
// )
if (startableItems.length === 0) {
ElMessage.warning('当前页没有可以开始下载的任务')
return
}
// console.log('currentPageItems-->',currentPageItems)
// console.log('startableItems-->',startableItems)
try {
await ElMessageBox.confirm(`确定要下载当前页的 ${startableItems.length} 个任务吗?`, '下载当前页', {
confirmButtonText: '确定',
......@@ -1239,21 +1220,20 @@ const downloadCurrentPage = async () => {
// 用户取消
}
}
// async function getFileSize(url) {
// try {
// const response = await axios.head(url);
// const size = response.headers["content-length"];
// return size ? parseInt(size, 10) : null;
// } catch (err) {
// console.error("获取文件大小失败:", err);
// return null;
// }
// }
async function getFileSize(url) {
try {
const response = await axios.head(url);
const size = response.headers["content-length"];
return size ? parseInt(size, 10) : null;
} catch (err) {
console.error("获取文件大小失败:", err);
return null;
}
}
// 暂停当前页所有任务
const pauseCurrentPage = async () => {
const currentPageItems = paginatedDownloads.value
// const currentPageItems = deTableData
if (currentPageItems.length === 0) {
ElMessage.warning('当前页没有下载任务')
return
......@@ -1288,29 +1268,25 @@ const pauseCurrentPage = async () => {
}
}
// 处理分页大小变化
// 处理下载任务管理 列表分页条数变化
const handleSizeChange = (size) => {
// deQuery.value.pageSize = size
// deQuery.value.current = 1
pageSize.value = size
currentPage.value = 1
loadDetailTableData()
}
// 处理当前页变化
// 处理下载任务管理 列表页码变化
const handleCurrentChange = (page) => {
// deQuery.value.current = page
currentPage.value = page
loadDetailTableData()
}
// 处理已上传Excel文件 列表分页条数变化
const handleUpSizeChange = (size) => {
upQuery.value.pageSize = size
upQuery.value.current = 1
loadUpTableData()
}
// 处理当前页变化
// 处理已上传Excel文件 列表页码变化
const handleUpCurrentChange = (page) => {
upQuery.value.current = page
loadUpTableData()
......@@ -1318,9 +1294,7 @@ const handleUpCurrentChange = (page) => {
// 处理状态筛选变化
const handleStatusFilterChange = () => {
// currentPage.value = 1 // 重置当前页为1,以便重新加载数据
// deQuery.value.current = 1
currentPage.value = 1
currentPage.value = 1 // 重置当前页为1,以便重新加载数据
loadDetailTableData()
}
......@@ -1330,6 +1304,7 @@ const startSingleDownload = async (downloadId) => {
try {
await downloadStore.startDownload(downloadId)
loadDetailTableData()
loadUploadDetailTotalNum()
} finally {
downloadStore.isSingleDownloading = false
}
......@@ -1340,6 +1315,8 @@ const resumeSingleDownload = async (downloadId) => {
downloadStore.isSingleDownloading = true
try {
await downloadStore.resumeDownload(downloadId)
loadDetailTableData()
loadUploadDetailTotalNum()
} finally {
downloadStore.isSingleDownloading = false
}
......@@ -1581,5 +1558,4 @@ const handleUserCommand = (command) => {
.user-info:hover {
background-color: #f5f5f5;
}
</style>
uo
\ No newline at end of file
</style>
\ No newline at end of file
......@@ -130,15 +130,13 @@
<el-table-column prop="fileSize" label="文件大小" width="120">
<template #default="scope">
<!-- {{ formatFileSize(scope.row.fileSize) }} -->
{{ scope.row.fileSize }}
{{ scope.row.status=='completed' ? scope.row.fileSize : '-' }}
</template>
</el-table-column>
<el-table-column prop="downloadedBytes" label="已下载" width="120">
<template #default="scope">
<!-- {{ formatFileSize(scope.row.downloadedBytes) }} -->
{{ scope.row.fileSize }}
{{ scope.row.status=='completed' ? scope.row.fileSize : '-' }}
</template>
</el-table-column>
......@@ -436,7 +434,6 @@ const getStatusText = (status) => {
// 查看详情
const viewDetails = (record) => {
// selectedRecord.value = record
http.post(config.detailInfo,{detailId: record.id}).then(res=>{
if (res.code === 200){
selectedRecord.value = {
......@@ -448,7 +445,7 @@ const viewDetails = (record) => {
"status": statusMap[res.data.fileStatus],
"progress": res.data.fileStatus == 3 ? 100: 0,
"fileSize": res.data.fileLength,
"downloadedBytes": res.data.fileStatus == 3 ? res.data.fileLength: '0 KB',
"downloadedBytes": res.data.fileStatus == 3 ? res.data.fileLength: '-',
"startTime": res.data.createTime,
"endTime": '',
"error": res.data.errorMsg
......@@ -492,16 +489,15 @@ const clearAllHistory = async () => {
type: 'warning'
}
)
authStore.clearDownloadHistory()
// loadHistory()
// ElMessage.success('历史记录已清空')
http.post(config.uploadDetailDeleteAll, {
type: 1
}).then(res => {
if (res.code === 200) {
loadHistory()
ElMessage.success('历史记录已清空')
loadHistory()
loadUploadDetailTotalNum()
} else {
ElMessage.error(res.message)
}
......@@ -515,14 +511,11 @@ const clearAllHistory = async () => {
const handleSizeChange = (size) => {
pageSize.value = size
currentPage.value = 1
// deQuery.value.pageSize = size
// deQuery.value.current = 1
loadHistory()
}
const handleCurrentChange = (page) => {
currentPage.value = page
// deQuery.value.current = page
loadHistory()
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment