修改 付款 收款 和认领页面
This commit is contained in:
@@ -71,4 +71,11 @@ export class financeService {
|
||||
params
|
||||
})
|
||||
}
|
||||
// 绑定付款记录到收款记录
|
||||
static bindPaymentRecord(params:any) {
|
||||
return request.post<Api.Common.AddResponse>({
|
||||
url: '/admin/receipt/payment',
|
||||
params
|
||||
})
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,346 @@
|
||||
<template>
|
||||
<el-dialog
|
||||
v-model="visible"
|
||||
title="付款记录详情"
|
||||
width="800px"
|
||||
:close-on-click-modal="false"
|
||||
@close="handleClose"
|
||||
>
|
||||
<div class="payment-detail-dialog" v-loading="loading">
|
||||
<div v-if="paymentData" class="detail-content">
|
||||
<!-- 基本信息 -->
|
||||
<div class="section">
|
||||
<div class="section-title">
|
||||
<span class="border"></span>
|
||||
<span class="title">基本信息</span>
|
||||
</div>
|
||||
<div class="info-grid">
|
||||
<div class="info-item">
|
||||
<label>创建日期:</label>
|
||||
<span>{{ formatDate(paymentData.created_at) }}</span>
|
||||
</div>
|
||||
<div class="info-item">
|
||||
<label>付款来源:</label>
|
||||
<span>{{ paymentData.country_name || '—' }}</span>
|
||||
</div>
|
||||
<div class="info-item">
|
||||
<label>汇款人:</label>
|
||||
<span>{{ paymentData.remitter || '—' }}</span>
|
||||
</div>
|
||||
<div class="info-item">
|
||||
<label>账户:</label>
|
||||
<span>{{ paymentData.account_name || '—' }}</span>
|
||||
</div>
|
||||
<div class="info-item">
|
||||
<label>币种:</label>
|
||||
<span>{{ paymentData.currency_name || '—' }}</span>
|
||||
</div>
|
||||
<div class="info-item">
|
||||
<label>金额:</label>
|
||||
<span class="amount">{{ formatAmount(paymentData.amount, paymentData.currency_name) }}</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 关联信息 -->
|
||||
<div class="section" v-if="paymentData.payment_apply_id">
|
||||
<div class="section-title">
|
||||
<span class="border"></span>
|
||||
<span class="title">关联信息</span>
|
||||
</div>
|
||||
<div class="info-grid">
|
||||
<div class="info-item">
|
||||
<label>付款申请ID:</label>
|
||||
<span>{{ paymentData.payment_apply_id }}</span>
|
||||
</div>
|
||||
<div class="info-item">
|
||||
<label>关联状态:</label>
|
||||
<el-tag :type="getStatusType(paymentData.status)">
|
||||
{{ getStatusText(paymentData.status) }}
|
||||
</el-tag>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 收款记录关联 -->
|
||||
<div class="section" v-if="paymentData.receipt_records && paymentData.receipt_records.length">
|
||||
<div class="section-title">
|
||||
<span class="border"></span>
|
||||
<span class="title">关联收款记录</span>
|
||||
</div>
|
||||
<el-table :data="paymentData.receipt_records" style="margin-top: 12px">
|
||||
<el-table-column label="收款记录ID" prop="id" min-width="120" />
|
||||
<el-table-column label="创建日期" prop="created_at" min-width="140">
|
||||
<template #default="scope">
|
||||
{{ formatDate(scope.row.created_at) }}
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="金额" prop="amount" min-width="120">
|
||||
<template #default="scope">
|
||||
{{ formatAmount(scope.row.amount, scope.row.currency_name) }}
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="状态" prop="status" min-width="100">
|
||||
<template #default="scope">
|
||||
<el-tag :type="getStatusType(scope.row.status)">
|
||||
{{ getStatusText(scope.row.status) }}
|
||||
</el-tag>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
</div>
|
||||
|
||||
<!-- 备注信息 -->
|
||||
<div class="section" v-if="paymentData.remark">
|
||||
<div class="section-title">
|
||||
<span class="border"></span>
|
||||
<span class="title">备注信息</span>
|
||||
</div>
|
||||
<div class="remark-content">
|
||||
{{ paymentData.remark }}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 无数据状态 -->
|
||||
<div v-else-if="!loading" class="no-data">
|
||||
<i class="iconfont-sys"></i>
|
||||
<span>暂无数据</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<template #footer>
|
||||
<div class="dialog-footer">
|
||||
<el-button @click="handleClose">关闭</el-button>
|
||||
</div>
|
||||
</template>
|
||||
</el-dialog>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { financeService } from '@/api/admin/finance'
|
||||
|
||||
interface PaymentRecord {
|
||||
id: string | number
|
||||
created_at: string
|
||||
country_name: string
|
||||
remitter: string
|
||||
account_name: string
|
||||
currency_name: string
|
||||
amount: number
|
||||
status: string
|
||||
payment_apply_id?: string | number
|
||||
receipt_records?: any[]
|
||||
remark?: string
|
||||
}
|
||||
|
||||
interface Props {
|
||||
modelValue: boolean
|
||||
paymentId?: string | number
|
||||
}
|
||||
|
||||
interface Emits {
|
||||
(e: 'update:modelValue', value: boolean): void
|
||||
}
|
||||
|
||||
const props = defineProps<Props>()
|
||||
const emit = defineEmits<Emits>()
|
||||
|
||||
const visible = computed({
|
||||
get: () => props.modelValue,
|
||||
set: (value) => emit('update:modelValue', value)
|
||||
})
|
||||
|
||||
const loading = ref(false)
|
||||
const paymentData = ref<PaymentRecord | null>(null)
|
||||
|
||||
// 获取付款记录详情
|
||||
const getPaymentDetail = async () => {
|
||||
if (!props.paymentId) return
|
||||
|
||||
loading.value = true
|
||||
try {
|
||||
const res = await financeService.getPaymentDetail({ id: props.paymentId })
|
||||
paymentData.value = res
|
||||
} catch (error) {
|
||||
console.error('获取付款记录详情失败:', error)
|
||||
paymentData.value = null
|
||||
} finally {
|
||||
loading.value = false
|
||||
}
|
||||
}
|
||||
|
||||
// 关闭对话框
|
||||
const handleClose = () => {
|
||||
visible.value = false
|
||||
paymentData.value = null
|
||||
}
|
||||
|
||||
// 打印功能
|
||||
const handlePrint = () => {
|
||||
window.print()
|
||||
}
|
||||
|
||||
// 格式化日期
|
||||
const formatDate = (dateStr: string) => {
|
||||
if (!dateStr) return '—'
|
||||
try {
|
||||
return new Date(dateStr).toLocaleString('zh-CN')
|
||||
} catch {
|
||||
return dateStr
|
||||
}
|
||||
}
|
||||
|
||||
// 格式化金额
|
||||
const formatAmount = (amount: number, currency: string) => {
|
||||
return `${currency || ''} ${amount?.toLocaleString() || 0}`
|
||||
}
|
||||
|
||||
// 获取状态类型
|
||||
const getStatusType = (status: string) => {
|
||||
const statusMap: Record<string, string> = {
|
||||
'available': 'success',
|
||||
'used': 'info',
|
||||
'pending': 'warning',
|
||||
'cancelled': 'danger',
|
||||
'bound': 'success',
|
||||
'unbound': 'info'
|
||||
}
|
||||
return statusMap[status] || 'info'
|
||||
}
|
||||
|
||||
// 获取状态文本
|
||||
const getStatusText = (status: string) => {
|
||||
const statusMap: Record<string, string> = {
|
||||
'available': '可用',
|
||||
'used': '已使用',
|
||||
'pending': '待处理',
|
||||
'cancelled': '已取消',
|
||||
'bound': '已绑定',
|
||||
'unbound': '未绑定'
|
||||
}
|
||||
return statusMap[status] || status
|
||||
}
|
||||
|
||||
// 监听对话框显示状态
|
||||
watch(visible, (newVal) => {
|
||||
if (newVal && props.paymentId) {
|
||||
getPaymentDetail()
|
||||
}
|
||||
})
|
||||
|
||||
// 监听付款ID变化
|
||||
watch(() => props.paymentId, (newId) => {
|
||||
if (visible.value && newId) {
|
||||
getPaymentDetail()
|
||||
}
|
||||
})
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
.payment-detail-dialog {
|
||||
.detail-content {
|
||||
.section {
|
||||
margin-bottom: 24px;
|
||||
|
||||
&:last-child {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
.section-title {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
margin-bottom: 16px;
|
||||
font-weight: 600;
|
||||
color: #222;
|
||||
|
||||
.border {
|
||||
width: 4px;
|
||||
height: 16px;
|
||||
background: #3d7bff;
|
||||
margin-right: 8px;
|
||||
border-radius: 2px;
|
||||
}
|
||||
|
||||
.title {
|
||||
font-size: 16px;
|
||||
}
|
||||
}
|
||||
|
||||
.info-grid {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
|
||||
gap: 16px;
|
||||
|
||||
.info-item {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
padding: 8px 0;
|
||||
|
||||
label {
|
||||
font-weight: 500;
|
||||
color: #666;
|
||||
min-width: 100px;
|
||||
margin-right: 8px;
|
||||
}
|
||||
|
||||
span {
|
||||
color: #333;
|
||||
flex: 1;
|
||||
|
||||
&.amount {
|
||||
font-weight: 600;
|
||||
color: #3d7bff;
|
||||
font-size: 16px;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.remark-content {
|
||||
padding: 12px;
|
||||
background: #f8f9fa;
|
||||
border-radius: 6px;
|
||||
color: #666;
|
||||
line-height: 1.6;
|
||||
min-height: 60px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.no-data {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
padding: 60px 0;
|
||||
color: #999;
|
||||
|
||||
i {
|
||||
font-size: 48px;
|
||||
margin-bottom: 12px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.dialog-footer {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
gap: 12px;
|
||||
}
|
||||
|
||||
// 打印样式
|
||||
@media print {
|
||||
.dialog-footer {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.payment-detail-dialog {
|
||||
.section-title {
|
||||
.border {
|
||||
background: #000 !important;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,260 @@
|
||||
<template>
|
||||
<el-dialog
|
||||
v-model="visible"
|
||||
title="选择付款记录"
|
||||
width="80%"
|
||||
:close-on-click-modal="false"
|
||||
@close="handleClose"
|
||||
>
|
||||
<div class="payment-record-dialog">
|
||||
<!-- 搜索栏 -->
|
||||
<div class="search-bar">
|
||||
<el-input
|
||||
v-model="searchKeyword"
|
||||
placeholder="请输入汇款人、账户或金额"
|
||||
clearable
|
||||
style="width: 300px"
|
||||
@keyup.enter="getPaymentRecords"
|
||||
>
|
||||
<template #suffix>
|
||||
<el-icon class="clickable" @click="getPaymentRecords"><Search /></el-icon>
|
||||
</template>
|
||||
</el-input>
|
||||
<el-button type="primary" @click="getPaymentRecords">搜索</el-button>
|
||||
</div>
|
||||
|
||||
<!-- 付款记录表格 -->
|
||||
<el-table
|
||||
ref="tableRef"
|
||||
:data="paymentRecords"
|
||||
:loading="loading"
|
||||
row-key="id"
|
||||
@selection-change="handleSelectionChange"
|
||||
@row-click="handleRowClick"
|
||||
highlight-current-row
|
||||
style="margin-top: 16px"
|
||||
>
|
||||
<el-table-column type="radio" width="55">
|
||||
<template #default="scope">
|
||||
<el-radio
|
||||
v-model="selectedRecordId"
|
||||
:value="scope.row.id"
|
||||
@change="handleRadioChange(scope.row)"
|
||||
/>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="创建日期" prop="created_at" min-width="160" />
|
||||
<el-table-column label="付款来源" prop="country_name" min-width="120" />
|
||||
<el-table-column label="汇款人" prop="remitter" min-width="120" />
|
||||
<el-table-column label="账户" prop="account_name" min-width="120" />
|
||||
<el-table-column label="账币" prop="currency_name" min-width="120" />
|
||||
<el-table-column label="金额" prop="amount" min-width="120">
|
||||
<template #default="scope">
|
||||
{{ formatAmount(scope.row.amount, scope.row.currency_name) }}
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
|
||||
<!-- 分页 -->
|
||||
<div class="pagination-wrapper">
|
||||
<el-pagination
|
||||
v-model:current-page="pagination.currentPage"
|
||||
v-model:page-size="pagination.pageSize"
|
||||
:total="pagination.total"
|
||||
:page-sizes="[10, 20, 50, 100]"
|
||||
layout="total, sizes, prev, pager, next, jumper"
|
||||
@size-change="handleSizeChange"
|
||||
@current-change="handleCurrentChange"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<template #footer>
|
||||
<div class="dialog-footer">
|
||||
<el-button @click="handleClose">取消</el-button>
|
||||
<el-button type="primary" :disabled="!selectedRecord" @click="handleConfirm">
|
||||
确认绑定
|
||||
</el-button>
|
||||
</div>
|
||||
</template>
|
||||
</el-dialog>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { financeService } from '@/api/admin/finance'
|
||||
import { ElMessage } from 'element-plus'
|
||||
|
||||
interface PaymentRecord {
|
||||
id: string | number
|
||||
created_at: string
|
||||
country_name: string
|
||||
remitter: string
|
||||
account_name: string
|
||||
currency_name: string
|
||||
amount: number
|
||||
status: string
|
||||
}
|
||||
|
||||
interface Props {
|
||||
modelValue: boolean
|
||||
receiptId?: string | number
|
||||
}
|
||||
|
||||
interface Emits {
|
||||
(e: 'update:modelValue', value: boolean): void
|
||||
(e: 'confirm', record: PaymentRecord): void
|
||||
}
|
||||
|
||||
const props = defineProps<Props>()
|
||||
const emit = defineEmits<Emits>()
|
||||
|
||||
const visible = computed({
|
||||
get: () => props.modelValue,
|
||||
set: (value) => emit('update:modelValue', value)
|
||||
})
|
||||
|
||||
const loading = ref(false)
|
||||
const searchKeyword = ref('')
|
||||
const paymentRecords = ref<PaymentRecord[]>([])
|
||||
const selectedRecord = ref<PaymentRecord | null>(null)
|
||||
const selectedRecordId = ref<string | number | null>(null)
|
||||
const tableRef = ref()
|
||||
|
||||
const pagination = reactive({
|
||||
currentPage: 1,
|
||||
pageSize: 10,
|
||||
total: 0
|
||||
})
|
||||
|
||||
// 获取付款记录列表
|
||||
const getPaymentRecords = async () => {
|
||||
loading.value = true
|
||||
try {
|
||||
const params = {
|
||||
current: pagination.currentPage,
|
||||
size: pagination.pageSize,
|
||||
keyword: searchKeyword.value,
|
||||
scene:'correlation',
|
||||
correlation: 'unbind' // 只显示可用的付款记录
|
||||
}
|
||||
|
||||
const { records, current, size, total } = await financeService.getPaymentList(params)
|
||||
paymentRecords.value = records || []
|
||||
Object.assign(pagination, { currentPage: current, pageSize: size, total })
|
||||
} catch (error) {
|
||||
console.error('获取付款记录失败:', error)
|
||||
ElMessage.error('获取付款记录失败')
|
||||
} finally {
|
||||
loading.value = false
|
||||
}
|
||||
}
|
||||
|
||||
// 处理选择变化(保留兼容性)
|
||||
const handleSelectionChange = (selection: PaymentRecord[]) => {
|
||||
// 单选模式下不使用此方法
|
||||
}
|
||||
|
||||
// 处理单选按钮变化
|
||||
const handleRadioChange = (record: PaymentRecord) => {
|
||||
selectedRecord.value = record
|
||||
selectedRecordId.value = record.id
|
||||
}
|
||||
|
||||
// 处理行点击
|
||||
const handleRowClick = (record: PaymentRecord) => {
|
||||
selectedRecord.value = record
|
||||
selectedRecordId.value = record.id
|
||||
}
|
||||
|
||||
// 分页处理
|
||||
const handleSizeChange = (size: number) => {
|
||||
pagination.pageSize = size
|
||||
pagination.currentPage = 1
|
||||
getPaymentRecords()
|
||||
}
|
||||
|
||||
const handleCurrentChange = (page: number) => {
|
||||
pagination.currentPage = page
|
||||
getPaymentRecords()
|
||||
}
|
||||
|
||||
// 确认绑定
|
||||
const handleConfirm = () => {
|
||||
if (!selectedRecord.value) {
|
||||
ElMessage.warning('请选择一条付款记录')
|
||||
return
|
||||
}
|
||||
emit('confirm', selectedRecord.value)
|
||||
handleClose()
|
||||
}
|
||||
|
||||
// 关闭对话框
|
||||
const handleClose = () => {
|
||||
visible.value = false
|
||||
selectedRecord.value = null
|
||||
selectedRecordId.value = null
|
||||
searchKeyword.value = ''
|
||||
pagination.currentPage = 1
|
||||
}
|
||||
|
||||
// 格式化金额显示
|
||||
const formatAmount = (amount: number, currency: string) => {
|
||||
return `${currency} ${amount?.toLocaleString() || 0}`
|
||||
}
|
||||
|
||||
// 获取状态类型
|
||||
const getStatusType = (status: string) => {
|
||||
const statusMap: Record<string, string> = {
|
||||
'available': 'success',
|
||||
'used': 'info',
|
||||
'pending': 'warning',
|
||||
'cancelled': 'danger'
|
||||
}
|
||||
return statusMap[status] || 'info'
|
||||
}
|
||||
|
||||
// 获取状态文本
|
||||
const getStatusText = (status: string) => {
|
||||
const statusMap: Record<string, string> = {
|
||||
'available': '可用',
|
||||
'used': '已使用',
|
||||
'pending': '待处理',
|
||||
'cancelled': '已取消'
|
||||
}
|
||||
return statusMap[status] || status
|
||||
}
|
||||
|
||||
// 监听对话框显示状态
|
||||
watch(visible, (newVal) => {
|
||||
if (newVal) {
|
||||
getPaymentRecords()
|
||||
}
|
||||
})
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
.payment-record-dialog {
|
||||
.search-bar {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 12px;
|
||||
margin-bottom: 16px;
|
||||
}
|
||||
|
||||
.clickable {
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.pagination-wrapper {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
margin-top: 20px;
|
||||
}
|
||||
}
|
||||
|
||||
.dialog-footer {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
gap: 12px;
|
||||
}
|
||||
</style>
|
||||
@@ -18,9 +18,9 @@
|
||||
</div>
|
||||
|
||||
<div class="boxshadow">
|
||||
<el-tabs v-model="activeTab" @tab-click="handleTabChange">
|
||||
<el-tab-pane label="未认领" name="unclaimed"></el-tab-pane>
|
||||
<el-tab-pane label="已认领" name="claimed"></el-tab-pane>
|
||||
<el-tabs v-model="activeTab">
|
||||
<el-tab-pane label="未认领" name="not"></el-tab-pane>
|
||||
<el-tab-pane label="已认领" name="already"></el-tab-pane>
|
||||
</el-tabs>
|
||||
<ArtTable
|
||||
ref="tableRef"
|
||||
@@ -34,26 +34,16 @@
|
||||
@current-change="handleCurrentChange"
|
||||
>
|
||||
<template #default>
|
||||
<ElTableColumn label="阿里订单号/PI号" prop="flows_name" min-width="140" />
|
||||
<ElTableColumn label="创建日期" prop="biz_desc" min-width="160" />
|
||||
<ElTableColumn label="内勤" prop="initiator_name" min-width="120">
|
||||
<template #default="scope">
|
||||
<div style="display: flex; align-items: center">
|
||||
<img class="avatar" :src="scope.row.initiator_avatar" alt="" />
|
||||
<p>{{ scope.row.initiator_name }}</p>
|
||||
</div>
|
||||
</template>
|
||||
</ElTableColumn>
|
||||
<ElTableColumn label="付款来源" prop="approver_name" min-width="120" />
|
||||
<ElTableColumn label="汇款人" prop="status_desc" min-width="120" />
|
||||
<ElTableColumn label="账户" prop="created_at" min-width="120" />
|
||||
<ElTableColumn label="账币种户" prop="created_at" min-width="120" />
|
||||
<ElTableColumn label="金额" prop="created_at" min-width="120" />
|
||||
<ElTableColumn label="创建日期" prop="created_at" min-width="160" />
|
||||
<ElTableColumn label="付款来源" prop="country_name" min-width="120" />
|
||||
<ElTableColumn label="汇款人" prop="remitter" min-width="120" />
|
||||
<ElTableColumn label="账户" prop="account_name" min-width="120" />
|
||||
<ElTableColumn label="账币" prop="currency_name" min-width="120" />
|
||||
<ElTableColumn label="金额" prop="amount" min-width="120" />
|
||||
<ElTableColumn label="操作" fixed="right" min-width="140" align="center">
|
||||
<template #default>
|
||||
<template #default="scope">
|
||||
<ElRow :gutter="10" justify="center">
|
||||
<el-link
|
||||
v-if="hasAuth('receipt_records@show')"
|
||||
type="primary"
|
||||
underline="never"
|
||||
@click="handleView()"
|
||||
@@ -62,20 +52,12 @@
|
||||
<i class="iconfont-sys"></i> 查看
|
||||
</el-link>
|
||||
<el-link
|
||||
v-if="hasAuth('receipt_records@update')"
|
||||
v-if="!scope.row.payment_apply_id"
|
||||
type="success"
|
||||
underline="never"
|
||||
@click="handleEdit()"
|
||||
@click="handleClaim(scope.row)"
|
||||
>
|
||||
<i class="iconfont-sys"></i> 修改
|
||||
</el-link>
|
||||
<el-link
|
||||
v-if="hasAuth('receipt_records@destroy')"
|
||||
type="danger"
|
||||
underline="never"
|
||||
@click="handleDelete()"
|
||||
>
|
||||
<i class="iconfont-sys"></i> 删除
|
||||
<i class="iconfont-sys"></i> 认领
|
||||
</el-link>
|
||||
</ElRow>
|
||||
</template>
|
||||
@@ -83,15 +65,23 @@
|
||||
</template>
|
||||
</ArtTable>
|
||||
</div>
|
||||
|
||||
<!-- 付款记录选择对话框 -->
|
||||
<PaymentRecordDialog
|
||||
v-model="paymentDialogVisible"
|
||||
:receipt-id="currentReceiptId"
|
||||
@confirm="handlePaymentRecordConfirm"
|
||||
/>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { manageService } from '@/api/adminApi'
|
||||
import { financeService } from '@/api/financeApi'
|
||||
import { financeService } from '@/api/admin/finance'
|
||||
import { ElMessage } from 'element-plus'
|
||||
import type { FormInstance, FormRules } from 'element-plus'
|
||||
import { useAuth } from '@/composables/useAuth'
|
||||
import PaymentRecordDialog from '@/components/custom/PaymentRecordDialog.vue'
|
||||
defineOptions({ name: 'Adminclaim' })
|
||||
const { hasAuth } = useAuth()
|
||||
const loading = ref(false)
|
||||
@@ -99,7 +89,11 @@
|
||||
const tableRef = ref()
|
||||
const tableData = ref<any[]>([])
|
||||
const pagination = reactive({ currentPage: 1, pageSize: 10, total: 0 })
|
||||
const activeTab = ref('unclaimed')
|
||||
const activeTab = ref('not')
|
||||
|
||||
// 付款记录对话框相关
|
||||
const paymentDialogVisible = ref(false)
|
||||
const currentReceiptId = ref<string | number>('')
|
||||
|
||||
// 审批弹出框相关
|
||||
onMounted(() => {
|
||||
@@ -110,7 +104,10 @@
|
||||
pagination.currentPage = 1
|
||||
// 不自动请求,保持与截图行为一致,点击搜索或回车触发
|
||||
})
|
||||
|
||||
watch([activeTab], () => {
|
||||
pagination.currentPage = 1
|
||||
getList()
|
||||
})
|
||||
const getList = async () => {
|
||||
loading.value = true
|
||||
try {
|
||||
@@ -118,11 +115,11 @@
|
||||
const params = {
|
||||
current: currentPage,
|
||||
size: pageSize,
|
||||
scene: 'todo',
|
||||
payment_apply: activeTab.value,
|
||||
keyword: keyword.value
|
||||
}
|
||||
|
||||
const { records, current, size, total } = await manageService.stockapprovalrecord(params)
|
||||
const { records, current, size, total } = await financeService.getReceiptList(params)
|
||||
tableData.value = records || []
|
||||
Object.assign(pagination, { currentPage: current, pageSize: size, total })
|
||||
} catch (error) {
|
||||
@@ -141,13 +138,31 @@
|
||||
getList()
|
||||
}
|
||||
const handleView = () => {}
|
||||
const handleEdit = () => {}
|
||||
const handleDelete = () => {}
|
||||
const handleTabChange = (tab: any) => {
|
||||
activeTab.value = tab.name
|
||||
pagination.currentPage = 1
|
||||
getList()
|
||||
|
||||
// 处理认领操作
|
||||
const handleClaim = (row: any) => {
|
||||
currentReceiptId.value = row.id
|
||||
paymentDialogVisible.value = true
|
||||
}
|
||||
|
||||
// 处理付款记录确认绑定
|
||||
const handlePaymentRecordConfirm = async (paymentRecord: any) => {
|
||||
try {
|
||||
const params = {
|
||||
id: currentReceiptId.value,
|
||||
payment_apply_id: paymentRecord.id
|
||||
}
|
||||
|
||||
await financeService.bindPaymentRecord(params)
|
||||
ElMessage.success('认领成功')
|
||||
getList() // 刷新列表
|
||||
} catch (error) {
|
||||
console.error('认领失败:', error)
|
||||
ElMessage.error('认领失败,请稍后重试')
|
||||
}
|
||||
}
|
||||
|
||||
const handleDelete = () => {}
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
|
||||
@@ -52,7 +52,7 @@
|
||||
v-if="hasAuth('payment_records@show')"
|
||||
type="primary"
|
||||
underline="never"
|
||||
@click="handleView()"
|
||||
@click="handleView(scope.row)"
|
||||
style="margin-right: 8px"
|
||||
>
|
||||
<i class="iconfont-sys"></i> 查看
|
||||
@@ -362,6 +362,12 @@
|
||||
<ElButton type="primary" @click="orderPicker.visible = false">关闭</ElButton>
|
||||
</template>
|
||||
</el-dialog>
|
||||
|
||||
<!-- 付款记录详情查看对话框 -->
|
||||
<PaymentRecordDetailDialog
|
||||
v-model="detailDialogVisible"
|
||||
:payment-id="currentPaymentId"
|
||||
/>
|
||||
</div>
|
||||
</template>
|
||||
<script lang="ts"></script>
|
||||
@@ -369,6 +375,7 @@
|
||||
import { commonService } from '@/api/commonApi'
|
||||
import { financeService } from '@/api/admin/finance'
|
||||
import { UserService } from '@/api/usersApi'
|
||||
import PaymentRecordDetailDialog from '@/components/custom/PaymentRecordDetailDialog.vue'
|
||||
import { ElMessage } from 'element-plus'
|
||||
import type { FormInstance, FormRules } from 'element-plus'
|
||||
import { purchaseService } from '@/api/admin/procurement'
|
||||
@@ -593,6 +600,10 @@
|
||||
const createLoading = ref(false)
|
||||
const isEdit = ref(false)
|
||||
const currentId = ref<string | number | null>(null)
|
||||
|
||||
// 详情对话框相关
|
||||
const detailDialogVisible = ref(false)
|
||||
const currentPaymentId = ref<string | number>('')
|
||||
const createFormRef = ref<FormInstance>()
|
||||
const form = ref({
|
||||
payment_apply_id: '',
|
||||
@@ -609,7 +620,7 @@
|
||||
swift: '',
|
||||
voucher_file: [] as string[],
|
||||
voucher_file_list: [] as string[],
|
||||
submit_files: [] as string[],
|
||||
submit_files: [] as object[],
|
||||
submit_files_list: [] as string[]
|
||||
})
|
||||
const createRules: FormRules = {
|
||||
@@ -668,6 +679,7 @@
|
||||
const payload: any = { ...form.value }
|
||||
delete payload.submit_files_list
|
||||
delete payload.voucher_file_list
|
||||
delete payload.sales_user_name
|
||||
payload.voucher_file = payload.voucher_file.join(',')
|
||||
// 将所选备货单 ID 列表传给后端字段(兼容旧字段)
|
||||
if (Array.isArray(payload.stock_id)) {
|
||||
@@ -688,6 +700,7 @@
|
||||
const { message } = await financeService.updatePayment(forms)
|
||||
ElMessage.success(message)
|
||||
} else {
|
||||
// console.log('payload:', payload)
|
||||
const { message } = await financeService.addPayment(payload)
|
||||
ElMessage.success(message)
|
||||
}
|
||||
@@ -698,7 +711,10 @@
|
||||
}
|
||||
})
|
||||
}
|
||||
const handleView = () => {}
|
||||
const handleView = (row: any) => {
|
||||
currentPaymentId.value = row.id
|
||||
detailDialogVisible.value = true
|
||||
}
|
||||
const handleEdit = async (row?: any) => {
|
||||
resetCreateForm()
|
||||
isEdit.value = true
|
||||
@@ -722,7 +738,7 @@
|
||||
}
|
||||
form.value.sales_user_id = row.sales_user_id ?? form.value.sales_user_id
|
||||
form.value.sales_user_name = row.sales_user_name ?? form.value.sales_user_name
|
||||
form.value.corp_id = row.corp_id ?? form.value.corp_id
|
||||
form.value.corp_id = String(row.corp_id ?? '')
|
||||
form.value.country_id = row.country_id ?? form.value.country_id
|
||||
form.value.remitter = row.remitter ?? form.value.remitter
|
||||
form.value.account_id = row.account_id ?? form.value.account_id
|
||||
@@ -747,18 +763,11 @@
|
||||
}
|
||||
// 处理入账资料提交文件
|
||||
if (row.submit_files) {
|
||||
const submitFiles = Array.isArray(row.submit_files)
|
||||
? row.submit_files
|
||||
: String(row.submit_files)
|
||||
.split(',')
|
||||
.map((s: string) => s.trim())
|
||||
.filter(Boolean)
|
||||
const submitFiles = row.submit_files
|
||||
form.value.submit_files = submitFiles
|
||||
// 构造预览URL列表
|
||||
const baseUrl = import.meta.env.VITE_API_URL || ''
|
||||
form.value.submit_files_list = submitFiles.map((file: string) =>
|
||||
file.startsWith('http') ? file : `${baseUrl}/${file}`
|
||||
)
|
||||
form.value.submit_files_list = submitFiles.map((file: any) => file.file_name)
|
||||
}
|
||||
}
|
||||
loadOptions()
|
||||
@@ -805,7 +814,13 @@
|
||||
const fileName = response?.data?.file_name || ''
|
||||
const fileUrl = response?.data?.file_url || response?.data?.full_url || response?.url || ''
|
||||
const names = Array.isArray(form.value.submit_files) ? [...form.value.submit_files] : []
|
||||
if (fileName) names.push(fileName)
|
||||
const files = ref({
|
||||
file_src: '',
|
||||
file_name: ''
|
||||
})
|
||||
files.value.file_src = fileName
|
||||
files.value.file_name = response?.data?.original_name || ''
|
||||
if (fileName) names.push(files.value)
|
||||
form.value.submit_files = names
|
||||
const list = Array.isArray(form.value.submit_files_list) ? form.value.submit_files_list : []
|
||||
list.push(fileUrl)
|
||||
|
||||
@@ -46,6 +46,12 @@
|
||||
<ElTableColumn label="币种" prop="currency_name" min-width="120" />
|
||||
<ElTableColumn label="金额" prop="amount" min-width="120" />
|
||||
<ElTableColumn label="折让金额" prop="discount_amount" min-width="120" />
|
||||
<ElTableColumn label="入账" prop="id" min-width="120">
|
||||
<template #default="scope">
|
||||
<span v-if="scope.row.received_at">{{ scope.row.received_at }}</span>
|
||||
<el-button v-else type="primary" size="small" @click="handlebtn">确认入账</el-button>
|
||||
</template>
|
||||
</ElTableColumn>
|
||||
<ElTableColumn label="操作" fixed="right" min-width="140" align="center">
|
||||
<template #default="scope">
|
||||
<ElRow :gutter="10" justify="center">
|
||||
@@ -53,7 +59,7 @@
|
||||
v-if="hasAuth('receipt_records@show')"
|
||||
type="primary"
|
||||
underline="never"
|
||||
@click="handleView()"
|
||||
@click="handleView(scope.row)"
|
||||
style="margin-right: 8px"
|
||||
>
|
||||
<i class="iconfont-sys"></i> 查看
|
||||
@@ -246,6 +252,118 @@
|
||||
<el-button type="primary" @click="handleSubmit">提交</el-button>
|
||||
</template>
|
||||
</el-dialog>
|
||||
<el-dialog
|
||||
v-model="dialogVisibleshow"
|
||||
title="查看收款记录"
|
||||
width="900px"
|
||||
class="receipt-dialog"
|
||||
>
|
||||
<el-form ref="createFormRef" :model="formshow" label-width="180px" class="receipt-form">
|
||||
<ElRow :gutter="12" class="item-row-wrap">
|
||||
<ElCol :sm="24" :md="12" :lg="12">
|
||||
<el-form-item label="付款来源">
|
||||
<el-input v-model="formshow.country_name" disabled />
|
||||
</el-form-item>
|
||||
</ElCol>
|
||||
<ElCol :sm="24" :md="12" :lg="12">
|
||||
<el-form-item label="汇款人">
|
||||
<el-input v-model="formshow.remitter" disabled />
|
||||
</el-form-item>
|
||||
</ElCol>
|
||||
<ElCol :sm="24" :md="12" :lg="12">
|
||||
<el-form-item label="账户">
|
||||
<el-input v-model="formshow.account_name" disabled />
|
||||
</el-form-item>
|
||||
</ElCol>
|
||||
<ElCol :sm="24" :md="12" :lg="12">
|
||||
<el-form-item label="币种">
|
||||
<el-input v-model="formshow.currency_name" disabled />
|
||||
</el-form-item>
|
||||
</ElCol>
|
||||
<ElCol :sm="24" :md="12" :lg="12">
|
||||
<el-form-item label="金额">
|
||||
<el-input v-model="formshow.amount" disabled />
|
||||
</el-form-item>
|
||||
</ElCol>
|
||||
<ElCol :sm="24" :md="12" :lg="12">
|
||||
<el-form-item label="到账时间">
|
||||
<el-input v-model="formshow.arrived_at" disabled />
|
||||
</el-form-item>
|
||||
</ElCol>
|
||||
<ElCol :sm="24" :md="12" :lg="12">
|
||||
<el-form-item label="折让金额">
|
||||
<el-input v-model="formshow.discount_amount" disabled />
|
||||
</el-form-item>
|
||||
</ElCol>
|
||||
<ElCol :sm="24" :md="12" :lg="12">
|
||||
<el-form-item label="收汇凭证号">
|
||||
<el-input v-model="formshow.voucher_no" disabled />
|
||||
</el-form-item>
|
||||
</ElCol>
|
||||
<ElCol :sm="24" :md="12" :lg="12">
|
||||
<el-form-item label="实际汇率(出纳)">
|
||||
<el-input v-model="formshow.exchange_rate" disabled />
|
||||
</el-form-item>
|
||||
</ElCol>
|
||||
<ElCol :sm="24" :md="12" :lg="12">
|
||||
<el-form-item label="总金额(人民币)实际汇率">
|
||||
<el-input v-model="formshow.total_amount_cny" disabled />
|
||||
</el-form-item>
|
||||
</ElCol>
|
||||
<ElCol :sm="24" :md="12" :lg="12">
|
||||
<el-form-item label="是否转回内地">
|
||||
<el-radio-group v-model="formshow.is_domestic_return" disabled>
|
||||
<el-radio :label="0">否</el-radio>
|
||||
<el-radio :label="1">是</el-radio>
|
||||
</el-radio-group>
|
||||
</el-form-item>
|
||||
</ElCol>
|
||||
<ElCol :sm="24" :md="12" :lg="12">
|
||||
<el-form-item label="外汇到账回单(出纳)">
|
||||
<div
|
||||
v-if="
|
||||
Array.isArray(formshow.fx_receipt_file_list) &&
|
||||
formshow.fx_receipt_file_list.length
|
||||
"
|
||||
style="margin-top: 8px"
|
||||
>
|
||||
<div
|
||||
v-for="(u, i) in formshow.fx_receipt_file_list"
|
||||
:key="i"
|
||||
style="display: flex; align-items: center; gap: 8px; margin-bottom: 6px"
|
||||
>
|
||||
<img
|
||||
v-if="/\.(png|jpe?g|gif|webp|bmp|svg)(\?|$)/i.test((u || '').split('?')[0])"
|
||||
:src="u"
|
||||
style="
|
||||
width: 60px;
|
||||
height: 60px;
|
||||
object-fit: cover;
|
||||
border-radius: 6px;
|
||||
border: 1px solid var(--el-border-color);
|
||||
"
|
||||
/>
|
||||
<a
|
||||
v-else
|
||||
:href="u"
|
||||
target="_blank"
|
||||
rel="noopener"
|
||||
style="
|
||||
flex: 1;
|
||||
white-space: nowrap;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
width: 200px;
|
||||
"
|
||||
>{{ (u || '').split('?')[0].split('/').pop() }}</a
|
||||
>
|
||||
</div>
|
||||
</div>
|
||||
</el-form-item>
|
||||
</ElCol>
|
||||
</ElRow>
|
||||
</el-form>
|
||||
</el-dialog>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
@@ -262,6 +380,7 @@
|
||||
defineOptions({ name: 'AdminReceiptRecords' })
|
||||
const { hasAuth } = useAuth()
|
||||
const loading = ref(false)
|
||||
const dialogVisibleshow = ref(false)
|
||||
const keyword = ref('')
|
||||
const tableRef = ref()
|
||||
const tableData = ref<any[]>([])
|
||||
@@ -366,7 +485,21 @@
|
||||
account_id: [{ required: true, message: '请选择账户', trigger: 'change' }],
|
||||
currency_id: [{ required: true, message: '请选择币种', trigger: 'change' }]
|
||||
}
|
||||
|
||||
const formshow = ref({
|
||||
country_name: '',
|
||||
remitter: '',
|
||||
account_name: '',
|
||||
currency_name: '',
|
||||
amount: '',
|
||||
arrived_at: '',
|
||||
discount_amount: '',
|
||||
voucher_no: '',
|
||||
total_amount_cny: '',
|
||||
exchange_rate: '',
|
||||
is_domestic_return: 0,
|
||||
fx_receipt_file: '',
|
||||
fx_receipt_file_list: [] as string[]
|
||||
})
|
||||
const resetCreateForm = () => {
|
||||
Object.assign(form.value, {
|
||||
country_id: '',
|
||||
@@ -403,7 +536,11 @@
|
||||
createLoading.value = true
|
||||
// TODO: 根据新增/编辑调用对应接口
|
||||
if (isEdit.value) {
|
||||
const forms = { ...form.value, id: currentId.value }
|
||||
const formData = { ...form.value }
|
||||
if ('fx_receipt_file_list' in formData) {
|
||||
delete formData.fx_receipt_file_list
|
||||
}
|
||||
const forms = { ...formData, id: currentId.value }
|
||||
const { message } = await financeService.updateReceipt(forms)
|
||||
ElMessage.success(message)
|
||||
} else {
|
||||
@@ -417,7 +554,15 @@
|
||||
}
|
||||
})
|
||||
}
|
||||
const handleView = () => {}
|
||||
const handleView = (row?: any) => {
|
||||
const fx_receipt_file_full = []
|
||||
if (row.fx_receipt_file_full) {
|
||||
fx_receipt_file_full.push(row.fx_receipt_file_full)
|
||||
}
|
||||
formshow.value = row
|
||||
formshow.value.fx_receipt_file_list = fx_receipt_file_full
|
||||
dialogVisibleshow.value = true
|
||||
}
|
||||
const handleEdit = (row?: any) => {
|
||||
resetCreateForm()
|
||||
isEdit.value = true
|
||||
@@ -435,8 +580,13 @@
|
||||
form.value.exchange_rate = row.exchange_rate ?? form.value.exchange_rate
|
||||
form.value.is_domestic_return = row.is_domestic_return ?? form.value.is_domestic_return
|
||||
form.value.fx_receipt_file = row.fx_receipt_file ?? form.value.fx_receipt_file
|
||||
form.value.fx_receipt_file_list = Array.isArray(row.fx_receipt_file_list)
|
||||
? row.fx_receipt_file_list
|
||||
|
||||
const fx_receipt_file_full = []
|
||||
if (row.fx_receipt_file_full) {
|
||||
fx_receipt_file_full.push(row.fx_receipt_file_full)
|
||||
}
|
||||
form.value.fx_receipt_file_list = Array.isArray(fx_receipt_file_full)
|
||||
? fx_receipt_file_full
|
||||
: form.value.fx_receipt_file_list
|
||||
}
|
||||
fetchAccountOptions()
|
||||
@@ -444,6 +594,18 @@
|
||||
fetchCountryOptions()
|
||||
dialogVisible.value = true
|
||||
}
|
||||
const handlebtn = () => {
|
||||
ElMessageBox.confirm('你是否确认入账?', '入账', {
|
||||
confirmButtonText: '确定',
|
||||
cancelButtonText: '取消',
|
||||
type: 'warning'
|
||||
}).then(() => {
|
||||
// financeService.deleteReceipt({ id: currentId.value }).then((res) => {
|
||||
// ElMessage.success(res.message)
|
||||
// getList()
|
||||
// })
|
||||
})
|
||||
}
|
||||
const handleDelete = () => {
|
||||
ElMessageBox.confirm('确定删除吗?', '提示', {
|
||||
confirmButtonText: '确定',
|
||||
|
||||
Reference in New Issue
Block a user