Selaa lähdekoodia

Merge branch 'feature_20260506_增加照片上传进度UI效果' into release

zhujindu 18 tuntia sitten
vanhempi
commit
cf2f1415d8
1 muutettua tiedostoa jossa 237 lisäystä ja 13 poistoa
  1. 237 13
      src/components/uploadVNormalTaskPhoto.vue

+ 237 - 13
src/components/uploadVNormalTaskPhoto.vue

@@ -31,6 +31,32 @@
       @normalFlow="normalFlow"
       @close="close">
     </imageWhiteStore>
+    <!-- 上传动画 -->
+    <div class="uploadImgDemoMask" v-show="uploadImgFlag">
+      <div class="uploadImgDemo">
+        <div class="ring-area" id="d2area" style="display: flex">
+          <div class="ring-wrap">
+            <svg width="90" height="90" viewBox="0 0 90 90">
+              <circle class="ring-bg" cx="45" cy="45" r="40" />
+              <circle class="ring-progress" id="d2ring" cx="45" cy="45" r="40" />
+            </svg>
+            <div class="ring-text">
+              <span class="ring-pct" id="d2pct">0%</span>
+              <span class="ring-sub" id="d2sub">上传中</span>
+            </div>
+          </div>
+          <div class="ring-info">
+            <div class="ring-filename" id="d2name"></div>
+            <div class="ring-list" id="d2dots">
+              <div
+                v-for="(value, index) in uploadImgTotal"
+                class="ring-dot"
+                :id="`dot${index}`"></div>
+            </div>
+          </div>
+        </div>
+      </div>
+    </div>
   </div>
 </template>
 
@@ -114,8 +140,16 @@ export default {
       imageWhiteStoreData: null,
       imageWhiteStoreFlag: false,
       localIdsArr: [],
+      uploadImgFlag: false, //上传图片中
+      uploadImgTotal: 0, // 上传图片总数
+      d2running: false,
+      d2count: 0,
+      d2timer: null,
     };
   },
+  activated() {
+    this.resetDemo2();
+  },
   methods: {
     // 原生H5拍照图片
     // url: base64
@@ -232,6 +266,9 @@ export default {
                   //   collectionItemId: that.collectionItemId,
                   //   source: 'weixin',
                   // });
+                  that.uploadImgFlag = true;
+                  that.uploadImgTotal = localIds.length;
+                  that.startDemo2();
                   that.syncUpload(localIds);
                 },
               });
@@ -296,6 +333,7 @@ export default {
           this.requestThen(res);
         })
         .catch((error) => {
+          this.resetDemo2();
           this.requestCatch(error);
         });
     },
@@ -324,6 +362,7 @@ export default {
           }
         }
       } else {
+        this.resetDemo2();
         that.$toast('上传失败!');
       }
     },
@@ -336,20 +375,48 @@ export default {
     },
     // 正常流程
     normalFlow(res) {
-      this.$toast('上传成功!');
-      let fileInfoList = [];
-      res.data.forEach((val) => {
-        fileInfoList.push({
-          fileUrl: val.url,
-          id: val.fileId,
-          type: 2,
+      if (this.d2timer) {
+        clearTimeout(this.d2timer);
+      }
+      try {
+        this.runD2(500, false, () => {
+          this.resetDemo2();
+          this.$toast('上传成功!');
+          let fileInfoList = [];
+          res.data.forEach((val) => {
+            fileInfoList.push({
+              fileUrl: val.url,
+              id: val.fileId,
+              type: 2,
+            });
+          });
+          this.$emit('newimgarr', {
+            fileInfoList: fileInfoList,
+            photoIdentifyType: this.photoIdentifyType,
+            source: 'H5',
+          });
         });
-      });
-      this.$emit('newimgarr', {
-        fileInfoList: fileInfoList,
-        photoIdentifyType: this.photoIdentifyType,
-        source: 'H5',
-      });
+      } catch (error) {
+        this.resetDemo2();
+      }
+    },
+    resetDemo2() {
+      if (this.d2timer) {
+        clearTimeout(this.d2timer);
+      }
+      this.d2running = false;
+      this.d2count = 0;
+      this.uploadImgTotal = 0;
+      if (document.getElementById('d2ring')) {
+        document.getElementById('d2ring').style.strokeDashoffset = 251.2;
+      }
+      if (document.getElementById('d2pct')) {
+        document.getElementById('d2pct').textContent = '0%';
+      }
+      if (document.getElementById('d2sub')) {
+        document.getElementById('d2sub').textContent = '上传中';
+      }
+      this.uploadImgFlag = false;
     },
     // 照片是否入库,1.照片识别三次不通过仍要上传,2.照片识别通过
     // isUpdate:是否更新店招照片,只有门店店招需要更新
@@ -410,6 +477,55 @@ export default {
           this.confirmUpload(res);
         });
     },
