Java基础-JVM

阅读 15

2024-11-06

概览

uniapp实现多文件下载,保存到本地,因为使用的是uni.downloadFile 实现文件的下载,每次只能下载一个,需要下载多个文件,并保存到本地,并把保存的地址存储到对应的数据组中,并实现进度条显示。

需求分析

1、文件下载并保存到本地 直接使用uni.downloadFile 和uni.saveFile 两个方法既可以实现。

2、如有多个文件下载,需要异步一个一个去下载,并把保存到本地的路径赋值给传过来的数据。

3、如果使用for循环,会存存储数据混乱的情况,或者说直接保存的路径只保存到了最后一个数组对象中,无法实现保存对应的存储路径到数组。

4、进度条显示,根据下载的方法,进行监听进度返回到页面进行显示进度条的变化。

具体实现

download.js 代码

// +----------------------------------------------------------------------
// | 下载工具类
// +----------------------------------------------------------------------
import {
HTTP_REQUEST_URL
} from '@/config/app';
export const hostUrlUpLoad = HTTP_REQUEST_URL + '/upload/';
export const hostUrl = HTTP_REQUEST_URL;
import {
getStudyData,
getTestData
} from '@/api/api.js';

/**
* 下载分类相关数据
* 图片加载到本地
* @returns boolean
*/

export async function downloadClass(data, inta) {
if (data.length > 0 && inta < data.length) {
try {
const downloadTask = await uni.downloadFile({
url: data[inta].icon_path.includes('upload') ? hostUrl + data[inta].icon_path :
hostUrlUpLoad + data[inta].icon_path,
success: res => {
if (res.statusCode === 200) {
uni.saveFile({
tempFilePath: res.tempFilePath, // 下载文件的临时路径
success: saveRes => {
data[inta].icon_path = saveRes.savedFilePath
if (inta < data.length - 1) {
inta = inta + 1
downloadClass(data, inta)
} else {
uni.setStorageSync('classData', data)
}
},
fail: err => {
if (inta < data.length - 1) {
inta = inta + 1
downloadClass(data, inta)
} else {
uni.setStorageSync('classData', data)
}
}
});
} else {
if (inta < data.length - 1) {
inta = inta + 1
downloadClass(data, inta)
} else {
uni.setStorageSync('classData', data)
}
}
},
fail: err => {
if (inta < data.length - 1) {
inta = inta + 1
downloadClass(data, inta)
} else {
uni.setStorageSync('classData', data)
}
}
});
downloadTask.onProgressUpdate(resda => {})
} catch (e) {
if (inta < data.length - 1) {
inta = inta + 1
downloadClass(data, inta)
} else {
uni.setStorageSync('classData', data)
}
//TODO handle the exception
}
}
}

/**
* 下载科目数据
* 图片加载到本地
* @returns boolean
*/

export async function downloadSubject(data, inta, callBack) {
var callBackFun = callBack;
if (data.length > 0 && inta < data.length) {
try {
const downloadTask = await uni.downloadFile({
url: data[inta].icon_path.includes('upload') ? hostUrl + data[inta].icon_path :
hostUrlUpLoad + data[inta].icon_path,
success: res => {
if (res.statusCode === 200) {
uni.saveFile({
tempFilePath: res.tempFilePath, // 下载文件的临时路径
success: saveRes => {
data[inta].icon_path = saveRes.savedFilePath
if (inta < data.length - 1) {
inta = inta + 1
downloadSubject(data, inta, callBackFun)
} else {
uni.setStorageSync('SubjectData', data, callBackFun)
requestSubjectClass(data, 0, callBackFun)
}
},
fail: err => {
if (inta < data.length - 1) {
inta = inta + 1
downloadSubject(data, inta, callBackFun)
} else {
uni.setStorageSync('SubjectData', data)
requestSubjectClass(data, 0, callBackFun)
}
}
});
} else {
if (inta < data.length - 1) {
inta = inta + 1
downloadSubject(data, inta, callBackFun)
} else {
uni.setStorageSync('SubjectData', data)
requestSubjectClass(data, 0, callBackFun)
}
}
},
fail: err => {
if (inta < data.length - 1) {
inta = inta + 1
downloadSubject(data, inta, callBackFun)
} else {
uni.setStorageSync('SubjectData', data)
requestSubjectClass(data, 0, callBackFun)
}
}
});
downloadTask.onProgressUpdate(resda => {
callBackFun(resda.progress, false)
})
} catch (e) {
//TODO handle the exception
if (inta < data.length - 1) {
inta = inta + 1
downloadSubject(data, inta, callBackFun)
} else {
uni.setStorageSync('SubjectData', data)
requestSubjectClass(data, 0, callBackFun)
}
}
}
}


