新增撞车订单人工退款

This commit is contained in:
yml2213
2026-07-31 21:57:35 +08:00
parent 8c2431c4f2
commit 9511b580e4
13 changed files with 516 additions and 20 deletions
@@ -1,16 +1,17 @@
<script setup lang="ts">
import { onMounted, ref } from 'vue'
import { ElMessage, ElMessageBox } from 'element-plus'
import { Refresh } from '@element-plus/icons-vue'
import { Money, Refresh } from '@element-plus/icons-vue'
import {
cancelAdminMohongOrder,
completeAdminMohongOrder,
fetchAdminMohongOrders,
mohongOrderStatusLabel,
receiveAdminMohongOrder,
refundAdminMohongOrder,
type MohongOrder,
} from '@/features/mohong/api/mohong'
import { formatCent } from '@/shared/utils/money'
import { centToYuan, formatCent, yuanToCent } from '@/shared/utils/money'
import { formatDateTime } from '@/shared/utils/time'
import { readError } from '@/shared/utils/error'
import AdminTablePagination from '../components/AdminTablePagination.vue'
@@ -23,6 +24,7 @@ const pageSize = ref(20)
const keyword = ref('')
const status = ref('')
const detail = ref<MohongOrder | null>(null)
const refundingId = ref<number | null>(null)
onMounted(load)
@@ -85,6 +87,38 @@ async function handleCancel(row: MohongOrder) {
}
}
async function handleRefund(row: MohongOrder) {
const defaultAmount = centToYuan(row.amount_cent).toFixed(2)
try {
const { value } = await ElMessageBox.prompt(
`请输入退款金额(元),默认全额 ¥${defaultAmount}`,
'人工退款',
{
inputValue: defaultAmount,
inputPlaceholder: defaultAmount,
confirmButtonText: '确认退款',
cancelButtonText: '返回',
type: 'warning',
inputValidator(input: string) {
const amount = Number(input)
if (!Number.isFinite(amount) || amount <= 0) return '请输入大于 0 的退款金额'
if (yuanToCent(amount) > row.amount_cent) return '退款金额不能超过订单金额'
return true
},
}
)
const amountCent = yuanToCent(Number(value))
refundingId.value = row.id
const result = await refundAdminMohongOrder(row.id, amountCent, '后台撞车订单人工退款')
ElMessage.success(result?.status === 'refunded' ? '退款成功' : '退款已提交')
await load()
} catch (error) {
if (error !== 'cancel') ElMessage.error(readError(error, '退款失败'))
} finally {
refundingId.value = null
}
}
function canReceive(row: MohongOrder) {
return row.status === 'paid'
}
@@ -99,6 +133,10 @@ function canCancel(row: MohongOrder) {
)
}
function canRefund(row: MohongOrder) {
return row.status === 'cancelled' && Boolean(row.paid_at) && Number(row.amount_cent || 0) > 0
}
async function copyText(text: string) {
try {
await navigator.clipboard.writeText(text)
@@ -127,6 +165,7 @@ async function copyText(text: string) {
<el-option label="接待中" value="receiving" />
<el-option label="已完成" value="completed" />
<el-option label="已取消" value="cancelled" />
<el-option label="已退款" value="refunded" />
</el-select>
<el-button type="primary" @click=";(page = 1), load()">查询</el-button>
</div>
@@ -150,7 +189,7 @@ async function copyText(text: string) {
<el-table-column label="下单时间" min-width="160">
<template #default="{ row }">{{ formatDateTime(row.created_at) }}</template>
</el-table-column>
<el-table-column label="操作" width="260" fixed="right">
<el-table-column label="操作" width="310" fixed="right">
<template #default="{ row }">
<el-button link type="primary" @click="detail = row">详情</el-button>
<el-button v-if="canReceive(row)" link type="warning" @click="handleReceive(row)">
@@ -162,6 +201,16 @@ async function copyText(text: string) {
<el-button v-if="canCancel(row)" link type="danger" @click="handleCancel(row)">
取消
</el-button>
<el-button
v-if="canRefund(row)"
link
type="warning"
:icon="Money"
:loading="refundingId === row.id"
@click="handleRefund(row)"
>
退款
</el-button>
</template>
</el-table-column>
</el-table>