This commit is contained in:
@@ -17,6 +17,14 @@
|
||||
>
|
||||
重新申请
|
||||
</ElButton>
|
||||
<ElButton
|
||||
v-if="refund && canRecoverApproval(refund) && hasAuth('refund:detail')"
|
||||
type="warning"
|
||||
:loading="recoverApprovalLoading"
|
||||
@click="handleRecoverApproval"
|
||||
>
|
||||
恢复审批
|
||||
</ElButton>
|
||||
<template v-if="refund && canManualApproveRefund(refund)">
|
||||
<ElButton
|
||||
v-if="hasAuth('refund:approve')"
|
||||
@@ -173,7 +181,7 @@
|
||||
<script setup lang="ts">
|
||||
import { ref, onMounted, computed, h, reactive } from 'vue'
|
||||
import { useRoute, useRouter } from 'vue-router'
|
||||
import { ElButton, ElCard, ElIcon, ElMessage } from 'element-plus'
|
||||
import { ElButton, ElCard, ElIcon, ElMessage, ElMessageBox } from 'element-plus'
|
||||
import type { FormInstance, FormRules } from 'element-plus'
|
||||
import { ArrowLeft, Loading } from '@element-plus/icons-vue'
|
||||
import DetailPage from '@/components/common/DetailPage.vue'
|
||||
@@ -208,6 +216,7 @@
|
||||
const isRestrictedCustomerRole = computed(() => [3, 4].includes(Number(userStore.info.user_type)))
|
||||
|
||||
const loading = ref(false)
|
||||
const recoverApprovalLoading = ref(false)
|
||||
const refund = ref<Refund | null>(null)
|
||||
const refundVoucherFileKeys = ref<string[]>([])
|
||||
const approvalDialogVisible = ref(false)
|
||||
@@ -572,6 +581,20 @@
|
||||
label: '审批状态',
|
||||
formatter: (_, data) => getRefundApprovalStatusText(data)
|
||||
},
|
||||
{
|
||||
label: '审批提交状态',
|
||||
formatter: (_, data) => data.submission_status_name || '-'
|
||||
},
|
||||
{
|
||||
label: '审批失败摘要',
|
||||
formatter: (_, data) => data.approval_failure_summary || '-',
|
||||
fullWidth: true
|
||||
},
|
||||
{
|
||||
label: '最近恢复时间',
|
||||
formatter: (_, data) =>
|
||||
data.approval_last_recovery_at ? formatDateTime(data.approval_last_recovery_at) : '-'
|
||||
},
|
||||
...(!isRestrictedCustomerRole.value
|
||||
? [
|
||||
{
|
||||
@@ -707,6 +730,72 @@
|
||||
return canResubmitRefund(item)
|
||||
}
|
||||
|
||||
const canRecoverApproval = (item: Refund) => item.approval_recoverable === true
|
||||
|
||||
const isApprovalRecoveryConflict = (error: unknown, message = '') => {
|
||||
if (!error || typeof error !== 'object') {
|
||||
return message.includes('状态不允许恢复') || message.includes('不可恢复')
|
||||
}
|
||||
|
||||
const candidate = error as {
|
||||
code?: unknown
|
||||
response?: { status?: unknown; data?: { code?: unknown } }
|
||||
}
|
||||
const code = candidate.response?.data?.code ?? candidate.code
|
||||
const normalizedMessage = message || getErrorMessage(error, '')
|
||||
return (
|
||||
candidate.response?.status === 409 ||
|
||||
code === 'APPROVAL_RECOVERY_CONFLICT' ||
|
||||
code === 'REFUND_APPROVAL_NOT_RECOVERABLE' ||
|
||||
normalizedMessage.includes('状态不允许恢复') ||
|
||||
normalizedMessage.includes('不可恢复')
|
||||
)
|
||||
}
|
||||
|
||||
const handleRecoverApproval = async () => {
|
||||
if (!refund.value || !canRecoverApproval(refund.value) || recoverApprovalLoading.value) return
|
||||
|
||||
try {
|
||||
await ElMessageBox.confirm(
|
||||
`确定要恢复退款单号 ${refund.value.refund_no} 的原审批提交吗?`,
|
||||
'恢复审批',
|
||||
{
|
||||
confirmButtonText: '确定',
|
||||
cancelButtonText: '取消',
|
||||
type: 'warning'
|
||||
}
|
||||
)
|
||||
} catch {
|
||||
return
|
||||
}
|
||||
|
||||
recoverApprovalLoading.value = true
|
||||
try {
|
||||
const res = await RefundService.recoverApproval(refund.value.id)
|
||||
if (res.code !== 0) {
|
||||
if (isApprovalRecoveryConflict(res, res.msg || '')) {
|
||||
ElMessage.error('当前退款审批状态不允许恢复')
|
||||
await fetchRefundDetail(refund.value.id)
|
||||
return
|
||||
}
|
||||
ElMessage.error(res.msg || '恢复审批失败')
|
||||
return
|
||||
}
|
||||
ElMessage.success('恢复审批成功')
|
||||
await fetchRefundDetail(refund.value.id)
|
||||
} catch (error) {
|
||||
const message = getErrorMessage(error, '恢复审批失败')
|
||||
if (isApprovalRecoveryConflict(error, message)) {
|
||||
ElMessage.error('当前退款审批状态不允许恢复')
|
||||
await fetchRefundDetail(refund.value.id)
|
||||
} else {
|
||||
ElMessage.error(message)
|
||||
}
|
||||
} finally {
|
||||
recoverApprovalLoading.value = false
|
||||
}
|
||||
}
|
||||
|
||||
const handleShowResubmit = () => {
|
||||
if (!refund.value || !canResubmit(refund.value)) return
|
||||
resubmitForm.requested_refund_amount =
|
||||
|
||||
@@ -216,7 +216,7 @@
|
||||
getCurrentApproverSummaryText,
|
||||
getProcessingStatusText
|
||||
} from '@/utils/business/approvalSummary'
|
||||
import { toVoucherKeyList } from '@/utils/business'
|
||||
import { getErrorMessage, toVoucherKeyList } from '@/utils/business'
|
||||
import { RoutesAlias } from '@/router/routesAlias'
|
||||
import { AUDIT_PERMISSIONS } from '@/config/constants/audit'
|
||||
import {
|
||||
@@ -255,6 +255,7 @@
|
||||
const resubmitLoading = ref(false)
|
||||
const resubmitVoucherUploading = ref(false)
|
||||
const triggerApprovalLoading = ref(false)
|
||||
const recoverApprovalLoading = ref(false)
|
||||
const tableRef = ref()
|
||||
const resubmitUploadRef = ref<InstanceType<typeof VoucherUpload>>()
|
||||
const createDialogVisible = ref(false)
|
||||
@@ -380,6 +381,9 @@
|
||||
{ label: '审批渠道', prop: 'approval_provider' },
|
||||
{ label: '提交人', prop: 'submitter_name' },
|
||||
{ label: '审批状态', prop: 'approval_status' },
|
||||
{ label: '审批提交状态', prop: 'submission_status_name' },
|
||||
{ label: '审批失败摘要', prop: 'approval_failure_summary' },
|
||||
{ label: '最近恢复时间', prop: 'approval_last_recovery_at' },
|
||||
{ label: '当前审批人摘要', prop: 'current_approver_summary' },
|
||||
{ label: '业务处理状态', prop: 'processing_status_name' },
|
||||
{ label: '退款原因', prop: 'refund_reason' },
|
||||
@@ -628,6 +632,27 @@
|
||||
width: 120,
|
||||
formatter: (row: Refund) => row.approval_status_name || '-'
|
||||
},
|
||||
{
|
||||
prop: 'submission_status_name',
|
||||
label: '审批提交状态',
|
||||
width: 140,
|
||||
showOverflowTooltip: true,
|
||||
formatter: (row: Refund) => row.submission_status_name || '-'
|
||||
},
|
||||
{
|
||||
prop: 'approval_failure_summary',
|
||||
label: '审批失败摘要',
|
||||
minWidth: 200,
|
||||
showOverflowTooltip: true,
|
||||
formatter: (row: Refund) => row.approval_failure_summary || '-'
|
||||
},
|
||||
{
|
||||
prop: 'approval_last_recovery_at',
|
||||
label: '最近恢复时间',
|
||||
width: 180,
|
||||
formatter: (row: Refund) =>
|
||||
row.approval_last_recovery_at ? formatDateTime(row.approval_last_recovery_at) : '-'
|
||||
},
|
||||
{
|
||||
prop: 'current_approver_summary',
|
||||
label: '当前审批人摘要',
|
||||
@@ -926,6 +951,28 @@
|
||||
return row.status === RefundStatus.PENDING && approvalStatusEmpty
|
||||
}
|
||||
|
||||
const canRecoverApproval = (row: Refund) => row.approval_recoverable === true
|
||||
|
||||
const isApprovalRecoveryConflict = (error: unknown, message = '') => {
|
||||
if (!error || typeof error !== 'object') {
|
||||
return message.includes('状态不允许恢复') || message.includes('不可恢复')
|
||||
}
|
||||
|
||||
const candidate = error as {
|
||||
code?: unknown
|
||||
response?: { status?: unknown; data?: { code?: unknown; msg?: unknown } }
|
||||
}
|
||||
const code = candidate.response?.data?.code ?? candidate.code
|
||||
const normalizedMessage = message || getErrorMessage(error, '')
|
||||
return (
|
||||
candidate.response?.status === 409 ||
|
||||
code === 'APPROVAL_RECOVERY_CONFLICT' ||
|
||||
code === 'REFUND_APPROVAL_NOT_RECOVERABLE' ||
|
||||
normalizedMessage.includes('状态不允许恢复') ||
|
||||
normalizedMessage.includes('不可恢复')
|
||||
)
|
||||
}
|
||||
|
||||
// 补发历史退款审批
|
||||
const handleTriggerApproval = (row: Refund) => {
|
||||
if (triggerApprovalLoading.value) return
|
||||
@@ -957,6 +1004,47 @@
|
||||
})
|
||||
}
|
||||
|
||||
// 恢复退款原审批提交
|
||||
const handleRecoverApproval = (row: Refund) => {
|
||||
if (recoverApprovalLoading.value || !canRecoverApproval(row)) return
|
||||
|
||||
ElMessageBox.confirm(`确定要恢复退款单号 ${row.refund_no} 的原审批提交吗?`, '恢复审批', {
|
||||
confirmButtonText: '确定',
|
||||
cancelButtonText: '取消',
|
||||
type: 'warning'
|
||||
})
|
||||
.then(async () => {
|
||||
recoverApprovalLoading.value = true
|
||||
try {
|
||||
const res = await RefundService.recoverApproval(row.id)
|
||||
if (res.code !== 0) {
|
||||
if (isApprovalRecoveryConflict(res, res.msg || '')) {
|
||||
ElMessage.error('当前退款审批状态不允许恢复')
|
||||
await getTableData()
|
||||
return
|
||||
}
|
||||
ElMessage.error(res.msg || '恢复审批失败')
|
||||
return
|
||||
}
|
||||
ElMessage.success('恢复审批成功')
|
||||
await getTableData()
|
||||
} catch (error) {
|
||||
const message = getErrorMessage(error, '恢复审批失败')
|
||||
if (isApprovalRecoveryConflict(error, message)) {
|
||||
ElMessage.error('当前退款审批状态不允许恢复')
|
||||
await getTableData()
|
||||
} else {
|
||||
ElMessage.error(message)
|
||||
}
|
||||
} finally {
|
||||
recoverApprovalLoading.value = false
|
||||
}
|
||||
})
|
||||
.catch(() => {
|
||||
// 用户取消
|
||||
})
|
||||
}
|
||||
|
||||
// 获取操作按钮
|
||||
const getActions = (row: Refund) => {
|
||||
const actions: any[] = []
|
||||
@@ -1024,6 +1112,14 @@
|
||||
})
|
||||
}
|
||||
|
||||
if (canRecoverApproval(row) && hasAuth('refund:detail')) {
|
||||
actions.push({
|
||||
label: '恢复审批',
|
||||
handler: () => handleRecoverApproval(row),
|
||||
type: 'warning'
|
||||
})
|
||||
}
|
||||
|
||||
if (canManualApproveRefund(row) && hasAuth('refund:approve')) {
|
||||
actions.push({
|
||||
label: '通过',
|
||||
|
||||
Reference in New Issue
Block a user