Files
dukang/apps/mini-user/src/pages/redeem-success/index.tsx
T
jacy fc2e5b65de
CI / verify (pull_request) Has been cancelled
v3.5.3版本更新1
2026-08-20 18:54:15 +08:00

162 lines
4.7 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import { useMemo, useState } from 'react';
import { View, Text } from '@tarojs/components';
import '../../styles/redeem.css';
import Taro, { useRouter } from '@tarojs/taro';
import PageShell from '../../components/PageShell';
import SubPageHeader from '../../components/SubPageHeader';
import { request, toast } from '../../lib/api';
import { formatShanghaiDateTime } from '../../lib/datetime';
import { formatMoney, toMoneyNumber } from '../../lib/money';
import BenefitFigure from '../../components/BenefitFigure';
const LAST_REDEEM_RESULT_KEY = 'lastRedeemResult';
type RedeemRecord = {
id: string;
redeemNo: string;
amount: number;
storeId: string;
storeName: string;
createdAt: string;
};
/** 与权益「历史记录」一致:2026-08-03 13:53:03Asia/Shanghai */
function formatChinaDateTime(input?: string | null) {
return formatShanghaiDateTime(input ?? new Date());
}
function StarRating({
label,
value,
onChange,
}: {
label: string;
value: number;
onChange: (score: number) => void;
}) {
return (
<View className="redeem-rating-row">
<Text className="redeem-rating-label">{label}</Text>
<View className="redeem-star-row">
{[1, 2, 3, 4, 5].map((score) => (
<Text
key={score}
className={`redeem-star-btn${score <= value ? ' redeem-star-btn--active' : ''}`}
onClick={() => onChange(score)}
>
</Text>
))}
</View>
</View>
);
}
export default function RedeemSuccessPage() {
const router = useRouter();
const [serviceScore, setServiceScore] = useState(5);
const [envScore, setEnvScore] = useState(5);
const [loading, setLoading] = useState(false);
const record = useMemo<RedeemRecord | null>(() => {
try {
const cached = Taro.getStorageSync(LAST_REDEEM_RESULT_KEY);
return cached ? (JSON.parse(String(cached)) as RedeemRecord) : null;
} catch {
return null;
}
}, []);
const amount = toMoneyNumber(record?.amount ?? router.params.amount);
const storeName = record?.storeName || '门店';
const redeemNo = record?.redeemNo || '—';
const redeemedAt = formatChinaDateTime(record?.createdAt);
function clearCache() {
try {
Taro.removeStorageSync(LAST_REDEEM_RESULT_KEY);
} catch {
/* ignore */
}
}
function goBenefit() {
clearCache();
Taro.switchTab({ url: '/pages/benefit/index' });
}
function goHome() {
clearCache();
Taro.switchTab({ url: '/pages/home/index' });
}
async function submitRatingAndFinish() {
setLoading(true);
try {
if (record?.id) {
await request('/redeem/ratings', {
method: 'POST',
data: {
redeemRecordId: record.id,
serviceScore,
envScore,
},
});
toast('评价已提交', 'success');
}
} catch {
/* 评价失败不阻塞返回 */
} finally {
setLoading(false);
goBenefit();
}
}
return (
<PageShell variant="sub" className="redeem-success-page">
<SubPageHeader title="核销成功" onBack={goBenefit} />
<View className="sub-page-body">
<View className="redeem-success-icon">
<Text></Text>
</View>
<Text className="redeem-success-title">核销成功</Text>
<BenefitFigure value={formatMoney(amount)} size="lg" className="redeem-success-amount" />
<Text className="redeem-success-desc">已在 {storeName} 完成核销</Text>
<View className="redeem-success-details">
<View className="redeem-success-detail-row">
<Text>核销门店</Text>
<Text>{storeName}</Text>
</View>
<View className="redeem-success-detail-row">
<Text>核销时间</Text>
<Text>{redeemedAt}</Text>
</View>
<View className="redeem-success-detail-row">
<Text>核销单号</Text>
<Text className="redeem-success-mono">{redeemNo}</Text>
</View>
</View>
<View className="redeem-success-rating">
<Text className="redeem-success-rating-title">为门店服务评分</Text>
<StarRating label="服务态度" value={serviceScore} onChange={setServiceScore} />
<StarRating label="用餐环境" value={envScore} onChange={setEnvScore} />
</View>
<View
className={`redeem-submit${loading ? ' redeem-submit--disabled' : ''}`}
onClick={() => {
if (!loading) void submitRatingAndFinish();
}}
>
<Text>{loading ? '提交中…' : '提交评价并返回'}</Text>
</View>
<View className="redeem-cancel-btn" onClick={goHome}>
<Text>回到首页</Text>
</View>
</View>
</PageShell>
);
}