Răsfoiți Sursa

feat(mallApp): 完善首页登录态门店绑定

- 首页配置请求携带分享邀请人并在绑定成功后清理缓存
- 登录后缓存接口返回的 hdId,确保商品、分类和购物车跳转使用当前门店
- 旧入口跳转不再回填本地 hdId,避免携带过期门店绑定
shizhongqi 1 zi în urmă
părinte
comite
ff5340fc04

+ 22 - 2
mallApp/src/api/home-page-config/index.js

@@ -1,11 +1,31 @@
 /**
  * 商城首页配置只读接口
  * 与 hd 管理端共用 Redis,请求需带 account(shopId)
+ * 登录态 get-home 会解析/创建门店 hd 绑定并返回 hdId,供首页缓存后拼到跳转链接
  */
 import https from '@/plugins/luch-request_0.0.7/request'
+import { getShareInviterCustomId, clearShareInviter } from '@/utils/launchScene'
 
-/** 一次拉取首页全部模块,便于首页组装 */
-export const getHome = data => https.get('/home-page-config/get-home', data)
+/**
+ * 一次拉取首页全部模块,便于首页组装。
+ * 有分享邀请缓存时一并提交 inviterCustomId,避免首页建客漏掉拉新绑定。
+ * @param {Object} [data]
+ * @returns {Promise}
+ */
+export const getHome = data => {
+	const params = Object.assign({}, data || {})
+	const account = uni.getStorageSync('account') || ''
+	const inviterCustomId = getShareInviterCustomId(account)
+	if (inviterCustomId > 0) {
+		params.inviterCustomId = inviterCustomId
+	}
+	return https.get('/home-page-config/get-home', params).then(res => {
+		if (res && res.code === 1 && res.data && Number(res.data.inviteBound) === 1) {
+			clearShareInviter(account)
+		}
+		return res
+	})
+}
 export const getBanner = data => https.get('/home-page-config/get-banner', data)
 export const getNavGrid = data => https.get('/home-page-config/get-nav-grid', data)
 export const getSeckill = data => https.get('/home-page-config/get-seckill', data)

+ 60 - 13
mallApp/src/pages/home/index.vue

@@ -4,6 +4,7 @@
   顶部导航与搜索、轮播图、公告、金刚区导航、秒杀专区、团购专区、热门推荐、今日上新、下拉商品。
   数据来自 home-page-config 接口的 getHome,与 hdApp 后台「预览」使用同一套后端组装逻辑,
   保证顾客看到的效果与商家预览一致。
+  登录态 get-home 会返回 hdId:写入本地缓存并回填页面,分类/商品/购物车等跳转都带上。
   未登录可浏览首页:默认不弹登录层;加购 / 客服 / 消息入口再弹 wangCg。
   浏览类接口不强制登录(避免「请先登录哈」toast)。
 -->
