Selaa lähdekoodia

feat(PageOne): enhance image saving functionality with improved user prompts and error handling

Yannay 2 kuukautta sitten
vanhempi
commit
c8b60dd4bf

+ 140 - 14
pages/orderDetailRefactored/components/PageOne.vue

@@ -313,27 +313,153 @@ export default {
313 313
       })
314 314
     },
315 315
 
316
-    /**
317
-     * 保存全部图片
318
-     */
319
-    async handleSaveAllImages() {
320
-      const allUrls = this.truePicList.map(item => item.fileUrl)
321
-      if (allUrls.length === 0) {
316
+    //一键复制
317
+    handleSaveAllImages() {
318
+      // 合并所有图片
319
+      const allImages = [...this.truePicList]
320
+      //取出所有图的url
321
+      const allUrls = allImages.map(item => item.fileUrl)
322
+      if (allUrls.length > 0) {
323
+        // 显示保存图片确认弹窗
324
+        uni.showModal({
325
+          title: '保存图片',
326
+          content: `是否将 ${allUrls.length} 张图片保存到本地相册?`,
327
+          confirmText: '保存',
328
+          // cancelText: '仅复制链接',
329
+          success: (res) => {
330
+            if (res.confirm) {
331
+              // 用户选择保存图片
332
+              this.saveImagesToLocal(allUrls)
333
+            } else if (res.cancel) {
334
+              // 用户选择仅复制链接
335
+              this.copyImageUrls(allUrls)
336
+            }
337
+          }
338
+        })
339
+      } else {
322 340
         uni.showToast({
323 341
           title: '没有图片可保存',
324 342
           icon: 'none'
325 343
         })
326
-        return
327 344
       }
345
+    },
328 346
 
329
-      uni.showModal({
330
-        title: '保存图片',
331
-        content: `是否将 ${allUrls.length} 张图片保存到本地相册?`,
332
-        confirmText: '保存',
333
-        success: (res) => {
334
-          if (res.confirm) {
335
-            imageUpload.saveImagesToLocal(allUrls)
347
+    // 保存图片到本地相册
348
+    async saveImagesToLocal(imageUrls) {
349
+      try {
350
+        uni.showLoading({
351
+          title: '正在保存图片...',
352
+          mask: true
353
+        })
354
+
355
+        const savedImages = []
356
+        const failedImages = []
357
+
358
+        // 逐个保存图片
359
+        for (let i = 0; i < imageUrls.length; i++) {
360
+          const url = imageUrls[i]
361
+          try {
362
+            await this.saveSingleImage(url)
363
+            savedImages.push(url)
364
+          } catch (error) {
365
+            console.error(`保存图片失败: ${url}`, error)
366
+            failedImages.push(url)
336 367
           }
368
+
369
+          // 更新进度
370
+          uni.showLoading({
371
+            title: `正在保存图片... (${i + 1}/${imageUrls.length})`,
372
+            mask: true
373
+          })
374
+        }
375
+
376
+        uni.hideLoading()
377
+
378
+        // 显示结果
379
+        let message = `成功保存 ${savedImages.length} 张图片`
380
+        if (failedImages.length > 0) {
381
+          message += `,${failedImages.length} 张保存失败`
382
+        }
383
+
384
+        uni.showToast({
385
+          title: message,
386
+          icon: 'none',
387
+          duration: 3000
388
+        })
389
+
390
+        // 如果有失败的图片,也复制链接作为备选
391
+        if (failedImages.length > 0) {
392
+          const allUrls = [...savedImages, ...failedImages]
393
+          this.copyImageUrls(allUrls)
394
+        }
395
+      } catch (error) {
396
+        uni.hideLoading()
397
+        console.error('保存图片过程中发生错误:', error)
398
+        uni.showToast({
399
+          title: '保存图片失败',
400
+          icon: 'error'
401
+        })
402
+      }
403
+    },
404
+
405
+    // 保存单张图片
406
+    saveSingleImage(url) {
407
+      return new Promise((resolve, reject) => {
408
+        // 先下载图片
409
+        uni.downloadFile({
410
+          url: url,
411
+          success: (res) => {
412
+            if (res.statusCode === 200) {
413
+              // 保存到相册
414
+              uni.saveImageToPhotosAlbum({
415
+                filePath: res.tempFilePath,
416
+                success: () => {
417
+                  console.log('图片保存成功:', url)
418
+                  resolve()
419
+                },
420
+                fail: (err) => {
421
+                  console.error('保存到相册失败:', err)
422
+                  // 如果是权限问题,尝试请求权限
423
+                  if (err.errMsg.includes('auth denied')) {
424
+                    uni.showModal({
425
+                      title: '权限不足',
426
+                      content: '需要访问相册权限来保存图片,是否去设置?',
427
+                      success: (modalRes) => {
428
+                        if (modalRes.confirm) {
429
+                          // 打开设置页面
430
+                          uni.openSetting({
431
+                            success: (settingRes) => {
432
+                              console.log('设置页面结果:', settingRes)
433
+                            }
434
+                          })
435
+                        }
436
+                      }
437
+                    })
438
+                  }
439
+                  reject(err)
440
+                }
441
+              })
442
+            } else {
443
+              reject(new Error('下载失败'))
444
+            }
445
+          },
446
+          fail: (err) => {
447
+            console.error('下载图片失败:', err)
448
+            reject(err)
449
+          }
450
+        })
451
+      })
452
+    },
453
+
454
+    // 复制图片链接
455
+    copyImageUrls(urls) {
456
+      uni.setClipboardData({
457
+        data: JSON.stringify(urls),
458
+        success: () => {
459
+          uni.showToast({
460
+            title: '图片链接已复制',
461
+            icon: 'none'
462
+          })
337 463
         }
338 464
       })
339 465
     },

+ 88 - 31
pages/orderDetailRefactored/utils/imageUpload.js

@@ -163,40 +163,97 @@ export default {
163 163
    */
164 164
   saveImageToLocal(url) {
165 165
     return new Promise((resolve, reject) => {
166
-      uni.downloadFile({
167
-        url,
168
-        success: (res) => {
169
-          if (res.statusCode === 200) {
170
-            uni.saveImageToPhotosAlbum({
171
-              filePath: res.tempFilePath,
172
-              success: () => {
173
-                resolve()
174
-              },
175
-              fail: (err) => {
176
-                console.error('保存到相册失败:', err)
177
-                if (err.errMsg.includes('auth denied')) {
178
-                  uni.showModal({
179
-                    title: '权限不足',
180
-                    content: '需要访问相册权限来保存图片,是否去设置?',
181
-                    success: (modalRes) => {
182
-                      if (modalRes.confirm) {
183
-                        uni.openSetting()
184
-                      }
166
+      this._doSaveImage(url, resolve, reject)
167
+    })
168
+  },
169
+
170
+  /**
171
+   * 执行保存图片操作
172
+   * @private
173
+   */
174
+  _doSaveImage(url, resolve, reject) {
175
+    uni.downloadFile({
176
+      url,
177
+      success: (res) => {
178
+        if (res.statusCode === 200 && res.tempFilePath) {
179
+          uni.saveImageToPhotosAlbum({
180
+            filePath: res.tempFilePath,
181
+            success: () => {
182
+              resolve()
183
+            },
184
+            fail: (err) => {
185
+              console.error('保存到相册失败:', err)
186
+              // 错误代码 12 通常表示权限问题
187
+              const isPermissionError = err.code === 12 || 
188
+                                       err.errCode === 12 || 
189
+                                       err.errMsg.includes('auth denied') || 
190
+                                       err.errMsg.includes('permission') ||
191
+                                       err.errMsg.includes('UNKOWN ERROR')
192
+              
193
+              if (isPermissionError) {
194
+                uni.showModal({
195
+                  title: '权限不足',
196
+                  content: '需要访问相册权限来保存图片,是否前往设置开启权限?',
197
+                  confirmText: '去设置',
198
+                  cancelText: '取消',
199
+                  success: (modalRes) => {
200
+                    if (modalRes.confirm) {
201
+                      uni.openSetting({
202
+                        success: (settingRes) => {
203
+                          // 检查是否开启了相册权限
204
+                          const hasPermission = settingRes.authSetting && 
205
+                                              settingRes.authSetting['scope.writePhotosAlbum']
206
+                          if (hasPermission) {
207
+                            uni.showToast({
208
+                              title: '权限已开启,请重试保存',
209
+                              icon: 'none',
210
+                              duration: 2000
211
+                            })
212
+                          } else {
213
+                            uni.showToast({
214
+                              title: '请在设置中开启相册权限',
215
+                              icon: 'none',
216
+                              duration: 2000
217
+                            })
218
+                          }
219
+                        },
220
+                        fail: () => {
221
+                          uni.showToast({
222
+                            title: '无法打开设置',
223
+                            icon: 'none'
224
+                          })
225
+                        }
226
+                      })
185 227
                     }
186
-                  })
187
-                }
188
-                reject(err)
228
+                  }
229
+                })
230
+              } else {
231
+                uni.showToast({
232
+                  title: '保存失败,请稍后重试',
233
+                  icon: 'none'
234
+                })
189 235
               }
190
-            })
191
-          } else {
192
-            reject(new Error('下载失败'))
193
-          }
194
-        },
195
-        fail: (err) => {
196
-          console.error('下载图片失败:', err)
197
-          reject(err)
236
+              reject(err)
237
+            }
238
+          })
239
+        } else {
240
+          const errorMsg = `下载失败,状态码: ${res.statusCode}`
241
+          console.error(errorMsg)
242
+          uni.showToast({
243
+            title: '下载图片失败',
244
+            icon: 'none'
245
+          })
246
+          reject(new Error(errorMsg))
198 247
         }
199
-      })
248
+      },
249
+      fail: (err) => {
250
+        console.error('下载图片失败:', err)
251
+        uni.showToast({
252
+          title: '下载图片失败,请检查网络',
253
+          icon: 'none'
254
+        })
255
+        reject(err)
256
+      }
200 257
     })
201 258
   },
202 259