import Taro, { useReachBottom } from '@tarojs/taro';
|
import { useState, useEffect } from 'react';
|
import { View, Text, Image } from '@tarojs/components';
|
import './index.less';
|
import icon from '../../assets/Subtract.png'
|
import close from '../../assets/close.png'
|
import { getCouponList, receiveCoupon, getCouponDetail, CouponItem, CouponDetail } from '../../../robotaxi/api/coupon';
|
|
export default function CouponPage() {
|
const [couponStatus] = useState([
|
// { label: '全部', value: '' },
|
// { label: '待领取', value: 0 },
|
{ label: '未使用', value: 1 },
|
{ label: '已使用', value: 2 },
|
{ label: '已失效', value: 3 }])
|
const [activeStatus, setActiveStatus] = useState<string | number>(1)
|
const [couponList, setCouponList] = useState<CouponItem[]>([])
|
const [animationData, setAnimationData] = useState<any>(null)
|
const [visible, setVisible] = useState(false)
|
const [pageNum, setPageNum] = useState(1)
|
const [hasMore, setHasMore] = useState(true)
|
const [currentCoupon, setCurrentCoupon] = useState<CouponDetail | null>(null)
|
const pageSize = 10
|
|
const getList = async (page: number, status: string | number, isRefresh = false) => {
|
try {
|
const res = await getCouponList({ pageNum: page, pageSize, status });
|
const newList = res.list || [];
|
if (isRefresh) {
|
setCouponList(newList);
|
} else {
|
setCouponList(prev => [...prev, ...newList]);
|
}
|
// 如果返回数量少于 pageSize,说明没有更多数据了
|
setHasMore(newList.length >= pageSize);
|
} catch (e) {
|
console.error(e);
|
// 出错时如果是刷新,清空列表
|
if (isRefresh) setCouponList([]);
|
}
|
}
|
const formatTime = (t?: string, type?: string) => {
|
const d = new Date(t);
|
const y = d.getFullYear();
|
const m = String(d.getMonth() + 1).padStart(2, '0');
|
const day = String(d.getDate()).padStart(2, '0');
|
const h = String(d.getHours()).padStart(2, '0');
|
const min = String(d.getMinutes()).padStart(2, '0');
|
return type == 'list' ? `${y}年${m}月${day}日 ${h}:${min}` : `${y}-${m}-${day}`;
|
}
|
|
useEffect(() => {
|
// 切换 tab 时重置并加载第一页
|
setPageNum(1);
|
setHasMore(true);
|
getList(1, activeStatus, true);
|
}, [activeStatus])
|
|
useReachBottom(() => {
|
if (hasMore) {
|
const nextPage = pageNum + 1;
|
setPageNum(nextPage);
|
getList(nextPage, activeStatus);
|
}
|
})
|
|
const changeStatus = (value: string | number) => {
|
setActiveStatus(value)
|
}
|
|
const openPopup = async (item: CouponItem) => {
|
try {
|
Taro.showLoading({ title: '加载中...' });
|
const detail = await getCouponDetail(item.couponId);
|
setCurrentCoupon(detail);
|
Taro.hideLoading();
|
|
const animation = Taro.createAnimation({
|
duration: 300,
|
timingFunction: 'ease-out'
|
});
|
animation.translateY(0).step();
|
setAnimationData(animation.export())
|
setVisible(true)
|
} catch (error) {
|
Taro.hideLoading();
|
Taro.showToast({ title: '获取详情失败', icon: 'none' });
|
}
|
}
|
|
const closePopup = () => {
|
const animation = Taro.createAnimation({
|
duration: 300,
|
timingFunction: 'ease-in'
|
});
|
animation.translateY(500).step();
|
setAnimationData(animation.export())
|
setVisible(false)
|
}
|
|
const handleReceive = async (e, item: CouponItem) => {
|
e.stopPropagation();
|
try {
|
await receiveCoupon({ couponId: item.couponId });
|
Taro.showToast({ title: '领取成功', icon: 'success' });
|
// 领取成功后刷新列表
|
getList(1, activeStatus, true);
|
setPageNum(1);
|
} catch (error) {
|
Taro.showToast({ title: '领取失败', icon: 'none' });
|
}
|
}
|
|
const toHome = () => {
|
Taro.reLaunch({
|
url: '/pages/robotaxi/home/index'
|
})
|
}
|
|
return (
|
<View className='coupon-page'>
|
<View className='tab-card'>
|
{couponStatus.map((item, index) => {
|
return <View className={`tab-item ${activeStatus === item.value ? 'active-status' : ''}`} key={item.value || index} onClick={() => changeStatus(item.value)}>{item.label}</View>
|
})}
|
</View>
|
{
|
couponList.length > 0 &&
|
<View className='coupon-card'>
|
{couponList.map((item, index) => {
|
return <View className='coupon-item' key={item.couponId || index} style={{ opacity: ![0, 1].includes(item.status) ? 0.5 : 1 }}>
|
<View className='coupon-content'>
|
<View className='coupon-price'>
|
<Text className='price'>{item.discountAmount}</Text>
|
<Text className='unit'>元</Text>
|
</View>
|
<View className='coupon-info'>
|
<Text className='name'>{item.title}</Text>
|
<Text className='time'>{formatTime(item.expireTime, 'list')}到期</Text>
|
<View className='more' onClick={() => openPopup(item)}>
|
<Text className='more-detail'>查看详情</Text>
|
<Image className='more-img' src={icon}></Image>
|
</View>
|
</View>
|
</View>
|
{/* 状态 1-未使用 2-已使用 3-已过期 0待领取 */}
|
{
|
// item.status === 0 ? (
|
// <View className='receive' onClick={(e) => handleReceive(e, item)}>领取</View>
|
// ) :
|
item.status === 1 ? (
|
<View onClick={toHome} className='receive' style={{ backgroundColor: '#F58900' }}>去使用</View>
|
) : item.status === 2 ? (
|
<Image className='status-img' src={require('../../assets/coupon-used.png')} />
|
) : item.status === 3 ? (
|
<Image className='status-img' src={require('../../assets/coupon-lost-efficacy.png')} />
|
) : ''}
|
</View>
|
})}
|
</View>
|
}
|
{
|
!couponList.length && <View className='no-data-box'>
|
<Image className='no-data-image' src={require('../../assets/no-data-coupon.png')} />
|
<View>暂无优惠券</View>
|
</View>
|
}
|
|
{/* 优惠券说明 */}
|
{visible && currentCoupon && <View className='privacy-popup' catchMove>
|
<View className='privacy-mask' onClick={closePopup}></View>
|
<View className='privacy-content' animation={animationData}>
|
{/* 头部:标题 + 关闭*/}
|
<View className='privacy-header'>
|
<Text className='title'>优惠券说明</Text>
|
<Image className='close' src={close} onClick={() => closePopup()}></Image>
|
</View>
|
{/* 内容文案 */}
|
<View className='remark-card'>
|
<Text className='remark-label'>有效时间</Text>
|
<Text className='remark-value'>{formatTime(currentCoupon.expireTime, 'popup')} 失效</Text>
|
</View>
|
<View className='remark-card'>
|
<Text className='remark-label'>使用时段</Text>
|
<Text className='remark-value'>全天</Text>
|
</View>
|
<View className='remark-card'>
|
<Text className='remark-label'>使用地区</Text>
|
<Text className='remark-value'> 广州</Text>
|
</View>
|
<View className='remark-card'>
|
<Text className='remark-label'>使用说明</Text>
|
<Text className='remark-value'>{currentCoupon.usageInstructions}</Text>
|
</View>
|
|
</View>
|
</View>
|
}
|
|
</View>
|
)
|
}
|