新增撞车订单人工退款

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>
@@ -26,7 +26,7 @@ const filters = reactive({
const payAmount = computed(() =>
payments.value
.filter(item => item.biz_type === 'order_pay')
.filter(item => item.biz_type === 'order_pay' || item.biz_type === 'mohong_pay')
.reduce((sum, item) => sum + Number(item.amount_cent || 0), 0)
)
const refundAmount = computed(() =>
@@ -104,6 +104,8 @@ function bizTypeLabel(type: string) {
deposit_refund: '押金退款',
rent_refund: '租金退款',
arbitration_refund: '仲裁退款',
mohong_pay: '撞车支付',
mohong_refund: '撞车退款',
}
return map[type] || type
}
@@ -167,10 +169,12 @@ function jsonText(value: unknown) {
<el-form-item label="业务类型">
<el-select v-model="filters.biz_type" clearable placeholder="全部业务" class="full-control">
<el-option label="订单支付" value="order_pay" />
<el-option label="撞车支付" value="mohong_pay" />
<el-option label="结账退款" value="checkout_refund" />
<el-option label="仲裁退款" value="arbitration_refund" />
<el-option label="人工退款" value="admin_refund" />
<el-option label="取消退款" value="cancel_refund" />
<el-option label="撞车退款" value="mohong_refund" />
</el-select>
</el-form-item>
<el-form-item label="状态">