import {useState} from "react"; import Taro, {useDidShow} from '@tarojs/taro' import { Button, Empty, ConfigProvider, SearchBar, InfiniteLoading, Loading, PullToRefresh, Tabs, TabPane } from '@nutui/nutui-react-taro' import {Plus, Filter} from '@nutui/icons-react-taro' import {View} from '@tarojs/components' import {ShopUserCoupon} from "@/api/shop/shopUserCoupon/model"; import {pageShopUserCoupon, getMyAvailableCoupons, getMyUsedCoupons, getMyExpiredCoupons} from "@/api/shop/shopUserCoupon"; import CouponList from "@/components/CouponList"; import CouponStats from "@/components/CouponStats"; import CouponGuide from "@/components/CouponGuide"; import CouponFilter from "@/components/CouponFilter"; import CouponExpireNotice, {ExpiringSoon} from "@/components/CouponExpireNotice"; import {CouponCardProps} from "@/components/CouponCard"; import dayjs from "dayjs"; import {transformCouponData} from "@/utils/couponUtils"; const CouponManage = () => { const [list, setList] = useState([]) const [loading, setLoading] = useState(false) const [hasMore, setHasMore] = useState(true) const [searchValue, setSearchValue] = useState('') const [page, setPage] = useState(1) const [total, setTotal] = useState(0) console.log('total = ', total) const [activeTab, setActiveTab] = useState('0') // 0-可用 1-已使用 2-已过期 const [stats, setStats] = useState({ available: 0, used: 0, expired: 0 }) const [showGuide, setShowGuide] = useState(false) const [showFilter, setShowFilter] = useState(false) const [showExpireNotice, setShowExpireNotice] = useState(false) const [expiringSoonCoupons, setExpiringSoonCoupons] = useState([]) const [filters, setFilters] = useState({ type: [] as number[], minAmount: undefined as number | undefined, sortBy: 'createTime' as 'createTime' | 'amount' | 'expireTime', sortOrder: 'desc' as 'asc' | 'desc' }) // 获取优惠券状态过滤条件 const reload = async (isRefresh = false) => { // 直接调用reloadWithTab,使用当前的activeTab await reloadWithTab(activeTab, isRefresh) } // 搜索功能 const handleSearch = (value: string) => { setSearchValue(value) reload(true) } // 下拉刷新 const handleRefresh = async () => { await reload(true) } // Tab切换 const handleTabChange = (value: string | number) => { const tabValue = String(value) console.log('Tab切换:', {from: activeTab, to: tabValue}) setActiveTab(tabValue) setPage(1) setList([]) setHasMore(true) // 直接调用reload,传入新的tab值 reloadWithTab(tabValue) } // 根据指定tab加载数据 const reloadWithTab = async (tab: string, isRefresh = true) => { if (isRefresh) { setPage(1) setList([]) setHasMore(true) } setLoading(true) try { let res: any = null // 根据tab选择对应的API switch (tab) { case '0': // 可用优惠券 res = await getMyAvailableCoupons() break case '1': // 已使用优惠券 res = await getMyUsedCoupons() break case '2': // 已过期优惠券 res = await getMyExpiredCoupons() break default: res = await getMyAvailableCoupons() } console.log('使用Tab加载数据:', { tab, data: res }) if (res && res.length > 0) { // 应用搜索过滤 let filteredList = res if (searchValue) { filteredList = res.filter((item: any) => item.name?.includes(searchValue) || item.description?.includes(searchValue) ) } // 应用其他筛选条件 if (filters.type.length > 0) { filteredList = filteredList.filter((item: any) => filters.type.includes(item.type) ) } if (filters.minAmount) { filteredList = filteredList.filter((item: any) => parseFloat(item.minPrice || '0') >= filters.minAmount! ) } // 排序 filteredList.sort((a: any, b: any) => { const aValue = getValueForSort(a, filters.sortBy) const bValue = getValueForSort(b, filters.sortBy) if (filters.sortOrder === 'asc') { return aValue - bValue } else { return bValue - aValue } }) setList(filteredList) setTotal(filteredList.length) setHasMore(false) // 一次性加载所有数据,不需要分页 } else { setList([]) setTotal(0) setHasMore(false) } } catch (error) { console.error('获取优惠券失败:', error) Taro.showToast({ title: '获取优惠券失败', icon: 'error' }); setList([]) setTotal(0) setHasMore(false) } finally { setLoading(false) } } // 获取排序值的辅助函数 const getValueForSort = (item: any, sortBy: string) => { switch (sortBy) { case 'amount': return parseFloat(item.reducePrice || item.discount || '0') case 'expireTime': return new Date(item.endTime || '').getTime() case 'createTime': default: return new Date(item.createTime || '').getTime() } } // 转换优惠券数据并添加使用按钮 const transformCouponDataWithAction = (coupon: ShopUserCoupon): CouponCardProps => { console.log('原始优惠券数据:', coupon) // 使用统一的转换函数 const transformedCoupon = transformCouponData(coupon) console.log('转换后的优惠券数据:', transformedCoupon) // 添加使用按钮和点击事件 const result = { ...transformedCoupon, showUseBtn: transformedCoupon.status === 0, // 只有未使用的券显示使用按钮 onUse: () => handleUseCoupon(coupon) } console.log('最终优惠券数据:', result) return result } // 使用优惠券 const handleUseCoupon = (_: ShopUserCoupon) => { // 这里可以跳转到商品页面或购物车页面 Taro.navigateTo({ url: '/shop/category/index?id=4326' }) } // 优惠券点击事件 const handleCouponClick = (_coupon: CouponCardProps, index: number) => { const originalCoupon = list[index] if (originalCoupon) { // 显示优惠券详情 showCouponDetail(originalCoupon) } } // 显示优惠券详情 const showCouponDetail = (coupon: ShopUserCoupon) => { // 跳转到优惠券详情页 Taro.navigateTo({ url: `/user/coupon/detail?id=${coupon.id}` }) } // 加载优惠券统计数据 const loadCouponStats = async () => { try { // 并行获取各状态的优惠券数量 const [availableRes, usedRes, expiredRes] = await Promise.all([ getMyAvailableCoupons(), getMyUsedCoupons(), getMyExpiredCoupons() ]) setStats({ available: availableRes?.length || 0, used: usedRes?.length || 0, expired: expiredRes?.length || 0 }) } catch (error) { console.error('获取优惠券统计失败:', error) // 设置默认值 setStats({ available: 0, used: 0, expired: 0 }) } } // 统计卡片点击事件 const handleStatsClick = (type: 'available' | 'used' | 'expired') => { const tabMap = { available: '0', used: '1', expired: '2' } handleTabChange(tabMap[type]) } // 筛选条件变更 const handleFiltersChange = (newFilters: any) => { setFilters(newFilters) reload(true).then() } // 检查即将过期的优惠券 const checkExpiringSoonCoupons = async () => { try { // 获取即将过期的优惠券(3天内过期) const res = await pageShopUserCoupon({ page: page, limit: 50, status: 0, // 未使用 isExpire: 0 // 未过期 }) if (res && res.list) { const now = dayjs() const expiringSoon = res.list .map(coupon => { const endTime = dayjs(coupon.endTime) const daysLeft = endTime.diff(now, 'day') return { id: coupon.id || 0, name: coupon.name || '', type: coupon.type || 10, amount: coupon.type === 10 ? coupon.reducePrice || '0' : coupon.type === 20 ? coupon.discount?.toString() || '0' : '0', minAmount: coupon.minPrice, endTime: coupon.endTime || '', daysLeft } }) .filter(coupon => coupon.daysLeft >= 0 && coupon.daysLeft <= 3) .sort((a, b) => a.daysLeft - b.daysLeft) if (expiringSoon.length > 0) { // @ts-ignore setExpiringSoonCoupons(expiringSoon) // 延迟显示提醒,避免与页面加载冲突 setTimeout(() => { setShowExpireNotice(true) }, 1000) } } } catch (error) { console.error('检查即将过期优惠券失败:', error) } } // 使用即将过期的优惠券 const handleUseExpiringSoonCoupon = (coupon: ExpiringSoon) => { console.log(coupon, '使用即将过期优惠券') setShowExpireNotice(false) // 跳转到商品页面 Taro.navigateTo({ url: '/pages/index/index' }) } // 加载更多 const loadMore = async () => { if (!loading && hasMore) { await reload(false) // 不刷新,追加数据 } } useDidShow(() => { reload(true).then() loadCouponStats().then() // 只在可用优惠券tab时检查即将过期的优惠券 if (activeTab === '0') { checkExpiringSoonCoupons().then() } }); return ( {/* 搜索栏和领取入口 */} {/* 优惠券统计 */} {/* Tab切换 */} {/* 优惠券列表 */} {list.length === 0 && !loading ? ( ) : ( 加载中... } loadMoreText={ {list.length === 0 ? "暂无数据" : "没有更多了"} } > )} {/* 使用指南弹窗 */} setShowGuide(false)} /> {/*/!* 筛选弹窗 *!/*/} setShowFilter(false)} /> {/*/!* 到期提醒弹窗 *!/*/} setShowExpireNotice(false)} onUseCoupon={handleUseExpiringSoonCoupon} /> ); }; export default CouponManage;