From f96f952d95930e1295051c1bfe348dd324ebf878 Mon Sep 17 00:00:00 2001
From: lxf <1371462558@qq.com>
Date: Wed, 16 Jul 2025 13:38:53 +0800
Subject: [PATCH] 添加缓存

---
 src/components/foreign/foreign-popup-delivery/index.vue |    6 
 src/views/my/newindex.vue                               |    3 
 src/views/news/index.vue                                |   26 ++--
 src/components/Transform/list-quotation/index.vue       |   14 +-
 src/views/cryptos/index.vue                             |  198 ++++++++++++++++++++------------
 src/components/Transform/trade-order-area/index.vue     |   17 +-
 src/config/index.js                                     |    5 
 src/views/cryptos/TrendDetails/index.vue                |    3 
 src/components/Transform/popup-delivery/index.vue       |   21 ++-
 src/router/index.js                                     |    5 
 src/components/Transform/perpetual-open/index.vue       |   60 +++++----
 11 files changed, 208 insertions(+), 150 deletions(-)

diff --git a/src/components/Transform/list-quotation/index.vue b/src/components/Transform/list-quotation/index.vue
index 83af001..d74095e 100644
--- a/src/components/Transform/list-quotation/index.vue
+++ b/src/components/Transform/list-quotation/index.vue
@@ -30,7 +30,7 @@
                 <p class="flex flex-col">
                   <span class="flex items-end font-32 flex items-center">
                     <span class="textColor font-600 font-30">{{ item.name || '--'
-                      }}</span>
+                    }}</span>
                   </span>
                   <span class="font-24 text-grey text-left">{{ (item.amount * 1).toFixed(2) }}</span>
                 </p>
@@ -39,10 +39,8 @@
                 <p class="textColor font-32 font-600">{{ item.close || '--' }}</p>
               </li>
               <li class="right flex items-center justify-end">
-                <p 
-                  class="w-153 font-31 h-71 text-white border-0 text-center btn" 
-                  :class="item.change_ratio > 0 ? 'bg-green' : 'bg-red'"
-                >
+                <p class="w-153 font-31 h-71 text-white border-0 text-center btn"
+                  :class="item.change_ratio > 0 ? 'bg-green' : 'bg-red'">
                   {{ item.change_ratio === 0 ? 0 : item.change_ratio }}%
                 </p>
               </li>
@@ -75,6 +73,7 @@
       type: 'left' //left 从左往右 right 从有王座
     }
   },
+
   props: {
     showMore: {
       type: Boolean,
@@ -98,8 +97,7 @@
     [List.name]: List,
     [Cell.name]: Cell,
     ExTabs
-  },
-  mounted() {
+  }, mounted() {
     this.SET_CURRENCY()
   },
   methods: {
@@ -178,7 +176,7 @@
       } else if (this.active == 3) {
         this.showList = [...this.listData].sort(this.compare("volume", 'up'))
       }
-      this.$forceUpdate()
+      this.$forceUpdate();
     }
   }
 }
diff --git a/src/components/Transform/perpetual-open/index.vue b/src/components/Transform/perpetual-open/index.vue
index bcd59e2..15dd02a 100644
--- a/src/components/Transform/perpetual-open/index.vue
+++ b/src/components/Transform/perpetual-open/index.vue
@@ -34,26 +34,28 @@
                 </p>
               </div>
               <div class="mt-22 mb-30" style="position:relative;">
-                <div class="greyBg flex justify-between items-center w-full h-76 rounded-lg textColor" @click="selectBtn">
+                <div class="greyBg flex justify-between items-center w-full h-76 rounded-lg textColor"
+                  @click="selectBtn">
                   <img src="../../../assets/image/public/warn.png" alt="warn-icon" class="w-25 h-25 ml-20" />
                   <div class="text-center" style="width:80%;">{{ title }}</div>
                   <img src="../../../assets/image/public/grey-select.png" alt="select-icon" class="w-22 h-11 mr-20" />
                 </div>
                 <div class="option-box" v-show="isShow">
-                  <div class="font-30" v-for="item in selectData" :key="item.type" @click="selectItem(item)">{{ item.title
-                  }}</div>
+                  <div class="font-30" v-for="item in selectData" :key="item.type" @click="selectItem(item)">{{
+                    item.title
+                    }}</div>
                 </div>
               </div>
             </template>
