forked from gxwebsoft/mp-10550
fix(order): 修复订单退款时间窗口限制逻辑
- 在开发环境中切换回本地API接口配置 - 修正首页商品卡片按钮链接到正确的购买页面 - 添加退款时间窗口检查函数来限制退款申请时机 - 更新订单详情页退款按钮显示条件,确保仅在有效期内显示 - 在用户订单列表中实现相同的退款时间窗口验证逻辑 - 确保退款功能仅在支付后60分钟内可访问
This commit is contained in:
@@ -2,8 +2,8 @@
|
|||||||
export const ENV_CONFIG = {
|
export const ENV_CONFIG = {
|
||||||
// 开发环境
|
// 开发环境
|
||||||
development: {
|
development: {
|
||||||
// API_BASE_URL: 'http://127.0.0.1:9200/api',
|
API_BASE_URL: 'http://127.0.0.1:9200/api',
|
||||||
API_BASE_URL: 'https://mp-api.websoft.top/api',
|
// API_BASE_URL: 'https://mp-api.websoft.top/api',
|
||||||
APP_NAME: '开发环境',
|
APP_NAME: '开发环境',
|
||||||
DEBUG: 'true',
|
DEBUG: 'true',
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -313,7 +313,7 @@ function Home() {
|
|||||||
<View className="goods-card__actions">
|
<View className="goods-card__actions">
|
||||||
<View
|
<View
|
||||||
className="goods-card__btn goods-card__btn--ghost"
|
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>
|
<Text className="goods-card__btnText">买水票更优惠</Text>
|
||||||
</View>
|
</View>
|
||||||
|
|||||||
@@ -10,6 +10,17 @@ import dayjs from "dayjs";
|
|||||||
import PaymentCountdown from "@/components/PaymentCountdown";
|
import PaymentCountdown from "@/components/PaymentCountdown";
|
||||||
import './index.scss'
|
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 OrderDetail = () => {
|
||||||
const [order, setOrder] = useState<ShopOrder | null>(null);
|
const [order, setOrder] = useState<ShopOrder | null>(null);
|
||||||
const [orderGoodsList, setOrderGoodsList] = useState<ShopOrderGoods[]>([]);
|
const [orderGoodsList, setOrderGoodsList] = useState<ShopOrderGoods[]>([]);
|
||||||
@@ -228,7 +239,9 @@ const OrderDetail = () => {
|
|||||||
<Space>
|
<Space>
|
||||||
{!order.payStatus && <Button onClick={() => console.log('取消订单')}>取消订单</Button>}
|
{!order.payStatus && <Button onClick={() => console.log('取消订单')}>取消订单</Button>}
|
||||||
{!order.payStatus && <Button type="primary" 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 && (
|
{canConfirmReceive && (
|
||||||
<Button type="primary" onClick={() => setConfirmReceiveDialogVisible(true)}>
|
<Button type="primary" onClick={() => setConfirmReceiveDialogVisible(true)}>
|
||||||
确认收货
|
确认收货
|
||||||
|
|||||||
@@ -27,6 +27,17 @@ const isPaymentExpired = (createTime: string, timeoutHours: number = 24): boolea
|
|||||||
return now.isAfter(expireTime);
|
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 => ({
|
const getInfiniteUlStyle = (showSearch: boolean = false): CSSProperties => ({
|
||||||
marginTop: showSearch ? '0' : '0', // 如果显示搜索框,增加更多的上边距
|
marginTop: showSearch ? '0' : '0', // 如果显示搜索框,增加更多的上边距
|
||||||
height: showSearch ? '75vh' : '84vh', // 相应调整高度
|
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) => {
|
<Button size={'small'} onClick={(e) => {
|
||||||
e.stopPropagation();
|
e.stopPropagation();
|
||||||
applyRefund(item);
|
applyRefund(item);
|
||||||
|
|||||||
Reference in New Issue
Block a user