@@ -187,7 +188,12 @@ export default {
       /** 下拉商品当前渲染条数,滚动触底递增 */
       pullGoodsLimit: PULL_GOODS_PAGE_SIZE,
       /** 底部哨兵观察器,驱动模块与下拉商品的按需加载 */
-      _loadMoreObserver: null
+      _loadMoreObserver: null,
+      /**
+       * get-home 回填的当前门店 hd 绑定。
+       * 单独放 data:storage 不是响应式,不写这里跳转链接拿不到刚建的 hdId。
+       */
+      boundHdId: ''
     }
   },
   created() {
@@ -212,10 +218,14 @@ export default {
     }
   },
   watch: {
-    loginInfo(val) {
+    loginInfo(val, oldVal) {
       if (!this.$util.isEmpty(val)) {
         this.cartLoginStyle = 1
       }
+      // 页内从游客变为登录(wangCg / 登录页返回)时补拉 hdId,onLoad 不会重跑
+      if (this.$util.isEmpty(oldVal) && !this.$util.isEmpty(val)) {
+        this.refreshHomeHdIdAfterLogin()
+      }
     }
   },
   onShareAppMessage() {
@@ -253,7 +263,8 @@ export default {
       return (this.option && this.option.account) || uni.getStorageSync('account') || ''
     },
     hdId() {
-      return (this.option && this.option.hdId) || uni.getStorageSync('hdId') || ''
+      // 登录后接口回填优先,避免 URL 上过期 hdId 或 storage 未触发视图更新
+      return this.boundHdId || (this.option && this.option.hdId) || uni.getStorageSync('hdId') || ''
     },
     modules() {
       return (this.pageData && this.pageData.modules) || []
@@ -299,7 +310,8 @@ export default {
       })
     },
     /**
-     * 加购/客服等登录成功:收起弹层,并重拉 shop/info 建客/拉新绑定
+     * 加购/客服等登录成功:收起弹层,并重拉 shop/info 补客户与门店信息。
+     * hdId 由 loginInfo 从空到有时的 refreshHomeHdIdAfterLogin 负责缓存。
      */
     onCartLoginSuccess() {
       this.cartLoginStyle = 1
@@ -314,14 +326,16 @@ export default {
         if (data.info) {
           this.shopInfo = data.info
         }
+        if (data.hd && (data.hd.id || data.hd.hdId)) {
+          this.cacheHomeHdId(data.hd.id || data.hd.hdId)
+        }
         this.checkHbArrival()
       })
     },
     /**
      * 页面初始化
-     * 首屏只等 getHome:门店信息(syncMyCustomId)仅供分享参数与红包提醒使用,
-     * 且无 hdId 缓存时是 getHdInfo → getInfo 两跳串行请求,
-     * 放在 Promise.all 里会白白拖慢首屏渲染,因此改为并行且不阻塞 loading。
+     * 首屏只等 getHome(含登录态 hdId 回填);门店信息(syncMyCustomId)仅供分享参数与红包提醒,
+     * 放在 getHome 完成之后,这样已登录能直接用新 hdId 拉 shop/info,避免再走 getHdInfo 建客。
      */
     init() {
       this.loading = true
@@ -337,19 +351,52 @@ export default {
             this.renderModuleCount = INITIAL_MODULE_COUNT
             this.pullGoodsLimit = PULL_GOODS_PAGE_SIZE
             this.pageData = homeRes.data
+            if (this.isLoggedIn) {
+              this.cacheHomeHdId(homeRes.data.hdId)
+            }
           }
         })
         .finally(() => {
           this.loading = false
           // 必须等 loading 关掉、模块真正上屏后再观察,否则查不到底部哨兵节点
           this.initLoadMoreObserver()
+          // 等 get-home 写入 hdId 后再拉客户信息,避免再走 getHdInfo 重复建客
+          this.syncMyCustomId()
+            .then(() => {
+              this.checkHbArrival()
+            })
+            .catch(() => {})
         })
-      // 红包提醒依赖登录态与 shopInfo.id;未登录不请求,避免「请先登录哈」
-      this.syncMyCustomId()
-        .then(() => {
-          this.checkHbArrival()
-        })
-        .catch(() => {})
+    },
+    /**
+     * 登录态把 get-home 返回的 hdId 写入页面状态和本地缓存。
+     * 首页各模块跳转(商品详情/列表/分类/购物车)都从 computed hdId 读取。
+     * @param {string|number} hdId 当前门店 xhHd.id
+     */
+    cacheHomeHdId(hdId) {
+      const id = Number(hdId) || 0
+      if (id <= 0) {
+        return
+      }
+      this.boundHdId = id
+      uni.setStorageSync('hdId', id)
+      if (this.option) {
+        this.$set(this.option, 'hdId', id)
+      }
+    },
+    /**
+     * 游客变为登录后重拉 get-home,补建客并缓存 hdId。
+     * 已有 boundHdId 说明本次进店已经绑过,避免 onShow/弹层重复请求。
+     */
+    refreshHomeHdIdAfterLogin() {
+      if (!this.isLoggedIn || this.boundHdId) {
+        return Promise.resolve()
+      }
+      return getHome().then((homeRes) => {
+        if (homeRes && homeRes.code === 1 && homeRes.data) {
+          this.cacheHomeHdId(homeRes.data.hdId)
+        }
+      }).catch(() => {})
     },
     /**
      * 建立「加载更多」的哨兵观察。

+ 1 - 1
mallApp/src/utils/launchScene.js

@@ -107,7 +107,7 @@ export function redirectToShopHome(option) {
 	const query = option || {}
 	const url = buildLaunchUrl('/pages/home/index', {
 		account: query.account || uni.getStorageSync('account') || '',
-		hdId: query.hdId || uni.getStorageSync('hdId') || '',
+		hdId: query.hdId || '',
 		inviterCustomId: query.inviterCustomId || '',
 		staffId: query.staffId || '',
 		token: query.token || ''