feat(web-admin): payment-info 缴费明细 dialog with list-mode transfers
Open sample-level detail from the list; manage transfers like SamplePaymentPanel; remove direct PaymentReceiptConfirmDialog path. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
1 parent
ea5fba9dc2
commit
842aa0847f
2 files changed
+846
-102
No files matched your search
@@ -169,11 +169,11 @@
|
||||
<el-icon><Document /></el-icon>协议单
|
||||
</el-button>
|
||||
<el-button
|
||||
v-if="row.canConfirm"
|
||||
class="btn-op-item primary"
|
||||
@click="handleConfirm(row)"
|
||||
:disabled="!row.id"
|
||||
@click="handleOpenDetail(row)"
|
||||
>
|
||||
<el-icon><Check /></el-icon>缴费确认
|
||||
<el-icon><List /></el-icon>缴费明细
|
||||
</el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
@@ -253,25 +253,13 @@
|
||||
<el-button class="btn-ghost" @click="periodDialogVisible = false">
|
||||
<el-icon><Close /></el-icon>关闭
|
||||
</el-button>
|
||||
<el-button
|
||||
v-if="periodCanConfirm"
|
||||
class="btn-main"
|
||||
type="primary"
|
||||
:loading="confirming"
|
||||
@click="openConfirmFromPeriod"
|
||||
>
|
||||
<el-icon><Check /></el-icon>缴费确认
|
||||
</el-button>
|
||||
</template>
|
||||
</el-dialog>
|
||||
|
||||
<PaymentReceiptConfirmDialog
|
||||
v-model="receiptDialogVisible"
|
||||
:preview-row="receiptPreviewRow"
|
||||
:is-transfer="true"
|
||||
:target-id="receiptTargetId"
|
||||
@saved="onReceiptRefresh"
|
||||
@submitted="onReceiptRefresh"
|
||||
<SamplePaymentDetailDialog
|
||||
v-model="detailVisible"
|
||||
:sample-payment-id="detailSamplePaymentId"
|
||||
@changed="loadData"
|
||||
/>
|
||||
|
||||
<el-dialog
|
||||
@@ -303,16 +291,12 @@
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { Search, RefreshLeft, Check, Document, Close } from '@element-plus/icons-vue'
|
||||
import { Search, RefreshLeft, Document, Close, List } from '@element-plus/icons-vue'
|
||||
import ProtocolViewDialog from '../protocol/ProtocolViewDialog.vue'
|
||||
import ProtocolAttachmentReadonly from '../protocol/ProtocolAttachmentReadonly.vue'
|
||||
import PaymentReceiptConfirmDialog from '@/components/business/payment-receipt-confirm-dialog/index.vue'
|
||||
import SamplePaymentDetailDialog from '@/components/business/sample-payment-detail-dialog/index.vue'
|
||||
import { downloadAttachmentFile } from '@/utils/download-attachment'
|
||||
import {
|
||||
fetchSamplePaymentList,
|
||||
fetchSamplePaymentDetail,
|
||||
fetchCreatePaymentTransfer
|
||||
} from '@/api/protocol-sample-payment'
|
||||
import { fetchSamplePaymentList, fetchSamplePaymentDetail } from '@/api/protocol-sample-payment'
|
||||
import { type CollectionProtocolRow } from '@/api/collection-protocol'
|
||||
import { formatDisplayOrDash } from '@/utils/datetime-display'
|
||||
import { formatMoneyDisplay } from '@/utils/money-format'
|
||||
@@ -366,14 +350,9 @@
|
||||
arrearsAmount: null as number | null
|
||||
})
|
||||
const periodTransfers = ref<Record<string, any>[]>([])
|
||||
const periodCanConfirm = ref(false)
|
||||
const periodSchedule = ref<Record<string, any> | null>(null)
|
||||
const periodSamplePaymentId = ref('')
|
||||
const confirming = ref(false)
|
||||
|
||||
const receiptDialogVisible = ref(false)
|
||||
const receiptPreviewRow = ref<Record<string, any> | null>(null)
|
||||
const receiptTargetId = ref('')
|
||||
const detailVisible = ref(false)
|
||||
const detailSamplePaymentId = ref('')
|
||||
|
||||
const protocolVisible = ref(false)
|
||||
const protocolViewId = ref('')
|
||||
@@ -513,93 +492,32 @@
|
||||
async function openPeriodDialog(row: Record<string, any>, idx: number) {
|
||||
const cell = periodRaw(row, idx)
|
||||
if (!cell?.scheduleId) return
|
||||
periodSamplePaymentId.value = String(row.id || '')
|
||||
periodDialogTitle.value = `${row.motherName || ''} · ${row.protocolNo || ''} · 第 ${idx + 1} 期转账记录`
|
||||
periodDialogVisible.value = true
|
||||
periodLoading.value = true
|
||||
periodTransfers.value = []
|
||||
periodCanConfirm.value = false
|
||||
periodSchedule.value = null
|
||||
try {
|
||||
const detail = await fetchSamplePaymentDetail(String(row.id))
|
||||
const schedules = ((detail.schedules as any[]) || []) as Record<string, any>[]
|
||||
const sch = schedules.find((s) => String(s.id) === String(cell.scheduleId))
|
||||
periodSchedule.value = sch || null
|
||||
periodSummary.dueAmount = sch?.dueAmount ?? cell.dueAmount ?? null
|
||||
// 列表 displayPaidAmount / arrearsAmount 与详情 paidAmount 已对齐(含 dfj+jfqrz+yjf)
|
||||
periodSummary.paidAmount =
|
||||
sch?.paidAmount ?? cell.displayPaidAmount ?? null
|
||||
periodSummary.arrearsAmount =
|
||||
sch?.arrearsAmount ?? cell.arrearsAmount ?? null
|
||||
periodSummary.paidAmount = sch?.paidAmount ?? cell.displayPaidAmount ?? null
|
||||
periodSummary.arrearsAmount = sch?.arrearsAmount ?? cell.arrearsAmount ?? null
|
||||
periodTransfers.value = (sch?.transfers || []) as Record<string, any>[]
|
||||
const hasJfqrz = periodTransfers.value.some((t) => String(t.payStatus) === 'jfqrz')
|
||||
const arrears = Number(periodSummary.arrearsAmount)
|
||||
periodCanConfirm.value = !hasJfqrz && Number.isFinite(arrears) && arrears > 0
|
||||
} finally {
|
||||
periodLoading.value = false
|
||||
}
|
||||
}
|
||||
|
||||
async function openConfirmFromPeriod() {
|
||||
const schedule = periodSchedule.value
|
||||
if (!schedule?.id) return
|
||||
confirming.value = true
|
||||
try {
|
||||
const transfers = (schedule.transfers || []) as Record<string, any>[]
|
||||
const dfj = transfers.find((t) => String(t.payStatus) === 'dfj')
|
||||
let transferId = dfj?.id ? String(dfj.id) : ''
|
||||
if (!transferId) {
|
||||
const arrears = Number(schedule.arrearsAmount)
|
||||
const due = Number(schedule.dueAmount)
|
||||
const amount = arrears > 0 ? arrears : due
|
||||
const created = await fetchCreatePaymentTransfer({
|
||||
scheduleId: String(schedule.id),
|
||||
transferAmount: amount
|
||||
})
|
||||
transferId = String((created as any)?.id || (created as any)?.data?.id || '')
|
||||
if (!transferId) {
|
||||
ElMessage.error('创建转账笔失败')
|
||||
return
|
||||
}
|
||||
}
|
||||
receiptTargetId.value = transferId
|
||||
receiptPreviewRow.value = {
|
||||
motherName: periodDialogTitle.value,
|
||||
installmentNo: schedule.scheduleNo,
|
||||
dueAmount: schedule.dueAmount,
|
||||
installmentDueDate: schedule.dueDate,
|
||||
scheduleId: schedule.id,
|
||||
transferAmount: schedule.arrearsAmount || schedule.dueAmount
|
||||
}
|
||||
receiptDialogVisible.value = true
|
||||
periodDialogVisible.value = false
|
||||
} finally {
|
||||
confirming.value = false
|
||||
}
|
||||
}
|
||||
|
||||
async function handleConfirm(row: Record<string, any>) {
|
||||
const detail = await fetchSamplePaymentDetail(String(row.id))
|
||||
const schedules = ((detail.schedules as any[]) || []) as Record<string, any>[]
|
||||
const target = [...schedules]
|
||||
.sort((a, b) => Number(a.scheduleNo || 0) - Number(b.scheduleNo || 0))
|
||||
.find((s) => {
|
||||
const transfers = (s.transfers || []) as any[]
|
||||
if (transfers.some((t) => String(t.payStatus) === 'jfqrz')) return false
|
||||
return Number(s.arrearsAmount) > 0
|
||||
})
|
||||
if (!target) {
|
||||
ElMessage.warning('暂无可确认的期次')
|
||||
function handleOpenDetail(row: Record<string, any>) {
|
||||
const id = String(row.id || '')
|
||||
if (!id) {
|
||||
ElMessage.warning('缺少缴费方案,无法查看明细')
|
||||
return
|
||||
}
|
||||
periodSamplePaymentId.value = String(row.id)
|
||||
periodSchedule.value = target
|
||||
periodDialogTitle.value = `${row.motherName || ''} · ${row.protocolNo || ''} · 第 ${target.scheduleNo} 期`
|
||||
await openConfirmFromPeriod()
|
||||
}
|
||||
|
||||
function onReceiptRefresh() {
|
||||
loadData()
|
||||
detailSamplePaymentId.value = id
|
||||
detailVisible.value = true
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
|
||||
Reference in new issue
Block a user