钱包结算所有, 第三方充值到钱包

This commit is contained in:
yml
2026-06-03 17:41:24 +08:00
parent eb7c0045cd
commit a1942c8453
9 changed files with 211 additions and 102 deletions
+5 -6
View File
@@ -91,6 +91,10 @@ export interface PaymentOrder {
updated_at: string
}
export interface PayOrderResult {
paid: boolean
}
export interface SubmitCheckoutPayload {
content: string
consumable_amount: number
@@ -116,12 +120,7 @@ export async function createOrder(listingId: number) {
}
export async function payOrder(id: number) {
const { data } = await apiClient.post<ApiResponse<PaymentOrder>>(`/orders/${id}/pay`)
return data.data
}
export async function queryOrderPayment(id: number) {
const { data } = await apiClient.post<ApiResponse<PaymentOrder>>(`/orders/${id}/pay/query`)
const { data } = await apiClient.post<ApiResponse<PayOrderResult>>(`/orders/${id}/pay`)
return data.data
}
+26 -45
View File
@@ -1,10 +1,10 @@
<script setup lang="ts">
import { onMounted, ref, computed } from "vue";
import { useRouter, useRoute } from "vue-router";
import { showDialog, showToast } from "vant";
import { showConfirmDialog, showToast } from "vant";
import MobileBottomNav from "@/components/MobileBottomNav.vue";
import { fetchOrders, payOrder, queryOrderPayment, type Order, type PaymentOrder } from "@/api/orders";
import { fetchOrders, payOrder, type Order } from "@/api/orders";
import { useSessionStore } from "@/stores/session";
import { formatDateMinute } from "@/utils/time";
@@ -75,63 +75,44 @@ function goDetail(id: number) {
async function handlePay(order: Order) {
payingOrderId.value = order.id;
try {
const payment = await payOrder(order.id);
if (payment.paid) {
showToast({ message: "支付成功", icon: "passed" });
} else {
await showPaymentDialog(order, payment);
}
await payOrder(order.id);
showToast({ message: "支付成功,等待号主交接", icon: "passed" });
await loadOrders();
} catch (error) {
showToast({ message: readError(error, "支付失败"), icon: "cross" });
const message = readError(error, "支付失败");
if (isInsufficientBalance(error)) {
await showRechargeGuide(message);
} else {
showToast({ message, icon: "cross" });
}
} finally {
payingOrderId.value = null;
}
}
async function showPaymentDialog(order: Order, payment: PaymentOrder) {
const payURL = payment.jspay_url || payment.td_code || payment.jspay_info || "";
const message = payURL
? `支付单已创建,金额 ¥${(payment.amount_cent / 100).toFixed(2)}。请复制或打开支付链接完成付款,付款后可刷新订单状态。\n\n${payURL}`
: "支付单已创建,请完成付款后刷新订单状态。";
await showDialog({
title: "去支付",
message,
confirmButtonText: payURL ? "打开/复制" : "刷新状态",
cancelButtonText: "刷新状态",
async function showRechargeGuide(message: string) {
await showConfirmDialog({
title: "余额不足",
message: `${message}。订单支付只使用钱包余额,请先充值后再支付订单。`,
confirmButtonText: "去充值",
cancelButtonText: "稍后再说",
showCancelButton: true,
})
.then(async () => {
if (payURL) {
await openOrCopyPayURL(payURL);
}
await refreshPayment(order.id);
.then(() => {
router.push("/wallet");
})
.catch(async () => {
await refreshPayment(order.id);
.catch(() => {
// 用户取消引导时不需要额外提示。
});
}
async function openOrCopyPayURL(payURL: string) {
if (/^https?:\/\//.test(payURL)) {
window.open(payURL, "_blank");
return;
}
try {
await navigator.clipboard?.writeText(payURL);
showToast({ message: "支付链接已复制", icon: "passed" });
} catch {
showToast({ message: "请手动复制支付链接", icon: "warning-o" });
}
}
async function refreshPayment(orderId: number) {
const payment = await queryOrderPayment(orderId);
if (payment.paid) {
showToast({ message: "支付成功", icon: "passed" });
} else {
showToast({ message: "支付未完成", icon: "clock-o" });
function isInsufficientBalance(error: unknown) {
if (typeof error === "object" && error && "response" in error) {
const response = (error as { response?: { data?: { code?: string } } })
.response;
return response?.data?.code === "insufficient_balance";
}
return false;
}
function readError(error: unknown, fallback: string) {