From 44e422febb7a38c46399f656185c1210ab76b946 Mon Sep 17 00:00:00 2001 From: liu <2302563948@qq.com> Date: Sun, 13 Sep 2026 01:23:35 +0800 Subject: [PATCH] =?UTF-8?q?=E5=95=86=E5=93=81=E5=88=97=E8=A1=A8=E7=8A=B6?= =?UTF-8?q?=E6=80=81=E4=BF=9D=E5=AD=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/pages/product/index.tsx | 68 +++++++++++++++++++++++++++++++++---- 1 file changed, 62 insertions(+), 6 deletions(-) diff --git a/src/pages/product/index.tsx b/src/pages/product/index.tsx index b81dfcb..a003900 100644 --- a/src/pages/product/index.tsx +++ b/src/pages/product/index.tsx @@ -5,6 +5,8 @@ import { Empty, Search } from '@antmjs/vantui' import useCartStore from '@/stores/cart/useCartStore' import { getCategoriesApi, getProductListApi } from '@/services/product' import type { ProductListParams } from '@/services/product' +import { getCartApi } from '@/services/cart' +import { getToken } from '@/utils/request' import { getProductCover } from '@/types/product' import type { Category, Product, ProductCartPatch } from '@/types/product' import CartBall from '@/components/CartBall' @@ -42,6 +44,10 @@ export default function ProductPage() { const reqSeqRef = useRef(0) /** 是否有请求进行中(仅用于避免"加载更多"并发) */ const loadingRef = useRef(false) + /** 是否已完成首次加载(区分首次进入与从详情页返回) */ + const hasLoadedRef = useRef(false) + /** 上次加载时的登录态(登录/登出后需整列刷新价格与购物车字段) */ + const tokenRef = useRef(null) /** 当前选中二级分类所属的一级分类ID(用于父级高亮) */ const activeParentId = useMemo(() => { @@ -131,8 +137,38 @@ export default function ProductPage() { } }, []) + /** + * 仅同步已加载商品的订货量(详情页加购返回时调用): + * 拉一次购物车,按 product_id 回写列表项的 cart_id/cart_quantity, + * 不重拉列表,保留滚动位置与已加载分页 + */ + const syncCartFields = useCallback(async () => { + // 未登录无购物车(接口固定 401,会触发清登录态跳登录页),直接跳过 + if (!getToken()) return + try { + const res = await getCartApi() + const itemMap = new Map(res.data.items.map(it => [it.product_id, it])) + setProducts(prev => { + let changed = false + const next = prev.map(p => { + const item = itemMap.get(p.id) + const cartId = item?.id ?? 0 + const cartQty = item?.quantity ?? '0.00' + if ((p.cart_id ?? 0) === cartId && Number(p.cart_quantity ?? 0) === Number(cartQty)) { + return p + } + changed = true + return { ...p, cart_id: cartId, cart_quantity: cartQty } + }) + return changed ? next : prev + }) + } catch { + // 错误已由 request 层 toast + } + }, []) + useDidShow(() => { - // 处理首页搜索跳转带入的关键词 + // 处理首页搜索跳转带入的关键词(switchTab 无法带参,经本地存储传递) let pendingKeyword: string | null = null try { pendingKeyword = Taro.getStorageSync(PENDING_KEYWORD_KEY) || null @@ -140,12 +176,32 @@ export default function ProductPage() { } catch { // noop } - if (pendingKeyword) { - setInputKey(pendingKeyword) - setSearchKey(pendingKeyword) + // 首页分类跳转带入的分类(只读取,由 loadCategories 消费移除) + let pendingCategory: number | null = null + try { + pendingCategory = Taro.getStorageSync(PENDING_CATEGORY_KEY) || null + } catch { + // noop + } + + const token = getToken() + /** 登录态变化(登录/登出/换账号):价格与购物车字段都变了,需整列刷新 */ + const authChanged = hasLoadedRef.current && token !== tokenRef.current + + if (!hasLoadedRef.current || pendingKeyword || pendingCategory || authChanged) { + // 首次进入 / 首页带参跳转 / 登录态变化:整列刷新 + hasLoadedRef.current = true + tokenRef.current = token + if (pendingKeyword) { + setInputKey(pendingKeyword) + setSearchKey(pendingKeyword) + } + loadCategories() + fetchList(1, true, pendingKeyword ?? undefined) + } else { + // 从详情页等返回:保留列表与滚动位置,仅同步订货量 + syncCartFields() } - loadCategories() - fetchList(1, true, pendingKeyword ?? undefined) }) /** 右侧列表触底加载(页面为固定布局不滚动,由 ScrollView 触发) */