-            <contract-futrue v-if="selectIndex == 2" class="mb-20"
-              :initFutrue="initFutrue" @paraId="onParaId" />
+            <contract-futrue v-if="selectIndex == 2" class="mb-20" :initFutrue="initFutrue" @paraId="onParaId" />
             <div class="h-76 lh-76 greyBg mb-30 flex pr-20 justify-center rounded-lg textColor" v-if="selectIndex == 1">
               <input placeholder="" class="greyBg w-full pl-20  h-76 border-none text-left rounded-lg"
                 :disabled="type / 1 === 1" @focus="focus = true" v-model="form.price" />
               <span class="ml-20">{{ queryType === 'cryptos' ? 'USDT' : 'USD' }}</span>
             </div>
 
-            <div class=" flex items-center greyBg h-76 lh-76 rounded-lg" style="background-color:#f5f5f5;" v-if="initFutrue" >
+            <div class=" flex items-center greyBg h-76 lh-76 rounded-lg" style="background-color:#f5f5f5;"
+              v-if="initFutrue">
               <!-- <div v-if="selectIndex == 1 && initFutrue.para && initFutrue.para.length > 0"
                 class="w-80 flex items-center justify-center" style="height:100%;" @click="onReduce">
                 <img src="../../../assets/image/public/reduce.png" alt="add" class="w-30 h-6" />
@@ -62,8 +64,8 @@
                 style="width: 156px;" v-model="form.amount" type="number" @input="onInput" /> -->
               <input v-if="selectIndex == 2 && JSON.stringify(initFutrue.para) != '[]'"
                 :placeholder="($t('最少') + initFutrue && initFutrue.para ? $t('最小金额') + initFutrue.para[paraIndex].buy_min : '')"
-                class="border-none greyBg text-center textColor" style="width: 226px;background-color:#f5f5f5;" v-model="form.amount" type="number"
-                @input="onInput" />
+                class="border-none greyBg text-center textColor" style="width: 226px;background-color:#f5f5f5;"
+                v-model="form.amount" type="number" @input="onInput" />
               <div class="w-80 flex items-center justify-center" style="height:100%;background-color:#f5f5f5;">
                 <template v-if="selectIndex == 1">
                   <img @click="onAdd" src="../../../assets/image/public/add.png" alt="reduce" class="w-30 h-30" />
@@ -88,14 +90,14 @@
               <template v-slot:step="{ active }">
                 <div :class="['custom-step', { active }]"></div>
               </template>
-            </vue-slider>
-            <div style="color: #868D9A" class="mt-36 font-24 w-full flex justify-between items-center">
-              <span class="flex-1 text-left">0%</span>
-              <span class="flex-1 text-left">25%</span>
-              <span class="flex-1 text-center">50%</span>
-              <span class="flex-1 text-right">75%</span>
-              <span class="flex-1 text-right">100%</span>
-            </div> -->
+</vue-slider>
+<div style="color: #868D9A" class="mt-36 font-24 w-full flex justify-between items-center">
+  <span class="flex-1 text-left">0%</span>
+  <span class="flex-1 text-left">25%</span>
+  <span class="flex-1 text-center">50%</span>
+  <span class="flex-1 text-right">75%</span>
+  <span class="flex-1 text-right">100%</span>
+</div> -->
               <!-- 张数输入 -->
               <amount-slider ref="sliderRef" :maxAmount="getVolumnByLever()" @getAmount="getAmount"></amount-slider>
             </template>
@@ -116,7 +118,7 @@
                 <div class="text-grey">{{ $t("建仓手续费") }}</div>
                 <div class="textColor">{{ userInfo.perpetual_contracts_status === '1' ? initData.fee *
                   (form.amount / 1) : initData.fee * (form.amount / 1) * form.lever_rate }} {{ queryType === 'cryptos' ?
-    'USDT' : 'USD' }}</div>
+                  'USDT' : 'USD' }}</div>
               </div>
             </template>
 
@@ -195,7 +197,8 @@
                 <p class="pt-8">{{ $t('登陆后继续') }}</p>
               </div>
               <div class="h-80 lh-80 btnBackground flex text-white rounded-md justify-center mt-50"
-                @click="$router.push('/login')">{{ $t('logIn') }}</div>
+                @click="$router.push('/login')">
+                {{ $t('logIn') }}</div>
             </div>
           </div>
           <!-- <div class="ml-30">
@@ -286,8 +289,8 @@
         </div>
       </div>
       <van-popup v-model:show="show" class="rounded-2xl">
-        <popup-delivery style="padding: 10px;" showBtns :detailData="detailData" :key="detailData.order_no" @close="onClose"
-          @continueToBuy="continueTobuy" @timeEnd="handleTimeEnd" :price="price" />
+        <popup-delivery style="padding: 10px;" showBtns :detailData="detailData" :key="detailData.order_no"
+          @close="onClose" @continueToBuy="continueTobuy" @timeEnd="handleTimeEnd" :price="price" />
       </van-popup>
       <van-action-sheet v-model:show="isSelectShow" @select="onSelect" :actions="actions" :cancel-text="$t('取消')"
         close-on-click-action @cancel="onCancel">