/**
* 根据科目列表赋值分类数据
* @param {Object} data
* @param {Object} inta
*/

export async function requestSubjectClass(data, inta, callBack) {
const callBackFun = callBack;
if (data.length > 0 && inta < data.length) {
try {
await getStudyData(data[inta].id).then(res => {
if (res.data.code == 200 && res.data.status == 'success' && res.data.data.count > 0) {
data[inta].categoryData = res.data.data.list
if (inta < data.length - 1) {
inta = inta + 1
requestSubjectClass(data, inta, callBackFun)
} else {
uni.setStorageSync('SubjectData', data)
downloadSubjectFile(data, 0, 0, callBackFun)
}
} else {
if (inta < data.length - 1) {
inta = inta + 1
requestSubjectClass(data, inta, callBackFun)
} else {
uni.setStorageSync('SubjectData', data)
downloadSubjectFile(data, 0, 0, callBackFun)
}
}
})
} catch (e) {
//TODO handle the exception
if (inta < data.length - 1) {
inta = inta + 1
requestSubjectClass(data, inta, callBackFun)
} else {
uni.setStorageSync('SubjectData', data)
downloadSubjectFile(data, 0, 0, callBackFun)
}
}
}
}

/**
* 下载文件到本地
* @returns boolean
*/

export async function downloadSubjectFile(data, inta, intaClass, callBack) {
const callBackFun = callBack;
if (data.length > 0 && inta < data.length) {
if (data[inta].categoryData.length > 0 && intaClass < data[inta].categoryData.length) {
try {
var filePath = ''
if (data[inta].categoryData[intaClass].file_path.includes('upload')) {
if (data[inta].categoryData[intaClass].file_path.charAt(0) == '/') {
filePath = hostUrl + data[inta].categoryData[intaClass].file_path
} else {
filePath = "http://" + data[inta].categoryData[intaClass].file_path
}
} else {
filePath = hostUrlUpLoad + data[inta].categoryData[intaClass].file_path
}
const downloadTask = await uni.downloadFile({
url: filePath,
success: res => {
if (res.statusCode === 200) {
uni.saveFile({
tempFilePath: res.tempFilePath, // 下载文件的临时路径
success: saveRes => {
data[inta].categoryData[intaClass].file_path = saveRes.savedFilePath
if (intaClass < data[inta].categoryData.length - 1) {
intaClass = intaClass + 1
downloadSubjectFile(data, inta, intaClass,callBackFun)
} else {
if (inta < data.length - 1) {
inta = inta + 1
downloadSubjectFile(data, inta, 0, callBackFun)
} else {
uni.setStorageSync('SubjectData', data)
callBackFun(100, true)
}
}
},
fail: err => {
console.log("保存文件失败 ")
if (intaClass < data[inta].categoryData.length - 1) {
intaClass = intaClass + 1
downloadSubjectFile(data, inta, intaClass,
callBackFun)
} else {
if (inta < data.length - 1) {
inta = inta + 1
downloadSubjectFile(data, inta, 0, callBackFun)
} else {
uni.setStorageSync('SubjectData', data)
callBackFun(100, true)
}
}
}
});
} else {
if (intaClass < data[inta].categoryData.length - 1) {
intaClass = intaClass + 1
downloadSubjectFile(data, inta, intaClass, callBackFun)
} else {
if (inta < data.length - 1) {
inta = inta + 1
downloadSubjectFile(data, inta, 0, callBackFun)
} else {
uni.setStorageSync('SubjectData', data)
callBackFun(100, true)
}
}
}
},
fail: err => {
console.log("下载失败 fail ")
if (intaClass < data[inta].categoryData.length - 1) {
intaClass = intaClass + 1
downloadSubjectFile(data, inta, intaClass, callBackFun)
} else {
if (inta < data.length - 1) {
inta = inta + 1
downloadSubjectFile(data, inta, 0, callBackFun)
} else {
uni.setStorageSync('SubjectData', data)
callBackFun(100, true)
}
}
}
});
downloadTask.onProgressUpdate(resda => {
callBackFun(resda.progress, false)
})
} catch (e) {
//TODO handle the exception
console.log("downloadSubjectFile catch " + JSON.stringify(e))
if (intaClass < data[inta].categoryData.length - 1) {
intaClass = intaClass + 1
downloadSubjectFile(data, inta, intaClass, callBackFun)
} else {
if (inta < data.length - 1) {
inta = inta + 1
downloadSubjectFile(data, inta, 0, callBackFun)
} else {
console.log("打印保存的科目数据 downloadSubjectFile " + JSON.stringify(data))
uni.setStorageSync('SubjectData', data)
callBackFun(100, true)
}
}
}
} else {
if (intaClass < data[inta].categoryData.length - 1) {
intaClass = intaClass + 1
downloadSubjectFile(data, inta, intaClass, callBackFun)
} else {
if (inta < data.length - 1) {
inta = inta + 1
downloadSubjectFile(data, inta, 0, callBackFun)
} else {
console.log("打印保存的科目数据 downloadSubjectFile " + JSON.stringify(data))
uni.setStorageSync('SubjectData', data)
callBackFun(100, true)
}
}
}

}
}



