diff --git a/src/pages/user/components/UserCard.tsx b/src/pages/user/components/UserCard.tsx index dfb6385..6389fa7 100644 --- a/src/pages/user/components/UserCard.tsx +++ b/src/pages/user/components/UserCard.tsx @@ -12,12 +12,14 @@ import {getStoredInviteParams} from "@/utils/invite"; import UnifiedQRButton from "@/components/UnifiedQRButton"; import {useThemeStyles} from "@/hooks/useTheme"; import {getRootDomain} from "@/utils/domain"; +import { getMyGltUserTicketTotal } from '@/api/glt/gltUserTicket' const UserCard = forwardRef((_, ref) => { const {data, refresh} = useUserData() const {getDisplayName} = useUser(); const [IsLogin, setIsLogin] = useState(false) const [userInfo, setUserInfo] = useState() + const [ticketTotal, setTicketTotal] = useState(0) const themeStyles = useThemeStyles(); @@ -29,6 +31,7 @@ const UserCard = forwardRef((_, ref) => { // 下拉刷新 const handleRefresh = async () => { await refresh() + reloadTicketTotal() Taro.showToast({ title: '刷新成功', icon: 'success' @@ -41,6 +44,9 @@ const UserCard = forwardRef((_, ref) => { })) useEffect(() => { + // 独立于用户信息授权:只要有登录 token,就可以拉取水票总数 + reloadTicketTotal() + // Taro.getSetting:获取用户的当前设置。返回值中只会出现小程序已经向用户请求过的权限。 Taro.getSetting({ success: (res) => { @@ -57,6 +63,20 @@ const UserCard = forwardRef((_, ref) => { }); }, []); + const reloadTicketTotal = () => { + const token = Taro.getStorageSync('access_token') + if (!token) { + setTicketTotal(0) + return + } + getMyGltUserTicketTotal() + .then((total) => setTicketTotal(typeof total === 'number' ? total : 0)) + .catch((err) => { + console.error('个人中心水票总数加载失败:', err) + setTicketTotal(0) + }) + } + const reload = () => { Taro.getUserInfo({ success: (res) => { @@ -73,6 +93,7 @@ const UserCard = forwardRef((_, ref) => { Taro.setStorageSync('UserId', data.userId) // 登录态已就绪后刷新卡片统计(余额/积分/券/水票) refresh().then() + reloadTicketTotal() // 获取openId if (!data.openid) { @@ -172,6 +193,7 @@ const UserCard = forwardRef((_, ref) => { setIsLogin(true) // 登录态已就绪后刷新卡片统计(余额/积分/券/水票) refresh().then() + reloadTicketTotal() } }) } else { @@ -282,7 +304,7 @@ const UserCard = forwardRef((_, ref) => { navTo('/user/gift/index', true)}> 水票 - {data?.giftCards || 0} + {ticketTotal} diff --git a/src/rider/index.tsx b/src/rider/index.tsx index f737458..b8d59c4 100644 --- a/src/rider/index.tsx +++ b/src/rider/index.tsx @@ -242,7 +242,7 @@ const DealerIndex: React.FC = () => { - navigateToPage('/rider/ticket/verification/index')}> + navigateToPage('/rider/ticket/verification/index?auto=1')}> diff --git a/src/rider/ticket/verification/index.tsx b/src/rider/ticket/verification/index.tsx index f07a537..545e4ac 100644 --- a/src/rider/ticket/verification/index.tsx +++ b/src/rider/ticket/verification/index.tsx @@ -1,6 +1,6 @@ -import React, { useMemo, useState } from 'react' +import React, { useEffect, useMemo, useRef, useState } from 'react' import { View, Text } from '@tarojs/components' -import Taro from '@tarojs/taro' +import Taro, { useDidShow, useRouter } from '@tarojs/taro' import { Button, Card, ConfigProvider } from '@nutui/nutui-react-taro' import { Scan, Success, Failure, Tips } from '@nutui/icons-react-taro' @@ -29,11 +29,14 @@ type VerifyRecord = { const RiderTicketVerificationPage: React.FC = () => { const { hasRole, isAdmin } = useUser() + const router = useRouter() const [loading, setLoading] = useState(false) const [lastTicket, setLastTicket] = useState(null) const [lastQty, setLastQty] = useState(1) const [records, setRecords] = useState([]) + const autoScanOnceRef = useRef(false) + const canVerify = useMemo(() => { return ( hasRole('rider') || @@ -44,6 +47,11 @@ const RiderTicketVerificationPage: React.FC = () => { ) }, [hasRole, isAdmin]) + const autoScanEnabled = useMemo(() => { + const p: any = router?.params || {} + return p.auto === '1' || p.auto === 'true' + }, [router]) + const addRecord = (rec: Omit) => { const item: VerifyRecord = { id: Date.now(), @@ -162,6 +170,25 @@ const RiderTicketVerificationPage: React.FC = () => { } } + // If navigated in "auto" mode, open scan on first show when user has permission. + useDidShow(() => { + // Reset the flag when user manually re-enters the page via navigation again. + // (This runs on every show; only the first show with auto enabled will trigger scan.) + if (!autoScanEnabled) autoScanOnceRef.current = false + }) + + useEffect(() => { + if (!autoScanEnabled) return + if (autoScanOnceRef.current) return + if (!canVerify) return + autoScanOnceRef.current = true + // Defer to ensure page is fully mounted before opening camera. + setTimeout(() => { + handleScan().catch(() => {}) + }, 80) + // eslint-disable-next-line react-hooks/exhaustive-deps + }, [autoScanEnabled, canVerify]) + return (