|
|
@@ -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;
|
|
|
}
|