@@ -638,9 +641,10 @@
     },
     continueTobuy(detailData) {
       this.show = false
-      setTimeout(() => {
-        this.$router.push(`/trendDetails/${detailData.symbol}?direction=${detailData.direction}`)
-      }, 300);
+      // this.order()
+      // setTimeout(() => {
+      //   this.$router.push(`/trendDetails/${detailData.symbol}?direction=${detailData.direction}`)
+      // }, 300);
     },
     onQuickPrice(price) { // 点击金额变化
       if (this.type === '2') {
@@ -839,7 +843,7 @@
       })
     },
     //数字排序
-    orderListAsc(filed, type = "asc"){
+    orderListAsc(filed, type = "asc") {
       return (a, b) => {
         if (type == "asc") return parseFloat(a[filed]) > parseFloat(b[filed]) ? 1 : -1;
         return parseFloat(a[filed]) > parseFloat(b[filed]) ? -1 : 1;
@@ -1062,12 +1066,16 @@
     margin-right: 20px;
   }
 }
-.diviLine{
+
+.diviLine {
   background-color: #f5f5f5;
 }
-.textColor2, .textColor{
+
+.textColor2,
+.textColor {
   color: #fff;
 }
+
 .deep-div {
   min-height: 370px;
 }
diff --git a/src/components/Transform/popup-delivery/index.vue b/src/components/Transform/popup-delivery/index.vue
index 295fd46..d909823 100644
--- a/src/components/Transform/popup-delivery/index.vue
+++ b/src/components/Transform/popup-delivery/index.vue
@@ -17,8 +17,10 @@
         </van-circle>
       </div>
       <div class="mt-45 font-50 text-center"
-        :class="{ 'text-green': detailData.profit_state === '1', 'text-red': detailData.profit_state === '0' }" v-else>{{
-          $t('服务费') }}<span>{{ detailData.profit_state === '1' ? '+' : '' }}{{ detailData.profit }}</span> {{ routeType == 'cryptos' ? 'USDT' : 'USD' }}</div>
+        :class="{ 'text-green': detailData.profit_state === '1', 'text-red': detailData.profit_state === '0' }" v-else>
+        {{
+          $t('服务费') }}<span>{{ detailData.profit_state === '1' ? '+' : '' }}{{ detailData.profit }}</span> {{ routeType ==
+          'cryptos' ? 'USDT' : 'USD' }}</div>
       <ul class="flex flex-col pb-61 textColor">
         <li v-for="item in listItem" :key="item.id" class="flex justify-between px-38 mt-28">
           <p class="text-grey font-30">{{ item.text }}</p>
@@ -37,12 +39,12 @@
           <p class="font-30 " :class="colorChoose(item)" v-else>{{ handleBuyWord(item) }}</p>
         </li>
       </ul>
-      <div v-if="showBtns" class="flex justify-between text-white px-38 pb-61">
+      <div v-if="showBtns" class="flex justify-center text-white px-38 pb-61">
         <p :class="{ 'btnMain': detailData.state !== 'created', 'bgDark': detailData.state === 'created' }"
           class="w-255 h-90 rounded-lg flex justify-center items-center mr-20" @click="onClose">{{ $t('关闭') }}</p>
-        <p @click="continueToBuy"
+        <!-- <p @click="continueToBuy"
           :class="{ 'btnMain': detailData.state === 'created', 'bgDark': detailData.state !== 'created', 'disableBtn': disabled }"
-          class="w-385 h-90 rounded-lg flex justify-center items-center">{{ $t('继续下单') }}</p>
+          class="w-385 h-90 rounded-lg flex justify-center items-center">{{ $t('继续下单') }}</p> -->
       </div>
     </div>
   </div>
@@ -138,14 +140,15 @@
       //     {id: 4, text: '数量', key: 'amount', extro: 'USDT'},
       //     {id: 5, text: '交割时间', key: 'settlement_time'}
       // ]
-      routeType:'cryptos'
+      routeType: 'cryptos'
     }
   },
   methods: {
     continueToBuy() {
-      if (this.detailData.state !== 'created') {
-        return
-      }
+      console.log('detailData: ', this.detailData)
+      // if (this.detailData.state !== 'created') {
+      //   return
+      // }
       this.$emit('continueToBuy', this.detailData)
 
       //this.$router.push(`/trendDetails/${symbol}`)
diff --git a/src/components/Transform/trade-order-area/index.vue b/src/components/Transform/trade-order-area/index.vue
index f6f1ae7..543fb6e 100644
--- a/src/components/Transform/trade-order-area/index.vue
+++ b/src/components/Transform/trade-order-area/index.vue
@@ -2,9 +2,9 @@
   <div class="flex flex-col flex-1 font-28" style="width: 280px;">
     <div class="flex items-center h-66 tabBackground text-grey">
       <p class="font-28 flex-1 flex items-center justify-center h-66 buy-item"
-        :class="currentType == 'open' ? 'open' : ''" @click="changeTab('open')">{{ $t('买入') }}</p>
+        :class="currentType === 'open' ? 'open' : ''" @click="currentType = 'open'">{{ $t('买入') }}</p>
       <p class="font-28 flex-1 flex items-center justify-center h-66 buy-item"
-        :class="currentType == 'close' ? 'close' : ''" @click="changeTab('close')">{{ $t('卖出') }}</p>
+        :class="currentType === 'close' ? 'close' : ''" @click="currentType = 'close'">{{ $t('卖出') }}</p>
     </div>
 
     <div class="mt-22 mb-22 inputBackground" style="position:relative;">
@@ -18,6 +18,7 @@
         </div>
       </div>
     </div>
+    <!-- {{ form }} -->
     <div class="h-70 lh-70  inputBackground mb-25 flex justify-center px-16 textColor2">
       <input placeholder="" class="targetPrice  w-full  h-70 border-none" v-model="form.price"
         :disabled="type / 1 === 1" />
@@ -90,11 +91,6 @@
     [Tab.name]: Tab
   },
   props: {
-	
-    symbol: {
-      type: String,
-      default: ''
-    },
     symbol: {
       type: String,
       default: ''
@@ -167,7 +163,7 @@
         order_price_type: 'opponent', // 市价or限价
       },
       type: "1",//选中市价或限价类型
-      // currentType: "close", //开仓类型
+      currentType: 'open', // 默认选中买入
       interval: 0.001,
       marks: (val) => val % 25 === 0,
       isTotal: false,
@@ -181,7 +177,7 @@
     ]
     this.title = this.selectData[0].title
     this.type = this.selectData[0].type
-	// this.currentType = this.currentTypes
+    // this.currentType = this.currentTypes
     this.form.order_price_type = 'opponent'
   },
   methods: {
@@ -482,7 +478,7 @@
 .close {
   background-color: #DE5D56;
   // background: url(@/assets/image/public/close-bg.png) no-repeat left center;
-  
+
   background-size: 100% 100%;
   color: white;
 }
@@ -589,4 +585,3 @@
   color: $text_color;
 }
 </style>
-
diff --git a/src/components/foreign/foreign-popup-delivery/index.vue b/src/components/foreign/foreign-popup-delivery/index.vue
index 573ad0b..2d5813f 100644
--- a/src/components/foreign/foreign-popup-delivery/index.vue
+++ b/src/components/foreign/foreign-popup-delivery/index.vue
@@ -36,12 +36,12 @@
         <p class="font-30 " :class="colorChoose(item)" v-else>{{ handleBuyWord(item) }}</p>
       </li>
     </ul>
-    <div v-if="showBtns" class="flex justify-between text-white px-18 pb-30">
+    <div v-if="showBtns" class="flex justify-center text-white px-18 pb-30">
       <p :class="{ 'btnMain': detailData.state !== 'created', 'bgDark': detailData.state === 'created' }"
         class="w-122 h-44 rounded-lg flex justify-center items-center mr-10" @click="onClose">{{ $t('close') }}</p>
-      <p @click="continueToBuy"
+      <!-- <p @click="continueToBuy"
         :class="{ 'btnMain': detailData.state === 'created', 'bgDark': detailData.state !== 'created', 'disableBtn': disabled }"
-        class="w-162 h-44 rounded-lg flex justify-center items-center">{{ $t('继续下单') }}</p>
+        class="w-162 h-44 rounded-lg flex justify-center items-center">{{ $t('继续下单') }}</p> -->
     </div>
   </div>
 </template>
diff --git a/src/config/index.js b/src/config/index.js
index 5deddf3..3143a30 100644
--- a/src/config/index.js
+++ b/src/config/index.js
@@ -7,7 +7,12 @@
 export const REQUEST_TIMEOUT = 30000
 
 // 请求频率
+// 全局基础超时时间
 export const TIME_OUT = 2000
+// 行情轮询间隔(毫秒) - 优化性能调整为5秒
+export const QUOTE_POLLING_INTERVAL = 5000
+// 缓存过期时间(毫秒)
+export const CACHE_EXPIRE = 5 * 60 * 1000 // 5分钟
 
 // 表单类型key
 export const CONTENT_TYPE = 'Content-Type'
diff --git a/src/router/index.js b/src/router/index.js
index 92749df..5977a89 100644
--- a/src/router/index.js
+++ b/src/router/index.js
@@ -107,8 +107,8 @@
         },
         component: () => import('@/views/Layout.vue'),
         children: [
-          { path: 'index', meta: { tarbar: false, keepAlive: true }, component: () => import('@/views/position/newindex.vue') },
-          // { path: 'index', meta: { tarbar: false, keepAlive: true }, component: () => import('@/views/position/index.vue') },
+          { path: 'index', meta: { tarbar: false, keepAlive: true }, component: () => import(/* webpackChunkName: "cryptos" */ /* webpackPrefetch: true */ '@/views/cryptos/index.vue') }
+          // { path: 'index', meta: { tarbar: false, keepAlive: true }, component: () => import(/* webpackChunkName: "cryptos" */ /* webpackPrefetch: true */ '@/views/cryptos/index.vue') }
         ]
       },
       {
@@ -184,6 +184,7 @@
         },
         component: () => import('@/views/Layout.vue'),
         children: [
+          { path: 'index', meta: { tarbar: false, keepAlive: true }, component: () => import(/* webpackChunkName: "cryptos" */ /* webpackPrefetch: true */ '@/views/cryptos/index.vue') },
           { path: 'announce', meta: { tarbar: false, keepAlive: true }, component: () => import('@/views/cryptos/Announce/index.vue') },
           { path: 'announceDetail', meta: { tarbar: false, keepAlive: true }, component: () => import('@/views/cryptos/Announce/announceDetail.vue') },
           { path: 'exchangePage', meta: { tarbar: false, keepAlive: true }, component: () => import('@/views/cryptos/Exchange/exchangePage.vue') },
diff --git a/src/views/cryptos/TrendDetails/index.vue b/src/views/cryptos/TrendDetails/index.vue
index b8860d4..680de1d 100644
--- a/src/views/cryptos/TrendDetails/index.vue
+++ b/src/views/cryptos/TrendDetails/index.vue
@@ -219,7 +219,7 @@
           :balance="initFutrue.amount" :price="quote.close" @close="onClose" @confirm="onOrderConfirm"
           v-if="popType === 'confirm'" />
         <popup-delivery showBtns :detailData="detailData" :key="detailData.order_no" @close="onClose"
-          @continueToBuy="order()" @timeEnd="handleTimeEnd" :price="quote.close" v-else />
+          @continueToBuy="order" @timeEnd="handleTimeEnd" :price="quote.close" v-else />
       </van-popup>
     </div>
   </div>
@@ -338,6 +338,7 @@
       }
     },
     order() {
+      console.log('order', this.direction)
       this.onSubmit(this.direction);
     },
     onTab(e) {
diff --git a/src/views/cryptos/index.vue b/src/views/cryptos/index.vue
index 19acbaf..685cb79 100644
--- a/src/views/cryptos/index.vue
+++ b/src/views/cryptos/index.vue
@@ -4,7 +4,7 @@
     <!-- <ioe-swiper /> -->
     <!-- <div class="py-10"> -->
 
-   
+
     <!-- <van-notice-bar class="font-26 textColor" left-icon="" :scrollable="false" background="transparent">
       <div slot="left-icon" class=" flex items-center more-img"><img class="w-20 h-20  more-img"
           src="../../assets/Horn.png" alt="">
@@ -17,7 +17,7 @@
           class="w-20 h-20 more-img" src="../../assets/more.png" alt="">
       </div>
     </van-notice-bar> -->
-  <!-- </div> -->
+    <!-- </div> -->
     <!-- <cry-nav /> -->
     <!-- <div class="quickly">
       <div class="quickBox chongbi" :class="THEME == 'dark' ? 'dark' : 'white'"
@@ -42,13 +42,13 @@
       </div>
     </div> -->
     <!-- <ex-hot :listData="hList"></ex-hot> -->
-    <list-quatation :listData="qList" @onfetchQList="fetchQList"/>
+    <list-quatation :listData="qList" :hList="filteredHList" @onfetchQList="fetchQList" />
     <van-popup v-model:show="item.showPopUp" style="border-radius:10px;" :close-on-click-overlay="false"
       v-for="item in popupNewsList" :key="item.id">
       <div class="w-350 p-20 box-border">
         <div class="font-700 text-center font-28 textColor">{{ item.title }}</div>
-        <div class="flex justify-center mt-30" v-if="item.imgUrl"><img
-            :src="`${item.imgUrl}`" class="w-200 h-200" alt="" /></div>
+        <div class="flex justify-center mt-30" v-if="item.imgUrl"><img :src="`${item.imgUrl}`" class="w-200 h-200"
+            alt="" /></div>
         <div class="py-10 textColor   content-title" v-html="item.content"></div>
         <van-button color="#1194F7" class="w-full h-40 rounded-full" type="info" @click="closePopNotice(item)">
           {{ $t('我知道了') }}
@@ -62,7 +62,7 @@
 import IoeSwiper from "@/components/Transform/ioe-swiper/index.vue";
 import ListQuatation from "@/components/Transform/list-quotation/index.vue";
 import { mapGetters, mapActions } from "vuex";
-import { TIME_OUT } from "@/config";
+import { TIME_OUT, QUOTE_POLLING_INTERVAL, CACHE_EXPIRE } from "@/config";
 import { SET_COIN_LIST } from '@/store/const.store'
 import { _getHomeList } from '@/service/cryptos.api'
 import ExHeader from "@/components/Transform/ex-header/index.vue";
@@ -73,7 +73,7 @@
 import { _getUnreadMsg } from '@/service/im.api'
 import { _getNewsList1, _getPopupNews } from '@/service/user.api'
 import { BASE_URL } from "@/config";
-import { _getCoinList } from '@/service/quotes.api'; 
+import { _getCoinList } from '@/service/quotes.api';
 const THEME = 'dark'
 export default {
   name: "HomePage",
@@ -87,6 +87,14 @@
     [Swipe.name]: Swipe,
     [SwipeItem.name]: SwipeItem,
   },
+  watch: {
+    hotArr(newVal) {
+      // 当热门币种列表更新时重新计算hList
+      if (this.qList && newVal.length) {
+        this.hList = this.qList.filter(item => newVal.includes(item.symbol)).slice(0, 3);
+      }
+    }
+  },
   async created() {
     this.init();
     this.checkingMesk();
@@ -94,6 +102,17 @@
     await this.fetchQList()
   },
   computed: {
+    // 优化:使用计算属性高效生成热门列表
+    filteredHList() {
+      const result = [];
+      for (const item of this.qList) {
+        if (this.hotArr.includes(item.symbol)) {
+          result.push(item);
+          if (result.length >= 3) break;
+        }
+      }
+      return result;
+    },
     ...mapGetters({
       coinList: 'home/coinList',
       currency: 'home/currency',
@@ -103,19 +122,20 @@
     }),
   },
   data() {
-    const arr = [] // 初始化数据
-    for (let i = 0; i < 10; i++) {
-      arr.push({ id: i })
-    }
+    // 优先从localStorage加载缓存数据
+    const cachedData = getStorage('qoutes');
+    const now = Date.now();
+    const isCacheValid = cachedData && cachedData.timestamp && (now - cachedData.timestamp < CACHE_EXPIRE);
+
     return {
       BASE_URL,
       THEME,
       account: "",
-      hList: arr.slice(0, 3), // 热门
-      qList: arr, // 行情列表
+
+      qList: isCacheValid ? cachedData.data : [], // 行情列表 - 优先使用缓存
       active: 0,
       timeout: null,
-      loading: true,
+      loading: !isCacheValid, // 有缓存数据时不显示加载状态
       announceTitle: '',
       announceId: '',
       announceList: [],
@@ -135,61 +155,79 @@
       })
     },
     async fetchQList(v) { // 获取行情
-      let coninArr = ''
-      // if (v) { this.getVal = v }
-      let arr = getStorage('qoutes')
+      // 优化:使用缓存数据快速展示,同时后台更新
+      const cachedQuotes = getStorage('quotes');
+      if (cachedQuotes && cachedQuotes.data && Date.now() - cachedQuotes.timestamp < CACHE_EXPIRE) {
+        this.qList = cachedQuotes.data;
+        this.hList = cachedQuotes.data.filter(item => this.hotArr.includes(item.symbol)).slice(0, 3);
+        this.loading = false;
+        return;
+      }
 
-      // 优先用本地缓存的 coins
-      let coins = (arr && arr.coins && arr.coins.length) ? arr.coins : arr
+      // 优化:变量名修正与符号拼接
+      let coinArr = '';
+      const arr = getStorage('quotes');
+      const coins = (arr && arr.coins && arr.coins.length) ? arr.coins : arr;
 
       if (coins && coins.length) {
-        // 如果本地有 coins,优先用本地
-        coins.forEach(item => {
-          coninArr += item.symbol + ','
-        })
+        // 优化:使用map和join提升性能
+        coinArr = coins.map(item => item.symbol).join(',');
       } else {
-        // 如果本地没有 coins,拉取接口
-        const quotesData = await _getCoinList()
-        if (quotesData && quotesData.coins && quotesData.coins.length) {
-          quotesData.coins.forEach(item => {
-            coninArr += item.symbol + ','
-          })
+        const quotesData = await _getCoinList().catch(err => {
+          console.error('获取币种列表失败:', err);
+          this.loading = false; // 错误状态处理
+          return null;
+        });
+        if (quotesData?.coins?.length) {
+          coinArr = quotesData.coins.map(item => item.symbol).join(',');
         }
       }
-      console.log('fetchQList', v, coninArr)
       // if()
-      const list = await _getHomeList(coninArr).catch(() => {
-        //请求失败时,1秒后重试
-        this.timeout = setTimeout(() => {
-          this.fetchQList()
-        }, 1000)
-      })
-      if (!(list instanceof Array)) {
-        return
-      }
-      // console.log('接口:_getHomeList 热门:',list)
-      this.loading = false
-      // this.qList = list.slice(0,10);
-      this.qList = list;
+      const list = await _getHomeList(coinArr).catch(err => {
+        console.error('获取行情列表失败:', err);
+        this.loading = false;
+        return [];
+      });
+      //请求失败时,1秒后重试
+      this.timeout = setTimeout(() => {
+        this.fetchQList();
+      }, 1000);
 
-      this.hList = list.filter(item => this.hotArr.includes(item.symbol));
-      if (this.hList.length == 4) {
-        this.hList.pop()
+      // console.log('接口:_getHomeList 热门:',list)
+      this.loading = false;
+
+      // 优化:仅在获取有效数据时更新
+      if (list.length) {
+        // 冻结数据减少响应式开销提升性能
+        this.qList = Object.freeze(list);
+        setStorage('quotes', { data: list, timestamp: Date.now() });
       }
-      console.log(this.hList)
+
       if (this.timeout) {
         clearTimeout(this.timeout)
       }
+      // 检查缓存是否有效
+      const cacheData = getStorage('quotes');
+      const now = Date.now();
+      const isCacheValid = cacheData && cacheData.timestamp && (now - cacheData.timestamp < CACHE_EXPIRE);
+
       this.timeout = setTimeout(async () => {
-        await this.fetchQList()
-      }, TIME_OUT)
+        // 如果缓存有效则直接使用缓存数据
+        // if (isCacheValid) {
+        //   this.qList = cacheData.data;
+        //   this.hList = cacheData.data.filter(item => this.hotArr.includes(item.symbol));
+        //   if (this.hList.length === 4) this.hList.pop();
+        // } else {
+        await this.fetchQList();
+        // }
+      }, QUOTE_POLLING_INTERVAL);
     },
     getNews() {
       _getNewsList1({
         language: this.$i18n.locale,
       }).then(res => {
-        this.announceList = res
-      })
+        this.announceList = res;
+      });
     },
     getPopupNews() {
       _getPopupNews({
@@ -200,62 +238,70 @@
           if (!getStorage('popNotice')) {
             let list = res
             list.forEach(item => {
-              item.showPopUp = true
-            })
+              item.showPopUp = true;
+            });
             this.popupNewsList = list
           }
         }
       })
     },
     closePopNotice(item) {
-      item.showPopUp = false
-      setStorage('popNotice', true)
+      item.showPopUp = false;
+      setStorage('popNotice', true);
     },
     toAnnounceDetail(announceId) {
       if (announceId) {
-        this.$router.push({ path: '/cryptos/AnnounceDetail', query: { id: announceId } })
+        this.$router.push({ path: '/cryptos/AnnounceDetail', query: { id: announceId } });
       }
     },
     onClickLeft() { },
     onClickRight() { },
     startTimeout() {
-      this.clearTimeout()
-      this.fetchQList()
+      this.clearTimeout();
+      this.fetchQList();
     },
     clearTimeout() {
       if (this.timeout) {
-        clearTimeout(this.timeout)
-        this.timeout = null
+        clearTimeout(this.timeout);
+        this.timeout = null;
       }
     }
   },
   async created() {
     this.getNews();
-    this.getPopupNews()
-    await this.SET_COIN_LIST('cryptos')
-    this.startTimeout()
+    this.getPopupNews();
+    this.startTimeout(); // 优先执行缓存加载
+    await this.SET_COIN_LIST('cryptos');
+    // 缓存已加载,重新计算hList
+    if (this.qList && this.qList.length) {
+      this.hList = this.qList.filter(item => this.hotArr.includes(item.symbol)).slice(0, 3);
+    }
   },
   async activated() {
-    this.getNews()
-    this.getPopupNews()
-    await this.SET_COIN_LIST('cryptos')
-    this.startTimeout()
+    this.getNews();
+    this.getPopupNews();
+    this.startTimeout(); // 优先执行缓存加载
+    await this.SET_COIN_LIST('cryptos');
+    // 缓存已加载,重新计算hList
+    if (this.qList && this.qList.length) {
+      this.hList = this.qList.filter(item => this.hotArr.includes(item.symbol)).slice(0, 3);
+    }
     if (this.userInfo.token) {
-      this.fetchUnread()
-      this.unreadMsg_timer = setInterval(() => { this.fetchUnread() }, 5000);
+      this.fetchUnread();
+      this.unreadMsg_timer = setInterval(() => { this.fetchUnread(); }, 5000);
     } else {
-      this.unreadMsg_num = ''
+      this.unreadMsg_num = '';
     }
   },
   deactivated() {
-    this.clearTimeout()
+    this.clearTimeout();
     if (this.unreadMsg_timer) {
       clearInterval(this.unreadMsg_timer);
       this.unreadMsg_timer = null;
     }
   },
   beforeUnmount() {
-    this.clearTimeout()
+    this.clearTimeout();
     if (this.unreadMsg_timer) {
       clearInterval(this.unreadMsg_timer);
       this.unreadMsg_timer = null;
@@ -336,7 +382,8 @@
     }
 
     span {
-      color: $text_color1;;
+      color: $text_color1;
+      ;
       font-size: 22px;
       line-height: 30px;
     }
@@ -485,7 +532,8 @@
   height: 40px !important;
   margin-top: 8px;
 }
