74 lines
1.9 KiB
TypeScript
74 lines
1.9 KiB
TypeScript
import { useMemo } from 'react';
|
|
import { View, Text, Swiper, SwiperItem } from '@tarojs/components';
|
|
import { formatRedeemRelativeTime } from '../lib/datetime';
|
|
|
|
export type StoreRedeemMarqueeItem = {
|
|
userLabel: string;
|
|
amount: string;
|
|
createdAt?: string | null;
|
|
};
|
|
|
|
type StoreRedeemMarqueeProps = {
|
|
items: StoreRedeemMarqueeItem[];
|
|
};
|
|
|
|
const STAY_MS = 5000;
|
|
|
|
function MarqueeRow({ item }: { item: StoreRedeemMarqueeItem }) {
|
|
const timeLabel = formatRedeemRelativeTime(item.createdAt);
|
|
return (
|
|
<View className="store-detail-marquee-inner">
|
|
<View className="store-detail-marquee-dot" />
|
|
<Text className="store-detail-marquee-text">
|
|
{item.userLabel} {timeLabel}到店核销
|
|
</Text>
|
|
<Text className="store-detail-marquee-amount">{item.amount}</Text>
|
|
</View>
|
|
);
|
|
}
|
|
|
|
/** 核销记录:单条静止;多条竖向循环,支持手动滑动,每条停留 5 秒 */
|
|
export default function StoreRedeemMarquee({ items }: StoreRedeemMarqueeProps) {
|
|
const list = useMemo(
|
|
() =>
|
|
items
|
|
.map((row) => ({
|
|
userLabel: String(row.userLabel || '用户***').trim() || '用户***',
|
|
amount: String(row.amount || '').trim(),
|
|
createdAt: row.createdAt ?? null,
|
|
}))
|
|
.filter((row) => row.amount),
|
|
[items],
|
|
);
|
|
|
|
if (!list.length) return null;
|
|
|
|
if (list.length === 1) {
|
|
return (
|
|
<View className="store-detail-marquee">
|
|
<MarqueeRow item={list[0]} />
|
|
</View>
|
|
);
|
|
}
|
|
|
|
return (
|
|
<View className="store-detail-marquee">
|
|
<Swiper
|
|
className="store-detail-marquee-swiper"
|
|
vertical
|
|
circular
|
|
autoplay
|
|
interval={STAY_MS}
|
|
duration={400}
|
|
indicatorDots={false}
|
|
>
|
|
{list.map((row, index) => (
|
|
<SwiperItem key={`${row.userLabel}|${row.amount}|${row.createdAt}|${index}`}>
|
|
<MarqueeRow item={row} />
|
|
</SwiperItem>
|
|
))}
|
|
</Swiper>
|
|
</View>
|
|
);
|
|
}
|