开始增加支付-1
This commit is contained in:
@@ -70,6 +70,27 @@ export interface HandoffRecord {
|
||||
created_at: string
|
||||
}
|
||||
|
||||
export interface PaymentOrder {
|
||||
id: number
|
||||
payment_no: string
|
||||
order_id: number
|
||||
order_no: string
|
||||
provider: string
|
||||
third_order_id: string
|
||||
provider_order_id: string
|
||||
pay_way: string
|
||||
jspay_flag: string
|
||||
amount_cent: number
|
||||
status: string
|
||||
td_code?: string
|
||||
jspay_url?: string
|
||||
jspay_info?: string
|
||||
paid: boolean
|
||||
paid_at?: string
|
||||
created_at: string
|
||||
updated_at: string
|
||||
}
|
||||
|
||||
export interface SubmitCheckoutPayload {
|
||||
content: string
|
||||
consumable_amount: number
|
||||
@@ -95,7 +116,12 @@ export async function createOrder(listingId: number) {
|
||||
}
|
||||
|
||||
export async function payOrder(id: number) {
|
||||
const { data } = await apiClient.post<ApiResponse<{ paid: boolean }>>(`/orders/${id}/pay`)
|
||||
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`)
|
||||
return data.data
|
||||
}
|
||||
|
||||
|
||||
@@ -2,6 +2,7 @@ import { apiClient } from './client'
|
||||
|
||||
import type { ApiResponse, PaginatedResult } from './types'
|
||||
import type { BalanceType, LedgerDirection, WalletStatus } from '@/types/status'
|
||||
import type { PaymentOrder } from './orders'
|
||||
|
||||
export interface WalletAccount {
|
||||
user_id: number
|
||||
@@ -41,3 +42,13 @@ export async function rechargeWallet(amount: number) {
|
||||
const { data } = await apiClient.post<ApiResponse<WalletAccount>>('/wallet/recharge', { amount })
|
||||
return data.data
|
||||
}
|
||||
|
||||
export async function startWalletRechargePayment(amount: number) {
|
||||
const { data } = await apiClient.post<ApiResponse<PaymentOrder>>('/wallet/recharge/pay', { amount })
|
||||
return data.data
|
||||
}
|
||||
|
||||
export async function queryWalletRechargePayment(id: number) {
|
||||
const { data } = await apiClient.post<ApiResponse<PaymentOrder>>(`/wallet/recharge/pay/${id}/query`)
|
||||
return data.data
|
||||
}
|
||||
|
||||
@@ -1,8 +1,16 @@
|
||||
<script setup lang="ts">
|
||||
import { onMounted, ref } from 'vue'
|
||||
import { ElMessage } from 'element-plus'
|
||||
import { ElMessage, ElMessageBox } from 'element-plus'
|
||||
|
||||
import { fetchWalletBalance, fetchWalletLedger, rechargeWallet, type WalletAccount, type WalletLedger } from '@/api/wallet'
|
||||
import {
|
||||
fetchWalletBalance,
|
||||
fetchWalletLedger,
|
||||
queryWalletRechargePayment,
|
||||
startWalletRechargePayment,
|
||||
type WalletAccount,
|
||||
type WalletLedger,
|
||||
} from '@/api/wallet'
|
||||
import type { PaymentOrder } from '@/api/orders'
|
||||
import { balanceTypeLabel, ledgerDirectionLabel, walletStatusLabel } from '@/utils/statusLabels'
|
||||
import { formatDateTime } from '@/utils/time'
|
||||
|
||||
@@ -41,8 +49,12 @@ function loadLedgerPage() {
|
||||
async function handleRecharge() {
|
||||
recharging.value = true
|
||||
try {
|
||||
account.value = await rechargeWallet(rechargeAmount.value)
|
||||
ElMessage.success('充值成功')
|
||||
const payment = await startWalletRechargePayment(rechargeAmount.value)
|
||||
if (payment.paid) {
|
||||
ElMessage.success('充值成功')
|
||||
} else {
|
||||
await showRechargePaymentDialog(payment)
|
||||
}
|
||||
await loadWallet()
|
||||
} catch (error) {
|
||||
ElMessage.error(readError(error, '充值失败'))
|
||||
@@ -51,6 +63,51 @@ async function handleRecharge() {
|
||||
}
|
||||
}
|
||||
|
||||
async function showRechargePaymentDialog(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 ElMessageBox.confirm(message, '支付充值', {
|
||||
confirmButtonText: payURL ? '打开/复制' : '刷新状态',
|
||||
cancelButtonText: '刷新状态',
|
||||
distinguishCancelAndClose: true,
|
||||
})
|
||||
.then(async () => {
|
||||
if (payURL) {
|
||||
await openOrCopyPayURL(payURL)
|
||||
}
|
||||
await refreshRechargePayment(payment.id)
|
||||
})
|
||||
.catch(async (action) => {
|
||||
if (action === 'cancel') {
|
||||
await refreshRechargePayment(payment.id)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
async function openOrCopyPayURL(payURL: string) {
|
||||
if (/^https?:\/\//.test(payURL)) {
|
||||
window.open(payURL, '_blank')
|
||||
return
|
||||
}
|
||||
try {
|
||||
await navigator.clipboard?.writeText(payURL)
|
||||
ElMessage.success('支付链接已复制')
|
||||
} catch {
|
||||
ElMessage.warning('请手动复制支付链接')
|
||||
}
|
||||
}
|
||||
|
||||
async function refreshRechargePayment(paymentID: number) {
|
||||
const payment = await queryWalletRechargePayment(paymentID)
|
||||
if (payment.paid) {
|
||||
ElMessage.success('充值成功')
|
||||
} else {
|
||||
ElMessage.info('支付未完成')
|
||||
}
|
||||
}
|
||||
|
||||
function readError(error: unknown, fallback: string) {
|
||||
if (typeof error === 'object' && error && 'response' in error) {
|
||||
const response = (error as { response?: { data?: { message?: string } } }).response
|
||||
@@ -84,9 +141,9 @@ function readError(error: unknown, fallback: string) {
|
||||
</div>
|
||||
|
||||
<div class="table-panel recharge-panel">
|
||||
<h2>开发充值</h2>
|
||||
<h2>支付充值</h2>
|
||||
<el-input-number v-model="rechargeAmount" :min="1" :precision="0" controls-position="right" />
|
||||
<el-button type="primary" :loading="recharging" @click="handleRecharge">充值</el-button>
|
||||
<el-button type="primary" :loading="recharging" @click="handleRecharge">发起充值</el-button>
|
||||
</div>
|
||||
|
||||
<el-table class="table-panel" :data="ledger">
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
<script setup lang="ts">
|
||||
import { onMounted, ref, computed } from "vue";
|
||||
import { useRouter, useRoute } from "vue-router";
|
||||
import { showToast } from "vant";
|
||||
import { showDialog, showToast } from "vant";
|
||||
import MobileBottomNav from "@/components/MobileBottomNav.vue";
|
||||
|
||||
import { fetchOrders, payOrder, type Order } from "@/api/orders";
|
||||
import { fetchOrders, payOrder, queryOrderPayment, type Order, type PaymentOrder } from "@/api/orders";
|
||||
import { useSessionStore } from "@/stores/session";
|
||||
import { formatDateMinute } from "@/utils/time";
|
||||
|
||||
@@ -75,8 +75,12 @@ function goDetail(id: number) {
|
||||
async function handlePay(order: Order) {
|
||||
payingOrderId.value = order.id;
|
||||
try {
|
||||
await payOrder(order.id);
|
||||
showToast({ message: "支付成功", icon: "passed" });
|
||||
const payment = await payOrder(order.id);
|
||||
if (payment.paid) {
|
||||
showToast({ message: "支付成功", icon: "passed" });
|
||||
} else {
|
||||
await showPaymentDialog(order, payment);
|
||||
}
|
||||
await loadOrders();
|
||||
} catch (error) {
|
||||
showToast({ message: readError(error, "支付失败"), icon: "cross" });
|
||||
@@ -85,6 +89,51 @@ async function handlePay(order: Order) {
|
||||
}
|
||||
}
|
||||
|
||||
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: "刷新状态",
|
||||
showCancelButton: true,
|
||||
})
|
||||
.then(async () => {
|
||||
if (payURL) {
|
||||
await openOrCopyPayURL(payURL);
|
||||
}
|
||||
await refreshPayment(order.id);
|
||||
})
|
||||
.catch(async () => {
|
||||
await refreshPayment(order.id);
|
||||
});
|
||||
}
|
||||
|
||||
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 readError(error: unknown, fallback: string) {
|
||||
if (typeof error === "object" && error && "response" in error) {
|
||||
const response = (error as { response?: { data?: { message?: string } } })
|
||||
|
||||
Reference in New Issue
Block a user