|
@@ -0,0 +1,648 @@
|
|
|
+import { getToken, getTokenFromApi } from './auth'
|
|
|
+import { saveTaskInfo, saveTaskPhoto, saveTaskKeyProcess, saveTaskRecord, saveTaskRecordItem, getLatestTask, removeTaskAndRecord } from '@/api/work'
|
|
|
+import { globalConfig } from '@/config'
|
|
|
+
|
|
|
+
|
|
|
+// 类型定义保持不变
|
|
|
+export type ApiResponse = {
|
|
|
+ code : number;
|
|
|
+ msg : string;
|
|
|
+ data : AppTaskInfo;
|
|
|
+}
|
|
|
+
|
|
|
+export type AppTaskInfo = {
|
|
|
+ gxpk : string;
|
|
|
+ pk_serial: string;
|
|
|
+ cardno ?: string;
|
|
|
+ productcode ?: string;
|
|
|
+ model ?: string;
|
|
|
+ workorder ?: string;
|
|
|
+ invname ?: string;
|
|
|
+ graphid ?: string;
|
|
|
+ processno ?: string;
|
|
|
+ ver ?: string;
|
|
|
+ lastupdatetime ?: string;
|
|
|
+ qcrecord ?: AppTaskRecord;
|
|
|
+ photolist ?: AppTaskPhoto[];
|
|
|
+ keyprocesslist ?: AppTaskKeyProcess[];
|
|
|
+}
|
|
|
+
|
|
|
+export type AppTaskRecord = {
|
|
|
+ pk ?: string;
|
|
|
+ fk_invcode ?: string;
|
|
|
+ no ?: string;
|
|
|
+ invcode ?: string;
|
|
|
+ invname : string;
|
|
|
+ processStep ?: string;
|
|
|
+ fk_processTask ?: string;
|
|
|
+ checkTarget ?: string;
|
|
|
+ checknum ?: number;
|
|
|
+ oknum ?: number;
|
|
|
+ ngnum ?: number;
|
|
|
+ status ?: string;
|
|
|
+ result ?: string;
|
|
|
+ checkTime ?: string;
|
|
|
+ cs ?: string;
|
|
|
+ ts ?: string;
|
|
|
+ items ?: AppTaskRecordItem[];
|
|
|
+}
|
|
|
+
|
|
|
+export type AppTaskRecordItem = {
|
|
|
+ pk ?: string;
|
|
|
+ fk_qcRecord ?: string;
|
|
|
+ fk_prodcode ?: string;
|
|
|
+ prodno ?: string;
|
|
|
+ name ?: string;
|
|
|
+ no ?: string;
|
|
|
+ nature ?: string;
|
|
|
+ unit ?: string;
|
|
|
+ maxNum ?: number;
|
|
|
+ minNum ?: number;
|
|
|
+ status ?: string;
|
|
|
+ memo ?: string;
|
|
|
+ measuredvalue ?: string;
|
|
|
+ result ?: string;
|
|
|
+ cs ?: string;
|
|
|
+ ts ?: string;
|
|
|
+}
|
|
|
+
|
|
|
+export type AppTaskPhoto = {
|
|
|
+ pk : string;
|
|
|
+ photographpoint ?: string;
|
|
|
+ photographdescription ?: string;
|
|
|
+ photourl ?: string;
|
|
|
+ photoname ?: string;
|
|
|
+ fk_qcRecord ?: string;
|
|
|
+ fk_prodcode ?: string;
|
|
|
+ prodno ?: string;
|
|
|
+ fk_creator ?: string;
|
|
|
+ fks_operator ?: string;
|
|
|
+ operator ?: string;
|
|
|
+ processStep ?: string;
|
|
|
+ fk_processTask ?: string;
|
|
|
+ cs ?: string;
|
|
|
+ ts ?: string;
|
|
|
+}
|
|
|
+
|
|
|
+export type AppTaskKeyProcess = {
|
|
|
+ pk ?: string;
|
|
|
+ pdid ?: string;
|
|
|
+ testapparatus ?: string;
|
|
|
+ tableid ?: string;
|
|
|
+ testrequirelower ?: string;
|
|
|
+ testrequireupper ?: string;
|
|
|
+ parametername ?: string;
|
|
|
+ parameterorder ?: string;
|
|
|
+ measureunit ?: string;
|
|
|
+ parameterinstruction ?: string;
|
|
|
+ parameterid ?: string;
|
|
|
+ fk_creator ?: string;
|
|
|
+ fk_prodcode ?: string;
|
|
|
+ prodno ?: string;
|
|
|
+ processstep ?: string;
|
|
|
+ fk_processtask ?: string;
|
|
|
+ measuredvaluemin ?: string;
|
|
|
+ measuredvaluemax ?: string;
|
|
|
+ fks_operator ?: string;
|
|
|
+ cs ?: string;
|
|
|
+ ts ?: string;
|
|
|
+}
|
|
|
+
|
|
|
+export const showProgress = (index : number, title : string) => {
|
|
|
+ // 在Android设备上,需要给hideLoading和showLoading之间添加延迟
|
|
|
+ // 先隐藏之前的加载提示
|
|
|
+ uni.hideLoading();
|
|
|
+ // 添加50ms的延迟,确保hideLoading完全执行后再显示新的进度
|
|
|
+ setTimeout(() => {
|
|
|
+ uni.showLoading({
|
|
|
+ title: `正在${title}第${index}个任务数据`,
|
|
|
+ mask: true
|
|
|
+ });
|
|
|
+ }, 50);
|
|
|
+}
|
|
|
+
|
|
|
+//声像任务下载
|
|
|
+export const downloadDataFromAPI = async (productCode : string, callback ?: () => void) : Promise<boolean> => {
|
|
|
+ try {
|
|
|
+ uni.showLoading({ title: '任务开始下载' });
|
|
|
+ const apiToken = await getTokenFromApi();
|
|
|
+
|
|
|
+ if (apiToken == null || apiToken == '') {
|
|
|
+ uni.hideLoading();
|
|
|
+ uni.showToast({ title: `获取Token失败,请联系技术IT`, icon: 'error' });
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+
|
|
|
+ //校验是否已经存在未执行的产品号,若已经存在则提示用户该产品号是否需要被覆盖,
|
|
|
+ //如果没有则直接保存。如果有存在已经在执行中的产品号,则提示已存在执行中的任务
|
|
|
+ const infoJson = await getLatestTask(productCode, null);
|
|
|
+ console.log(infoJson);
|
|
|
+ if (infoJson?.['data'] != null) {
|
|
|
+ let info = infoJson?.['data'] as UTSJSONObject ?? {} as UTSJSONObject
|
|
|
+ // let ingNum = parseInt(info?.['pdid'] 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) {
|
|
|
+ if (info != null) {
|
|
|
+ //可以被覆盖,需要有提示框,给用户确认
|
|
|
+ uni.showModal({
|
|
|
+ title: '系统提示',
|
|
|
+ content: '该产品号已存在任务是否覆盖掉?',
|
|
|
+ cancelText: '取消',
|
|
|
+ confirmText: '确定',
|
|
|
+ success: function (res) {
|
|
|
+ if (res.confirm) {
|
|
|
+ // 标记为需要覆盖
|
|
|
+ overwiteFlag.value = true;
|
|
|
+ // 执行删除数据操作
|
|
|
+ removeTaskAndRecord(productCode).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 {
|
|
|
+ // 不需要显示确认框,直接解析Promise
|
|
|
+ resolve(true);
|
|
|
+ }
|
|
|
+ });
|
|
|
+
|
|
|
+ // 等待删除数据操作完成
|
|
|
+ const canContinue : boolean = await deleteDataPromise;
|
|
|
+ if (!canContinue) {
|
|
|
+ // 如果不能继续(删除失败或用户取消),则终止函数执行
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ // 直接使用async/await处理HTTP请求,避免嵌套Promise
|
|
|
+ const requestResult = await new Promise<UTSJSONObject>((resolve, reject) => {
|
|
|
+ uni.request({
|
|
|
+ url: `${globalConfig.host}${globalConfig.downloadTaskURL}${productCode}`,
|
|
|
+ method: 'GET',
|
|
|
+ header: {
|
|
|
+ 'token': apiToken
|
|
|
+ },
|
|
|
+ success: (res) => resolve(res?.['data'] as UTSJSONObject ?? {} as UTSJSONObject),
|
|
|
+ fail: (err) => reject(err)
|
|
|
+ });
|
|
|
+ });
|
|
|
+
|
|
|
+ // 处理请求结果
|
|
|
+ if (requestResult != null && requestResult.code == 666) {
|
|
|
+ let taskInfo = requestResult?.['data'] as UTSJSONObject ?? {} as UTSJSONObject;
|
|
|
+ if (taskInfo != null) {
|
|
|
+ let data = JSON.parse<AppTaskInfo>(taskInfo.toJSONString());
|
|
|
+ if (data != null) {
|
|
|
+ // 保存任务信息
|
|
|
+ const resSave = await saveTaskInfo(taskInfo);
|
|
|
+ const lastIdStr = resSave?.['lastId'] as string | null;
|
|
|
+ const lastId = lastIdStr != null ? parseInt(lastIdStr) : null;
|
|
|
+
|
|
|
+ if (lastId != null) {
|
|
|
+ let photoList = taskInfo?.['photolist'] as UTSJSONObject[] ?? Array<UTSJSONObject>();
|
|
|
+ if (photoList != null && photoList.length > 0) {
|
|
|
+ const totalRecords = photoList.length;
|
|
|
+
|
|
|
+ // 按顺序处理所有图片记录
|
|
|
+ for (let i = 0; i < photoList.length; i++) {
|
|
|
+ // 更新进度
|
|
|
+ showProgress(i + 1, '下载');
|
|
|
+
|
|
|
+ let photoObj = photoList[i] as UTSJSONObject;
|
|
|
+ // 获取各个字段的值
|
|
|
+ const pk = photoObj['pk'] as string;
|
|
|
+ const photographpoint = photoObj['photographpoint'] as string | null;
|
|
|
+ const photographdescription = photoObj['photographdescription'] as string | null;
|
|
|
+ const photourl = photoObj['photourl'] as string | null;
|
|
|
+ const photoname = photoObj['photoname'] as string | null;
|
|
|
+ const fk_qcRecord = photoObj['fk_qcRecord'] as string | null;
|
|
|
+ const fk_prodcode = photoObj['fk_prodcode'] as string | null;
|
|
|
+ const prodno = photoObj['prodno'] as string | null;
|
|
|
+ const fk_creator = photoObj['fk_creator'] as string | null;
|
|
|
+ const fks_operator = photoObj['fks_operator'] as string | null;
|
|
|
+ const operator = photoObj['operator'] as string | null;
|
|
|
+ const processStep = photoObj['processStep'] as string | null;
|
|
|
+ const fk_processTask = photoObj['fk_processTask'] as string | null;
|
|
|
+ const cs = photoObj['cs'] as string | null;
|
|
|
+ const ts = photoObj['ts'] as string | null;
|
|
|
+
|
|
|
+ // 获取图片
|
|
|
+ let imagePathsArr = [] as string[];
|
|
|
+ try {
|
|
|
+ // 串行执行,等待前一张图片处理完成再处理下一张
|
|
|
+ const tempFilePath = await downloadAndSaveImage(pk, apiToken);
|
|
|
+ if (tempFilePath != null && tempFilePath != '') {
|
|
|
+ imagePathsArr.push(tempFilePath);
|
|
|
+ }
|
|
|
+ } catch (error) {
|
|
|
+ console.error(`处理图片时出错:`, error);
|
|
|
+ // 出错后继续处理下一张图片
|
|
|
+ }
|
|
|
+
|
|
|
+ // 拼接图片ID和路径
|
|
|
+ const imagePaths = imagePathsArr.join(",");
|
|
|
+ // 使用三目运算符判断,当值为null时直接插入null,否则用单引号括起来
|
|
|
+ var values = `${lastId === null ? 0 : lastId},${pk === null ? '' : `'${pk}'`}, ${photographpoint === null ? 'null' : `'${photographpoint}'`}, ${photographdescription === null ? 'null' : `'${photographdescription}'`},${photourl === null ? 'null' : `'${photourl}'`},
|
|
|
+ ${imagePaths === null ? 'null' : `'${imagePaths}'`},${photoname === null ? 'null' : `'${photoname}'`},${fk_qcRecord === null ? 'null' : `'${fk_qcRecord}'`},${fk_prodcode === null ? 'null' : `'${fk_prodcode}'`}, ${prodno === null ? 'null' : `'${prodno}'`},
|
|
|
+ ${fk_creator === null ? 'null' : `'${fk_creator}'`},${fks_operator === null ? 'null' : `'${fks_operator}'`}, ${operator === null ? 'null' : `'${operator}'`}, ${processStep === null ? 'null' : `'${processStep}'`}, ${fk_processTask === null ? 'null' : `'${fk_processTask}'`}, ${cs === null ? 'null' : `'${cs}'`}, ${ts === null ? 'null' : `'${ts}'`}`;
|
|
|
+
|
|
|
+ // 立即保存当前图片的任务信息
|
|
|
+ saveTaskPhoto(values);
|
|
|
+ }
|
|
|
+ //保存关键工序
|
|
|
+ let keyProcessList = taskInfo?.['keyprocesslist'] as UTSJSONObject[] ?? Array<UTSJSONObject>();
|
|
|
+ if (keyProcessList != null && keyProcessList.length > 0) {
|
|
|
+ keyProcessList.forEach(item =>{
|
|
|
+ item['pdid'] = lastId;
|
|
|
+ console.log(item);
|
|
|
+ saveTaskKeyProcess(item);
|
|
|
+ })
|
|
|
+ }
|
|
|
+
|
|
|
+ //保存检验记录
|
|
|
+ let recordObj = taskInfo?.['qcrecord'] as UTSJSONObject ?? {} as UTSJSONObject;
|
|
|
+ if (recordObj != null) {
|
|
|
+ recordObj['pdid'] = lastId;
|
|
|
+ const resSave = await saveTaskRecord(recordObj);
|
|
|
+ const recordIdStr = resSave?.['lastId'] as string | null;
|
|
|
+ const recordId = recordIdStr != null ? parseInt(recordIdStr) : null;
|
|
|
+ if (recordId != null) {
|
|
|
+ let recordItemList = recordObj?.['items'] as UTSJSONObject[] ?? Array<UTSJSONObject>();
|
|
|
+ if (recordItemList != null && recordItemList.length > 0) {
|
|
|
+ recordItemList.forEach(item =>{
|
|
|
+ item['psxid'] = recordId;
|
|
|
+ console.log(item);
|
|
|
+ saveTaskRecordItem(item);
|
|
|
+ })
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ console.log('保存媒体信息成功,但未获取到主键ID');
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ // 所有记录处理完成,显示完成提示
|
|
|
+ uni.hideLoading();
|
|
|
+ uni.showToast({ title: `下载完成`, icon: 'success' });
|
|
|
+ if (callback != null) {
|
|
|
+ callback();
|
|
|
+ }
|
|
|
+ return true;
|
|
|
+ } else {
|
|
|
+ const errorMsg = requestResult?.msg != null ? requestResult.msg : '未知错误';
|
|
|
+ uni.hideLoading();
|
|
|
+ uni.showToast({ title: `请求失败: ${errorMsg}`, icon: 'error' });
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+ } catch (error) {
|
|
|
+ console.error('下载数据时发生错误:', error);
|
|
|
+ uni.hideLoading();
|
|
|
+ uni.showToast({ title: '下载失败,请重试', icon: 'error' });
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+// 辅助函数:下载并保存图片
|
|
|
+const downloadAndSaveImage = async (pk: string, apiToken: string): Promise<string> => {
|
|
|
+ return new Promise<string>((resolve, reject) => {
|
|
|
+ // 使用uni.downloadFile下载图片
|
|
|
+ uni.downloadFile({
|
|
|
+ url: `${globalConfig.getImgURL}${pk}`,
|
|
|
+ header: {
|
|
|
+ 'token': apiToken
|
|
|
+ },
|
|
|
+ success: (res) => {
|
|
|
+ if (res.statusCode === 200) {
|
|
|
+ // 等待一小段时间确保文件完全下载
|
|
|
+ setTimeout(() => {
|
|
|
+ // 图片下载成功,使用uni.saveImageToPhotosAlbum保存到相册
|
|
|
+ uni.saveImageToPhotosAlbum({
|
|
|
+ filePath: res.tempFilePath,
|
|
|
+ success: () => {
|
|
|
+ console.log('图片保存成功:', res.tempFilePath);
|
|
|
+ // 保存成功后等待1秒再处理下一张
|
|
|
+ setTimeout(() => {
|
|
|
+ resolve(res.tempFilePath);
|
|
|
+ }, 1000);
|
|
|
+ },
|
|
|
+ fail: (err) => {
|
|
|
+ console.error('保存图片失败:', err);
|
|
|
+ // 保存失败返回空字符串继续处理
|
|
|
+ setTimeout(() => {
|
|
|
+ resolve('');
|
|
|
+ }, 500);
|
|
|
+ }
|
|
|
+ });
|
|
|
+ }, 500); // 等待500ms确保文件完全下载
|
|
|
+ } else {
|
|
|
+ console.error('下载图片失败,状态码:', res.statusCode);
|
|
|
+ reject(new Error(`下载图片失败,状态码: ${res.statusCode}`));
|
|
|
+ }
|
|
|
+ },
|
|
|
+ fail: (err) => {
|
|
|
+ console.error('请求图片失败:', err);
|
|
|
+ reject(err);
|
|
|
+ }
|
|
|
+ });
|
|
|
+ });
|
|
|
+}
|
|
|
+
|
|
|
+
|
|
|
+//声像任务上传
|
|
|
+// export const uploadDataToAPI = async (productCode : string, callback ?: () => void) : Promise<boolean> => {
|
|
|
+
|
|
|
+// try {
|
|
|
+// //暂定需要上传的数据文件
|
|
|
+// //const infoJson = await getLatestRecord(productCode, null);
|
|
|
+// const apiToken = await getTokenFromApi();
|
|
|
+// if (apiToken == null || apiToken == '') {
|
|
|
+// uni.hideLoading();
|
|
|
+// uni.showToast({ title: `获取Token失败,请联系技术IT`, icon: 'error' });
|
|
|
+// return false
|
|
|
+// }
|
|
|
+
|
|
|
+// // 获取数据
|
|
|
+// const res = await getJoinList('app_media_record as r', 'app_media_info as i', 'r.*,i.productno, i.uploadFlag', 'r.pid=i.pdid', 'i.productno', productCode, null);
|
|
|
+// let dataList = res?.['data'] as UTSJSONObject[] ?? Array<UTSJSONObject>();
|
|
|
+// console.log(dataList);
|
|
|
+
|
|
|
+// if (dataList == null || dataList.length === 0) {
|
|
|
+// uni.hideLoading();
|
|
|
+// uni.showToast({ title: '未获取到数据', icon: 'error' });
|
|
|
+// return false;
|
|
|
+// }
|
|
|
+
|
|
|
+// 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(() => {
|
|
|
+// resolve();
|
|
|
+// }, 1000);
|
|
|
+// } else {
|
|
|
+// setTimeout(() => {
|
|
|
+// reject('响应数据无效');
|
|
|
+// }, 500);
|
|
|
+// }
|
|
|
+// } 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();
|
|
|
+// }
|
|
|
+
|
|
|
+// if (finalFailedCount === 0) {
|
|
|
+// let updatedData = " uploadflag = 1 "
|
|
|
+// updateData('app_media_info', updatedData, 'productno', productCode).then((res : UTSJSONObject) => {
|
|
|
+// console.log(`更新完上传标识 ${productCode}`)
|
|
|
+// });
|
|
|
+// }
|
|
|
+
|
|
|
+// return finalFailedCount === 0;
|
|
|
+// } catch (error) {
|
|
|
+// console.error(error);
|
|
|
+// uni.showToast({ title: '上传失败,请重试', icon: 'error' });
|
|
|
+// uni.hideLoading();
|
|
|
+// return false;
|
|
|
+// }
|
|
|
+// }
|