ソースを参照

优化:优化加载响应速度

haiyang 1 週間 前
コミット
aa7d990268

+ 1 - 1
scripts/open-dev-tools.js

@@ -52,7 +52,7 @@ function _openDevTools() {
                 console.log('❌ 未配置微信开发者工具路径,请在 .env 文件中设置 VITE_WECHAT_DEV_TOOL_PROJECT_PATH')
                 return
             }
-            console.log("🚀项目输出路径:", projectPath)
+            console.log("🚀 项目输出路径:", projectPath)
             const cliPath = path.join(wechatDevToolPath, 'cli.bat')
             command = `${cliPath} open --project "${projectPath}"`
         }

+ 14 - 3
src/api/home.ts

@@ -5,11 +5,20 @@ import { http } from '@/http/alova'
  *
  * @returns 获取首页优惠券数据
  */
-export function getCouponList() {
-    return http.Get<CouponList>('/couponCenter/APP/couponTemplate/queryByType', {
+export function getCouponList(limit: number = 3) {
+    return http.Get('/couponCenter/APP/couponTemplate/queryByType', {
         meta: {
             ignoreAuth: true,
         },
+        transform(data, headers) {
+            const respondedData = data as CouponList
+            const discountCoupon = respondedData?.discountCoupon || []
+            const couponList = respondedData?.fullReduceCoupon || []
+            return {
+                discountVoucherList: discountCoupon.slice(0, limit),
+                couponList: couponList.slice(0, limit),
+            }
+        },
     })
 }
 
@@ -18,7 +27,9 @@ export function getCouponList() {
  * @returns 获取首页收益总数
  */
 export function getAccountCount() {
-    return http.Get<AccountCount>('/couponCenter/APP/couponIssuerAccount/queryByUserId')
+    return http.Get<AccountCount>('/couponCenter/APP/couponIssuerAccount/queryByUserId', {
+        shareRequest: true,
+    })
 }
 
 /**

+ 52 - 0
src/http/tools/delayLoadingMiddleware.ts

@@ -0,0 +1,52 @@
+/**
+ * 延迟loading中间件(支持延迟显示和延迟关闭)
+ * @param delayShowTimer 延迟显示时间,默认1000ms
+ * @param delayHideTimer 延迟关闭时间,默认300ms
+ * @returns 中间件函数
+ */
+export const delayLoadingMiddleware =
+    (delayShowTimer = 1000, delayHideTimer = 300) =>
+        async (ctx, next) => {
+            const { loading } = ctx.proxyStates;
+            // 自行控制loading
+            ctx.controlLoading();
+
+            let showTimer: NodeJS.Timeout | null = null;
+            let hideTimer: NodeJS.Timeout | null = null;
+
+            try {
+                if (delayShowTimer <= 0) {
+                    loading.v = true;
+                } else {
+                    // 延迟显示loading
+                    showTimer = setTimeout(() => {
+                        loading.v = true;
+                    }, delayShowTimer);
+                }
+
+                await next();
+
+                //  清除延迟显示定时器
+                if (showTimer) {
+                    clearTimeout(showTimer);
+                    showTimer = null;
+                }
+
+                // 延迟关闭loading(无论是否显示过loading)
+                hideTimer = setTimeout(() => {
+                    loading.v = false;
+                }, delayHideTimer);
+            } catch (error) {
+                // 发生错误时也需要正确处理定时器
+                if (showTimer) clearTimeout(showTimer);
+                if (hideTimer) clearTimeout(hideTimer);
+
+                // 延迟关闭loading
+                hideTimer = setTimeout(() => {
+                    loading.value = false;
+                }, delayHideTimer);
+
+                // 重新抛出错误,确保后续错误处理中间件能捕获到
+                throw error
+            }
+        }

+ 10 - 11
src/pages/home/home.vue

@@ -1,16 +1,17 @@
 <script lang="ts" setup>
 import { useRequest } from 'alova/client'
 import { storeToRefs } from 'pinia'
-import { ref, watch } from 'vue'
+import { ref, watch, computed } from 'vue'
 import { getAccountCount, getCouponDetail, getCouponSituation, getShareInfo } from '@/api/home'
 import DiscountCoupon from '@/components/DiscountCoupon.vue'
 import SpendAndSaveCoupon from '@/components/SpendAndSaveCoupon.vue'
 import { useShare } from '@/hooks/useShare'
-import { useCouponStore } from '@/store/coupon'
+import { useNewCouponStore as useCouponStore } from '@/store/coupon'
 import { useTokenStore } from '@/store/token'
 import { useUserStore } from '@/store/user'
 import { getImageUrl } from '@/utils/imageUtil'
 import { toLoginPage } from '@/utils/toLoginPage'
+import { delayLoadingMiddleware } from '@/http/tools/delayLoadingMiddleware'
 
 defineOptions({
     name: 'Home',
@@ -31,19 +32,18 @@ const userStore = useUserStore()
 
 const refreshing = ref(false)
 
-// 分享配置
-const shareConfig = ref(null)
-const shareButtonRef = ref<HTMLElement | null>(null)
-const currentCouponId = ref<string>('')
-
 // 获取优惠券
 const couponStore = useCouponStore()
-const { couponList, discountVoucherList, loading } = storeToRefs(couponStore)
+const { loading, data } = storeToRefs(couponStore)
+const discountVoucherList = computed(() => data.value.discountVoucherList)
+const couponList = computed(() => data.value.couponList)
+
 
 // 获取首页收益
 const { send: getAccountCountRequest, data: accountCountData, loading: accountCountLoading } = useRequest(getAccountCount, {
     immediate: false,
     dependencies: [],
+    middleware: delayLoadingMiddleware(150, 200)
 })
 
 // 获取首页领券情况数据
@@ -81,7 +81,6 @@ onShareTimeline(() => {
 
 onShow((options) => {
     couponStore.getCouponListByType()
-    console.log(hasLogin.value)
     // 登录后查询收益数据
     if (hasLogin.value) {
         Promise.allSettled([getAccountCountRequest(), getCouponSituationRequest()])
@@ -212,7 +211,7 @@ async function onRefresh() {
                     </view>
                 </view>
                 <view class="home-header-coupon-content">
-                    <template v-for="item in couponList" :key="item.id">
+                    <template v-for="(item, index) in couponList" :key="index">
                         <spend-and-save-coupon :coupon="item" />
                     </template>
                     <view v-if="loading" class="coupon-content-loading">
@@ -247,7 +246,7 @@ async function onRefresh() {
                     </view>
                 </view>
                 <view class="home-coupon-content">
-                    <template v-for="item in discountVoucherList" :key="item.id">
+                    <template v-for="(item, index) in discountVoucherList" :key="index">
                         <discount-coupon :coupon="item" />
                     </template>
                     <view v-if="loading" class="home-coupon-content-loading">

+ 6 - 3
src/pages/my/my.vue

@@ -1,7 +1,7 @@
 <script lang="ts" setup>
 import { useRequest } from 'alova/client'
 import { storeToRefs } from 'pinia'
-import { computed, ref } from 'vue'
+import { computed, ref, watch } from 'vue'
 import { getCouponSituation } from '@/api/home'
 import { getCouponIssuerApplyById, getShareState } from '@/api/me'
 import { useShare } from '@/hooks/useShare'
@@ -10,6 +10,7 @@ import { useInviterStore } from '@/store/inviter'
 import { useTokenStore } from '@/store/token'
 import { changtime, safeAreaInsets } from '@/utils'
 import { getImageUrl } from '@/utils/imageUtil'
+import { delayLoadingMiddleware } from '@/http/tools/delayLoadingMiddleware'
 
 definePage({
     style: {
@@ -29,11 +30,14 @@ const deadline = ref(Date.now())
 // 用户优惠券统计数据
 const { send: getCouponSituationRequest, data: couponSituationData, loading: couponSituationLoading } = useRequest(getCouponSituation, {
     immediate: false,
+    middleware: delayLoadingMiddleware(0, 500)
 })
 const { send: getShareStateRequest, data: shareStateData, loading: shareStateLoading } = useRequest(getShareState, {
     immediate: false,
+    middleware: delayLoadingMiddleware(0, 500)
 })
 
+
 onShow(async () => {
     console.log('登录判断:', hasLogin.value)
     // 登录后查询收益数据
@@ -214,8 +218,7 @@ onShareTimeline(async () => {
                 <view class="me-header-tips">
                     <view class="me-header-tips-row header-data-time">
                         <view class="desc-time">
-                            <up-loading-icon v-if="couponSituationLoading || shareStateLoading" size="23rpx"
-                                :loading="couponSituationLoading || shareStateLoading" color="#fff" />
+                            <up-loading-icon v-if="couponSituationLoading" size="23rpx" :loading="true" color="#fff" />
                             <up-icon v-else name="info-circle" size="23rpx" color="#fff" />
                             <view v-if="couponSituationLoading || shareStateLoading" class="desc-text">
                                 数据加载中...

+ 26 - 3
src/store/coupon.ts

@@ -1,5 +1,7 @@
 import { defineStore } from 'pinia'
 import { getCouponList } from '@/api/home'
+import { useRequest } from 'alova/client'
+import { delayLoadingMiddleware } from '@/http/tools/delayLoadingMiddleware'
 
 export const useCouponStore = defineStore('coupon', {
     state: () => ({
@@ -11,10 +13,10 @@ export const useCouponStore = defineStore('coupon', {
         async getCouponListByType() {
             try {
                 this.loading = true
-                const res = await getCouponList()
+                const res = await getCouponList(3)
                 this.loading = false
-                this.discountVoucherList = (res.discountCoupon || []).slice(0, 3)
-                this.couponList = (res.fullReduceCoupon || []).slice(0, 3)
+                this.discountVoucherList = res.discountVoucherList
+                this.couponList = res.couponList
             }
             catch (error) {
                 this.loading = false
@@ -22,3 +24,24 @@ export const useCouponStore = defineStore('coupon', {
         }
     }
 })
+
+export const useNewCouponStore = defineStore('newCoupon', () => {
+    const { send, data, loading, } = useRequest(getCouponList, {
+        immediate: false,
+        initialData: {
+            discountVoucherList: [], // 折扣券
+            couponList: [], // 满减券
+        },
+        middleware: delayLoadingMiddleware(100, 150)
+    })
+
+    const getCouponListByType = async () => {
+        await send()
+    }
+
+    return {
+        data,
+        loading,
+        getCouponListByType,
+    }
+})

+ 1 - 1
src/store/loading.ts

@@ -15,7 +15,7 @@ export const useLoadingStore = defineStore('loading', () => {
     }
 
     // 隐藏加载页
-    const hideLoading = (delay = 100) => {
+    const hideLoading = (delay = 0) => {
         setTimeout(() => {
             isLoading.value = false
         }, delay)