/**
* 根据科目列表获取题库
* @param {Object} subjectData
*/

export async function requestSubjectTestData(subjectData) {
try {
await getTestData(subjectData.id).then(res => {
if (res.data.code == 200 && res.data.status == 'success') {
uni.removeStorageSync('CNLLIST' + subjectData.id)
uni.removeStorageSync('CNLLISTCOUNT' + subjectData.id)
uni.removeStorageSync('ENLLIST' + subjectData.id)
uni.removeStorageSync('ENLLISTCOUNT' + subjectData.id)
uni.setStorageSync('CNLLIST' + subjectData.id, res.data.data.list)
uni.setStorageSync('CNLLISTCOUNT' + subjectData.id, res.data.data.count)
uni.setStorageSync('ENLLIST' + subjectData.id, res.data.data.english_list)
uni.setStorageSync('ENLLISTCOUNT' + subjectData.id, res.data.data.english_count)
} else {
uni.removeStorageSync('CNLLIST' + subjectData.id)
uni.removeStorageSync('CNLLISTCOUNT' + subjectData.id)
uni.removeStorageSync('ENLLIST' + subjectData.id)
uni.removeStorageSync('ENLLISTCOUNT' + subjectData.id)
}
})
} catch (e) {
console.log('报错信息 ' + JSON.stringify(subjectData.id))
//TODO handle the exception
}
}

/**
* 根据科目列表赋值分类数据
* @param {Object} data
* @param {Object} inta
*/

export async function requestSubjectClassSize(data, inta, callBack) {
if (data.length > 0 && inta < data.length) {
try {
await getStudyData(data[inta].id).then(res => {
if (res.data.code == 200 && res.data.status == 'success' && res.data.data.count > 0) {
data[inta].categoryData = res.data.data.list
if (inta < data.length - 1) {
inta = inta + 1
requestSubjectClassSize(data, inta, callBack)
} else {
requestDownloadFileSize(data, 0, 0,0, callBack)
}
} else {
if (inta < data.length - 1) {
inta = inta + 1
requestSubjectClassSize(data, inta, callBack)
} else {
requestDownloadFileSize(data, 0, 0,0, callBack)
}
}
})
} catch (e) {
//TODO handle the exception
if (inta < data.length - 1) {
inta = inta + 1
requestSubjectClassSize(data, inta, callBack)
} else {
requestDownloadFileSize(data, 0, 0,0, callBack)
}
}
}
}


