Browse Source

修改上传逻辑

zhangxike 2 months ago
parent
commit
a9d33b9664
3 changed files with 248 additions and 80 deletions
  1. 1 1
      pages/work/record/Camera.uvue
  2. 1 0
      pages/work/record/InfoList.uvue
  3. 246 79
      utils/dataProcessor.uts

+ 1 - 1
pages/work/record/Camera.uvue

@@ -60,7 +60,7 @@
 				listener: null as CameraContextCameraFrameListener | null,
 				maxZoom: 0,
 				imageSrc: "",
-				quality: "original",
+				quality: "normal",
 				timeout: 30,
 				compressed: false,
 				videoSrc: "",

+ 1 - 0
pages/work/record/InfoList.uvue

@@ -192,6 +192,7 @@
 		  title: '当前任务还未完成!',
 		  icon: 'error'
 		});
+		return
 	}
     console.log("开始上传...")
     uploadDataToAPI(productNo.value, () => {

+ 246 - 79
utils/dataProcessor.uts

@@ -51,6 +51,11 @@ export type PhotoFilesExample = {
 	_id ?: string,
 }
 
+export type UploadImg = {
+	pk : string,
+	path : string
+}
+
 export const showProgress = (index : number, title : string) => {
 	// 在Android设备上,需要给hideLoading和showLoading之间添加延迟
 	// 先隐藏之前的加载提示
@@ -343,95 +348,257 @@ export const uploadDataToAPI = async (productCode : string, callback ?: () => vo
 			return false
 		}
 
+		// 获取数据
+		const res = await getJoinList('app_media_record as r', 'app_media_info as i', 'r.*,i.productno', 'r.pid=i.pdid', 'i.productno', productCode, null);
+		let dataList = res?.['data'] as UTSJSONObject[] ?? Array<UTSJSONObject>();
+		console.log(dataList);
 
-		getJoinList('app_media_record as r', 'app_media_info as i', 'r.*,i.productno', 'r.pid=i.pdid', 'i.productno', productCode, null).then(async (res : UTSJSONObject) => {
-			let dataList = res?.['data'] as UTSJSONObject[] ?? Array<UTSJSONObject>()
-			console.log(dataList);
-			if (dataList != null && dataList.length > 0) {
-				let doneRecordList = dataList.filter(item => item.getString("status") == '3')
-				console.log(doneRecordList);
-				if (doneRecordList.length === 0) {
-					uni.showToast({ title: '上传图片数据为空', icon: 'error' });
-					return;
-				}
-				let processStep = 1;
-				for (let index = 0; index < dataList.length; index++) {
-					const record = dataList[index];
+		if (dataList == null || dataList.length === 0) {
+			uni.hideLoading();
+			uni.showToast({ title: '未获取到数据', icon: 'error' });
+			return false;
+		}
 
-					if (record.getString('urlpdt') == '' || record.getString('urlpdt') == null
-						|| record.getString('pk') == '' || record.getString('pk') == null) {
-						continue
-					}
-					showProgress(processStep, '上传');
-					//文件上传
-					let urlpdtStr = record.getString('urlpdt')
-					let pk = record.getString('pk')
-					let urlArr = urlpdtStr?.split(",") ?? []
-					
-					for (let j = 0; j < urlArr.length; j++) {
-						let path = urlArr[j];
-						const fullFilePath = `${uni.env.USER_DATA_PATH}` + path;
-						console.log(`开始上传文件: ${fullFilePath}, 索引: ${j}, apiToken: ${apiToken}, billid: ${pk}`);
-						await new Promise<void>((resolve, reject) => {
-							// 使用uni.uploadFile进行文件上传
-							uni.uploadFile({
-								url: `${globalConfig.uploadURL}`,
-								filePath: fullFilePath,
-								name: 'file', // 文件参数名
-								header: {
-									'token': apiToken
-								},
-								formData: {
-									'billid': pk
-								},
-								success: (uploadRes) => {
-									if (uploadRes.statusCode === 200) {
-										console.log(`文件${path}上传成功`, uploadRes);
-										// 解析响应数据
-										const resData = JSON.parse(uploadRes.data) as UTSJSONObject;
-										console.log(resData)
-										if (resData?.['_id'] != null && resData?.['_id'] != '') {
-											setTimeout(() => {
-												resolve();
-											}, 3000);
-										} else {
-											setTimeout(() => {
-												reject('');
-											}, 500);
-										}
-									}
-								},
-								fail: (err) => {
-									console.error(`文件${path}上传失败`, err);
-									uni.showToast({
-										title: `文件${j}上传失败: ${err.errMsg != null ? err.errMsg : '网络错误'}`,
-										icon: 'error'
-									});
+		let doneRecordList = dataList.filter(item => item.getString("status") == '3');
+		console.log(doneRecordList);
+		if (doneRecordList.length === 0) {
+			uni.hideLoading();
+			uni.showToast({ title: '上传图片数据为空', icon: 'error' });
+			return false;
+		}
+
+		// 1. 收集所有需要上传的图片
+		let allImagesToUpload : UploadImg[] = [];
+		let processStep = 1;
+
+		for (let index = 0; index < dataList.length; index++) {
+			const record = dataList[index];
+
+			if (record.getString('urlpdt') == '' || record.getString('urlpdt') == null
+				|| record.getString('pk') == '' || record.getString('pk') == null) {
+				continue
+			}
+
+			showProgress(processStep, '准备上传');
+			//收集图片信息
+			let urlpdtStr = record.getString('urlpdt');
+			let pk = record.getString('pk');
+			let urlArr = urlpdtStr?.split(",") ?? [];
+
+			for (let j = 0; j < urlArr.length; j++) {
+				let path = urlArr[j];
+				const fullFilePath = `${uni.env.USER_DATA_PATH}` + path;
+				allImagesToUpload.push({ pk: pk ?? '', path: fullFilePath });
+			}
+			processStep++;
+		}
+
+		// 2. 统计总图片数量
+		const totalImages = allImagesToUpload.length;
+		console.log(`总共需要上传${totalImages}张图片`);
+
+		if (totalImages === 0) {
+			uni.hideLoading();
+			uni.showToast({ title: '没有需要上传的图片', icon: 'none' });
+			return true;
+		}
+
+		// 3. 执行第一次上传
+		let failedImages : UploadImg[] = [];
+		let successCount = 0;
+
+		uni.showLoading({ title: `正在上传图片 (0/${totalImages})` });
+
+		for (let i = 0; i < allImagesToUpload.length; i++) {
+			const { pk, path } = allImagesToUpload[i];
+			console.log(`开始上传文件: ${path}, 索引: ${i}, apiToken: ${apiToken}, billid: ${pk}`);
+
+			try {
+				// 串行执行,等待前一个图片上传完成再处理下一张
+				await new Promise<void>((resolve, reject) => {
+					// 使用uni.uploadFile进行文件上传
+					console.log(`上传路径:${globalConfig.uploadURL}`)
+					const uploadTask = uni.uploadFile({
+						url: `${globalConfig.uploadURL}`,
+						filePath: path,
+						name: 'file', // 文件参数名
+						header: {
+							'token': apiToken
+						},
+						formData: {
+							'billid': pk
+						},
+						success: (uploadRes) => {
+							if (uploadRes.statusCode === 200) {
+								console.log(`文件${path}上传成功`, uploadRes);
+								// 解析响应数据
+								const resData = JSON.parse(uploadRes.data) as UTSJSONObject;
+								console.log(resData)
+								if (resData?.['_id'] != null && resData?.['_id'] != '') {
+									successCount++;
+									// 等待一小段时间确保文件完全上传并处理完成
 									setTimeout(() => {
-										reject(err); // 在fail回调中调用reject
+										resolve();
+									}, 1000);
+								} else {
+									setTimeout(() => {
+										reject('响应数据无效');
 									}, 500);
-								},
-								complete: () => {
-									console.log(`文件${path}上传完成`);
 								}
-							});
-						}).catch(err => {
-							// 捕获上传失败的错误,但继续上传下一个文件
-							console.log(`当前文件上传失败,但继续下一个文件上传,异常 ${err}`);
-						});
-					}
-					processStep++;
-				}
+							} else {
+								console.error(`文件${path}上传失败,状态码:`, uploadRes.statusCode);
+								setTimeout(() => {
+									reject(new Error(`上传失败,状态码: ${uploadRes.statusCode}`));
+								}, 500);
+							}
+						},
+						fail: (err) => {
+							console.error(`文件${path}上传失败`, err);
+							// 上传失败也继续处理下一张,但记录错误
+							setTimeout(() => {
+								reject(err);
+							}, 500);
+						},
+						complete: () => {
+							// console.log(`文件${path}上传操作完成`);
+							// 更新进度
+							uni.hideLoading();
+							uni.showLoading({ title: `正在上传图片 (${i + 1}/${totalImages})` });
+						}
+					});
 
+					uploadTask.onProgressUpdate((res) => {
+						console.log('上传进度' + res.progress);
+						console.log('已经上传的数据长度' + res.totalBytesSent);
+						console.log('预期需要上传的数据总长度' + res.totalBytesExpectedToSend);
+					});
+				});
+			} catch (error) {
+				// 捕获上传失败的错误,将失败的图片信息添加到错误数组
+				console.log(`处理第${i + 1}张图片时出错:`, error);
+				failedImages.push({ pk, path });
+				// 出错后继续处理下一张图片
+			}
+
+			// 在两次上传之间增加一个短暂的延迟,避免请求过于频繁
+			if (i < allImagesToUpload.length - 1) {
+				await new Promise<void>((resolve) => {
+					setTimeout(() => {
+						resolve()
+					}, 1000)
+				})
+			}
+		}
+
+		// 4. 执行重试逻辑(最多3次)
+		const maxRetries = 3;
+		let retryImages = [...failedImages]; // 复制初始失败的图片数组
+
+		for (let retryCount = 1; retryCount <= maxRetries; retryCount++) {
+			if (retryImages.length === 0) {
+				// 如果没有需要重试的图片,提前结束循环
+				break;
+			}
+
+			console.log(`开始第${retryCount}次重试上传失败的图片,共${retryImages.length}张`);
+			uni.hideLoading();
+			uni.showLoading({ title: `第${retryCount}次重试 (0/${retryImages.length})` });
+
+			// 创建新的错误数组,用于收集本次重试失败的图片
+			let currentFailedImages : UploadImg[] = [];
+			let currentSuccessCount = 0;
+
+			// 串行上传失败的图片
+			for (let i = 0; i < retryImages.length; i++) {
+				const { pk, path } = retryImages[i];
+				console.log(`重试上传文件: ${path}, 索引: ${i}, 重试次数: ${retryCount}, apiToken: ${apiToken}, billid: ${pk}`);
+				console.log(`重试上传路径:${globalConfig.uploadURL}`)
+
+				await new Promise<void>((resolve) => {
+					uni.uploadFile({
+						url: `${globalConfig.uploadURL}`,
+						filePath: path,
+						name: 'file',
+						header: {
+							'token': apiToken
+						},
+						formData: {
+							'billid': pk
+						},
+						success: (uploadRes) => {
+							if (uploadRes.statusCode === 200) {
+								console.log(`重试文件${path}上传成功`, uploadRes);
+								const resData = JSON.parse(uploadRes.data) as UTSJSONObject;
+								if (resData?.['_id'] != null && resData?.['_id'] != '') {
+									currentSuccessCount++;
+								} else {
+									currentFailedImages.push({ pk, path });
+								}
+							} else {
+								currentFailedImages.push({ pk, path });
+							}
+							console.log(`重试上传完成,当前成功: ${currentSuccessCount}, 当前失败: ${currentFailedImages.length}`);
+							resolve();
+						},
+						fail: (err) => {
+							console.error(`重试文件${path}上传失败`, err);
+							currentFailedImages.push({ pk, path });
+							resolve();
+						},
+						complete: () => {
+							// console.log(`重试文件${path}上传操作完成`);
+							// 更新进度
+							uni.hideLoading();
+							uni.showLoading({ title: `第${retryCount}次重试 (${i + 1}/${retryImages.length})` });
+						}
+					});
+				});
+
+				// 在两次上传之间增加一个短暂的延迟,避免请求过于频繁
+				if (i < retryImages.length - 1) {
+					await new Promise<void>((resolve) => {
+						setTimeout(() => {
+							resolve()
+						}, 1000)
+					})
+				}
 			}
-		})
+
+			// 更新成功数量
+			successCount += currentSuccessCount;
+			// 更新下一次重试的图片列表为本次失败的图片
+			retryImages = currentFailedImages;
+		}
+
+		// 5. 显示总结信息
+		const finalFailedCount = retryImages.length;
+		console.log(`上传总结: 总共${totalImages}张图片, 成功${successCount}张, 失败${finalFailedCount}张`);
+
+		uni.hideLoading();
+
+		// 三次重试后如果仍有失败的图片,显示提示
+		if (finalFailedCount > 0) {
+			uni.showModal({
+				title: '上传提示',
+				content: `总共需要上传${totalImages}张图片,成功${successCount}张,失败${finalFailedCount}张。\n经过${maxRetries}次重试后,仍有${finalFailedCount}张图片上传失败,请检查网络后重新上传。`,
+				showCancel: false
+			});
+		} else {
+			uni.showToast({
+				title: `上传完成!共${totalImages}张图片,全部成功。`,
+				icon: 'success'
+			});
+		}
+
+		if (callback != null) {
+			callback();
+		}
+
+		return finalFailedCount === 0;
 	} catch (error) {
 		console.error(error);
-		// uni.showToast({ title: '上传失败,请重试', icon: 'error' });
+		uni.showToast({ title: '上传失败,请重试', icon: 'error' });
 		uni.hideLoading();
 		return false;
 	}
-	
-	uni.hideLoading();
-	return true;
 }