feat(finance): 调整付款单和收票单详情展示及附件删除功能

- 修改付款单详情抽屉中的字段展示顺序和内容
- 移除收票单列表中的预计收票时间和实际收票时间列
- 增加附件作废按钮并实现删除逻辑
- 更新附件删除接口以支持根据关联ID软删除
- 在付款单中增加审批节点信息传递
- 调整合并收票对话框中日期选择器布局并修改提示文字
- 优化付款单状态更新逻辑,在删除附件后重置支付状态和时间
dev_1.0.1
chenhao 2025-12-18 17:57:59 +08:00
parent e7ed169f94
commit 1d85e92997
15 changed files with 123 additions and 65 deletions

View File

@ -29,6 +29,12 @@ export function getPaymentAttachments(id, params) {
params params
}) })
} }
export function deleteFile(id) {
return request({
url: `/finance/payment/attachment/${id}`,
method: 'delete'
})
}
// 上传付款单附件 // 上传付款单附件
export function uploadPaymentAttachment(data) { export function uploadPaymentAttachment(data) {

View File

@ -20,16 +20,16 @@
<el-input v-model="form.vendorName" readonly/> <el-input v-model="form.vendorName" readonly/>
</el-form-item> </el-form-item>
</el-col> </el-col>
<el-col :span="8"> <!-- <el-col :span="8">-->
<el-form-item label="预计收票时间" prop="ticketTime"> <!-- <el-form-item label="预计收票时间" prop="ticketTime">-->
<el-date-picker <!-- <el-date-picker-->
v-model="form.ticketTime" <!-- v-model="form.ticketTime"-->
type="date" <!-- type="date"-->
value-format="yyyy-MM-dd HH:mm:ss" <!-- value-format="yyyy-MM-dd HH:mm:ss"-->
placeholder="选择日期" <!-- placeholder="选择日期"-->
></el-date-picker> <!-- ></el-date-picker>-->
</el-form-item> <!-- </el-form-item>-->
</el-col> <!-- </el-col>-->
<el-col :span="8"> <el-col :span="8">
<el-form-item label="厂家开票时间" prop="vendorTicketTime"> <el-form-item label="厂家开票时间" prop="vendorTicketTime">
<el-date-picker <el-date-picker
@ -253,12 +253,12 @@ export default {
this.$modal.msgError('请选择收票单类型'); this.$modal.msgError('请选择收票单类型');
return; return;
} }
if (!this.form.ticketTime) { // if (!this.form.ticketTime) {
this.$modal.msgError('请选择预计收票时间'); // this.$modal.msgError('');
return; // return;
} // }
if (!this.form.vendorTicketTime) { if (!this.form.vendorTicketTime) {
this.$modal.msgError('请选择厂家开票时间'); this.$modal.msgError('请选择制造商开票时间');
return; return;
} }

View File

@ -34,7 +34,7 @@
</el-row> </el-row>
<el-row :gutter="20"> <el-row :gutter="20">
<el-col :span="8"> <el-col :span="8">
<div class="detail-item">付款单类型: <div class="detail-item">备注:
<dict-tag :options="dict.type.payment_bill_type" :value="detail.paymentBillType"/> <dict-tag :options="dict.type.payment_bill_type" :value="detail.paymentBillType"/>
</div> </div>
</el-col> </el-col>
@ -51,23 +51,23 @@
<dict-tag :options="dict.type.payment_method" :value="detail.paymentMethod"/> <dict-tag :options="dict.type.payment_method" :value="detail.paymentMethod"/>
</div> </div>
</el-col> </el-col>
<el-col :span="8">
<div class="detail-item">回执单/退款图:
<!-- <span onclick="downloadFile(this.detail.finAttachment)">{{detail.finAttachment?.fileName || '-'}}</span>-->
</div>
</el-col>
<el-col :span="8"> <el-col :span="8">
<div class="detail-item">付款状态: <div class="detail-item">付款状态:
<dict-tag :options="dict.type.payment_status" :value="detail.paymentStatus"/> <dict-tag :options="dict.type.payment_status" :value="detail.paymentStatus"/>
</div> </div>
</el-col> </el-col>
<el-col :span="8">
<div class="detail-item">审批节点: {{ detail.approveNode|| '-' }}</div>
</el-col>
</el-row> </el-row>
<el-row :gutter="20"> <el-row :gutter="20">
<el-col :span="8"> <el-col :span="8">
<div class="detail-item">备注: {{ detail.remark }}</div> <div class="detail-item">审批状态:
<dict-tag :options="dict.type.approve_status" :value="detail.approveStatus"/>
</div>
</el-col> </el-col>
<el-col :span="8"> <el-col :span="8">
<div class="detail-item">上传人姓名: {{ detail.createBy }}</div> <div class="detail-item">审批通过时间: {{ detail.approveTime || '-'}}</div>
</el-col> </el-col>
<el-col :span="8"> <el-col :span="8">
<div class="detail-item">账户名称: {{ detail.payName }}</div> <div class="detail-item">账户名称: {{ detail.payName }}</div>
@ -84,19 +84,6 @@
<div class="detail-item">银行行号: {{ detail.bankNumber }}</div> <div class="detail-item">银行行号: {{ detail.bankNumber }}</div>
</el-col> </el-col>
</el-row> </el-row>
<el-row :gutter="20">
<el-col :span="8">
<div class="detail-item">审批节点: {{ detail.approveNode|| '-' }}</div>
</el-col>
<el-col :span="8">
<div class="detail-item">审批状态:
<dict-tag :options="dict.type.approve_status" :value="detail.approveStatus"/>
</div>
</el-col>
<el-col :span="8">
<div class="detail-item">审批通过时间: {{ detail.approveTime || '-'}}</div>
</el-col>
</el-row>
</div> </div>
</div> </div>

View File

@ -43,6 +43,8 @@
</div> </div>
<div v-if="attachment.delFlag === '2'" class="void-overlay"></div> <div v-if="attachment.delFlag === '2'" class="void-overlay"></div>
</div> </div>
<el-row>
<el-col span="8">
<el-button <el-button
size="mini" size="mini"
type="primary" type="primary"
@ -50,6 +52,20 @@
icon="el-icon-download" icon="el-icon-download"
@click="downloadFile(attachment)" @click="downloadFile(attachment)"
>下载{{ titleText }}</el-button> >下载{{ titleText }}</el-button>
</el-col>
<el-col span="8">
<el-button
size="mini"
type="primary"
class="download-btn"
icon="el-icon-remove"
v-if="paymentData.paymentBillType==='PRE_PAYMENT' && attachment.delFlag !== '2'"
v-hasPermi="['finance:attachment:delete']"
@click="deleteFile(paymentData)"
>作废{{ titleText }}
</el-button>
</el-col>
</el-row>
</div> </div>
</div> </div>
<div class="detail-item"> <div class="detail-item">
@ -162,7 +178,7 @@
</template> </template>
<script> <script>
import { getPaymentAttachments, uploadPaymentAttachment } from "@/api/finance/payment"; import {deleteFile, getPaymentAttachments, uploadPaymentAttachment} from "@/api/finance/payment";
import request from '@/utils/request'; import request from '@/utils/request';
export default { export default {
@ -276,6 +292,11 @@ export default {
isPdf(filePath) { isPdf(filePath) {
return filePath && filePath.toLowerCase().endsWith('.pdf'); return filePath && filePath.toLowerCase().endsWith('.pdf');
}, },
deleteFile(paymentData) {
deleteFile(paymentData.id).then(() => {
this.fetchAttachments()
})
},
downloadFile(attachment) { downloadFile(attachment) {
const link = document.createElement('a'); const link = document.createElement('a');
link.href = this.getImageUrl(attachment.filePath); link.href = this.getImageUrl(attachment.filePath);

View File

@ -415,6 +415,7 @@ export default {
handleDetail(row) { handleDetail(row) {
getPayment(row.id).then(response => { getPayment(row.id).then(response => {
this.detailData = response.data; this.detailData = response.data;
this.detailData.approveNode=row.approveNode;
this.detailOpen = true; this.detailOpen = true;
}); });
}, },

View File

@ -14,10 +14,10 @@
<el-col :span="8"> <el-col :span="8">
<div class="detail-item">采购-收票单编号: {{ detail.ticketBillCode }}</div> <div class="detail-item">采购-收票单编号: {{ detail.ticketBillCode }}</div>
</el-col> </el-col>
<el-col :span="8"> <!-- <el-col :span="8">-->
<div class="detail-item">预计收票时间: {{ detail.ticketTime }}</div> <!-- <div class="detail-item">预计收票时间: {{ detail.ticketTime }}</div>-->
</el-col> <!-- </el-col>-->
<el-col :span="8"> <el-col :span="16">
<div class="detail-item">制造商开票时间: {{ detail.vendorTicketTime }}</div> <div class="detail-item">制造商开票时间: {{ detail.vendorTicketTime }}</div>
</el-col> </el-col>
</el-row> </el-row>

View File

@ -122,11 +122,11 @@
<el-table v-loading="loading" :data="receiptList"> <el-table v-loading="loading" :data="receiptList">
<el-table-column label="收票单编号" align="center" prop="ticketBillCode" /> <el-table-column label="收票单编号" align="center" prop="ticketBillCode" />
<el-table-column label="预计收票时间" align="center" prop="ticketTime" width="180"> <!-- <el-table-column label="预计收票时间" align="center" prop="ticketTime" width="180">-->
<template slot-scope="scope"> <!-- <template slot-scope="scope">-->
<span>{{ parseTime(scope.row.ticketTime, '{y}-{m}-{d} {h}:{i}:{s}') }}</span> <!-- <span>{{ parseTime(scope.row.ticketTime, '{y}-{m}-{d} {h}:{i}:{s}') }}</span>-->
</template> <!-- </template>-->
</el-table-column> <!-- </el-table-column>-->
<el-table-column label="制造商开票时间" align="center" prop="vendorTicketTime" width="180"> <el-table-column label="制造商开票时间" align="center" prop="vendorTicketTime" width="180">
<template slot-scope="scope"> <template slot-scope="scope">
<span>{{ parseTime(scope.row.vendorTicketTime, '{y}-{m}-{d} {h}:{i}:{s}') }}</span> <span>{{ parseTime(scope.row.vendorTicketTime, '{y}-{m}-{d} {h}:{i}:{s}') }}</span>
@ -146,11 +146,11 @@
<dict-tag :options="dict.type.receipt_status" :value="scope.row.ticketStatus"/> <dict-tag :options="dict.type.receipt_status" :value="scope.row.ticketStatus"/>
</template> </template>
</el-table-column> </el-table-column>
<el-table-column label="实际收票时间" align="center" prop="actualTicketTime" width="180"> <!-- <el-table-column label="实际收票时间" align="center" prop="actualTicketTime" width="180">-->
<template slot-scope="scope"> <!-- <template slot-scope="scope">-->
<span>{{ parseTime(scope.row.actualTicketTime, '{y}-{m}-{d} {h}:{i}:{s}') }}</span> <!-- <span>{{ parseTime(scope.row.actualTicketTime, '{y}-{m}-{d} {h}:{i}:{s}') }}</span>-->
</template> <!-- </template>-->
</el-table-column> <!-- </el-table-column>-->
<el-table-column label="审批状态" align="center" prop="approveStatus" > <el-table-column label="审批状态" align="center" prop="approveStatus" >
<template slot-scope="scope"> <template slot-scope="scope">
@ -316,6 +316,7 @@ export default {
handleDetail(row) { handleDetail(row) {
getReceipt(row.id).then(response => { getReceipt(row.id).then(response => {
this.detailData = response.data; this.detailData = response.data;
this.detailData.approveNode =row.approveNode;
this.detailOpen = true; this.detailOpen = true;
}); });
}, },

View File

@ -1,14 +1,12 @@
package com.ruoyi.sip.controller; package com.ruoyi.sip.controller;
import com.ruoyi.common.core.controller.BaseController; import com.ruoyi.common.core.controller.BaseController;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.sip.domain.OmsFinAttachment; import com.ruoyi.sip.domain.OmsFinAttachment;
import com.ruoyi.sip.service.IOmsFinAttachmentService; import com.ruoyi.sip.service.IOmsFinAttachmentService;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller; import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.*;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
@Controller @Controller
@RequestMapping("/finance/attachment") @RequestMapping("/finance/attachment")
@ -23,4 +21,11 @@ public class OmsFinAttachmentController extends BaseController {
{ {
return omsFinAttachmentService.selectOmsFinAttachmentById(id); return omsFinAttachmentService.selectOmsFinAttachmentById(id);
} }
@DeleteMapping("/{id}")
@ResponseBody
public AjaxResult deleteFile(@PathVariable("id") Long id) {
omsFinAttachmentService.deleteOmsFinAttachmentByRelationId(id);
return AjaxResult.success();
}
} }

View File

@ -224,6 +224,14 @@ public class OmsPaymentBillController extends BaseController
return AjaxResult.success( omsFinAttachmentService.list(Collections.singletonList(id),type)); return AjaxResult.success( omsFinAttachmentService.list(Collections.singletonList(id),type));
} }
@DeleteMapping("/attachment/{id}")
@ResponseBody
public AjaxResult deleteFile(@PathVariable("id") Long id) {
omsPaymentBillService.deleteFile(id);
return AjaxResult.success();
}
// //
/** /**
* *

View File

@ -62,4 +62,5 @@ public interface OmsFinAttachmentMapper
void deleteOmsFinAttachmentByPayment(@Param("list") List<Long> paymentBillCodeList,@Param("type") String type); void deleteOmsFinAttachmentByPayment(@Param("list") List<Long> paymentBillCodeList,@Param("type") String type);
void deleteOmsFinAttachmentByRelationId(Long id);
} }

View File

@ -74,4 +74,7 @@ public interface IOmsFinAttachmentService
List<OmsFinAttachment> list(List<Long> ids, String type); List<OmsFinAttachment> list(List<Long> ids, String type);
void deleteOmsFinAttachmentByPayment(List<Long> relatedIdList,String type); void deleteOmsFinAttachmentByPayment(List<Long> relatedIdList,String type);
void deleteOmsFinAttachmentByRelationId(Long id);
} }

View File

@ -112,4 +112,6 @@ public interface IOmsPaymentBillService
OmsPaymentBill selectOmsPaymentBillByCode(String paymentBillCode); OmsPaymentBill selectOmsPaymentBillByCode(String paymentBillCode);
List<OmsPaymentBill> listPreResidueAmountByVendorCodeList(List<String> collect); List<OmsPaymentBill> listPreResidueAmountByVendorCodeList(List<String> collect);
void deleteFile(Long id);
} }

View File

@ -58,6 +58,11 @@ public class OmsFinAttachmentServiceImpl implements IOmsFinAttachmentService
omsFinAttachmentMapper.deleteOmsFinAttachmentByPayment(relatedIdList,type); omsFinAttachmentMapper.deleteOmsFinAttachmentByPayment(relatedIdList,type);
} }
@Override
public void deleteOmsFinAttachmentByRelationId(Long id) {
omsFinAttachmentMapper.deleteOmsFinAttachmentByRelationId(id);
}
/** /**
* *
* *

View File

@ -21,7 +21,6 @@ import com.ruoyi.sip.domain.dto.PaymentBillDetailDTO;
import com.ruoyi.sip.domain.dto.PaymentBillPayableDetailDTO; import com.ruoyi.sip.domain.dto.PaymentBillPayableDetailDTO;
import com.ruoyi.sip.dto.WriteOffRequestDto; import com.ruoyi.sip.dto.WriteOffRequestDto;
import com.ruoyi.sip.flowable.domain.Todo; import com.ruoyi.sip.flowable.domain.Todo;
import com.ruoyi.sip.flowable.service.DeleteFlowableProcessInstanceCmd;
import com.ruoyi.sip.flowable.service.TodoCommonTemplate; import com.ruoyi.sip.flowable.service.TodoCommonTemplate;
import com.ruoyi.sip.flowable.service.TodoService; import com.ruoyi.sip.flowable.service.TodoService;
import com.ruoyi.sip.service.*; import com.ruoyi.sip.service.*;
@ -609,4 +608,15 @@ public class OmsPaymentBillServiceImpl implements IOmsPaymentBillService , TodoC
} }
return omsPaymentBillMapper.listPreResidueAmountByVendorCodeList(collect); return omsPaymentBillMapper.listPreResidueAmountByVendorCodeList(collect);
} }
@Override
public void deleteFile(Long id) {
omsFinAttachmentService.deleteOmsFinAttachmentByRelationId(id);
OmsPaymentBill updateBill = new OmsPaymentBill();
updateBill.setId(id);
updateBill.setPaymentStatus(OmsPaymentBill.PaymentStatusEnum.WAIT_PAYMENT.getCode());
updateBill.setActualPaymentTime(null);
omsPaymentBillMapper.updateReturnWriteOffBatch(Collections.singletonList(updateBill));
}
} }

View File

@ -103,7 +103,9 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
</update> </update>
<delete id="deleteOmsFinAttachmentById" parameterType="Long"> <delete id="deleteOmsFinAttachmentById" parameterType="Long">
delete from oms_fin_attachment where id = #{id} update oms_fin_attachment
set del_flag='2'
where id = #{id}
</delete> </delete>
<delete id="deleteOmsFinAttachmentByIds" parameterType="String"> <delete id="deleteOmsFinAttachmentByIds" parameterType="String">
@ -112,6 +114,12 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
#{id} #{id}
</foreach> </foreach>
</delete> </delete>
<update id="deleteOmsFinAttachmentByRelationId">
update oms_fin_attachment
set del_flag='2'
where related_bill_id = #{id}
</update>
<update id="deleteOmsFinAttachmentByPayment"> <update id="deleteOmsFinAttachmentByPayment">
update oms_fin_attachment set del_flag = 2 where related_bill_type = #{type} and del_flag=0 and update oms_fin_attachment set del_flag = 2 where related_bill_type = #{type} and del_flag=0 and
related_bill_id in related_bill_id in