/**
* 下载文件总大小
* @returns boolean
*/

export async function requestDownloadFileSize(data, inta, intaClass, contentLength, callBack) {
if (data.length > 0 && inta < data.length) {
if (data[inta].categoryData.length > 0 && intaClass < data[inta].categoryData.length) {
try {
var filePath = ''
if (data[inta].categoryData[intaClass].file_path.includes('upload')) {
if (data[inta].categoryData[intaClass].file_path.charAt(0) == '/') {
filePath = hostUrl + data[inta].categoryData[intaClass].file_path
} else {
filePath = "http://" + data[inta].categoryData[intaClass].file_path
}
} else {
filePath = hostUrlUpLoad + data[inta].categoryData[intaClass].file_path
}
await uni.request({
url: filePath,
method: 'head',
// responseType: 'arraybuffer', // 或者其他如'text'、'blob'等,取决于你需要的内容类型
// header: {
// 'Accept-Encoding': 'gzip, deflate'
// },
success(res) {

if (res.statusCode === 200) {
if (intaClass < data[inta].categoryData.length - 1) {
intaClass = intaClass + 1
if(res.header['Content-Length'] || res.header['content-length']){
console.log("filePath " + filePath + ' ' + JSON.stringify(res.header['Content-Length']))
contentLength = contentLength + parseInt(res.header['Content-Length']?res.header['Content-Length']:res.header['content-length'],10); // 获取Content-Length字段的值
}
requestDownloadFileSize(data, inta, intaClass,contentLength,callBack)
} else {
if (inta < data.length - 1) {
inta = inta + 1
if(res.header['Content-Length'] || res.header['content-length']){
contentLength = contentLength + parseInt(res.header['Content-Length']?res.header['Content-Length']:res.header['content-length'],10); // 获取Content-Length字段的值
}
requestDownloadFileSize(data, inta, 0,contentLength, callBack)
} else {
callBack(contentLength)
}
}
} else {
if (intaClass < data[inta].categoryData.length - 1) {
intaClass = intaClass + 1
requestDownloadFileSize(data, inta, intaClass,contentLength, callBack)
} else {
if (inta < data.length - 1) {
inta = inta + 1
requestDownloadFileSize(data, inta, 0,contentLength, callBack)
} else {
callBack(contentLength)
}
}
}
},
error(err) {
console.error('请求错误:', err);
if (intaClass < data[inta].categoryData.length - 1) {
intaClass = intaClass + 1
requestDownloadFileSize(data, inta, intaClass,contentLength, callBack)
} else {
if (inta < data.length - 1) {
inta = inta + 1
requestDownloadFileSize(data, inta, 0,contentLength, callBack)
} else {
callBack(contentLength)
}
}
},
networkTimeout: 5000, // 设置超时时间
timeout: 5000 // 设置整体请求超时时间
})
} catch (e) {
//TODO handle the exception
console.log("requestDownloadFileSize catch " + JSON.stringify(e))
if (intaClass < data[inta].categoryData.length - 1) {
intaClass = intaClass + 1
requestDownloadFileSize(data, inta, intaClass,contentLength, callBack)
} else {
if (inta < data.length - 1) {
inta = inta + 1
requestDownloadFileSize(data, inta, 0,contentLength, callBack)
} else {
callBack(contentLength)
}
}
}
} else {
if (intaClass < data[inta].categoryData.length - 1) {
intaClass = intaClass + 1
requestDownloadFileSize(data, inta, intaClass,contentLength, callBack)
} else {
if (inta < data.length - 1) {
inta = inta + 1
requestDownloadFileSize(data, inta, 0,contentLength, callBack)
} else {
callBack(contentLength)
}
}
}

}
}



