|
|
@@ -60,7 +60,6 @@ const HomePage: React.FC = () => {
|
|
|
const { addToCart } = useCart();
|
|
|
const [refreshing, setRefreshing] = React.useState(false);
|
|
|
const [showPrivacyModal, setShowPrivacyModal] = React.useState(false);
|
|
|
- const [isLoggingIn, setIsLoggingIn] = React.useState(false);
|
|
|
|
|
|
// 广告数据查询
|
|
|
const {
|
|
|
@@ -87,9 +86,6 @@ const HomePage: React.FC = () => {
|
|
|
staleTime: 5 * 60 * 1000, // 5分钟缓存
|
|
|
})
|
|
|
|
|
|
- const hasToken = Taro.getStorageSync('mini_token')
|
|
|
- console.debug('[首页] 商品查询状态:', { isLoggedIn, hasToken })
|
|
|
-
|
|
|
const {
|
|
|
data,
|
|
|
isLoading,
|
|
|
@@ -101,7 +97,7 @@ const HomePage: React.FC = () => {
|
|
|
} = useInfiniteQuery({
|
|
|
queryKey: ['home-goods-infinite'],
|
|
|
queryFn: async ({ pageParam = 1 }) => {
|
|
|
- console.debug('[首页] 请求商品数据,页码:', pageParam)
|
|
|
+ // console.debug('请求商品数据,页码:', pageParam)
|
|
|
// 使用类型断言绕过 RPC 客户端类型推断问题
|
|
|
const response = await (goodsClient.$get as any)({
|
|
|
query: {
|
|
|
@@ -112,16 +108,15 @@ const HomePage: React.FC = () => {
|
|
|
sortOrder: 'DESC' // 倒序排列
|
|
|
}
|
|
|
})
|
|
|
- console.debug('[首页] API响应状态:', response.status)
|
|
|
if (response.status !== 200) {
|
|
|
throw new Error('获取商品失败')
|
|
|
}
|
|
|
const result = await response.json()
|
|
|
- console.debug('[首页] API响应数据:', {
|
|
|
- page: pageParam,
|
|
|
- dataCount: result.data?.length || 0,
|
|
|
- pagination: result.pagination
|
|
|
- })
|
|
|
+ // console.debug('API响应数据:', {
|
|
|
+ // page: pageParam,
|
|
|
+ // dataCount: result.data?.length || 0,
|
|
|
+ // pagination: result.pagination
|
|
|
+ // })
|
|
|
return result
|
|
|
},
|
|
|
getNextPageParam: (lastPage, _allPages) => {
|
|
|
@@ -143,7 +138,7 @@ const HomePage: React.FC = () => {
|
|
|
},
|
|
|
staleTime: 5 * 60 * 1000,
|
|
|
initialPageParam: 1,
|
|
|
- enabled: isLoggedIn || !!hasToken,
|
|
|
+ enabled: isLoggedIn,
|
|
|
})
|
|
|
|
|
|
// 合并所有分页数据
|
|
|
@@ -247,62 +242,151 @@ const HomePage: React.FC = () => {
|
|
|
}
|
|
|
})
|
|
|
|
|
|
- // 未登录时显示隐私政策弹框(仅限从未登录过的用户)
|
|
|
+ // 未登录时先静默登录,检查是否是新用户
|
|
|
React.useEffect(() => {
|
|
|
- const hasToken = Taro.getStorageSync('mini_token')
|
|
|
- // 只有完全没有登录过的用户才显示隐私弹框
|
|
|
- if (!isLoggedIn && !hasToken) {
|
|
|
- setShowPrivacyModal(true)
|
|
|
+ const checkUserAndShowPrivacy = async () => {
|
|
|
+ console.log("isLoggedIn:",isLoggedIn);
|
|
|
+ console.debug("isLoggedIn:",isLoggedIn);
|
|
|
+ if (!isLoggedIn) {
|
|
|
+ try {
|
|
|
+ // 获取登录code
|
|
|
+ const loginRes = await Taro.login()
|
|
|
+ console.log("loginRes")
|
|
|
+ console.log(loginRes)
|
|
|
+ if (!loginRes.code) {
|
|
|
+ console.error('获取登录凭证失败')
|
|
|
+ return
|
|
|
+ }
|
|
|
+
|
|
|
+ // 调用后端静默登录API
|
|
|
+ const response = await authClient['mini-login'].$post({
|
|
|
+ json: {
|
|
|
+ code: loginRes.code,
|
|
|
+ tenantId: Number(process.env.TARO_APP_TENANT_ID) || 1
|
|
|
+ }
|
|
|
+ })
|
|
|
+
|
|
|
+ console.log("checkUserAndShowPrivacyResponse")
|
|
|
+ console.log(response)
|
|
|
+ if (response.status === 200) {
|
|
|
+ const { token, user, isNewUser } = await response.json()
|
|
|
+
|
|
|
+ // 保存token和用户信息
|
|
|
+ Taro.setStorageSync('userInfo', user)
|
|
|
+ Taro.setStorageSync('mini_token', token)
|
|
|
+ console.log("userInfo")
|
|
|
+ console.log(user)
|
|
|
+ setUser(user as any)
|
|
|
+ console.log("isNewUser")
|
|
|
+ console.log(isNewUser)
|
|
|
+ // 如果是新用户,显示隐私弹框
|
|
|
+ if (isNewUser) {
|
|
|
+ setShowPrivacyModal(true)
|
|
|
+ }
|
|
|
+ }
|
|
|
+ } catch (error) {
|
|
|
+ console.error('静默登录失败:', error)
|
|
|
+ }
|
|
|
+ }
|
|
|
}
|
|
|
- }, [isLoggedIn])
|
|
|
-
|
|
|
- // 同意隐私政策,直接静默登录获取openid
|
|
|
- const handleAgreePrivacy = async () => {
|
|
|
- setIsLoggingIn(true)
|
|
|
- try {
|
|
|
- // 获取登录code
|
|
|
- const loginRes = await Taro.login()
|
|
|
- if (!loginRes.code) {
|
|
|
- throw new Error('获取登录凭证失败')
|
|
|
+
|
|
|
+ checkUserAndShowPrivacy()
|
|
|
+ }, [isLoggedIn, setUser])
|
|
|
+
|
|
|
+ // 同意隐私政策,关闭弹框(已经登录过了)
|
|
|
+ const handleAgreePrivacy = async() => {
|
|
|
+ // setShowPrivacyModal(false)
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+ // 调用后端静默登录API
|
|
|
+ // const response = await authClient['mini-login'].$post({
|
|
|
+ // json: {
|
|
|
+ // code: loginRes.code,
|
|
|
+ // tenantId: Number(process.env.TARO_APP_TENANT_ID) || 1
|
|
|
+ // }
|
|
|
+ // })
|
|
|
+ const openid = Taro.getStorageSync('openid')
|
|
|
+ const response = await authClient['mini-login'].$post({
|
|
|
+ json: {
|
|
|
+ code: "1,"+openid,
|
|
|
+ tenantId: Number(process.env.TARO_APP_TENANT_ID) || 1,
|
|
|
}
|
|
|
+ })
|
|
|
|
|
|
- // 调用后端静默登录API(不传userInfo)
|
|
|
- const response = await authClient['mini-login'].$post({
|
|
|
- json: {
|
|
|
- code: loginRes.code,
|
|
|
- tenantId: Number(process.env.TARO_APP_TENANT_ID) || 1
|
|
|
+ if (response.status === 200) {
|
|
|
+ console.debug("response")
|
|
|
+ console.debug(response)
|
|
|
+ const { token, user, isNewUser } = await response.json();
|
|
|
+ // Taro.setStorageSync('openid', token);
|
|
|
+ Taro.setStorageSync('userInfo', JSON.stringify(user))
|
|
|
+
|
|
|
+ console.debug("token")
|
|
|
+ console.debug(token)
|
|
|
+ console.debug("user")
|
|
|
+ console.debug(user)
|
|
|
+
|
|
|
+ console.debug("isNewUser")
|
|
|
+ console.debug(isNewUser)
|
|
|
+ if(isNewUser){
|
|
|
+
|
|
|
+ }else{
|
|
|
+ //直接登录
|
|
|
+ const { token: newToken } = await response.json()
|
|
|
+ Taro.setStorageSync('mini_token', newToken)
|
|
|
+
|
|
|
+ // 重新获取完整的用户信息
|
|
|
+ const meResponse = await authClient.me.$get({})
|
|
|
+ if (meResponse.status === 200) {
|
|
|
+ const userNew = await meResponse.json()
|
|
|
+ if(userNew ){
|
|
|
+ Taro.setStorageSync('userInfo', JSON.stringify(userNew))
|
|
|
+ console.debug('静默登录成功,返回新用户信息')
|
|
|
+ setShowPrivacyModal(false) //隐藏框
|
|
|
+ //加载广告
|
|
|
+ handleRefresh()
|
|
|
+ return userNew
|
|
|
+ }else{
|
|
|
+ console.debug("静默登录失败")
|
|
|
+ }
|
|
|
}
|
|
|
- })
|
|
|
+
|
|
|
+ //加载商品列表啊
|
|
|
+
|
|
|
+
|
|
|
+ }
|
|
|
+ // const { token: newToken } = await response.json()
|
|
|
+ // Taro.setStorageSync('mini_token', newToken)
|
|
|
+
|
|
|
+ // // 重新获取完整的用户信息
|
|
|
+ // const meResponse = await authClient.me.$get({})
|
|
|
+ // if (meResponse.status === 200) {
|
|
|
+ // const user = await meResponse.json()
|
|
|
+ // if(user.id!=null ){
|
|
|
+ // Taro.setStorageSync('userInfo', JSON.stringify(user))
|
|
|
+ // console.debug('静默登录成功,返回新用户信息')
|
|
|
+ // return user
|
|
|
+ // }else{
|
|
|
+ // //打开弹框
|
|
|
+ // console.debug("静默登录失败")
|
|
|
+ // }
|
|
|
+
|
|
|
+ // }
|
|
|
+ }
|
|
|
|
|
|
- if (response.status === 200) {
|
|
|
- const { token, user } = await response.json()
|
|
|
+ Taro.showToast({ title: '欢迎使用', icon: 'success' })
|
|
|
|
|
|
- // 保存token和用户信息
|
|
|
- Taro.setStorageSync('userInfo', user)
|
|
|
- Taro.setStorageSync('mini_token', token)
|
|
|
- setUser(user as any)
|
|
|
|
|
|
- setShowPrivacyModal(false)
|
|
|
- Taro.showToast({ title: '登录成功', icon: 'success' })
|
|
|
- } else {
|
|
|
- throw new Error('登录失败')
|
|
|
- }
|
|
|
- } catch (error: any) {
|
|
|
- console.error('静默登录失败:', error)
|
|
|
- // 静默登录失败,跳转到登录页
|
|
|
- setShowPrivacyModal(false)
|
|
|
- Taro.navigateTo({ url: '/pages/login/index' })
|
|
|
- } finally {
|
|
|
- setIsLoggingIn(false)
|
|
|
- }
|
|
|
}
|
|
|
|
|
|
- // 拒绝隐私政策,跳转到登录页
|
|
|
+ // 拒绝隐私政策,只关闭弹框
|
|
|
const handleRejectPrivacy = () => {
|
|
|
setShowPrivacyModal(false)
|
|
|
- Taro.navigateTo({ url: '/pages/login/index' })
|
|
|
}
|
|
|
|
|
|
+ // 如果未登录,不渲染页面内容
|
|
|
+ if (!isLoggedIn) return null
|
|
|
+
|
|
|
// 跳转到商品详情
|
|
|
const handleGoodsClick = (goods: GoodsData, index: number) => {
|
|
|
console.log('点击商品:', goods, index)
|
|
|
@@ -385,107 +469,107 @@ const HomePage: React.FC = () => {
|
|
|
return (
|
|
|
<>
|
|
|
<TabBarLayout activeKey="home">
|
|
|
- <Navbar
|
|
|
- title="首页"
|
|
|
- leftIcon=""
|
|
|
- onClickLeft={() => Taro.navigateBack()}
|
|
|
- rightIcon=""
|
|
|
- onClickRight={() => {}}
|
|
|
- />
|
|
|
- <ScrollView
|
|
|
- className="home-scroll-view"
|
|
|
- scrollY
|
|
|
- refresherEnabled={true}
|
|
|
- refresherTriggered={refreshing}
|
|
|
- onRefresherRefresh={handleRefresh}
|
|
|
- onScrollToLower={handleScrollToLower} >
|
|
|
- {/* 页面头部 - 搜索栏和轮播图 */}
|
|
|
- <View className="home-page-header">
|
|
|
- {/* 搜索栏 */}
|
|
|
- <View className="search" onClick={handleSearchClick}>
|
|
|
- <TDesignSearch
|
|
|
- placeholder="搜索商品..."
|
|
|
- disabled={true}
|
|
|
- shape="round"
|
|
|
- />
|
|
|
- </View>
|
|
|
-
|
|
|
- {/* 轮播图 */}
|
|
|
- <View className="swiper-wrap">
|
|
|
- {isAdLoading ? (
|
|
|
- <View className="loading-container">
|
|
|
- <Text className="loading-text">广告加载中...</Text>
|
|
|
- </View>
|
|
|
- ) : adError ? (
|
|
|
- <View className="error-container">
|
|
|
- <Text className="error-text">广告加载失败</Text>
|
|
|
- </View>
|
|
|
- ) : finalImgSrcs && finalImgSrcs.length > 0 ? (
|
|
|
-
|
|
|
- <Carousel
|
|
|
- items={finalImgSrcs.filter((item: any) => item.imageFile?.fullUrl).map((item: any) => ({
|
|
|
- src: item.imageFile!.fullUrl,
|
|
|
- title: item.title || '',
|
|
|
- description: item.description || ''
|
|
|
- }))}
|
|
|
- height={800}
|
|
|
- autoplay={true}
|
|
|
- interval={3000}
|
|
|
- circular={true}
|
|
|
- imageMode="aspectFit"
|
|
|
- />
|
|
|
-
|
|
|
- )
|
|
|
- : (
|
|
|
- <View className="empty-container">
|
|
|
- <Text className="empty-text">暂无广告</Text>
|
|
|
- </View>
|
|
|
- )}
|
|
|
- </View>
|
|
|
+ <Navbar
|
|
|
+ title="首页"
|
|
|
+ leftIcon=""
|
|
|
+ onClickLeft={() => Taro.navigateBack()}
|
|
|
+ rightIcon=""
|
|
|
+ onClickRight={() => {}}
|
|
|
+ />
|
|
|
+ <ScrollView
|
|
|
+ className="home-scroll-view"
|
|
|
+ scrollY
|
|
|
+ refresherEnabled={true}
|
|
|
+ refresherTriggered={refreshing}
|
|
|
+ onRefresherRefresh={handleRefresh}
|
|
|
+ onScrollToLower={handleScrollToLower} >
|
|
|
+ {/* 页面头部 - 搜索栏和轮播图 */}
|
|
|
+ <View className="home-page-header">
|
|
|
+ {/* 搜索栏 */}
|
|
|
+ <View className="search" onClick={handleSearchClick}>
|
|
|
+ <TDesignSearch
|
|
|
+ placeholder="搜索商品..."
|
|
|
+ disabled={true}
|
|
|
+ shape="round"
|
|
|
+ />
|
|
|
</View>
|
|
|
|
|
|
- {/* 页面内容 - 商品列表 */}
|
|
|
- <View className="home-page-container">
|
|
|
- {isLoading ? (
|
|
|
+ {/* 轮播图 */}
|
|
|
+ <View className="swiper-wrap">
|
|
|
+ {isAdLoading ? (
|
|
|
<View className="loading-container">
|
|
|
- <Text className="loading-text">加载中...</Text>
|
|
|
+ <Text className="loading-text">广告加载中...</Text>
|
|
|
</View>
|
|
|
- ) : error ? (
|
|
|
+ ) : adError ? (
|
|
|
<View className="error-container">
|
|
|
- <Text className="error-text">加载失败,请重试</Text>
|
|
|
+ <Text className="error-text">广告加载失败</Text>
|
|
|
</View>
|
|
|
- ) : goodsList.length === 0 ? (
|
|
|
+ ) : finalImgSrcs && finalImgSrcs.length > 0 ? (
|
|
|
+
|
|
|
+ <Carousel
|
|
|
+ items={finalImgSrcs.filter(item => item.imageFile?.fullUrl).map(item => ({
|
|
|
+ src: item.imageFile!.fullUrl,
|
|
|
+ title: item.title || '',
|
|
|
+ description: (item as any).description || ''
|
|
|
+ }))}
|
|
|
+ height={800}
|
|
|
+ autoplay={true}
|
|
|
+ interval={4000}
|
|
|
+ circular={true}
|
|
|
+ imageMode="aspectFit"
|
|
|
+ />
|
|
|
+
|
|
|
+ )
|
|
|
+ : (
|
|
|
<View className="empty-container">
|
|
|
- <Text className="empty-text">暂无商品</Text>
|
|
|
+ <Text className="empty-text">暂无广告</Text>
|
|
|
</View>
|
|
|
- ) : (
|
|
|
- <>
|
|
|
- <GoodsList
|
|
|
- goodsList={goodsList}
|
|
|
- onClick={handleGoodsClick}
|
|
|
- onAddCart={handleAddCart}
|
|
|
- />
|
|
|
-
|
|
|
- {/* 加载更多状态 */}
|
|
|
- {isFetchingNextPage && (
|
|
|
- <View className="loading-more-container">
|
|
|
- <Text className="loading-more-text">加载更多...</Text>
|
|
|
- </View>
|
|
|
- )}
|
|
|
-
|
|
|
- {/* 无更多数据状态 */}
|
|
|
- {!hasNextPage && goodsList.length > 0 && (
|
|
|
- <View className="no-more-container">
|
|
|
- <Text className="no-more-text">
|
|
|
- {`已经到底啦 (共${goodsList.length}件商品)`}
|
|
|
- </Text>
|
|
|
+ )}
|
|
|
+ </View>
|
|
|
+ </View>
|
|
|
+
|
|
|
+ {/* 页面内容 - 商品列表 */}
|
|
|
+ <View className="home-page-container">
|
|
|
+ {isLoading ? (
|
|
|
+ <View className="loading-container">
|
|
|
+ <Text className="loading-text">加载中...</Text>
|
|
|
+ </View>
|
|
|
+ ) : error ? (
|
|
|
+ <View className="error-container">
|
|
|
+ <Text className="error-text">加载失败,请重试</Text>
|
|
|
+ </View>
|
|
|
+ ) : goodsList.length === 0 ? (
|
|
|
+ <View className="empty-container">
|
|
|
+ <Text className="empty-text">暂无商品</Text>
|
|
|
+ </View>
|
|
|
+ ) : (
|
|
|
+ <>
|
|
|
+ <GoodsList
|
|
|
+ goodsList={goodsList}
|
|
|
+ onClick={handleGoodsClick}
|
|
|
+ onAddCart={handleAddCart}
|
|
|
+ />
|
|
|
+
|
|
|
+ {/* 加载更多状态 */}
|
|
|
+ {isFetchingNextPage && (
|
|
|
+ <View className="loading-more-container">
|
|
|
+ <Text className="loading-more-text">加载更多...</Text>
|
|
|
</View>
|
|
|
)}
|
|
|
+
|
|
|
+ {/* 无更多数据状态 */}
|
|
|
+ {!hasNextPage && goodsList.length > 0 && (
|
|
|
+ <View className="no-more-container">
|
|
|
+ <Text className="no-more-text">
|
|
|
+ {`已经到底啦 (共${goodsList.length}件商品)`}
|
|
|
+ </Text>
|
|
|
+ </View>
|
|
|
+ )}
|
|
|
</>
|
|
|
)}
|
|
|
<View className='height130'></View>
|
|
|
</View>
|
|
|
-
|
|
|
+
|
|
|
</ScrollView>
|
|
|
</TabBarLayout>
|
|
|
|
|
|
@@ -533,9 +617,7 @@ const HomePage: React.FC = () => {
|
|
|
className="flex-1 bg-green-500 text-white text-center py-3 rounded-lg"
|
|
|
onClick={handleAgreePrivacy}
|
|
|
>
|
|
|
- <Text className="text-white font-medium">
|
|
|
- {isLoggingIn ? '登录中...' : '同意'}
|
|
|
- </Text>
|
|
|
+ <Text className="text-white font-medium">同意</Text>
|
|
|
</View>
|
|
|
</View>
|
|
|
</View>
|