-.content-title{
-  font-size: 28px; 
+
+.content-title {
+  font-size: 28px;
 }
 </style>
diff --git a/src/views/my/newindex.vue b/src/views/my/newindex.vue
index 94baed5..c67deee 100644
--- a/src/views/my/newindex.vue
+++ b/src/views/my/newindex.vue
@@ -41,7 +41,7 @@
       <div class="mt-15 p-15 rounded-15 bg-#f5f7f9">
         <div v-for="(item, index) in helpItems" :key="index" class="flex items-center justify-between text-16"
           :class="{ 'mt-15': index > 0 }" @click="onRoute(item.path)">
-          <div v-if="item.button" class="flex items-center" @click="loginOut">
+          <div v-if="item.button" class="flex items-center" @click.stop="loginOut">
             <img :src="`${item.icon}`" class="w-20 h-20">
             <div class="ml-10">{{ item.title }}</div>
           </div>
@@ -201,6 +201,7 @@
   }).then(res => {
     userStore.userInfo = {}
     store.state.user.userInfo = {}
+    router.push('/login')
   })
 }
 const getIdentify = () => {
diff --git a/src/views/news/index.vue b/src/views/news/index.vue
index 593f7d3..48a90eb 100644
--- a/src/views/news/index.vue
+++ b/src/views/news/index.vue
@@ -104,13 +104,11 @@
     </div>
     <div class="px-17 mt-10">
       <!-- 新闻条目1 -->
-      <div class="rounded-5 overflow-hidden mb-10" v-for="(t, i) in list" :key="t.dataId">
-        <div class="bg-#f5f7f9 py-12 px-15 " @click="openOriginUrl(t.originUrl)">
+      <div class="rounded-5 overflow-hidden mb-10" v-for="(t) in list" :key="t.dataId">
+        <div class="bg-#f5f7f9 py-12 px-15 ">
           <div class="flex" style="border-bottom: 1px solid rgb(209, 209, 209);">
-            <div class="text-12 h-70 flex-1 line3">{{ t.description }}</div>
-            <!-- <img class="w-90 h-55 flex-none rounded-10 ml-10"
-              :src="t.img"
-              draggable="false"> -->
+            <div class="text-12 h-70 flex-1 line3">{{ t.title }}</div>
+            <img class="w-90 h-55 flex-none rounded-10 ml-10" :src="t.imgUrl" draggable="false">
           </div>
           <div class="mt-5 text-10 text-#8c8c8c flex justify-between">
             <span>{{ t.createTime }}</span>
@@ -163,14 +161,14 @@
   goToPage('/customerService')
 }
 const goToPage = (path) => {
-	if(path=='/mining'){
-		showToast({
-		  message: 'Stay tuned',
-		  position: 'bottom',
-		})
-	}else{
-		router.push(path)
-	}
+  if (path == '/mining') {
+    showToast({
+      message: 'Stay tuned',
+      position: 'bottom',
+    })
+  } else {
+    router.push(path)
+  }
 }
 
 const getInformationList = () => {

--
Gitblit v1.9.3