瀏覽代碼

Enhance loading state management in SeoKeywordsRankList component and ensure default values for rank info are set correctly. Implemented promise chaining for data fetching to improve reliability.

Zenas 5 天之前
父節點
當前提交
c1a69a093a
共有 1 個文件被更改,包括 154 次插入69 次删除
  1. 154 69
      src/views/adweb/seo/SeoKeywordsRankList.vue

+ 154 - 69
src/views/adweb/seo/SeoKeywordsRankList.vue

@@ -57,71 +57,91 @@
       <a-col :span="8">
         <div class="wrap">
           <p class="t1">指定关键词排名</p>
-          <div class="content">
-            <div class="d1"><img src="../../../assets/seo/NO1.svg" />1-10位</div>
-            <div class="d2"><a @click="getTableInfoRank(3, 1)">{{ rankInfo.appointKeyword.firstNum }}</a>个
-            </div>
+          <div v-if="serverTimeLoading">
+            <a-spin tip="加载中..."></a-spin>
           </div>
-          <div class="content">
-            <div class="d1"><img src="../../../assets/seo/NO2.svg" />11-30位</div>
-            <div class="d2"><a @click="getTableInfoRank(7, 1)">{{ rankInfo.appointKeyword.secondNum }}</a>个
+          <template v-else>
+            <div class="content">
+              <div class="d1"><img src="../../../assets/seo/NO1.svg" />1-10位</div>
+              <div class="d2">
+                <a @click="getTableInfoRank(3, 1)">{{ rankInfo.appointKeyword && rankInfo.appointKeyword.firstNum || 0 }}</a>个
+              </div>
             </div>
-          </div>
-          <div class="content">
-            <div class="d1"><img src="../../../assets/seo/NO3.svg" />31-100位</div>
-            <div class="d2"><a @click="getTableInfoRank(8, 1)">{{ rankInfo.appointKeyword.thirdType }}</a>个
+            <div class="content">
+              <div class="d1"><img src="../../../assets/seo/NO2.svg" />11-30位</div>
+              <div class="d2">
+                <a @click="getTableInfoRank(7, 1)">{{ rankInfo.appointKeyword && rankInfo.appointKeyword.secondNum || 0 }}</a>个
+              </div>
             </div>
-          </div>
+            <div class="content">
+              <div class="d1"><img src="../../../assets/seo/NO3.svg" />31-100位</div>
+              <div class="d2">
+                <a @click="getTableInfoRank(8, 1)">{{ rankInfo.appointKeyword && rankInfo.appointKeyword.thirdType || 0 }}</a>个
+              </div>
+            </div>
+          </template>
         </div>
       </a-col>
       <a-col :span="8">
         <div class="wrap">
           <p class="t1">长尾关键词排名</p>
-          <div class="content">
-            <div class="d1"><img src="../../../assets/seo/NO1.svg" />1-10位</div>
-            <div class="d2">
-              <a @click="longGetTableInfoRank(3)">{{ rankInfo.longTailKeyword.firstNum }}</a>个
-            </div>
+          <div v-if="serverTimeLoading">
+            <a-spin tip="加载中..."></a-spin>
           </div>
-          <div class="content">
-            <div class="d1"><img src="../../../assets/seo/NO2.svg" />11-30位</div>
-            <div class="d2"><a @click="longGetTableInfoRank(7)">{{ rankInfo.longTailKeyword.secondNum }}</a>个
+          <template v-else>
+            <div class="content">
+              <div class="d1"><img src="../../../assets/seo/NO1.svg" />1-10位</div>
+              <div class="d2">
+                <a @click="longGetTableInfoRank(3)">{{ rankInfo.longTailKeyword && rankInfo.longTailKeyword.firstNum || 0 }}</a>个
+              </div>
             </div>
-          </div>
-          <div class="content">
-            <div class="d1"><img src="../../../assets/seo/NO3.svg" />31-100位</div>
-            <div class="d2"><a @click="longGetTableInfoRank(8)">{{ rankInfo.longTailKeyword.thirdType }}</a>个
+            <div class="content">
+              <div class="d1"><img src="../../../assets/seo/NO2.svg" />11-30位</div>
+              <div class="d2">
+                <a @click="longGetTableInfoRank(7)">{{ rankInfo.longTailKeyword && rankInfo.longTailKeyword.secondNum || 0 }}</a>个
+              </div>
             </div>
