Bläddra i källkod

优化图片保存逻辑,从并行改成串行,并且做delay

ZhangLeo 1 vecka sedan
förälder
incheckning
2b47337c0c
1 ändrade filer med 250 tillägg och 243 borttagningar
  1. 250 243
      utils/dataProcessor.uts

+ 250 - 243
utils/dataProcessor.uts

@@ -1,6 +1,6 @@
 import { getToken, getTokenFromApi } from './auth'
 import { saveMediaInfo, saveMediaRecord, getLatestRecord, removeInfoAndRecord } from '@/api/work'
-import {globalConfig} from '@/config'
+import { globalConfig } from '@/config'
 
 
 // 类型定义保持不变
@@ -51,255 +51,262 @@ export type PhotoFilesExample = {
 	_id ?: string,
 }
 
-export const downloadDataFromAPI = async (productCode: string, callback ?: () => void) : Promise<boolean> => {
-  try {
-	//校验是否已经存在未执行的产品号,若已经存在则提示用户该产品号是否需要被覆盖,
-	//如果没有则直接保存。如果有存在已经在执行中的产品号,则提示已存在执行中的任务
-	const infoJson = await getLatestRecord(productCode, null);
-	if (infoJson?.['data']!=null) {
-		let info = infoJson?.['data'] as UTSJSONObject ?? {} as UTSJSONObject
-		let ingNum = parseInt(info?.['statusRecordCount'] as string);
-		//覆盖标识位
-		let overwiteFlag = ref(false);
-		// 先检查是否有任务正在执行中
-		if (info != null && ingNum > 0) {
-			uni.showToast({ title: `当前产品号已有任务在执行中!`, icon: 'error' });
-			return false;
-		}
-		// 使用Promise来处理异步流程
-		let deleteDataPromise = new Promise<boolean>((resolve) => {
-			if(info != null && ingNum == 0) {
-				//可以被覆盖,需要有提示框,给用户确认
-				uni.showModal({
-					title: '系统提示',
-					content: '该产品号已存在任务是否覆盖掉?',
-					cancelText: '取消',
-					confirmText: '确定',
-					success: function (res) {
-						if (res.confirm) {
-							// 标记为需要覆盖
-							overwiteFlag.value = true;
-							// 执行删除数据操作
-							let pid = info?.['pdid'] as string;
-							removeInfoAndRecord(pid).then((recordDelResponse) => {
-								console.log('删除数据响应:', recordDelResponse);
-								// 删除成功,解析Promise并允许继续执行
-								// 确保模态框已完全关闭后再解析Promise
-								setTimeout(() => {
-									resolve(true);
-								}, 300);
-							}).catch((error) => {
-								console.error('删除数据失败:', error);
-								uni.showToast({ title: '删除旧数据失败', icon: 'error' });
+export const downloadDataFromAPI = async (productCode : string, callback ?: () => void) : Promise<boolean> => {
+	try {
+		//校验是否已经存在未执行的产品号,若已经存在则提示用户该产品号是否需要被覆盖,
+		//如果没有则直接保存。如果有存在已经在执行中的产品号,则提示已存在执行中的任务
+		const infoJson = await getLatestRecord(productCode, null);
+		if (infoJson?.['data'] != null) {
+			let info = infoJson?.['data'] as UTSJSONObject ?? {} as UTSJSONObject
+			let ingNum = parseInt(info?.['statusRecordCount'] as string);
+			//覆盖标识位
+			let overwiteFlag = ref(false);
+			// 先检查是否有任务正在执行中
+			if (info != null && ingNum > 0) {
+				uni.showToast({ title: `当前产品号已有任务在执行中!`, icon: 'error' });
+				return false;
+			}
+			// 使用Promise来处理异步流程
+			let deleteDataPromise = new Promise<boolean>((resolve) => {
+				if (info != null && ingNum == 0) {
+					//可以被覆盖,需要有提示框,给用户确认
+					uni.showModal({
+						title: '系统提示',
+						content: '该产品号已存在任务是否覆盖掉?',
+						cancelText: '取消',
+						confirmText: '确定',
+						success: function (res) {
+							if (res.confirm) {
+								// 标记为需要覆盖
+								overwiteFlag.value = true;
+								// 执行删除数据操作
+								let pid = info?.['pdid'] as string;
+								removeInfoAndRecord(pid).then((recordDelResponse) => {
+									console.log('删除数据响应:', recordDelResponse);
+									// 删除成功,解析Promise并允许继续执行
+									// 确保模态框已完全关闭后再解析Promise
+									setTimeout(() => {
+										resolve(true);
+									}, 300);
+								}).catch((error) => {
+									console.error('删除数据失败:', error);
+									uni.showToast({ title: '删除旧数据失败', icon: 'error' });
+									resolve(false);
+								});
+							} else {
+								// 用户取消覆盖
+								overwiteFlag.value = false;
 								resolve(false);
-							});
-						} else {
-							// 用户取消覆盖
-							overwiteFlag.value = false;
-							resolve(false);
+							}
 						}
-					}
-				});
-			} else {
-				// 不需要显示确认框,直接解析Promise
-				resolve(true);
+					});
+				} else {
+					// 不需要显示确认框,直接解析Promise
+					resolve(true);
+				}
+			});
+
+			// 等待删除数据操作完成
+			const canContinue : boolean = await deleteDataPromise;
+			if (!canContinue) {
+				// 如果不能继续(删除失败或用户取消),则终止函数执行
+				return false;
 			}
-		});
-		
-		// 等待删除数据操作完成
-		const canContinue: boolean = await deleteDataPromise;
-		if (!canContinue) {
-			// 如果不能继续(删除失败或用户取消),则终止函数执行
-			return false;
 		}
-	}
 
 
-	// 继续执行后续代码...
-    const apiToken = await getTokenFromApi();
-    uni.showLoading({ title: '数据下载中...' });
+		// 继续执行后续代码...
+		const apiToken = await getTokenFromApi();
+		uni.showLoading({ title: '数据下载中...' });
 
-	// 创建进度条
-	const showProgress = (percentage: number) => {
-		uni.showLoading({
-			title: `图片下载中...${percentage}%`,
-			mask: true
-		});
-	};
+		// 创建进度条
+		const showProgress = (percentage : number) => {
+			uni.showLoading({
+				title: `图片下载中...${percentage}%`,
+				mask: true
+			});
+		};
+
+
+		// 使用Promise处理HTTP请求,避免嵌套Promise
+		return new Promise<boolean>((resolve) => {
+			uni.request({
+				url: `${globalConfig.apiUrl}/loadQmImagetask?prodcode=${productCode}`,
+				method: 'GET',
+				header: {
+					'token': apiToken
+				},
+				success: (res) => {
+					let singleObject = res?.['data'] as UTSJSONObject ?? {} as UTSJSONObject;
+
+					if (singleObject != null && singleObject.code == 666) {
+						let mediaInfoList = singleObject?.['data'] as UTSJSONObject[] ?? Array<UTSJSONObject>();
+						if (mediaInfoList != null && mediaInfoList.length > 0) {
+							mediaInfoList.forEach(item => {
+								if (item != null) {
+									let data = JSON.parse<MediaInfoData>(item.toJSONString());
+									if (data != null) {
+										saveMediaInfo(item).then((resSave : UTSJSONObject) => {
+											const lastIdStr = resSave?.['lastId'] as string | null;
+											const lastId = lastIdStr != null ? parseInt(lastIdStr) : null;
+											if (lastId != null) {
+												let recordList = data?.['qmImageTaskClist'] as UTSJSONObject[] ?? Array<UTSJSONObject>();
+												if (recordList != null && recordList.length > 0) {
+													const totalRecords = recordList.length;
+													let processedRecords = 0;
+
+													// 使用async/await处理循环中的异步操作
+													const processAllRecords = async () => {
+														for (var i = 0; i < recordList.length; i++) {
+															// 更新进度
+															processedRecords++;
+															const progressPercentage = Math.floor((processedRecords / totalRecords) * 100);
+															showProgress(progressPercentage);
+
+															const record : MediaRecordData = recordList[i] as MediaRecordData;
+															// 获取各个字段的值
+															const senum = record.senum;
+															const photoitem = record.photoitem;
+															const part = record.part;
+															const partno = record.partno;
+															const pk = record.pk;
+															const descb = record.descb;
+															const num = record.num;
+															const urlspl = record.urlspl;
+															const imgname = record.imgname;
+															const urlpdt = record.urlpdt;
+															const createtime = record.createtime;
+															const createuser = record.createuser;
+															const updatetime = record.updatetime;
+															const updateuser = record.updateuser;
 
+															// 创建数组来存储图片ID和保存路径
+															var exampleidArr = [] as string[];
+															var imagePathsArr = [] as string[];
 
-    // 使用Promise处理HTTP请求,避免嵌套Promise
-    return new Promise<boolean>((resolve) => {
-      uni.request({
-        url: `${globalConfig.apiUrl}/loadQmImagetask?prodcode=${productCode}`,
-        method: 'GET',
-        header: {
-          'token': apiToken
-        },
-        success: (res) => {
-          let singleObject = res?.['data'] as UTSJSONObject ?? {} as UTSJSONObject;
-		  
-          if (singleObject != null && singleObject.code == 666) {
-            let mediaInfoList = singleObject?.['data'] as UTSJSONObject[] ?? Array<UTSJSONObject>();
-            if (mediaInfoList != null && mediaInfoList.length > 0) {
-              mediaInfoList.forEach(item => {
-                if (item != null) {
-                  let data = JSON.parse<MediaInfoData>(item.toJSONString());
-                  if (data != null) {
-                    saveMediaInfo(item).then((resSave : UTSJSONObject) => {
-                      const lastIdStr = resSave?.['lastId'] as string | null;
-                      const lastId = lastIdStr != null ? parseInt(lastIdStr) : null;
-                      if (lastId != null) {
-                        let recordList = data?.['qmImageTaskClist'] as UTSJSONObject[] ?? Array<UTSJSONObject>();
-                        if (recordList != null && recordList.length > 0) {
-                          const totalRecords = recordList.length;
-                          let processedRecords = 0;
-                           
-                          // 使用async/await处理循环中的异步操作
-                          const processAllRecords = async () => {
-                            for(var i =0; i < recordList.length; i++) {
-                              // 更新进度
-                              processedRecords++;
-                              const progressPercentage = Math.floor((processedRecords / totalRecords) * 100);
-                              showProgress(progressPercentage);
-                               
-                              const record: MediaRecordData = recordList[i] as MediaRecordData;
-                              // 获取各个字段的值
-                              const senum = record.senum;
-                              const photoitem = record.photoitem;
-                              const part = record.part;
-                              const partno = record.partno;
-                              const pk = record.pk;
-                              const descb = record.descb;
-                              const num = record.num;
-                              const urlspl = record.urlspl;
-                              const imgname = record.imgname;
-                              const urlpdt = record.urlpdt;
-                              const createtime = record.createtime;
-                              const createuser = record.createuser;
-                              const updatetime = record.updatetime;
-                              const updateuser = record.updateuser;
-                               
-                              // 创建数组来存储图片ID和保存路径
-                              var exampleidArr = [] as string[];
-                              var imagePathsArr = [] as string[];
-                               
-                              let exampleList = record?.['photoFiles_example'] as UTSJSONObject[] ?? Array<UTSJSONObject>();
-                              if(exampleList!=null && exampleList.length > 0) {
-                                // 下载所有图片并等待完成
-                                const imageDownloadPromises = [] as Promise<void>[];
-                                
-                                for(var j =0; j < exampleList.length; j++) {
-                                  const example: PhotoFilesExample = exampleList[j] as PhotoFilesExample;
-                                  if(example._id != null) {
-                                    exampleidArr.push(example._id);
-                                    
-                                    // 创建图片下载Promise
-                                    const downloadPromise = new Promise<void>((resolve, reject) => {
-                                      // 使用uni.downloadFile下载图片
-                                      uni.downloadFile({
-                                        url: `http://192.168.5.124:8080/api/images/getImage?fileId=${example._id}`,
-                                        header: {
-                                          'token': apiToken
-                                        },
-                                        success: (res) => {
-                                          if (res.statusCode === 200) {
-                                            // 图片下载成功,使用uni.saveImageToPhotosAlbum保存到相册
-                                            uni.saveImageToPhotosAlbum({
-                                              filePath: res.tempFilePath,
-                                              success: () => {
-                                                console.log('图片保存成功:', res.tempFilePath);
-                                                // 将保存路径添加到数组中
-                                                imagePathsArr.push(res.tempFilePath);
-                                                resolve();
-                                              },
-                                              fail: (err) => {
-                                                console.error('保存图片失败:', err);
-                                                reject(err);
-                                              }
-                                            });
-                                          } else {
-                                            console.error('下载图片失败,状态码:', res.statusCode);
-                                            reject(new Error(`下载图片失败,状态码: ${res.statusCode}`));
-                                          }
-                                        },
-                                        fail: (err) => {
-                                          console.error('请求图片失败:', err);
-                                          reject(err);
-                                        }
-                                      });
-                                    });
-                                     
-                                    imageDownloadPromises.push(downloadPromise);
-                                  }
-                                }
-                                
-                                // 等待所有图片下载完成
-                                try {
-                                  await Promise.all(imageDownloadPromises);
-                                } catch (error) {
-                                  console.error('图片下载失败:', error);
-                                }
-                              }
-                              
-                              // 拼接图片ID和路径
-                              const exampleid = exampleidArr.join(",");
-                              const imagePaths = imagePathsArr.join(",");
-							  console.log("=========================================>");
-							  console.log(imagePaths);
-                              
-                              // 使用三目运算符判断,当值为null时直接插入null,否则用单引号括起来
-                              var values = `${senum === null ? '1' : `'${senum}'`}, ${photoitem === null ? 'null' : `'${photoitem}'`}, ${data?.['productcode'] === null ? 'null' : `'${data?.['productcode']}'`},${part === null ? 'null' : `'${part}'`},${partno === null ? 'null' : `'${partno}'`},${pk === null ? 'null' : `'${pk}'`},${exampleid === null ? 'null' : `'${exampleid}'`},${descb === null ? 'null' : `'${descb}'`},${num === null ? 0 : num},1,'', ${imagePaths === null ? 'null' : `'${imagePaths}'`},${imgname === null ? 'null' : `'${imgname}'`},${urlpdt === null ? 'null' : `'${urlpdt}'`}, ${createtime === null ? 'null' : `'${createtime}'`}, ${createuser === null ? 'null' : `'${createuser}'`}, ${updatetime === null ? 'null' : `'${updatetime}'`}, ${updateuser === null ? 'null' : `'${updateuser}'`}, ${lastId === null ? 0 : lastId}`;
-                              
-                              // 只有在所有图片下载完成后才调用saveMediaRecord
-                              saveMediaRecord(values);
-                            }
-                            
-                            // 所有记录处理完成,显示完成提示
-                            setTimeout(() => {
-                              uni.hideLoading();
-                              uni.showToast({ title: `下载完成`, icon: 'success' });
-                              if (callback != null) {
-                                callback();
-                              }
-                            }, 500);
-                          };
-                          
-                          // 开始处理所有记录
-                          processAllRecords();
-                        }
-                      } else {
-                        console.log('保存媒体信息成功,但未获取到主键ID');
-                      }
-                    })
-                  }
-                }
-              });
-              resolve(true);
-            } else {
-              uni.hideLoading();
-              uni.showToast({ title: '未获取到数据', icon: 'error' });
-              resolve(false);
-            }
-          } else {
-              const errorMsg = singleObject.msg != null ? singleObject.msg : '未知错误';
-              uni.hideLoading();
-              uni.showToast({ title: `请求失败: ${errorMsg}`, icon: 'error' });
-              resolve(false);
-          }
-        },
-        fail: (err) => {
-          console.error('请求数据失败:', err);
-          uni.hideLoading();
-          uni.showToast({ title: `请求失败: ${err.errMsg}`, icon: 'error' });
-          resolve(false);
-        }
-      });
-    });
-  } catch (error) {
-    console.error(error);
-    uni.showToast({ title: '下载失败,请重试', icon: 'error' });
-    uni.hideLoading();
-    return false;
-  }
+															let exampleList = record?.['photoFiles_example'] as UTSJSONObject[] ?? Array<UTSJSONObject>();
+															if (exampleList != null && exampleList.length > 0) {
+																// 下载所有图片并等待完成
+																const imageDownloadPromises = [] as Promise<void>[];
+
+																// 顺序下载和保存图片,避免并行导致的随机失败
+																for (var j = 0; j < exampleList.length; j++) {
+																	const example : PhotoFilesExample = exampleList[j] as PhotoFilesExample;
+																	if (example._id != null) {
+																		exampleidArr.push(example._id);
+
+																		try {
+																			// 串行执行,等待前一张图片处理完成再处理下一张
+																			await new Promise<void>((resolve, reject) => {
+																				// 使用uni.downloadFile下载图片
+																				uni.downloadFile({
+																					url: `http://192.168.5.124:8080/api/images/getImage?fileId=${example._id}`,
+																					header: {
+																						'token': apiToken
+																					},
+																					success: (res) => {
+																						if (res.statusCode === 200) {
+																							// 等待一小段时间确保文件完全下载
+																							setTimeout(() => {
+																								// 图片下载成功,使用uni.saveImageToPhotosAlbum保存到相册
+																								uni.saveImageToPhotosAlbum({
+																									filePath: res.tempFilePath,
+																									success: () => {
+																										console.log('图片保存成功:', res.tempFilePath);
+																										// 将保存路径添加到数组中
+																										imagePathsArr.push(res.tempFilePath);
+
+																										// 保存成功后等待1秒再处理下一张
+																										setTimeout(() => {
+																											resolve();
+																										}, 1000);
+																									},
+																									fail: (err) => {
+																										console.error('保存图片失败:', err);
+																										// 保存失败也继续处理下一张,但记录错误
+																										setTimeout(() => {
+																											reject(err);
+																										}, 1000);
+																									}
+																								});
+																							}, 500); // 等待500ms确保文件完全下载
+																						} else {
+																							console.error('下载图片失败,状态码:', res.statusCode);
+																							reject(new Error(`下载图片失败,状态码: ${res.statusCode}`));
+																						}
+																					},
+																					fail: (err) => {
+																						console.error('请求图片失败:', err);
+																						reject(err);
+																					}
+																				});
+																			});
+																		} catch (error) {
+																			console.error(`处理第${j + 1}张图片时出错:`, error);
+																			// 出错后继续处理下一张图片
+																		}
+																	}
+																}
+															}
+
+															// 拼接图片ID和路径
+															const exampleid = exampleidArr.join(",");
+															const imagePaths = imagePathsArr.join(",");
+															console.log("=========================================>");
+															console.log(imagePaths);
+
+															// 使用三目运算符判断,当值为null时直接插入null,否则用单引号括起来
+															var values = `${senum === null ? '1' : `'${senum}'`}, ${photoitem === null ? 'null' : `'${photoitem}'`}, ${data?.['productcode'] === null ? 'null' : `'${data?.['productcode']}'`},${part === null ? 'null' : `'${part}'`},${partno === null ? 'null' : `'${partno}'`},${pk === null ? 'null' : `'${pk}'`},${exampleid === null ? 'null' : `'${exampleid}'`},${descb === null ? 'null' : `'${descb}'`},${num === null ? 0 : num},1,'', ${imagePaths === null ? 'null' : `'${imagePaths}'`},${imgname === null ? 'null' : `'${imgname}'`},${urlpdt === null ? 'null' : `'${urlpdt}'`}, ${createtime === null ? 'null' : `'${createtime}'`}, ${createuser === null ? 'null' : `'${createuser}'`}, ${updatetime === null ? 'null' : `'${updatetime}'`}, ${updateuser === null ? 'null' : `'${updateuser}'`}, ${lastId === null ? 0 : lastId}`;
+
+															// 只有在所有图片下载完成后才调用saveMediaRecord
+															saveMediaRecord(values);
+														}
+
+														// 所有记录处理完成,显示完成提示
+														setTimeout(() => {
+															uni.hideLoading();
+															uni.showToast({ title: `下载完成`, icon: 'success' });
+															if (callback != null) {
+																callback();
+															}
+														}, 500);
+													};
+
+													// 开始处理所有记录
+													processAllRecords();
+												}
+											} else {
+												console.log('保存媒体信息成功,但未获取到主键ID');
+											}
+										})
+									}
+								}
+							});
+							resolve(true);
+						} else {
+							uni.hideLoading();
+							uni.showToast({ title: '未获取到数据', icon: 'error' });
+							resolve(false);
+						}
+					} else {
+						const errorMsg = singleObject.msg != null ? singleObject.msg : '未知错误';
+						uni.hideLoading();
+						uni.showToast({ title: `请求失败: ${errorMsg}`, icon: 'error' });
+						resolve(false);
+					}
+				},
+				fail: (err) => {
+					console.error('请求数据失败:', err);
+					uni.hideLoading();
+					uni.showToast({ title: `请求失败: ${err.errMsg}`, icon: 'error' });
+					resolve(false);
+				}
+			});
+		});
+	} catch (error) {
+		console.error(error);
+		uni.showToast({ title: '下载失败,请重试', icon: 'error' });
+		uni.hideLoading();
+		return false;
+	}
 }