小程序修改
This commit is contained in:
@@ -1,18 +1,110 @@
|
||||
import { useEffect, 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 { toast } from '../../lib/api';
|
||||
import { ensurePayReady } from '../../lib/pay-ready';
|
||||
import {
|
||||
fetchClientConfig,
|
||||
fetchUserProfile,
|
||||
isWechatAuthRequiredError,
|
||||
needsWechatAuthForPay,
|
||||
payOrder,
|
||||
} from '../../lib/pay-wechat';
|
||||
import { request, toast } from '../../lib/api';
|
||||
|
||||
export default function PayPage() {
|
||||
const router = useRouter();
|
||||
const amount = router.params.amount ?? '0.00';
|
||||
const orderId = router.params.orderId ?? '';
|
||||
const [loading, setLoading] = useState(false);
|
||||
const [mockMode, setMockMode] = useState(true);
|
||||
const [needsWechatAuth, setNeedsWechatAuth] = useState(false);
|
||||
const [msg, setMsg] = useState('');
|
||||
const [orderNo, setOrderNo] = useState('');
|
||||
const [payAmount, setPayAmount] = useState('—');
|
||||
|
||||
function mockPay() {
|
||||
toast('支付成功(Mock)', 'success');
|
||||
setTimeout(() => {
|
||||
const returnPath = orderId
|
||||
? `/pages/pay/index?orderId=${orderId}`
|
||||
: '/pages/pay/index';
|
||||
|
||||
useEffect(() => {
|
||||
if (!orderId) return;
|
||||
void ensurePayReady(returnPath);
|
||||
}, [orderId, returnPath]);
|
||||
|
||||
useEffect(() => {
|
||||
async function load() {
|
||||
try {
|
||||
const [config, profile] = await Promise.all([fetchClientConfig(), fetchUserProfile()]);
|
||||
setMockMode(config.mockPay);
|
||||
setNeedsWechatAuth(needsWechatAuthForPay(config, profile));
|
||||
} catch {
|
||||
/* ignore */
|
||||
}
|
||||
}
|
||||
void load();
|
||||
}, []);
|
||||
|
||||
useEffect(() => {
|
||||
if (!orderId) {
|
||||
setOrderNo('');
|
||||
setPayAmount('—');
|
||||
return;
|
||||
}
|
||||
request<{ orderNo?: string; payAmount?: number | string; totalAmount?: number | string }>(
|
||||
`/trade/orders/${orderId}`,
|
||||
)
|
||||
.then((order) => {
|
||||
setOrderNo(order.orderNo || '');
|
||||
const amount = Number(order.payAmount ?? order.totalAmount ?? 0);
|
||||
if (Number.isFinite(amount) && amount > 0) {
|
||||
setPayAmount(amount.toFixed(2));
|
||||
}
|
||||
})
|
||||
.catch((e) => {
|
||||
setOrderNo('');
|
||||
toast(e instanceof Error ? e.message : '加载订单失败');
|
||||
});
|
||||
}, [orderId]);
|
||||
|
||||
async function pay() {
|
||||
if (!orderId) {
|
||||
toast('订单不存在');
|
||||
return;
|
||||
}
|
||||
if (needsWechatAuth) {
|
||||
setMsg('请先完成微信授权后再支付');
|
||||
const ready = await ensurePayReady(returnPath);
|
||||
if (!ready) return;
|
||||
return;
|
||||
}
|
||||
|
||||
const ready = await ensurePayReady(returnPath);
|
||||
if (!ready) return;
|
||||
|
||||
setLoading(true);
|
||||
setMsg('');
|
||||
try {
|
||||
const status = await payOrder(orderId);
|
||||
if (status === 'pending') {
|
||||
toast('支付结果确认中,请稍后在订单列表查看');
|
||||
} else {
|
||||
toast('支付成功', 'success');
|
||||
}
|
||||
Taro.redirectTo({ url: '/pages/orders/index?tab=paid' });
|
||||
}, 800);
|
||||
} catch (e) {
|
||||
if (isWechatAuthRequiredError(e)) {
|
||||
setNeedsWechatAuth(true);
|
||||
setMsg('微信支付需要先完成微信授权');
|
||||
await ensurePayReady(returnPath);
|
||||
return;
|
||||
}
|
||||
const message = e instanceof Error ? e.message : '支付失败';
|
||||
setMsg(message);
|
||||
toast(message);
|
||||
} finally {
|
||||
setLoading(false);
|
||||
}
|
||||
}
|
||||
|
||||
return (
|
||||
@@ -23,23 +115,36 @@ export default function PayPage() {
|
||||
<View className="pay-status-icon">
|
||||
<Text>¥</Text>
|
||||
</View>
|
||||
<Text className="pay-status-title">待支付</Text>
|
||||
<Text className="pay-status-amount">¥{amount}</Text>
|
||||
<Text className="pay-status-title">
|
||||
{needsWechatAuth ? '需完成微信授权' : '待支付'}
|
||||
</Text>
|
||||
<Text className="pay-status-amount">¥{payAmount}</Text>
|
||||
</View>
|
||||
<View className="order-card">
|
||||
<View className="order-row">
|
||||
<Text className="order-row-label">订单号</Text>
|
||||
<Text className="order-row-value">{orderNo || '—'}</Text>
|
||||
</View>
|
||||
<View className="order-row">
|
||||
<Text className="order-row-label">支付方式</Text>
|
||||
<Text className="order-row-value">微信支付</Text>
|
||||
</View>
|
||||
<View className="order-row">
|
||||
<Text className="order-row-label">说明</Text>
|
||||
<Text className="order-row-value">小程序支付后续接入</Text>
|
||||
<Text className="order-row-value">
|
||||
{mockMode ? 'Mock 模式由服务端直接标记已付款' : '将调起微信收银台'}
|
||||
</Text>
|
||||
</View>
|
||||
</View>
|
||||
{msg ? <Text className="u-muted" style={{ display: 'block', marginTop: 12 }}>{msg}</Text> : null}
|
||||
</View>
|
||||
<View className="pay-bar">
|
||||
<View className="order-confirm-submit" style={{ flex: 1 }} onClick={mockPay}>
|
||||
<Text>立即支付</Text>
|
||||
<View
|
||||
className="order-confirm-submit"
|
||||
style={{ flex: 1, opacity: loading ? 0.7 : 1 }}
|
||||
onClick={() => !loading && void pay()}
|
||||
>
|
||||
<Text>{loading ? '支付中…' : needsWechatAuth ? '去授权' : '立即支付'}</Text>
|
||||
</View>
|
||||
</View>
|
||||
</PageShell>
|
||||
|
||||
Reference in New Issue
Block a user