소스 검색

feat(report): 解析loading改为旋转动画+三阶段轮播文案,提升用户感知

E2E Test Bot 4 주 전
부모
커밋
ebf4f9d0eb
1개의 변경된 파일66개의 추가작업 그리고 2개의 파일을 삭제
  1. 66 2
      cfc-frontend/pages/health/report-detail.vue

+ 66 - 2
cfc-frontend/pages/health/report-detail.vue

@@ -24,8 +24,11 @@
       <view v-else>
         <!-- 解析中状态(仅 draft 模式,从上传页跳转后自动解析) -->
         <view class="parsing-banner" v-if="parsing">
-          <text class="parsing-icon">⏳</text>
-          <text class="parsing-text">正在解析报告,请稍候...</text>
+          <view class="parsing-spinner"></view>
+          <view class="parsing-content">
+            <text class="parsing-main-text">AI 正在解析您的报告</text>
+            <text class="parsing-sub-text" :key="parsingStep">{{ parsingText }}</text>
+          </view>
         </view>
 
         <view class="tip-banner">
@@ -405,6 +408,9 @@ export default {
       pageMode: 'view', // view / draft / edit
       directEdit: false, // 是否从列表 mode=edit 直入编辑模式(取消时返回上一页)
       parsing: false,
+      parsingText: '正在检测报告类型...',
+      parsingStep: 0,
+      parsingTimer: null,
       confirming: false,
       payload: {
         type: 'gut_flora',
@@ -648,8 +654,21 @@ export default {
     parseByDraftId() {
       var self = this
       self.parsing = true
+      self.parsingStep = 0
+      self.parsingText = '正在检测报告类型,识别报告来源...'
+      // 循环切换文案,让用户知道系统在工作
+      var messages = [
+        '正在检测报告类型,识别报告来源...',
+        'AI 大模型正在深度分析报告内容...',
+        '提取关键指标,请稍候...'
+      ]
+      self.parsingTimer = setInterval(function() {
+        self.parsingStep = (self.parsingStep + 1) % messages.length
+        self.parsingText = messages[self.parsingStep]
+      }, 2500)
       parseReportDraft(self.draftId).then(function(res) {
         self.parsing = false
+        if (self.parsingTimer) { clearInterval(self.parsingTimer); self.parsingTimer = null }
         if (res.code === 200) {
           self.applyParseResult(res.data)
         } else {
@@ -657,6 +676,7 @@ export default {
         }
       }).catch(function() {
         self.parsing = false
+        if (self.parsingTimer) { clearInterval(self.parsingTimer); self.parsingTimer = null }
         uni.showToast({ title: '解析异常', icon: 'none' })
       })
     },
@@ -1100,6 +1120,9 @@ export default {
       if (value == null) return
       items.push({ parentLabel: parentLabel, label: label, value: value, max: 100 })
     }
+  },
+  onUnload: function() {
+    if (this.parsingTimer) { clearInterval(this.parsingTimer); this.parsingTimer = null }
   }
 }
 </script>
@@ -1970,4 +1993,45 @@ export default {
   margin-left: 0;
   margin-right: 0;
 }
+/* 解析中 banner */
+.parsing-banner {
+  display: flex;
+  align-items: center;
+  background: linear-gradient(135deg, #FFF7ED, #FFF0E0);
+  border: 1rpx solid #FFD4A8;
+  border-radius: 20rpx;
+  padding: 28rpx 32rpx;
+  margin-bottom: 20rpx;
+}
+.parsing-spinner {
+  width: 48rpx;
+  height: 48rpx;
+  border: 4rpx solid #FFD4A8;
+  border-top-color: #FF8C42;
+  border-radius: 50%;
+  flex-shrink: 0;
+  animation: parsing-spin 0.8s linear infinite;
+}
+@keyframes parsing-spin {
+  to { transform: rotate(360deg); }
+}
+.parsing-content {
+  display: flex;
+  flex-direction: column;
+  margin-left: 20rpx;
+  flex: 1;
+}
+.parsing-main-text {
+  font-size: 28rpx;
+  font-weight: 600;
+  color: #D97706;
+  line-height: 1.5;
+}
+.parsing-sub-text {
+  font-size: 24rpx;
+  color: #92400E;
+  line-height: 1.5;
+  margin-top: 6rpx;
+  opacity: 0.8;
+}
 </style>