feat(finance): 新增付款单附件功能并优化表格显示

- 在新增付款单表单中添加附件上传组件
- 修改表格样式设置避免滚动条冲突
- 移除表格固定高度限制提升用户体验
- 在付款单详情页面显示附件信息
- 添加付款单删除功能支持预付款单删除
- 付款单编号列添加链接跳转至详情页
- 后端实体类和数据库映射增加文件ID字段
- 实现附件查询服务关联付款单数据
- 货币金额显示格式化为货币格式
- 文件上传组件集成到付款单流程中
dev_1.0.0
chenhao 2026-01-29 17:14:42 +08:00
parent a56d750f2d
commit 45f69d527e
8 changed files with 105 additions and 20 deletions

View File

@ -111,6 +111,14 @@ export function applyRefund(id) {
needLoading: true
})
}
export function deletePayment(id) {
return request({
url: '/finance/payment/remove',
method: 'post',
params:{ids:id},
needLoading: true
})
}
export function applyRefundApprove(id) {
return request({

View File

@ -417,7 +417,7 @@ export default {
return prev;
}
}, 0);
sums[index] = sums[index].toFixed(2);
sums[index] = this.formatCurrency(sums[index]);
} else {
sums[index] = 'N/A';
}

View File

@ -1,7 +1,8 @@
<template>
<el-dialog title="新增付款单" :visible.sync="internalVisible" width="1200px" @close="handleClose"
:close-on-click-modal="false" append-to-body>
<el-form ref="form" :model="form" :rules="rules" style="max-height: 70vh" label-width="120px">
<div style="max-height: 70vh;overflow: auto">
<el-form ref="form" :model="form" :rules="rules" label-width="120px">
<el-row>
<el-col :span="24">
<el-form-item label="制造商名称" prop="vendorCode">
@ -53,6 +54,12 @@
style="width: 100%"></el-input>
</el-form-item>
</el-col>
<el-col :span="24">
<el-form-item label="附件" prop="fileId">
<file-upload :value="fileList" @file-list-changed="handleFileListChanged" :limit="1"
:file-type="['png', 'jpg', 'jpeg', 'doc', 'docx', 'xls', 'xlsx', 'ppt', 'pptx', 'txt', 'pdf']"/>
</el-form-item>
</el-col>
</el-row>
<!-- Tables -->
<div v-if="form.vendorCode">
@ -64,7 +71,6 @@
border
style="width: 100%"
@selection-change="handleSelectionChange"
max-height="300"
row-key="id"
show-summary
:summary-method="getPayableSummary"
@ -133,7 +139,7 @@
@selection-change="handleSelectionChange"
@select="handleSelect"
@select-all="handleSelectAll"
max-height="300"
row-key="id"
>
<el-table-column type="selection" width="55" reserve-selection></el-table-column>
@ -160,6 +166,7 @@
请先选择制造商
</div>
</el-form>
</div>
<div slot="footer" class="dialog-footer">
<!-- <div v-if="form.paymentBillType === 'FROM_PAYABLE'" style="float: left; line-height: 36px;">-->
<!-- <span style="margin-right: 20px;">计划付款总金额: <el-tag type="success">{{-->
@ -192,10 +199,11 @@
import {listAllVendor} from "@/api/base/vendor";
import {listPayableBills, listOrders} from "@/api/finance/payment";
import PaymentPlanSelector from "../../payable/components/PaymentPlan";
import FileUpload from "@/components/FileUpload";
export default {
name: "AddForm",
components: {PaymentPlanSelector},
components: {PaymentPlanSelector, FileUpload},
props: {
visible: {
type: Boolean,
@ -221,7 +229,8 @@ export default {
vendorName: null,
remark: null,
totalPriceWithTax: 0,
estimatedPaymentTime: null
estimatedPaymentTime: null,
fileId: null
},
rules: {
vendorCode: [{required: true, message: "制造商名称不能为空", trigger: "change"}],
@ -234,6 +243,7 @@ export default {
isPaymentPlanSelectorOpen: false,
choosePayable: {},
currentPayableOrderIndexForPlan: -1,
fileList: [],
};
},
computed: {
@ -287,6 +297,10 @@ export default {
this.selectedRows = [];
this.loadTableData();
},
handleFileListChanged(fileList) {
this.fileList = fileList;
this.form.fileId = this.fileList.map(f => f.id).filter(id => !!id).join(',')
},
loadTableData() {
if (!this.form.vendorCode) return;
@ -460,7 +474,8 @@ export default {
vendorName: this.form.vendorName,
remark: this.form.remark,
payableOrders: processedPayableOrders,
totalMergePaymentAmount: this.totalPlannedAmount
totalMergePaymentAmount: this.totalPlannedAmount,
fileId: this.form.fileId
};
this.$emit("submit", submitData);
@ -484,7 +499,8 @@ export default {
projectName:order.projectName,
remark: this.form.remark,
paymentTime: this.form.estimatedPaymentTime,
totalPriceWithTax:this.form.totalPriceWithTax
totalPriceWithTax:this.form.totalPriceWithTax,
fileId: this.form.fileId
};
this.$emit("submit", submitData);

View File

@ -92,6 +92,12 @@
<el-col :span="24">
<div class="detail-item">其它特别说明: {{ detail.remark }}</div>
</el-col>
<el-col :span="24">
<div class="detail-item">
<span style="margin-right: 10px">附件:</span>
<file-upload :value="detail.fileList" :disabled="true" :show-remove="false" :show-upload-btn="false"/>
</div>
</el-col>
</el-row>
</div>
</div>
@ -121,8 +127,11 @@
</template>
<script>
import FileUpload from "@/components/FileUpload";
export default {
name: "DetailDrawer",
components: {FileUpload},
props: {
visible: {
type: Boolean,

View File

@ -149,7 +149,11 @@
</el-row>
<el-table v-loading="loading" :data="paymentList" show-summary :summary-method="getSummaries">
<el-table-column label="采购-付款单编号" width="200" align="center" prop="paymentBillCode"/>
<el-table-column label="采购-付款单编号" width="200" align="center" prop="paymentBillCode">
<template slot-scope="scope">
<a @click="handleDetail(scope.row)" class="link-type">{{ scope.row.paymentBillCode }}</a>
</template>
</el-table-column>
<el-table-column label="预计付款时间" align="center" prop="paymentTime" width="180">
<template slot-scope="scope">
<span>{{ parseTime(scope.row.paymentTime, '{y}-{m}-{d} {h}:{i}:{s}') }}</span>
@ -215,13 +219,7 @@
v-show="(scope.row.approveStatus==='0' || scope.row.approveStatus==='3') && (scope.row.paymentBillType==='FROM_PAYABLE'||scope.row.paymentBillType==='PRE_PAYMENT')"
@click="applyPayment(scope.row)"
>申请付款</el-button>
<!-- <el-button-->
<!-- size="mini"-->
<!-- type="text"-->
<!-- icon="el-icon-position"-->
<!-- v-show="(scope.row.approveStatus==='0' || scope.row.approveStatus==='3') && scope.row.paymentBillType==='REFUND' "-->
<!-- @click="applyRefundApprove(scope.row)"-->
<!-- >发起退款</el-button>-->
<el-button
size="mini"
type="text"
@ -243,6 +241,15 @@
v-if="(scope.row.approveStatus === '2' || scope.row.approveStatus==='3') && (scope.row.paymentStatus==='1'||scope.row.paymentStatus==='3')"
@click="handleRevoke(scope.row)"
>撤销</el-button>
<el-button
size="mini"
type="text"
icon="el-icon-delete"
v-hasPermi="['finance:payment:remove']"
v-show="(scope.row.approveStatus==='0' || scope.row.approveStatus==='3') && scope.row.paymentBillType==='PRE_PAYMENT' && scope.row.paymentStatus === '1' "
@click="handleDelete(scope.row.id)"
>删除
</el-button>
</template>
</el-table-column>
</el-table>
@ -309,7 +316,7 @@ import {
applyRefund,
addPayment,
handleRevoke,
exportPayment
exportPayment, deletePayment
} from "@/api/finance/payment";
import { addDateRange } from "@/utils/ruoyi";
import DetailDrawer from "./components/DetailDrawer.vue";
@ -497,6 +504,14 @@ export default {
this.$modal.msgSuccess("申请退款成功");
}).catch(() => {});
},
handleDelete(id){
this.$modal.confirm('确认删除该笔预付单数据吗?').then(() => {
return deletePayment(id);
}).then(() => {
this.getList();
this.$modal.msgSuccess("删除成功");
}).catch(() => {});
},
handleRevoke(row) {
let msg=row.paymentBillType==='REFUND'?'是否将该笔采购-退款单撤销,将退款单撤销至付款单':'是否将该笔采购-付款单撤销,撤销至付款单未审批状态';
this.$modal.confirm(msg).then(() => {
@ -525,7 +540,7 @@ export default {
return prev;
}
}, 0);
sums[index] = sums[index].toFixed(2);
sums[index] = this.formatCurrency(sums[index]);
} else {
sums[index] = 'N/A';
}

View File

@ -145,6 +145,12 @@ public class OmsPaymentBill extends BaseEntity
private BigDecimal writeOffAmountWithoutTax;
private BigDecimal writeOffTaxAmount;
/** 附件ID多个以逗号分隔 */
private String fileId;
/** 附件列表 */
private List<OmsFileLog> fileList;
@Getter
public enum PaymentBillTypeEnum {

View File

@ -69,6 +69,8 @@ public class OmsPaymentBillServiceImpl implements IOmsPaymentBillService , TodoC
protected ManagementService managementService;
@Autowired
private IOmsPayableWriteOffService writeOffService;
@Autowired
private IOmsFileLogService omsFileLogService;
/**
*
*
@ -78,7 +80,20 @@ public class OmsPaymentBillServiceImpl implements IOmsPaymentBillService , TodoC
@Override
public OmsPaymentBill selectOmsPaymentBillById(Long id)
{
return omsPaymentBillMapper.selectOmsPaymentBillById(id);
OmsPaymentBill omsPaymentBill = omsPaymentBillMapper.selectOmsPaymentBillById(id);
if (omsPaymentBill != null && StrUtil.isNotEmpty(omsPaymentBill.getFileId())) {
List<Integer> idList = StrUtil.split(omsPaymentBill.getFileId(), ',')
.stream()
.map(Integer::valueOf)
.collect(Collectors.toList());
if (CollUtil.isNotEmpty(idList)) {
OmsFileLog query = new OmsFileLog();
query.setIdList(idList);
List<OmsFileLog> fileList = omsFileLogService.queryAll(query);
omsPaymentBill.setFileList(fileList);
}
}
return omsPaymentBill;
}
/**
@ -186,6 +201,18 @@ public class OmsPaymentBillServiceImpl implements IOmsPaymentBillService , TodoC
@Override
public PaymentBillDetailDTO query(Long id) {
PaymentBillDetailDTO paymentBillDetailDTO = omsPaymentBillMapper.selectPaymentBillDetail(id);
if (paymentBillDetailDTO != null && StrUtil.isNotEmpty(paymentBillDetailDTO.getFileId())) {
List<Integer> idList = StrUtil.split(paymentBillDetailDTO.getFileId(), ',')
.stream()
.map(Integer::valueOf)
.collect(Collectors.toList());
if (CollUtil.isNotEmpty(idList)) {
OmsFileLog query = new OmsFileLog();
query.setIdList(idList);
List<OmsFileLog> fileList = omsFileLogService.queryAll(query);
paymentBillDetailDTO.setFileList(fileList);
}
}
List<PaymentBillPayableDetailDTO> paymentBillPayableDetailDTOS = detailService.listPayableByPaymentCode(paymentBillDetailDTO.getPaymentBillCode());
paymentBillDetailDTO.setPayableDetails(paymentBillPayableDetailDTOS);
return paymentBillDetailDTO;

View File

@ -34,6 +34,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
<result property="payBankNumber" column="pay_bank_number" />
<result property="payBankOpenAddress" column="pay_bank_open_address" />
<result property="bankNumber" column="bank_number" />
<result property="fileId" column="file_id" />
<result property="refundStatus" column="refund_status" />
</resultMap>
@ -101,7 +102,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
pb.pay_bank_number,
pb.pay_bank_open_address,
pb.bank_number,
pb.file_id,
pb.refund_status,
ovi.vendor_name,
ovi.pay_type,
@ -270,6 +271,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
<if test="payBankNumber != null">pay_bank_number,</if>
<if test="payBankOpenAddress != null">pay_bank_open_address,</if>
<if test="bankNumber != null">bank_number,</if>
<if test="fileId != null">file_id,</if>
<if test="refundStatus != null">refund_status,</if>
</trim>
<trim prefix="values (" suffix=")" suffixOverrides=",">
@ -300,6 +302,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
<if test="payBankNumber != null">#{payBankNumber},</if>
<if test="payBankOpenAddress != null">#{payBankOpenAddress},</if>
<if test="bankNumber != null">#{bankNumber},</if>
<if test="fileId != null">#{fileId},</if>
<if test="refundStatus != null">#{refundStatus},</if>
</trim>
</insert>
@ -334,6 +337,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
<if test="payBankNumber != null">pay_bank_number = #{payBankNumber},</if>
<if test="payBankOpenAddress != null">pay_bank_open_address = #{payBankOpenAddress},</if>
<if test="bankNumber != null">bank_number = #{bankNumber},</if>
<if test="fileId != null">file_id = #{fileId},</if>
<if test="refundStatus != null">refund_status = #{refundStatus},</if>
</trim>