feat(store): 门店可见白名单(对齐商品)

HQ 可配置 visibilityWhitelistEnabled + 手机号;C 端公开门店列表/详情按登录手机号过滤;登录态变化后小程序重新拉门店列表。

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
2026-08-03 13:58:35 +08:00
parent 06cbcdeb9c
commit fa3484041e
10 changed files with 344 additions and 32 deletions
+2
View File
@@ -22,6 +22,8 @@ export type StoresSessionCategory = {
export type StoresListCache = {
cityKey: string;
cityCode: string;
/** 登录态指纹:token 变化时需重新拉取(白名单) */
authKey: string;
listRegion: StoresSessionRegion;
items: unknown[];
filterRegion: StoresSessionRegion;
@@ -1,6 +1,6 @@
import { useEffect, useMemo, useState } from 'react';
import { useMemo, useState } from 'react';
import { View, Text, Image } from '@tarojs/components';
import Taro, { usePageScroll, useRouter, useShareAppMessage, useShareTimeline } from '@tarojs/taro';
import Taro, { useDidShow, usePageScroll, useRouter, useShareAppMessage, useShareTimeline } from '@tarojs/taro';
import PageShell from '../../components/PageShell';
import PageNavBar from '../../components/PageNavBar';
import ProductCarousel from '../../components/ProductCarousel';
@@ -78,20 +78,15 @@ export default function StoreDetailPage() {
setHeaderSolid(scrollTop > 100);
});
useEffect(() => {
useDidShow(() => {
if (!storeId) return;
request<Store>(`/stores/${storeId}`)
.then(setStore)
.catch(() => {
request<Store[]>('/stores')
.then((list) => {
const found = (Array.isArray(list) ? list : []).find((s) => s.id === storeId);
if (found) setStore(found);
else toast('门店不存在');
})
.catch((e) => toast(e instanceof Error ? e.message : '加载失败'));
setStore(null);
toast('门店不存在或暂不可见');
});
}, [storeId]);
});
const sharePayload = useMemo(
() => {
+29 -2
View File
@@ -27,7 +27,7 @@ import {
} from '../../lib/user-location';
import { FALLBACK_CITY_CODE } from '../../lib/product-images';
import { formatDistanceMeters } from '../../lib/geo';
import { request, toast } from '../../lib/api';
import { getToken, request, toast } from '../../lib/api';
import {
getStoresListCache,
isStoresSessionBootstrapped,
@@ -143,6 +143,7 @@ export default function StoresPage() {
setStoresListCache({
cityKey,
cityCode: nextCode,
authKey: getToken() || '',
listRegion: toCityWideRegion(listRegion),
items,
filterRegion,
@@ -160,12 +161,38 @@ export default function StoresPage() {
/**
* 首次进入:弹窗 + 定位 + 拉列表。
* 同次再切回:只同步 tab 选中态,不改筛选、不拉接口、不 setState
* 同次再切回:只同步 tab 选中态(登录态未变)
* 登录/退出后 token 变化:按缓存失效重新拉列表(白名单)。
*/
useDidShow(() => {
syncTabBarSelected(1);
const authKey = getToken() || '';
const cache = getStoresListCache();
if (isStoresSessionBootstrapped()) {
if (cache && (cache.authKey ?? '') === authKey) {
return;
}
// 登录态变了:保留筛选,重新拉列表
void (async () => {
setLoading(true);
const nextCode = cache?.cityCode || FALLBACK_CITY_CODE;
const listRegion = cache?.listRegion
? {
province: cache.listRegion.province,
city: cache.listRegion.city,
district: cache.listRegion.district || '全部',
}
: regionRef.current;
const nextCityKey = cache?.cityKey || makeCityKey(listRegion);
await fetchStores(
nextCode,
readCachedUserCoords(),
nextCityKey,
listRegion,
regionRef.current,
);
})();
return;
}
markStoresSessionBootstrapped();