Sfoglia il codice sorgente

feat: add entry scene tracking and root back home component

- Introduced a new `entryScene` property to track the scene value when entering the app.
- Implemented a `RootBackHome` component to manage navigation behavior when re-entering the app from specific scenes.
- Updated the `get` and `index` pages to utilize the `RootBackHome` component for improved navigation handling.
- Enhanced the `onShow` lifecycle method to ensure proper navigation flow based on the entry scene.
ylong 1 settimana fa
parent
commit
b2f017989b
4 ha cambiato i file con 123 aggiunte e 0 eliminazioni
  1. 3 0
      App.vue
  2. 87 0
      packet/components/root-back-home.vue
  3. 17 0
      packet/pages/get.vue
  4. 16 0
      packet/pages/index.vue

+ 3 - 0
App.vue

@@ -30,6 +30,8 @@ export default {
 
 		// 是否是冷启动
 		isColdLaunch: false,
+		// 本次进入小程序的场景值(如下拉最近使用)
+		entryScene: 0,
 		needPolicyConsent: false,
 		needPrivacyPopup: false,
 		pendingLaunchOptions: null,
@@ -41,6 +43,7 @@ export default {
 		this.handleLaunchWithPolicy(options)
 	},
 	onShow(options) {
+		this.globalData.entryScene = options && options.scene
 		updateCartBadge();
 		this.handleAppShowOptions(options);
 	},

+ 87 - 0
packet/components/root-back-home.vue

@@ -0,0 +1,87 @@
+<template>
+	<view class="root-back-home"></view>
+</template>
+
+<script>
+	// 不带 path 的再次进入(聊天下拉、最近使用等)会停在上次的红包页。
+	// 页面栈只有这一页时,返回会直接退出小程序。先打开首页再回到当前页,返回就能进首页。
+	const REOPEN_SCENES = [1001, 1089, 1090, 1103, 1104, 1106]
+	const HOME_URL = '/pages/sell/index'
+	let padding = false
+
+	function getEntryScene() {
+		try {
+			if (typeof uni.getEnterOptionsSync === 'function') {
+				const scene = uni.getEnterOptionsSync().scene
+				if (scene) return Number(scene)
+			}
+		} catch (e) {}
+		try {
+			const app = getApp()
+			return Number(app && app.globalData && app.globalData.entryScene) || 0
+		} catch (e) {
+			return 0
+		}
+	}
+
+	export default {
+		methods: {
+			sync() {
+				if (padding) return true
+				const pages = getCurrentPages()
+				if (pages.length !== 1) return false
+				if (!REOPEN_SCENES.includes(getEntryScene())) return false
+
+				const page = pages[0]
+				const route = page.route || ''
+				if (route.indexOf('packet/pages/') !== 0) return false
+
+				const query = {}
+				const pageOptions = page.options || {}
+				if (pageOptions.bianhao) query.bianhao = pageOptions.bianhao
+				const bianhao = this.$parent && this.$parent.bianhao
+				if (bianhao && !query.bianhao) query.bianhao = bianhao
+				const qs = Object.keys(query)
+					.map((key) => key + '=' + encodeURIComponent(query[key]))
+					.join('&')
+				const url = '/' + route + (qs ? '?' + qs : '')
+
+				padding = true
+				const openPacket = (retry) => {
+					uni.navigateTo({
+						url,
+						success: () => {
+							padding = false
+						},
+						fail: () => {
+							if (retry) {
+								setTimeout(() => openPacket(false), 200)
+								return
+							}
+							padding = false
+						}
+					})
+				}
+				uni.switchTab({
+					url: HOME_URL,
+					success: () => {
+						// 等首页切换完成再打开红包页,避免路由冲突
+						setTimeout(() => openPacket(true), 50)
+					},
+					fail: () => {
+						padding = false
+					}
+				})
+				return true
+			}
+		}
+	}
+</script>
+
+<style lang="scss" scoped>
+	.root-back-home {
+		height: 0;
+		width: 0;
+		overflow: hidden;
+	}
+</style>

+ 17 - 0
packet/pages/get.vue

@@ -1,5 +1,6 @@
 <template>
     <view class="get-page">
+        <root-back-home ref="rootBackHome" />
         <!-- Background -->
         <image src="/packet/static/get/bg.png" class="bg-image" mode="widthFix"></image>
 
@@ -72,7 +73,12 @@
 </template>
 
 <script>
+import RootBackHome from '../components/root-back-home.vue'
+
 export default {
+    components: {
+        RootBackHome
+    },
     data() {
         return {
             bianhao: '', // 红包编号
@@ -97,6 +103,17 @@ export default {
             this.getRedBagDetail();
         }
     },
+    onShow() {
+        // 下拉再次进入时,页面栈只有红包页,返回要去首页而不是退出
+        const guard = this.$refs.rootBackHome
+        if (guard) {
+            guard.sync()
+            return
+        }
+        this.$nextTick(() => {
+            this.$refs.rootBackHome && this.$refs.rootBackHome.sync()
+        })
+    },
     onShareAppMessage() {
         // 设置分享内容
         return {

+ 16 - 0
packet/pages/index.vue

@@ -1,5 +1,6 @@
 <template>
     <view class="packet-page">
+        <root-back-home ref="rootBackHome" />
         <!-- Background -->
         <image v-if="!isFailState" src="/packet/static/index/background.png" class="bg-image" mode="widthFix"></image>
 
@@ -90,8 +91,12 @@
 
 <script>
     import { silentLogin } from '@/api/auth'
+    import RootBackHome from '../components/root-back-home.vue'
 
     export default {
+        components: {
+            RootBackHome
+        },
         data() {
             return {
                 amount: '1.58',
@@ -142,6 +147,8 @@
             }
         },
         onShow() {
+            // 下拉进入且页面栈只有红包页时,会先去首页再回到本页,本次不再重复请求
+            if (this.syncRootBackHome()) return
             // 如果是从其他页面返回,重新获取红包数据
             if (this.bianhao) {
                 this.scanRedBag();
@@ -228,6 +235,15 @@
                     url: '/pages/sell/index'
                 });
             },
+            // 下拉再次进入时,页面栈只有红包页,返回要去首页而不是退出
+            syncRootBackHome() {
+                const guard = this.$refs.rootBackHome
+                if (guard) return !!guard.sync()
+                this.$nextTick(() => {
+                    this.$refs.rootBackHome && this.$refs.rootBackHome.sync()
+                })
+                return false
+            },
             openRulePopup() {
                 this.showRulePopup = true;
             },