Просмотр исходного кода

feature_20260506_增加照片上传进度UI效果

zhujindu 2 дней назад
Родитель
Сommit
73addb5cf5
1 измененных файлов с 200 добавлено и 13 удалено
  1. 200 13
      src/components/uploadVNormalTaskPhoto.vue

+ 200 - 13
src/components/uploadVNormalTaskPhoto.vue

@@ -31,6 +31,25 @@
       @normalFlow="normalFlow"
       @close="close">
     </imageWhiteStore>
+    <!-- 上传动画 -->
+    <div class="uploadImgDemo" v-if="uploadImgFlag">
+      <div class="ring-area" id="d2area">
+        <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>
+        </div>
+      </div>
+    </div>
   </div>
 </template>
 
@@ -43,10 +62,11 @@ import axios from 'axios';
 import uploadAliOss from '@/utils/uploadAliOss';
 import { addH5Photo } from '@/api/H5Camera';
 import { mapState } from 'vuex';
+import uploadImgDemo from './uploadImgDemo';
 
 export default {
   name: 'uploadImg',
-  components: { imageAIVerifyErr, H5Camera, imageWhiteStore },
+  components: { imageAIVerifyErr, H5Camera, imageWhiteStore, uploadImgDemo },
   props: {
     storeGroupId: {
       type: String,
@@ -114,6 +134,11 @@ export default {
       imageWhiteStoreData: null,
       imageWhiteStoreFlag: false,
       localIdsArr: [],
+      uploadImgFlag: false, //上传图片中
+      uploadImgTotal: 0, // 上传图片总数
+      d2running: false,
+      d2count: 0,
+      d2timer: null,
     };
   },
   methods: {
@@ -231,6 +256,9 @@ export default {
                   //   collectionItemId: that.collectionItemId,
                   //   source: 'weixin',
                   // });
+                  that.uploadImgFlag = true;
+                  that.uploadImgTotal = localIds.length;
+                  that.startDemo2();
                   that.syncUpload(localIds);
                 },
               });
@@ -335,19 +363,24 @@ export default {
     },
     // 正常流程
     normalFlow(res) {
-      this.$toast('上传成功!');
-      let fileInfoList = [];
-      res.data.forEach((val) => {
-        fileInfoList.push({
-          fileUrl: val.url,
-          id: val.fileId,
-          type: 2,
+      this.runD2(100);
+      this.$nextTick(() => {
+        clearTimeout(this.d2timer);
+        this.uploadImgFlag = false;
+        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',
       });
     },
     // 照片是否入库,1.照片识别三次不通过仍要上传,2.照片识别通过
@@ -409,6 +442,59 @@ export default {
           this.confirmUpload(res);
         });
     },
+    // ===== Demo 2 =====
+    startDemo2() {
+      if (this.d2running) return;
+      this.d2running = true;
+      this.d2count = 0;
+      const area = document.getElementById('d2area');
+      area.style.display = 'flex';
+      const dots = document.getElementById('d2dots');
+      dots.innerHTML = '';
+      for (let i = 0; i < this.uploadImgDemo; i++) {
+        const d = document.createElement('div');
+        d.className = 'ring-dot';
+        d.id = `dot${i}`;
+        dots.appendChild(d);
+      }
+      this.runD2(1000);
+    },
+    runD2(delay) {
+      //   this.NAMES = Array.from(
+      //     { length: this.uploadImgDemo },
+      //     (_, i) => `IMG_${String(2001 + i).padStart(4, '0')}.jpg`,
+      //   );
+      if (this.d2count >= this.uploadImgDemo) {
+        document.getElementById('d2sub').textContent = '完成';
+        document.getElementById('d2name').textContent = '全部上传成功 ✅';
+        return;
+      }
+      if (this.uploadImgDemo >= 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.uploadImgDemo) * 100);
+          document.getElementById('d2pct').textContent = pct + '%';
+          const offset = 251.2 * (1 - this.d2count / this.uploadImgDemo);
+          document.getElementById('d2ring').style.strokeDashoffset = offset;
+          document.getElementById('d2sub').textContent = `${this.d2count}/${this.uploadImgDemo}`;
+          if (this.d2count >= this.uploadImgDemo * 0.7) {
+            clearTimeout(this.d2timer);
+          }
+          this.runD2();
+        }, delay);
+      } else {
+        document.getElementById(`dot${this.d2count - 1}`).className = 'ring-dot done';
+        document.getElementById(`dot${this.d2count}`).className = 'ring-dot active';
+        document.getElementById('d2name').textContent = '正在上传。。。';
+        document.getElementById('d2pct').textContent = '30%';
+        document.getElementById('d2ring').style.strokeDashoffset = 30;
+        document.getElementById('d2sub').textContent = `0/${this.uploadImgDemo}`;
+      }
+    },
   },
 };
 </script>
@@ -447,3 +533,104 @@ export default {
   position: absolute;
 }
 </style>
+<style lang="scss">
+/* ===== 样例2:圆形进度环 ===== */
+.uploadImgDemo {
+  width: 90%;
+  height: 200px;
+  position: fixed;
+  top: 50%;
+  left: 50%;
+  transform: translate(-50%, -50%);
+  z-index: 9999;
+  background: #fff;
+}
+.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>