feat: 退款企微审批详情与业务处理状态
All checks were successful
构建并部署前端到测试环境 / build-and-deploy (push) Successful in 7m2s
All checks were successful
构建并部署前端到测试环境 / build-and-deploy (push) Successful in 7m2s
This commit is contained in:
@@ -54,130 +54,10 @@
|
||||
@close="refundVoucherFileKeys = []"
|
||||
/>
|
||||
|
||||
<!-- 审批通过对话框 -->
|
||||
<ElDialog
|
||||
v-model="approveDialogVisible"
|
||||
title="审批通过"
|
||||
width="500px"
|
||||
@closed="handleApproveDialogClosed"
|
||||
>
|
||||
<ElForm
|
||||
ref="approveFormRef"
|
||||
:model="approveForm"
|
||||
:rules="approveRules"
|
||||
label-width="120px"
|
||||
>
|
||||
<ElFormItem label="退款单号">
|
||||
<span>{{ currentRefund?.refund_no }}</span>
|
||||
</ElFormItem>
|
||||
<ElFormItem label="申请退款金额">
|
||||
<span>{{ formatCurrency(currentRefund?.requested_refund_amount) }}</span>
|
||||
</ElFormItem>
|
||||
<ElFormItem label="实际退款金额" prop="approved_refund_amount">
|
||||
<ElInputNumber
|
||||
v-model="approveForm.approved_refund_amount"
|
||||
:min="0"
|
||||
:precision="2"
|
||||
:step="1"
|
||||
style="width: 100%"
|
||||
placeholder="不填则默认使用申请金额"
|
||||
/>
|
||||
<div style="margin-top: 8px; font-size: 12px; color: var(--el-text-color-secondary)">
|
||||
不填则默认使用申请金额
|
||||
</div>
|
||||
</ElFormItem>
|
||||
<ElFormItem label="审批备注">
|
||||
<ElInput
|
||||
v-model="approveForm.remark"
|
||||
type="textarea"
|
||||
:rows="3"
|
||||
maxlength="500"
|
||||
show-word-limit
|
||||
placeholder="请输入审批备注"
|
||||
/>
|
||||
</ElFormItem>
|
||||
</ElForm>
|
||||
<template #footer>
|
||||
<div class="dialog-footer">
|
||||
<ElButton @click="approveDialogVisible = false">取消</ElButton>
|
||||
<ElButton type="primary" @click="handleApproveRefund" :loading="approveLoading">
|
||||
确认通过
|
||||
</ElButton>
|
||||
</div>
|
||||
</template>
|
||||
</ElDialog>
|
||||
|
||||
<!-- 审批拒绝对话框 -->
|
||||
<ElDialog
|
||||
v-model="rejectDialogVisible"
|
||||
title="审批拒绝"
|
||||
width="500px"
|
||||
@closed="handleRejectDialogClosed"
|
||||
>
|
||||
<ElForm ref="rejectFormRef" :model="rejectForm" :rules="rejectRules" label-width="120px">
|
||||
<ElFormItem label="退款单号">
|
||||
<span>{{ currentRefund?.refund_no }}</span>
|
||||
</ElFormItem>
|
||||
<ElFormItem label="拒绝原因" prop="reject_reason">
|
||||
<ElInput
|
||||
v-model="rejectForm.reject_reason"
|
||||
type="textarea"
|
||||
:rows="3"
|
||||
maxlength="500"
|
||||
show-word-limit
|
||||
placeholder="请输入拒绝原因"
|
||||
/>
|
||||
</ElFormItem>
|
||||
</ElForm>
|
||||
<template #footer>
|
||||
<div class="dialog-footer">
|
||||
<ElButton @click="rejectDialogVisible = false">取消</ElButton>
|
||||
<ElButton type="danger" @click="handleRejectRefund" :loading="rejectLoading">
|
||||
确认拒绝
|
||||
</ElButton>
|
||||
</div>
|
||||
</template>
|
||||
</ElDialog>
|
||||
|
||||
<!-- 退回对话框 -->
|
||||
<ElDialog
|
||||
v-model="returnDialogVisible"
|
||||
title="驳回申请"
|
||||
width="30%"
|
||||
@closed="handleReturnDialogClosed"
|
||||
>
|
||||
<ElForm ref="returnFormRef" :model="returnForm" :rules="returnRules" label-width="80">
|
||||
<ElFormItem label="退款单号">
|
||||
<span>{{ currentRefund?.refund_no }}</span>
|
||||
</ElFormItem>
|
||||
<ElFormItem label="退回备注">
|
||||
<ElInput
|
||||
v-model="returnForm.remark"
|
||||
type="textarea"
|
||||
:rows="3"
|
||||
maxlength="500"
|
||||
show-word-limit
|
||||
placeholder="请输入退回备注"
|
||||
/>
|
||||
</ElFormItem>
|
||||
</ElForm>
|
||||
<div class="return-dialog-tip">
|
||||
驳回后该订单不可再申请退款,若还需申请退款点击审核拒绝。
|
||||
</div>
|
||||
<template #footer>
|
||||
<div class="dialog-footer">
|
||||
<ElButton @click="returnDialogVisible = false">取消</ElButton>
|
||||
<ElButton type="warning" @click="handleReturnRefund" :loading="returnLoading">
|
||||
确认退回
|
||||
</ElButton>
|
||||
</div>
|
||||
</template>
|
||||
</ElDialog>
|
||||
|
||||
<!-- 重新提交对话框 -->
|
||||
<ElDialog
|
||||
v-model="resubmitDialogVisible"
|
||||
title="重新提交退款申请"
|
||||
title="重新申请退款"
|
||||
width="500px"
|
||||
@closed="handleResubmitDialogClosed"
|
||||
>
|
||||
@@ -227,6 +107,7 @@
|
||||
voucher-name="退款凭证"
|
||||
@uploading-change="resubmitVoucherUploading = $event"
|
||||
@change="resubmitFormRef?.validateField('refund_voucher_key')"
|
||||
@files-change="resubmitForm.attachments = $event"
|
||||
/>
|
||||
</ElFormItem>
|
||||
</ElForm>
|
||||
@@ -239,7 +120,7 @@
|
||||
:loading="resubmitLoading || resubmitVoucherUploading"
|
||||
:disabled="resubmitVoucherUploading"
|
||||
>
|
||||
{{ resubmitVoucherUploading ? '凭证上传中...' : '确认提交' }}
|
||||
{{ resubmitVoucherUploading ? '凭证上传中...' : '确认申请' }}
|
||||
</ElButton>
|
||||
</div>
|
||||
</template>
|
||||
@@ -259,10 +140,8 @@
|
||||
Refund,
|
||||
RefundQueryParams,
|
||||
RefundStatus,
|
||||
ApproveRefundRequest,
|
||||
RejectRefundRequest,
|
||||
ReturnRefundRequest,
|
||||
ResubmitRefundRequest
|
||||
ResubmitRefundRequest,
|
||||
RefundAttachment
|
||||
} from '@/types/api'
|
||||
import type { SearchFormItem } from '@/types'
|
||||
import { useCheckedColumns } from '@/composables/useCheckedColumns'
|
||||
@@ -272,7 +151,7 @@
|
||||
getCurrentApproverSummaryText,
|
||||
getProcessingStatusText
|
||||
} from '@/utils/business/approvalSummary'
|
||||
import { hasVoucherKeys, toVoucherKeyList } from '@/utils/business'
|
||||
import { toVoucherKeyList } from '@/utils/business'
|
||||
import { RoutesAlias } from '@/router/routesAlias'
|
||||
import PaymentVoucherDialog from '@/components/business/PaymentVoucherDialog.vue'
|
||||
import VoucherUpload from '@/components/business/VoucherUpload.vue'
|
||||
@@ -286,17 +165,11 @@
|
||||
const { hasAuth } = useAuth()
|
||||
|
||||
const loading = ref(false)
|
||||
const approveLoading = ref(false)
|
||||
const rejectLoading = ref(false)
|
||||
const returnLoading = ref(false)
|
||||
const resubmitLoading = ref(false)
|
||||
const resubmitVoucherUploading = ref(false)
|
||||
const tableRef = ref()
|
||||
const resubmitUploadRef = ref<InstanceType<typeof VoucherUpload>>()
|
||||
const createDialogVisible = ref(false)
|
||||
const approveDialogVisible = ref(false)
|
||||
const rejectDialogVisible = ref(false)
|
||||
const returnDialogVisible = ref(false)
|
||||
const resubmitDialogVisible = ref(false)
|
||||
const currentRefund = ref<Refund | null>(null)
|
||||
const refundVoucherFileKeys = ref<string[]>([])
|
||||
@@ -409,43 +282,21 @@
|
||||
{ label: '审批时间', prop: 'processed_at' }
|
||||
]
|
||||
|
||||
const approveFormRef = ref<FormInstance>()
|
||||
const rejectFormRef = ref<FormInstance>()
|
||||
const returnFormRef = ref<FormInstance>()
|
||||
const resubmitFormRef = ref<FormInstance>()
|
||||
|
||||
const approveRules = reactive<FormRules>({})
|
||||
|
||||
const rejectRules = reactive<FormRules>({
|
||||
reject_reason: [{ required: true, message: '请输入拒绝原因', trigger: 'blur' }]
|
||||
})
|
||||
|
||||
const returnRules = reactive<FormRules>({})
|
||||
|
||||
const resubmitRules = reactive<FormRules>({})
|
||||
|
||||
const approveForm = reactive<ApproveRefundRequest>({
|
||||
approved_refund_amount: undefined,
|
||||
remark: ''
|
||||
})
|
||||
|
||||
const rejectForm = reactive<RejectRefundRequest>({
|
||||
reject_reason: ''
|
||||
})
|
||||
|
||||
const returnForm = reactive<ReturnRefundRequest>({
|
||||
remark: ''
|
||||
})
|
||||
|
||||
const resubmitForm = reactive<{
|
||||
requested_refund_amount?: number
|
||||
actual_received_amount?: number
|
||||
refund_voucher_key: string[]
|
||||
attachments: RefundAttachment[]
|
||||
refund_reason?: string
|
||||
}>({
|
||||
requested_refund_amount: undefined,
|
||||
actual_received_amount: undefined,
|
||||
refund_voucher_key: [],
|
||||
attachments: [],
|
||||
refund_reason: ''
|
||||
})
|
||||
|
||||
@@ -752,119 +603,6 @@
|
||||
getTableData()
|
||||
}
|
||||
|
||||
// 显示审批通过对话框
|
||||
const handleShowApprove = (row: Refund) => {
|
||||
currentRefund.value = row
|
||||
approveDialogVisible.value = true
|
||||
}
|
||||
|
||||
// 审批通过对话框关闭后的清理
|
||||
const handleApproveDialogClosed = () => {
|
||||
approveFormRef.value?.resetFields()
|
||||
approveForm.approved_refund_amount = undefined
|
||||
approveForm.remark = ''
|
||||
currentRefund.value = null
|
||||
}
|
||||
|
||||
// 审批通过
|
||||
const handleApproveRefund = async () => {
|
||||
if (!approveFormRef.value || !currentRefund.value) return
|
||||
|
||||
await approveFormRef.value.validate(async (valid) => {
|
||||
if (valid) {
|
||||
approveLoading.value = true
|
||||
try {
|
||||
const data: ApproveRefundRequest = {
|
||||
approved_refund_amount: yuanToFen(approveForm.approved_refund_amount),
|
||||
remark: approveForm.remark || undefined
|
||||
}
|
||||
const refundId = currentRefund.value?.id
|
||||
if (!refundId) return
|
||||
await RefundService.approveRefund(refundId, data)
|
||||
ElMessage.success('审批通过成功')
|
||||
approveDialogVisible.value = false
|
||||
await getTableData()
|
||||
} catch (error) {
|
||||
console.error(error)
|
||||
} finally {
|
||||
approveLoading.value = false
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
// 显示审批拒绝对话框
|
||||
const handleShowReject = (row: Refund) => {
|
||||
currentRefund.value = row
|
||||
rejectDialogVisible.value = true
|
||||
}
|
||||
|
||||
// 审批拒绝对话框关闭后的清理
|
||||
const handleRejectDialogClosed = () => {
|
||||
rejectFormRef.value?.resetFields()
|
||||
rejectForm.reject_reason = ''
|
||||
currentRefund.value = null
|
||||
}
|
||||
|
||||
// 审批拒绝
|
||||
const handleRejectRefund = async () => {
|
||||
if (!rejectFormRef.value || !currentRefund.value) return
|
||||
|
||||
await rejectFormRef.value.validate(async (valid) => {
|
||||
if (valid) {
|
||||
rejectLoading.value = true
|
||||
try {
|
||||
const refundId = currentRefund.value?.id
|
||||
if (!refundId) return
|
||||
await RefundService.rejectRefund(refundId, rejectForm)
|
||||
ElMessage.success('审批拒绝成功')
|
||||
rejectDialogVisible.value = false
|
||||
await getTableData()
|
||||
} catch (error) {
|
||||
console.error(error)
|
||||
} finally {
|
||||
rejectLoading.value = false
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
// 显示退回对话框
|
||||
const handleShowReturn = (row: Refund) => {
|
||||
currentRefund.value = row
|
||||
returnDialogVisible.value = true
|
||||
}
|
||||
|
||||
// 退回对话框关闭后的清理
|
||||
const handleReturnDialogClosed = () => {
|
||||
returnFormRef.value?.resetFields()
|
||||
returnForm.remark = ''
|
||||
currentRefund.value = null
|
||||
}
|
||||
|
||||
// 退回
|
||||
const handleReturnRefund = async () => {
|
||||
if (!returnFormRef.value || !currentRefund.value) return
|
||||
|
||||
await returnFormRef.value.validate(async (valid) => {
|
||||
if (valid) {
|
||||
returnLoading.value = true
|
||||
try {
|
||||
const refundId = currentRefund.value?.id
|
||||
if (!refundId) return
|
||||
await RefundService.returnRefund(refundId, returnForm)
|
||||
ElMessage.success('退回成功')
|
||||
returnDialogVisible.value = false
|
||||
await getTableData()
|
||||
} catch (error) {
|
||||
console.error(error)
|
||||
} finally {
|
||||
returnLoading.value = false
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
// 显示重新提交对话框
|
||||
const handleShowResubmit = (row: Refund) => {
|
||||
currentRefund.value = row
|
||||
@@ -872,6 +610,7 @@
|
||||
resubmitForm.requested_refund_amount = fenToYuan(row.requested_refund_amount) || undefined
|
||||
resubmitForm.actual_received_amount = fenToYuan(row.actual_received_amount) || undefined
|
||||
resubmitForm.refund_voucher_key = []
|
||||
resubmitForm.attachments = []
|
||||
resubmitForm.refund_reason = row.refund_reason
|
||||
resubmitDialogVisible.value = true
|
||||
}
|
||||
@@ -882,6 +621,7 @@
|
||||
resubmitForm.requested_refund_amount = undefined
|
||||
resubmitForm.actual_received_amount = undefined
|
||||
resubmitForm.refund_voucher_key = []
|
||||
resubmitForm.attachments = []
|
||||
resubmitForm.refund_reason = ''
|
||||
resubmitVoucherUploading.value = false
|
||||
resubmitUploadRef.value?.clearFiles(false)
|
||||
@@ -905,14 +645,12 @@
|
||||
const data: ResubmitRefundRequest = {
|
||||
requested_refund_amount: yuanToFen(resubmitForm.requested_refund_amount),
|
||||
actual_received_amount: yuanToFen(resubmitForm.actual_received_amount),
|
||||
refund_reason: resubmitForm.refund_reason || undefined
|
||||
}
|
||||
if (hasVoucherKeys(resubmitForm.refund_voucher_key)) {
|
||||
data.refund_voucher_key = toVoucherKeyList(resubmitForm.refund_voucher_key)
|
||||
refund_reason: resubmitForm.refund_reason || undefined,
|
||||
attachments: resubmitForm.attachments
|
||||
}
|
||||
|
||||
await RefundService.resubmitRefund(refundId, data)
|
||||
ElMessage.success('重新提交成功')
|
||||
ElMessage.success('重新申请成功')
|
||||
resubmitDialogVisible.value = false
|
||||
await getTableData()
|
||||
} catch (error) {
|
||||
@@ -940,43 +678,36 @@
|
||||
})
|
||||
}
|
||||
|
||||
const getRefundAttachmentKeys = (row: Refund) => {
|
||||
const keys = row.attachments?.map((attachment) => attachment.file_key).filter(Boolean) || []
|
||||
return keys.length ? keys : toVoucherKeyList(row.refund_voucher_key)
|
||||
}
|
||||
|
||||
const canResubmit = (row: Refund) => {
|
||||
const statusText = [row.approval_status, row.approval_status_name, row.status_name]
|
||||
.filter(Boolean)
|
||||
.join(' ')
|
||||
.toLowerCase()
|
||||
|
||||
return (
|
||||
row.status === 3 ||
|
||||
statusText.includes('reject') ||
|
||||
statusText.includes('revoke') ||
|
||||
statusText.includes('delete') ||
|
||||
statusText.includes('驳回') ||
|
||||
statusText.includes('撤销') ||
|
||||
statusText.includes('删除')
|
||||
)
|
||||
}
|
||||
|
||||
// 获取操作按钮
|
||||
const getActions = (row: Refund) => {
|
||||
const actions: any[] = []
|
||||
const voucherKeys = toVoucherKeyList(row.refund_voucher_key)
|
||||
const voucherKeys = getRefundAttachmentKeys(row)
|
||||
|
||||
// 待审批状态可以打回重填、审批通过或审批拒绝
|
||||
if (row.status === 1) {
|
||||
// 审批通过
|
||||
if (hasAuth('refund:approve')) {
|
||||
actions.push({
|
||||
label: '审批通过',
|
||||
handler: () => handleShowApprove(row),
|
||||
type: 'primary'
|
||||
})
|
||||
}
|
||||
// 审批拒绝
|
||||
if (hasAuth('refund:reject')) {
|
||||
actions.push({
|
||||
label: '审批拒绝',
|
||||
handler: () => handleShowReject(row),
|
||||
type: 'danger'
|
||||
})
|
||||
}
|
||||
// 驳回
|
||||
if (hasAuth('refund:return')) {
|
||||
actions.push({
|
||||
label: '驳回',
|
||||
handler: () => handleShowReturn(row),
|
||||
type: 'primary'
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
// 只有已退回状态可以重新提交
|
||||
if (row.status === 4 && hasAuth('refund:resubmit')) {
|
||||
if (canResubmit(row) && hasAuth('refund:resubmit')) {
|
||||
actions.push({
|
||||
label: '重新提交',
|
||||
label: '重新申请',
|
||||
handler: () => handleShowResubmit(row),
|
||||
type: 'primary'
|
||||
})
|
||||
@@ -994,22 +725,14 @@
|
||||
}
|
||||
|
||||
const handleViewRefundVoucher = (row: Refund) => {
|
||||
const voucherKey = row.refund_voucher_key
|
||||
if (!hasVoucherKeys(voucherKey)) return
|
||||
refundVoucherFileKeys.value = toVoucherKeyList(voucherKey)
|
||||
const voucherKeys = getRefundAttachmentKeys(row)
|
||||
if (!voucherKeys.length) return
|
||||
refundVoucherFileKeys.value = voucherKeys
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
.refund-page {
|
||||
height: 100%;
|
||||
|
||||
.return-dialog-tip {
|
||||
margin-top: 8px;
|
||||
font-size: 12px;
|
||||
line-height: 1.6;
|
||||
color: var(--el-color-primary);
|
||||
text-align: center;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
Reference in New Issue
Block a user