fix(order): 修复订单退款时间窗口限制逻辑

- 在开发环境中切换回本地API接口配置
- 修正首页商品卡片按钮链接到正确的购买页面
- 添加退款时间窗口检查函数来限制退款申请时机
- 更新订单详情页退款按钮显示条件,确保仅在有效期内显示
- 在用户订单列表中实现相同的退款时间窗口验证逻辑
- 确保退款功能仅在支付后60分钟内可访问
This commit is contained in:
2026-02-07 15:44:00 +08:00
parent 6c83f6c082
commit f8672dec34
4 changed files with 29 additions and 5 deletions

View File

@@ -2,8 +2,8 @@
export const ENV_CONFIG = {
// 开发环境
development: {
// API_BASE_URL: 'http://127.0.0.1:9200/api',
API_BASE_URL: 'https://mp-api.websoft.top/api',
API_BASE_URL: 'http://127.0.0.1:9200/api',
// API_BASE_URL: 'https://mp-api.websoft.top/api',
APP_NAME: '开发环境',
DEBUG: 'true',
},

View File

@@ -313,7 +313,7 @@ function Home() {
<View className="goods-card__actions">
<View
className="goods-card__btn goods-card__btn--ghost"
onClick={() => Taro.navigateTo({ url: '/user/ticket/index' })}
onClick={() => Taro.navigateTo({ url: 'shop/orderConfirm/index?goodsId=10074' })}
>
<Text className="goods-card__btnText"></Text>
</View>

View File

@@ -10,6 +10,17 @@ import dayjs from "dayjs";
import PaymentCountdown from "@/components/PaymentCountdown";
import './index.scss'
// 申请退款:支付成功后仅允许在指定时间窗内发起(前端展示层限制,后端仍应校验)
const isWithinRefundWindow = (payTime?: string, windowMinutes: number = 60): boolean => {
if (!payTime) return false;
const raw = String(payTime).trim();
const t = /^\d+$/.test(raw)
? dayjs(Number(raw) < 1e12 ? Number(raw) * 1000 : Number(raw)) // 兼容秒/毫秒时间戳
: dayjs(raw);
if (!t.isValid()) return false;
return dayjs().diff(t, 'minute') <= windowMinutes;
};
const OrderDetail = () => {
const [order, setOrder] = useState<ShopOrder | null>(null);
const [orderGoodsList, setOrderGoodsList] = useState<ShopOrderGoods[]>([]);
@@ -228,7 +239,9 @@ const OrderDetail = () => {
<Space>
{!order.payStatus && <Button onClick={() => console.log('取消订单')}></Button>}
{!order.payStatus && <Button type="primary" onClick={() => console.log('立即支付')}></Button>}
{order.orderStatus === 1 && <Button onClick={handleApplyRefund}>退</Button>}
{order.orderStatus === 1 && order.payStatus && isWithinRefundWindow(order.payTime, 60) && (
<Button onClick={handleApplyRefund}>退</Button>
)}
{canConfirmReceive && (
<Button type="primary" onClick={() => setConfirmReceiveDialogVisible(true)}>

View File

@@ -27,6 +27,17 @@ const isPaymentExpired = (createTime: string, timeoutHours: number = 24): boolea
return now.isAfter(expireTime);
};
// 申请退款:支付成功后仅允许在指定时间窗内发起(前端展示层限制,后端仍应校验)
const isWithinRefundWindow = (payTime?: string, windowMinutes: number = 60): boolean => {
if (!payTime) return false;
const raw = String(payTime).trim();
const t = /^\d+$/.test(raw)
? dayjs(Number(raw) < 1e12 ? Number(raw) * 1000 : Number(raw)) // 兼容秒/毫秒时间戳
: dayjs(raw);
if (!t.isValid()) return false;
return dayjs().diff(t, 'minute') <= windowMinutes;
};
const getInfiniteUlStyle = (showSearch: boolean = false): CSSProperties => ({
marginTop: showSearch ? '0' : '0', // 如果显示搜索框,增加更多的上边距
height: showSearch ? '75vh' : '84vh', // 相应调整高度
@@ -821,7 +832,7 @@ function OrderList(props: OrderListProps) {
)}
{/* 待发货状态:显示申请退款 */}
{item.payStatus && item.deliveryStatus === 10 && item.orderStatus !== 2 && item.orderStatus !== 4 && !isOrderCompleted(item) && (
{item.payStatus && isWithinRefundWindow(item.payTime, 60) && item.deliveryStatus === 10 && item.orderStatus !== 2 && item.orderStatus !== 4 && !isOrderCompleted(item) && (
<Button size={'small'} onClick={(e) => {
e.stopPropagation();
applyRefund(item);