/**
* @param {Object} data
* @param {Object} inta
* @param {Object} contentLength
* @param {Object} callBack
*/

export async function requestFileSize(data, inta, contentLength, callBack) {
if (data.length > 0 && inta < data.length) {
try {
uni.request({
url: downloadUrl,
method: 'GET',
responseType: 'arraybuffer', // 或者其他如'text'、'blob'等,取决于你需要的内容类型
header: {
'Accept-Encoding': 'gzip, deflate'
},
success(res) {
if (res.statusCode === 200 && res.data) {
if (inta < data.length - 1) {
inta = inta + 1
if(res.header['Content-Length'] || res.header['content-length']){
contentLength = contentLength + parseInt(res.header['Content-Length']?res.header['Content-Length']:res.header['content-length'],10); // 获取Content-Length字段的值
}
console.log(contentLength + ' 字节');
requestFileSize(data, inta, contentLength, callBack)
} else {
callBack(contentLength)
}
} else {
if (inta < data.length - 1) {
inta = inta + 1
requestFileSize(data, inta, contentLength, callBack)
} else {
callBack(contentLength)
}
}
},
error(err) {
console.error('请求错误:', err);
if (inta < data.length - 1) {
inta = inta + 1
requestFileSize(data, inta, contentLength, callBack)
} else {
callBack(contentLength)
}
},
networkTimeout: 5000, // 设置超时时间
timeout: 5000 // 设置整体请求超时时间
});
} catch (e) {
//TODO handle the exception
if (inta < data.length - 1) {
inta = inta + 1
requestFileSize(data, inta, contentLength, callBack)
} else {
callBack(contentLength)
}
}
}
}


export default {
downloadClass,
downloadSubject,
requestSubjectTestData,
requestDownloadFileSize,
requestSubjectClassSize
};

实现的逻辑是,下载完成一个文件,然后把保存到本地的路径存储到传过来对应的数据中,把原来线上的文件地址替换为本地路径,然后在进行下一个。

进度条显示

<template>
	<view style="width: 100%;height: 100%;display: flex;align-items: center;justify-content: center;position: relative;">
		<view style="position: absolute;top: 80rpx;display: flex;flex-direction: column;align-items: center;justify-content: center;">
			<image src="../../static/kaoshilogo.png" style="width: 80rpx;" mode="widthFix"></image>
			<view style="margin-top: 20rpx;font-family: Source Han Sans-Bold;font-size: 18rpx;">{{language.AppName}}</view>
		</view>
		<view style="position: absolute;bottom: 30rpx;width: 100%;display: flex;align-items: center;justify-content: center;flex-direction: column;">
			<view style="width: 60%;font-size: 8rpx;text-align: center;margin-bottom: 3rpx;">{{language.zhengzaigengxinziliao}}</view>
			<view class="progress-bar">
				<view class="progress-bar__fill" :style="{width: progress}"></view>
			</view>
		</view>
		
	</view>
</template>