-          </div>
+            <div class="content">
+              <div class="d1"><img src="../../../assets/seo/NO3.svg" />31-100位</div>
+              <div class="d2">
+                <a @click="longGetTableInfoRank(8)">{{ rankInfo.longTailKeyword && rankInfo.longTailKeyword.thirdType || 0 }}</a>个
+              </div>
+            </div>
+          </template>
         </div>
       </a-col>
       <a-col :span="8">
         <div class="wrap">
           <p class="t1">服务情况</p>
-          <div class="content">
-            <div class="d1"><img src="../../../assets/seo/dachengshijian.svg"/>达成时间</div>
-            <div class="d2 d3"><span>{{
-                rankInfo.serverTime.reachStandardTime != null ? rankInfo.serverTime.reachStandardTime.substring(0,10) : '-'
-              }}</span></div>
+          <div v-if="serverTimeLoading">
+            <a-spin tip="加载中..."></a-spin>
           </div>
-          <template v-if=" rankInfo.serverTime.planServiceEndStatus === 1">
-            <div class="content">
-              <div class="d1"><img src="../../../assets/seo/dachengtianshu.svg"/>服务天数</div>
-              <div class="d2 d3"><span>{{getServiceDays(rankInfo.serverTime.planStartTime)}}</span>天</div>
-            </div>
-          </template>
           <template v-else>
             <div class="content">
-              <div class="d1"><img src="../../../assets/seo/dachengtianshu.svg"/>达成天数</div>
+              <div class="d1"><img src="../../../assets/seo/dachengshijian.svg"/>达成时间</div>
               <div class="d2 d3"><span>{{
-                  rankInfo.serverTime.reachStandardDays | filtr_null  }}</span>天</div>
+                  rankInfo.serverTime.reachStandardTime != null ? rankInfo.serverTime.reachStandardTime.substring(0,10) : '-'
+                }}</span></div>
+            </div>
+            <template v-if="rankInfo.serverTime && rankInfo.serverTime.planServiceEndStatus === 1">
+              <div class="content">
+                <div class="d1"><img src="../../../assets/seo/dachengtianshu.svg"/>服务天数</div>
+                <div class="d2 d3"><span>{{getServiceDays(rankInfo.serverTime.planStartTime)}}</span>天</div>
+              </div>
+            </template>
+            <template v-else-if="rankInfo.serverTime">
+              <div class="content">
+                <div class="d1"><img src="../../../assets/seo/dachengtianshu.svg"/>达成天数</div>
+                <div class="d2 d3"><span>{{
+                    rankInfo.serverTime.reachStandardDays | filtr_null  }}</span>天</div>
+              </div>
+            </template>
+            <div class="content" v-if="rankInfo.serverTime">
+              <div class="d1"><img src="../../../assets/seo/shengyufuwutianshu.svg"/>剩余服务天数</div>
+              <div class="d2 d3"><span>{{
+                  rankInfo.serverTime.remainServerDays | filtr_null}}</span>天</div>
             </div>
           </template>
-          <div class="content">
-            <div class="d1"><img src="../../../assets/seo/shengyufuwutianshu.svg"/>剩余服务天数</div>
-            <div class="d2 d3"><span>{{
-                rankInfo.serverTime.remainServerDays | filtr_null}}</span>天</div>
-          </div>
         </div>
       </a-col>
     </a-row>
