客服电话 → 13203801799(CUSTOMER_SERVICE_PHONE,协议文案走常量自动同步)

权益页去掉分享按钮,菜单分享保留
支付成功改 reLaunch 清栈;订单列表返回首页
减数量低于起购时 toast「同城/跨城/现场提货至少购买 N 瓶」
核销成功可评星并 POST /redeem/ratings;HQ 新增「门店评价」页 /store-ratings
成功页「回到首页」改用 .redeem-cancel-btn,不再撑破布局
历史记录改为核销流水:GET /redeem/records;生产库已有 2 笔(用户 13073729990)可验证。权益明细字段映射也一并修了
我的页头像提高点击层级,避免被卡片遮挡
This commit is contained in:
2026-08-03 13:09:59 +08:00
parent 9f67221457
commit 87c4af7364
22 changed files with 506 additions and 55 deletions
@@ -1,8 +1,9 @@
import { useMemo } from 'react';
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';
@@ -19,8 +20,38 @@ 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 {
@@ -38,14 +69,49 @@ export default function RedeemSuccessPage() {
? 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() {
Taro.removeStorageSync(LAST_REDEEM_RESULT_KEY);
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="核销成功" />
<SubPageHeader title="核销成功" onBack={goBenefit} />
<View className="sub-page-body">
<View className="redeem-success-icon">
<Text></Text>
@@ -69,14 +135,21 @@ export default function RedeemSuccessPage() {
</View>
</View>
<View className="redeem-submit" onClick={goBenefit}>
<Text></Text>
<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="u-btn u-btn--ghost u-btn--block"
style={{ margin: '0 20px', boxSizing: 'border-box' }}
onClick={() => Taro.switchTab({ url: '/pages/home/index' })}
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>