+    // ===== Demo 2 =====
+    startDemo2() {
+      if (this.d2running) return;
+      this.d2running = true;
+      this.d2count = 0;
+      this.runD2(1100, true);
+    },
+    runD2(delay, isFirst, callback) {
+      //   this.NAMES = Array.from(
+      //     { length: this.uploadImgTotal },
+      //     (_, i) => `IMG_${String(2001 + i).padStart(4, '0')}.jpg`,
+      //   );
+      if (this.d2count >= this.uploadImgTotal) {
+        document.getElementById('d2sub').textContent = '完成';
+        document.getElementById('d2name').textContent = '全部上传成功 ✅';
+        callback && callback();
+        return;
+      }
+      if (this.uploadImgTotal >= 2) {
+        this.d2timer = setTimeout(() => {
+          if (this.d2count > 0) {
+            document.getElementById(`dot${this.d2count - 1}`).className = 'ring-dot done';
+          }
+          document.getElementById(`dot${this.d2count}`).className = 'ring-dot active';
+          document.getElementById('d2name').textContent = '正在上传。。。';
+          this.d2count++;
+          const pct = Math.round((this.d2count / this.uploadImgTotal) * 100);
+          document.getElementById('d2pct').textContent = pct + '%';
+          const offset = 251.2 * (1 - this.d2count / this.uploadImgTotal);
+          document.getElementById('d2ring').style.strokeDashoffset = offset;
+          document.getElementById('d2sub').textContent = `${this.d2count}/${this.uploadImgTotal}`;
+          // this.d2count >= Math.floor(this.uploadImgTotal * (0.4 + Math.random() * 0.5))
+          if (this.d2count >= Math.floor(this.uploadImgTotal * 0.9) && isFirst) {
+            clearTimeout(this.d2timer);
+            return;
+          }
+          this.runD2(delay, isFirst, callback);
+        }, delay);
+      } else {
+        this.$nextTick(() => {
+          document.getElementById(`dot0`).className = 'ring-dot active';
+          document.getElementById('d2name').textContent = '正在上传。。。';
+          this.d2count++;
+          document.getElementById('d2pct').textContent = '50%';
+          document.getElementById('d2ring').style.strokeDashoffset = 50;
+          document.getElementById('d2sub').textContent = `0/${this.uploadImgTotal}`;
+        });
+      }
+    },
   },
 };
 </script>
@@ -448,3 +564,111 @@ export default {
   position: absolute;
 }
 </style>
+<style lang="scss">
+/* ===== 样例2:圆形进度环 ===== */
+.uploadImgDemoMask {
+  position: fixed;
+  inset: 0;
+  background: rgba(0, 0, 0, 0.5);
+  z-index: 9998;
+}
+.uploadImgDemo {
+  width: 95%;
+  position: fixed;
+  top: 50%;
+  left: 50%;
+  transform: translate(-50%, -50%);
+  z-index: 9999;
+  background: #fff;
+  padding: 10px 5px;
+  border-radius: 8px;
+}
+.uploadImgDemo .ring-area {
+  display: none;
+  // margin-top: 16px;
+  align-items: center;
+  gap: 20px;
+}
+.uploadImgDemo .ring-wrap {
+  position: relative;
+  width: 90px;
+  height: 90px;
+  flex-shrink: 0;
+}
+.uploadImgDemo .ring-wrap svg {
+  transform: rotate(-90deg);
+}
+.uploadImgDemo .ring-bg {
+  fill: none;
+  stroke: #e0f7f4;
+  stroke-width: 8;
+}
+.uploadImgDemo .ring-progress {
+  fill: none;
+  stroke: url(#greenGrad);
+  stroke-width: 8;
+  stroke-linecap: round;
+  stroke-dasharray: 251.2;
+  stroke-dashoffset: 251.2;
+  transition: stroke-dashoffset 0.35s ease;
+}
+.uploadImgDemo .ring-text {
+  position: absolute;
+  inset: 0;
+  display: flex;
+  flex-direction: column;
+  align-items: center;
+  justify-content: center;
+}
+.uploadImgDemo .ring-pct {
+  font-size: 18px;
+  font-weight: 700;
+  color: #11998e;
+}
+.uploadImgDemo .ring-sub {
+  font-size: 10px;
+  color: #aaa;
+}
+.uploadImgDemo .ring-info {
+  flex: 1;
+}
+.uploadImgDemo .ring-filename {
+  font-size: 13px;
+  font-weight: 500;
+  color: #333;
+  margin-bottom: 6px;
+  white-space: nowrap;
+  overflow: hidden;
+  text-overflow: ellipsis;
+  max-width: 160px;
+}
+.uploadImgDemo .ring-list {
+  display: flex;
+  flex-wrap: wrap;
+  gap: 4px;
+  margin-top: 8px;
+}
+.uploadImgDemo .ring-dot {
+  width: 10px;
+  height: 10px;
+  border-radius: 50%;
+  background: #e0e0e0;
+  transition: background 0.3s;
+}
+.uploadImgDemo .ring-dot.done {
+  background: #11998e;
+}
+.uploadImgDemo .ring-dot.active {
+  background: #38ef7d;
+  animation: pulse2 0.8s infinite;
+}
+@keyframes pulse2 {
+  0%,
+  100% {
+    transform: scale(1);
+  }
+  50% {
+    transform: scale(1.4);
+  }
+}
+</style>