This commit is contained in:
@@ -22,6 +22,14 @@
|
||||
</div>
|
||||
</ElCard>
|
||||
|
||||
<ElImageViewer
|
||||
v-if="voucherPreviewVisible"
|
||||
:url-list="refundVoucherUrls"
|
||||
:initial-index="voucherPreviewIndex"
|
||||
hide-on-click-modal
|
||||
@close="voucherPreviewVisible = false"
|
||||
/>
|
||||
|
||||
<!-- 审批通过对话框 -->
|
||||
<ElDialog
|
||||
v-model="approveDialogVisible"
|
||||
@@ -162,13 +170,13 @@
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { ref, onMounted, computed, h } from 'vue'
|
||||
import { ref, onMounted, computed, h, reactive } from 'vue'
|
||||
import { useRoute, useRouter } from 'vue-router'
|
||||
import { ElCard, ElButton, ElIcon, ElMessage, ElTag } from 'element-plus'
|
||||
import { ElCard, ElImageViewer, ElIcon, ElMessage, ElTag } from 'element-plus'
|
||||
import { ArrowLeft, Loading } from '@element-plus/icons-vue'
|
||||
import DetailPage from '@/components/common/DetailPage.vue'
|
||||
import type { DetailSection } from '@/components/common/DetailPage.vue'
|
||||
import { RefundService } from '@/api/modules'
|
||||
import { RefundService, StorageService } from '@/api/modules'
|
||||
import type {
|
||||
Refund,
|
||||
RefundStatus,
|
||||
@@ -177,7 +185,6 @@
|
||||
ResubmitRefundRequest
|
||||
} from '@/types/api'
|
||||
import { formatDateTime, yuanToFen } from '@/utils/business/format'
|
||||
import { RoutesAlias } from '@/router/routesAlias'
|
||||
|
||||
defineOptions({ name: 'RefundDetail' })
|
||||
|
||||
@@ -186,6 +193,9 @@
|
||||
|
||||
const loading = ref(false)
|
||||
const refund = ref<Refund | null>(null)
|
||||
const refundVoucherUrls = ref<string[]>([])
|
||||
const voucherPreviewVisible = ref(false)
|
||||
const voucherPreviewIndex = ref(0)
|
||||
|
||||
const pageTitle = computed(() => `退款详情`)
|
||||
|
||||
@@ -250,6 +260,14 @@
|
||||
return statusMap[status] || '-'
|
||||
}
|
||||
|
||||
const getVoucherKeys = (data: Refund): string[] => {
|
||||
const voucherKey = data.refund_voucher_key || ''
|
||||
return voucherKey
|
||||
.split(',')
|
||||
.map((key) => key.trim())
|
||||
.filter(Boolean)
|
||||
}
|
||||
|
||||
const detailSections = computed((): DetailSection[] => [
|
||||
{
|
||||
title: '退款信息',
|
||||
@@ -287,6 +305,24 @@
|
||||
render: (data) =>
|
||||
h(ElTag, { type: getStatusType(data.status) }, () => getStatusText(data.status))
|
||||
},
|
||||
{
|
||||
label: '退款凭证',
|
||||
fullWidth: true,
|
||||
render: () =>
|
||||
refundVoucherUrls.value.length
|
||||
? h(
|
||||
'div',
|
||||
{ class: 'refund-voucher-list' },
|
||||
refundVoucherUrls.value.map((url, index) =>
|
||||
h('img', {
|
||||
class: 'refund-voucher-image',
|
||||
src: url,
|
||||
onClick: () => handlePreviewRefundVoucher(index)
|
||||
})
|
||||
)
|
||||
)
|
||||
: h('span', '-')
|
||||
},
|
||||
{
|
||||
label: '资产重置',
|
||||
render: (data) =>
|
||||
@@ -354,6 +390,7 @@
|
||||
const res = await RefundService.getRefundById(id)
|
||||
if (res.code === 0) {
|
||||
refund.value = res.data
|
||||
await loadRefundVoucherUrls(res.data)
|
||||
}
|
||||
} catch (error) {
|
||||
console.error(error)
|
||||
@@ -367,6 +404,26 @@
|
||||
router.back()
|
||||
}
|
||||
|
||||
const loadRefundVoucherUrls = async (data: Refund) => {
|
||||
const fileKeys = getVoucherKeys(data)
|
||||
refundVoucherUrls.value = []
|
||||
if (!fileKeys.length) return
|
||||
|
||||
try {
|
||||
const res = await StorageService.batchDownloadUrls({ file_keys: fileKeys })
|
||||
if (res.code === 0) {
|
||||
refundVoucherUrls.value = fileKeys.map((key) => res.data.urls[key]).filter(Boolean)
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('获取退款凭证失败:', error)
|
||||
}
|
||||
}
|
||||
|
||||
const handlePreviewRefundVoucher = (index: number) => {
|
||||
voucherPreviewIndex.value = index
|
||||
voucherPreviewVisible.value = true
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
const id = route.params.id as string
|
||||
if (id) {
|
||||
@@ -395,7 +452,8 @@
|
||||
const handleApproveRefund = async () => {
|
||||
if (!approveFormRef.value || !refund.value) return
|
||||
|
||||
await approveFormRef.value.validate(async (valid) => {
|
||||
const refundId = refund.value.id
|
||||
await approveFormRef.value.validate(async (valid: boolean) => {
|
||||
if (valid) {
|
||||
approveLoading.value = true
|
||||
try {
|
||||
@@ -404,10 +462,10 @@
|
||||
remark: approveForm.remark || undefined
|
||||
}
|
||||
|
||||
await RefundService.approveRefund(refund.value.id, data)
|
||||
await RefundService.approveRefund(refundId, data)
|
||||
ElMessage.success('审批通过成功')
|
||||
approveDialogVisible.value = false
|
||||
await fetchRefundDetail(refund.value.id)
|
||||
await fetchRefundDetail(refundId)
|
||||
} catch (error) {
|
||||
console.error(error)
|
||||
} finally {
|
||||
@@ -420,14 +478,15 @@
|
||||
const handleRejectRefund = async () => {
|
||||
if (!rejectFormRef.value || !refund.value) return
|
||||
|
||||
await rejectFormRef.value.validate(async (valid) => {
|
||||
const refundId = refund.value.id
|
||||
await rejectFormRef.value.validate(async (valid: boolean) => {
|
||||
if (valid) {
|
||||
rejectLoading.value = true
|
||||
try {
|
||||
await RefundService.rejectRefund(refund.value.id, rejectForm)
|
||||
await RefundService.rejectRefund(refundId, rejectForm)
|
||||
ElMessage.success('审批拒绝成功')
|
||||
rejectDialogVisible.value = false
|
||||
await fetchRefundDetail(refund.value.id)
|
||||
await fetchRefundDetail(refundId)
|
||||
} catch (error) {
|
||||
console.error(error)
|
||||
} finally {
|
||||
@@ -440,7 +499,8 @@
|
||||
const handleResubmitRefund = async () => {
|
||||
if (!resubmitFormRef.value || !refund.value) return
|
||||
|
||||
await resubmitFormRef.value.validate(async (valid) => {
|
||||
const refundId = refund.value.id
|
||||
await resubmitFormRef.value.validate(async (valid: boolean) => {
|
||||
if (valid) {
|
||||
resubmitLoading.value = true
|
||||
try {
|
||||
@@ -450,10 +510,10 @@
|
||||
refund_reason: resubmitForm.refund_reason || undefined
|
||||
}
|
||||
|
||||
await RefundService.resubmitRefund(refund.value.id, data)
|
||||
await RefundService.resubmitRefund(refundId, data)
|
||||
ElMessage.success('重新提交成功')
|
||||
resubmitDialogVisible.value = false
|
||||
await fetchRefundDetail(refund.value.id)
|
||||
await fetchRefundDetail(refundId)
|
||||
} catch (error) {
|
||||
console.error(error)
|
||||
} finally {
|
||||
@@ -495,5 +555,21 @@
|
||||
font-size: 32px;
|
||||
}
|
||||
}
|
||||
|
||||
:deep(.refund-voucher-list) {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
gap: 12px;
|
||||
line-height: 1;
|
||||
}
|
||||
|
||||
:deep(.refund-voucher-image) {
|
||||
width: 96px;
|
||||
height: 96px;
|
||||
cursor: zoom-in;
|
||||
object-fit: cover;
|
||||
border: 1px solid var(--el-border-color);
|
||||
border-radius: 6px;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -36,7 +36,7 @@
|
||||
:marginTop="10"
|
||||
:actions="getActions"
|
||||
:actionsWidth="220"
|
||||
:inlineActionsCount="3"
|
||||
:inlineActionsCount="2"
|
||||
@size-change="handleSizeChange"
|
||||
@current-change="handleCurrentChange"
|
||||
>
|
||||
@@ -48,6 +48,9 @@
|
||||
<!-- 创建退款申请对话框 -->
|
||||
<CreateRefundDialog v-model="createDialogVisible" @success="handleCreateSuccess" />
|
||||
|
||||
<!-- 退款凭证预览 -->
|
||||
<PaymentVoucherDialog :file-key="refundVoucherFileKey" @close="refundVoucherFileKey = ''" />
|
||||
|
||||
<!-- 审批通过对话框 -->
|
||||
<ElDialog
|
||||
v-model="approveDialogVisible"
|
||||
@@ -248,6 +251,7 @@
|
||||
import { useCheckedColumns } from '@/composables/useCheckedColumns'
|
||||
import { fenToYuan, formatDateTime, yuanToFen } from '@/utils/business/format'
|
||||
import { RoutesAlias } from '@/router/routesAlias'
|
||||
import PaymentVoucherDialog from '@/components/business/PaymentVoucherDialog.vue'
|
||||
|
||||
import { useAuth } from '@/composables/useAuth'
|
||||
|
||||
@@ -269,6 +273,7 @@
|
||||
const returnDialogVisible = ref(false)
|
||||
const resubmitDialogVisible = ref(false)
|
||||
const currentRefund = ref<Refund | null>(null)
|
||||
const refundVoucherFileKey = ref('')
|
||||
|
||||
// 搜索表单初始值
|
||||
const initialSearchState: RefundQueryParams = {
|
||||
@@ -364,7 +369,6 @@
|
||||
{ label: '审批时间', prop: 'processed_at' }
|
||||
]
|
||||
|
||||
const createFormRef = ref<FormInstance>()
|
||||
const approveFormRef = ref<FormInstance>()
|
||||
const rejectFormRef = ref<FormInstance>()
|
||||
const returnFormRef = ref<FormInstance>()
|
||||
@@ -856,6 +860,7 @@
|
||||
// 获取操作按钮
|
||||
const getActions = (row: Refund) => {
|
||||
const actions: any[] = []
|
||||
const voucherKey = row.refund_voucher_key
|
||||
|
||||
// 待审批状态可以打回重填、审批通过或审批拒绝
|
||||
if (row.status === 1) {
|
||||
@@ -894,8 +899,22 @@
|
||||
})
|
||||
}
|
||||
|
||||
if (voucherKey && hasAuth('refund:view_voucher')) {
|
||||
actions.push({
|
||||
label: '查看退款凭证',
|
||||
handler: () => handleViewRefundVoucher(row),
|
||||
type: 'primary'
|
||||
})
|
||||
}
|
||||
|
||||
return actions
|
||||
}
|
||||
|
||||
const handleViewRefundVoucher = (row: Refund) => {
|
||||
const voucherKey = row.refund_voucher_key
|
||||
if (!voucherKey) return
|
||||
refundVoucherFileKey.value = voucherKey
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
|
||||
Reference in New Issue
Block a user