<script>
	import {
		getSubjectData,
		getClassData,
		getList,
		uploadStudyTime,
		uploadTestData,
		uploadOpen
	} from '@/api/api.js'
	export default {
		data() {
			return {
				fileManager: null,
				openData: [],
				progress: '',
				language: getApp().globalData.language,
			}
		},
		onLoad() {
			this.uploadOpen()
			//获取总分类数据
			if (!uni.getStorageSync("classData")) {
				this.getClassDataPage()
			}
			//获取科目数据
			if (!uni.getStorageSync("SubjectData")) {
				this.getSubjectDataPage()
			}else{
				if(uni.getStorageSync('userInfo')){
					uni.switchTab({
						url: '/pages/home/home'
					})
				}else{
					uni.navigateTo({
						url: '/pages/login/login'
					})
				}
			}
			if(uni.getStorageSync('userInfo') && uni.getStorageSync('userInfo').userName != 'Guest'){
				if(uni.getStorageSync('uploadTime')){
					this.uploadSyudyTime()
				}
				if(uni.getStorageSync('uploadTestTime')){
					this.uploadTestTime()
				}
			}
		},
		methods: {
			async getClassDataPage(){
				var that = this
				await getClassData().then(res => {
					if (res.data.code == 200 && res.data.status == 'success') {
						that.$download.downloadClass(res.data.data.list, 0)
					} else if (res.statusCode == '404' || res.status == 1) {
						console.log("网路请求失败")
					} else {
						console.log(res)
					}
				})
			},
			async getSubjectDataPage(){
				var that = this
				await getSubjectData().then(res => {
					if (res.data.code == 200 && res.data.status == 'success') {
						if(res.data && res.data.data && res.data.data.list && res.data.data.list.length > 0){
							for (var i = 0; i < res.data.data.list.length; i++) {
								this.$download.requestSubjectTestData(res.data.data.list[i]);
							}
							this.$download.downloadSubject(res.data.data.list, 0,function(progress,boobleTo){
								that.progress = progress + "%"
								if(boobleTo){
									getApp().globalData.version = '1.0.' + that.$utils.formatDateTime()
									if(uni.getStorageSync('userInfo')){
										uni.switchTab({
											url: '/pages/home/home'
										})
									}else{
										uni.navigateTo({
											url: '/pages/login/login'
										})
									}
								}
							});
						}else{
							if(uni.getStorageSync('userInfo')){
								uni.switchTab({
									url: '/pages/home/home'
								})
							}else{
								uni.navigateTo({
									url: '/pages/login/login'
								})
							}
						}
					} else if (res.statusCode == '404' || res.status == 1) {
						console.log("网路请求失败")
						uni.showToast({
							title: that.language.startToastnetworkMsg,
							icon: 'none',
							duration: 1500
						})
						if(uni.getStorageSync('userInfo')){
							uni.switchTab({
								url: '/pages/home/home'
							})
						}else{
							uni.navigateTo({
								url: '/pages/login/login'
							})
						}
					} else {
						uni.showToast({
							title: that.language.startToastnetworkMsg,
							icon: 'none',
							duration: 1500
						})
						if(uni.getStorageSync('userInfo')){
							uni.switchTab({
								url: '/pages/home/home'
							})
						}else{
							uni.navigateTo({
								url: '/pages/login/login'
							})
						}
					}
				})
			},
			async uploadSyudyTime(){
				await uploadStudyTime({"data": uni.getStorageSync('uploadTime')}).then(res=>{
					if(res.data.code == 200 && res.data.status == 'success'){
						uni.removeStorageSync('uploadTime')
					}
				})
			},
			async uploadTestTime(){
				await uploadTestData({"data": uni.getStorageSync('uploadTestTime')}).then(res=>{
					if(res.data.code == 200 && res.data.status == 'success'){
						uni.removeStorageSync('uploadTestTime')
					}
				})
			},
			async uploadOpen(){
				this.openData = [];
				if(uni.getStorageSync('uploadOpen')){
					this.openData = uni.getStorageSync('uploadOpen')
					this.openData.push({"date": this.$utils.formatDateTime()})
				}else{
					this.openData[0] = {"date": this.$utils.formatDateTime()}
				}
				await uploadOpen({"data": this.openData}).then(res=>{
					if(res.data.code == 200 && res.data.status == 'success'){
						uni.removeStorageSync('uploadOpen')
					}else{
						uni.setStorageSync('uploadOpen',this.openData)
					}
				})
			}
		}
	}
</script>

<style>
	page{
		width: 100%;
		height: 100vh;
	}
	
	.progress-bar {
	  background-color: #cccccc; /* 进度条背景颜色 */
	  height: 10rpx;
	  width: 60%;
	  border-radius: 5rpx;
	}
	
	.progress-bar__fill {
	  height: 100%;
	  background-color: green; /* 完成部分的颜色 */
	  transition: width 0.1s ease-in-out; /* 平滑过渡效果 */
	  border-radius: 5rpx;
	}
</style>

有部分不需要的代码,可以自己删除掉即可。

精彩评论(0)

0 0 举报