@@ -356,9 +376,17 @@ export default {
       disableMixinCreated: true,
       comprehenInfo: {},
       rankInfo: {
-        appointKeyword: {},
-        longTailKeyword: {},
-        serverTime: {},
+        appointKeyword: {
+          firstNum: 0,
+          secondNum: 0,
+          thirdType: 0
+        },
+        longTailKeyword: {
+          firstNum: 0,
+          secondNum: 0,
+          thirdType: 0
+        },
+        serverTime: {}
       },
       excelLoading: false,
       queryParam: {
@@ -410,6 +438,7 @@ export default {
       longWordsButtonStatus: true,
       /* 筛选参数 */
       filters: {},
+      serverTimeLoading: false,
     };
   },
   watch: {
@@ -430,12 +459,27 @@ export default {
       return option.componentOptions.children[0].text.toLowerCase().indexOf(input.toLowerCase()) >= 0;
     },
     getAllInfo() {
-      this.getComprehenInfo();
+      // 初始化状态
+      this.serverTimeLoading = true;
+      
+      // 使用Promise链确保顺序执行
+      this.getComprehenInfo()
+        .then(() => {
+          return this.getRankInfo();
+        })
+        .then(() => {
+          // 所有数据加载完成后,再加载表格数据
+          this.setTableQuery();
+          this.longSetTableQuery();
+        })
+        .catch(err => {
+          console.error('Failed to load data:', err);
+        });
     },
     resetAllInfo() {
       this.comprehenInfo = {};
-      this.rankInfo.appointKeyword = {};
-      this.rankInfo.longTailKeyword = {};
+      this.rankInfo.appointKeyword = {firstNum: 0, secondNum: 0, thirdType: 0};
+      this.rankInfo.longTailKeyword = {firstNum: 0, secondNum: 0, thirdType: 0};
       this.rankInfo.serverTime = {};
       this.dataSource = [];
       this.ipagination.current = 1;
@@ -603,17 +647,21 @@ export default {
         siteCode: that.siteCode,
         planId: that.planId ? that.planId : '',
       };
-      getAction('/seo/seoKeywordsRank/comprehensiveInfo', d)
-        .then((res) => {
-          if (res.code == 200) {
-            that.comprehenInfo = res.result;
-            that.getRankInfo();
-          }
-        })
-        .finally(() => {
-          this.setTableQuery();
-          this.longSetTableQuery();
-        });
+      
+      return new Promise((resolve, reject) => {
+        getAction('/seo/seoKeywordsRank/comprehensiveInfo', d)
+          .then((res) => {
+            if (res.code == 200) {
+              that.comprehenInfo = res.result;
+              resolve(res);
+            } else {
+              reject(res);
+            }
+          })
+          .catch(err => {
+            reject(err);
+          });
+      });
     },
 
     //获取三个list的数据
@@ -623,15 +671,52 @@ export default {
         siteCode: that.siteCode,
         subscriptionId: that.subscriptionId ? that.subscriptionId : '',
       };
-      that.loading = true;
-      getAction('/seo/seoKeywordsRank/getRankInfo', d).then((res) => {
-        if (res.code == 200) {
-          this.rankInfo.appointKeyword = res.result.appointKeyword;
-          this.rankInfo.longTailKeyword = res.result.longTailKeyword;
-          this.rankInfo.serverTime = res.result.serverTime;
-        }
-      }).finally(() => {
-        that.loading = false;
+      
+      // 添加专门的加载状态标志
+      this.serverTimeLoading = true;
+      
+      return new Promise((resolve, reject) => {
+        getAction('/seo/seoKeywordsRank/getRankInfo', d)
+          .then((res) => {
+            if (res.code == 200) {
+              // 确保即使后端返回null或undefined也能初始化为空对象
+              const appointKeyword = res.result.appointKeyword || {};
+              const longTailKeyword = res.result.longTailKeyword || {};
+              const serverTime = res.result.serverTime || {};
+              
+              // 使用Vue.set确保响应式更新
+              this.$set(this.rankInfo, 'appointKeyword', appointKeyword);
+              this.$set(this.rankInfo, 'longTailKeyword', longTailKeyword);
+              this.$set(this.rankInfo, 'serverTime', serverTime);
+              
+              // 确保各个数字属性有默认值
+              if (!appointKeyword.firstNum) this.$set(this.rankInfo.appointKeyword, 'firstNum', 0);
+              if (!appointKeyword.secondNum) this.$set(this.rankInfo.appointKeyword, 'secondNum', 0);
+              if (!appointKeyword.thirdType) this.$set(this.rankInfo.appointKeyword, 'thirdType', 0);
+              
+              if (!longTailKeyword.firstNum) this.$set(this.rankInfo.longTailKeyword, 'firstNum', 0);
+              if (!longTailKeyword.secondNum) this.$set(this.rankInfo.longTailKeyword, 'secondNum', 0);
+              if (!longTailKeyword.thirdType) this.$set(this.rankInfo.longTailKeyword, 'thirdType', 0);
+              
+              resolve(res);
+            } else {
+              // 初始化为空对象
+              this.$set(this.rankInfo, 'appointKeyword', {firstNum: 0, secondNum: 0, thirdType: 0});
+              this.$set(this.rankInfo, 'longTailKeyword', {firstNum: 0, secondNum: 0, thirdType: 0});
+              this.$set(this.rankInfo, 'serverTime', {});
+              reject(res);
+            }
+          })
+          .catch(err => {
+            // 初始化为空对象
+            this.$set(this.rankInfo, 'appointKeyword', {firstNum: 0, secondNum: 0, thirdType: 0});
+            this.$set(this.rankInfo, 'longTailKeyword', {firstNum: 0, secondNum: 0, thirdType: 0});
+            this.$set(this.rankInfo, 'serverTime', {});
+            reject(err);
+          })
+          .finally(() => {
+            this.serverTimeLoading = false;
+          });
       });
     },