87c4af7364
权益页去掉分享按钮,菜单分享保留 支付成功改 reLaunch 清栈;订单列表返回首页 减数量低于起购时 toast「同城/跨城/现场提货至少购买 N 瓶」 核销成功可评星并 POST /redeem/ratings;HQ 新增「门店评价」页 /store-ratings 成功页「回到首页」改用 .redeem-cancel-btn,不再撑破布局 历史记录改为核销流水:GET /redeem/records;生产库已有 2 笔(用户 13073729990)可验证。权益明细字段映射也一并修了 我的页头像提高点击层级,避免被卡片遮挡
159 lines
4.5 KiB
TypeScript
159 lines
4.5 KiB
TypeScript
import { useMemo, useState } from 'react';
|
|
import { View, Text } from '@tarojs/components';
|
|
import Taro, { useRouter } from '@tarojs/taro';
|
|
import PageShell from '../../components/PageShell';
|
|
import SubPageHeader from '../../components/SubPageHeader';
|
|
import { request, toast } from '../../lib/api';
|
|
|
|
const LAST_REDEEM_RESULT_KEY = 'lastRedeemResult';
|
|
|
|
type RedeemRecord = {
|
|
id: string;
|
|
redeemNo: string;
|
|
amount: number;
|
|
storeId: string;
|
|
storeName: string;
|
|
createdAt: string;
|
|
};
|
|
|
|
function formatMoney(amount: number) {
|
|
return amount.toLocaleString('zh-CN', { minimumFractionDigits: 2, maximumFractionDigits: 2 });
|
|
}
|
|
|
|
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 = Number(record?.amount ?? router.params.amount ?? 0);
|
|
const storeName = record?.storeName || '门店';
|
|
const redeemNo = record?.redeemNo || '—';
|
|
const redeemedAt = record?.createdAt
|
|
? new Date(record.createdAt).toLocaleString('zh-CN')
|
|
: new Date().toLocaleString('zh-CN');
|
|
|
|
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>
|
|
<Text className="redeem-success-amount">¥ {formatMoney(amount)}</Text>
|
|
<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>
|
|
);
|
|
}
|