feat(rider): 新增水票核销功能

- 添加水票核销扫码页面,支持扫描加密和明文二维码
- 实现水票验证逻辑,包括余额检查和核销确认
- 添加核销记录展示,最多保留最近10条记录
- 在骑手端界面增加水票核销入口
- 新增获取用户水票总数的API接口
- 优化首页轮播图加载,增加缓存和懒加载机制
- 添加门店选择功能,支持订单确认页切换门店
- 修复物流信息类型安全问题
- 更新用户中心门店相关文案显示
This commit is contained in:
2026-02-05 01:08:37 +08:00
parent fcbaa970d0
commit 8679b26f74
11 changed files with 454 additions and 39 deletions

View File

@@ -6,6 +6,7 @@ import {Image} from '@nutui/nutui-react-taro'
import {getCmsAdByCode} from "@/api/cms/cmsAd";
import navTo from "@/utils/common";
import {pageCmsArticle} from "@/api/cms/cmsArticle";
import Taro from '@tarojs/taro'
type AdImage = {
url?: string
@@ -41,41 +42,45 @@ const MyPage = () => {
const [loading, setLoading] = useState(true)
// const [disableSwiper, setDisableSwiper] = useState(false)
const CACHE_KEY = 'home_banner_mp-ad'
// 用于记录触摸开始位置
// const touchStartRef = useRef({x: 0, y: 0})
// 加载数据
const loadData = async () => {
setLoading(true)
const loadData = async (opts?: {silent?: boolean}) => {
if (!opts?.silent) setLoading(true)
try {
const [flashRes] = await Promise.allSettled([
getCmsAdByCode('mp-ad'),
getCmsAdByCode('hot_today'),
pageCmsArticle({ limit: 1, recommend: 1 }),
])
if (flashRes.status === 'fulfilled') {
console.log('flashflashflash', flashRes.value)
setCarouselData(flashRes.value)
} else {
console.error('Failed to fetch flash:', flashRes.reason)
}
// 只阻塞 banner 自己的数据;其他数据预热不应影响首屏展示速度
const flash = await getCmsAdByCode('mp-ad')
setCarouselData(flash)
void Taro.setStorage({ key: CACHE_KEY, data: flash }).catch(() => {})
} catch (error) {
console.error('Banner数据加载失败:', error)
} finally {
setLoading(false)
if (!opts?.silent) setLoading(false)
}
// 后台预热(不阻塞 banner 渲染)
void getCmsAdByCode('hot_today').catch(() => {})
void pageCmsArticle({ limit: 1, recommend: 1 }).catch(() => {})
}
useEffect(() => {
loadData().then()
const cached = Taro.getStorageSync(CACHE_KEY) as CmsAd | undefined
// 有缓存则先渲染缓存,避免首屏等待;再静默刷新
if (cached && normalizeAdImages(cached).length) {
setCarouselData(cached)
setLoading(false)
void loadData({ silent: true })
return
}
void loadData()
}, [])
// 轮播图高度默认300px
const carouselHeight = toNumberPx(carouselData?.height, 300)
const carouselImages = normalizeAdImages(carouselData)
console.log(carouselImages,'carouselImages')
// 骨架屏组件
const BannerSkeleton = () => (
@@ -149,7 +154,8 @@ const MyPage = () => {
src={src}
mode={'scaleToFill'}
onClick={() => (img.path ? navTo(`${img.path}`) : undefined)}
lazyLoad={false}
// 首张图优先加载,其余按需懒加载,避免并发图片请求拖慢首屏可见
lazyLoad={index !== 0}
style={{
height: `${carouselHeight}px`,
borderRadius: '4px',