feat: 支出和应收款模块新增Excel导出功能
后端: - fund-exp: 新增ExpenseExcel导出实体、导出接口和listExpenses方法 - fund-receipt: 新增ReceivableExcel导出实体、导出接口和listReceivables方法 前端: - fund-admin: 支出管理页面新增导出按钮 - fund-admin: 应收款管理页面新增导出按钮 - fund-admin: 新增exportExpense和exportReceivable API
This commit is contained in:
parent
ad4176ae8a
commit
06efab9596
@ -62,3 +62,39 @@ export function rejectExpense(id: number, comment: string) {
|
|||||||
export function confirmPayExpense(id: number, payChannel: string, payVoucher?: string) {
|
export function confirmPayExpense(id: number, payChannel: string, payVoucher?: string) {
|
||||||
return request.put(`/exp/api/v1/exp/expense/${id}/confirm-pay?payChannel=${payChannel}&payVoucher=${payVoucher || ''}`)
|
return request.put(`/exp/api/v1/exp/expense/${id}/confirm-pay?payChannel=${payChannel}&payVoucher=${payVoucher || ''}`)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 导出支出明细
|
||||||
|
export function exportExpense(params?: { title?: string; expenseType?: number; approvalStatus?: number; payStatus?: number }) {
|
||||||
|
const baseUrl = import.meta.env.VITE_API_URL || ''
|
||||||
|
const token = localStorage.getItem('token')
|
||||||
|
const tenantId = localStorage.getItem('tenantId') || '1'
|
||||||
|
|
||||||
|
const queryParams = new URLSearchParams()
|
||||||
|
if (params?.title) queryParams.append('title', params.title)
|
||||||
|
if (params?.expenseType) queryParams.append('expenseType', String(params.expenseType))
|
||||||
|
if (params?.approvalStatus !== undefined) queryParams.append('approvalStatus', String(params.approvalStatus))
|
||||||
|
if (params?.payStatus !== undefined) queryParams.append('payStatus', String(params.payStatus))
|
||||||
|
|
||||||
|
const queryString = queryParams.toString()
|
||||||
|
const url = `${baseUrl}/exp/api/v1/exp/expense/export${queryString ? '?' + queryString : ''}`
|
||||||
|
|
||||||
|
return fetch(url, {
|
||||||
|
headers: {
|
||||||
|
Authorization: `Bearer ${token}`,
|
||||||
|
'X-Tenant-Id': tenantId
|
||||||
|
}
|
||||||
|
}).then(response => {
|
||||||
|
if (!response.ok) throw new Error('导出失败')
|
||||||
|
|
||||||
|
const contentDisposition = response.headers.get('Content-Disposition')
|
||||||
|
let filename = '支出明细.xlsx'
|
||||||
|
if (contentDisposition) {
|
||||||
|
const match = contentDisposition.match(/filename\*=utf-8''(.+)/i)
|
||||||
|
if (match && match[1]) {
|
||||||
|
filename = decodeURIComponent(match[1])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return response.blob().then(blob => ({ blob, filename }))
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|||||||
@ -49,3 +49,39 @@ export function getReceiptById(id: number) {
|
|||||||
export function createReceipt(data: any) {
|
export function createReceipt(data: any) {
|
||||||
return request.post('/receipt/api/v1/receipt/receipt', data)
|
return request.post('/receipt/api/v1/receipt/receipt', data)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 导出应收款明细
|
||||||
|
export function exportReceivable(params?: { projectId?: number; customerId?: number; status?: string; confirmStatus?: number }) {
|
||||||
|
const baseUrl = import.meta.env.VITE_API_URL || ''
|
||||||
|
const token = localStorage.getItem('token')
|
||||||
|
const tenantId = localStorage.getItem('tenantId') || '1'
|
||||||
|
|
||||||
|
const queryParams = new URLSearchParams()
|
||||||
|
if (params?.projectId) queryParams.append('projectId', String(params.projectId))
|
||||||
|
if (params?.customerId) queryParams.append('customerId', String(params.customerId))
|
||||||
|
if (params?.status) queryParams.append('status', params.status)
|
||||||
|
if (params?.confirmStatus !== undefined) queryParams.append('confirmStatus', String(params.confirmStatus))
|
||||||
|
|
||||||
|
const queryString = queryParams.toString()
|
||||||
|
const url = `${baseUrl}/receipt/api/v1/receipt/receivable/export${queryString ? '?' + queryString : ''}`
|
||||||
|
|
||||||
|
return fetch(url, {
|
||||||
|
headers: {
|
||||||
|
Authorization: `Bearer ${token}`,
|
||||||
|
'X-Tenant-Id': tenantId
|
||||||
|
}
|
||||||
|
}).then(response => {
|
||||||
|
if (!response.ok) throw new Error('导出失败')
|
||||||
|
|
||||||
|
const contentDisposition = response.headers.get('Content-Disposition')
|
||||||
|
let filename = '应收款明细.xlsx'
|
||||||
|
if (contentDisposition) {
|
||||||
|
const match = contentDisposition.match(/filename\*=utf-8''(.+)/i)
|
||||||
|
if (match && match[1]) {
|
||||||
|
filename = decodeURIComponent(match[1])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return response.blob().then(blob => ({ blob, filename }))
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|||||||
@ -40,6 +40,7 @@
|
|||||||
<el-card shadow="never" style="margin-top: 10px">
|
<el-card shadow="never" style="margin-top: 10px">
|
||||||
<div style="margin-bottom: 15px">
|
<div style="margin-bottom: 15px">
|
||||||
<el-button type="primary" :icon="Plus" @click="handleAdd">新增支出</el-button>
|
<el-button type="primary" :icon="Plus" @click="handleAdd">新增支出</el-button>
|
||||||
|
<el-button type="success" :icon="Download" @click="handleExport" :loading="exporting">导出Excel</el-button>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<el-table :data="tableData" v-loading="loading" border stripe>
|
<el-table :data="tableData" v-loading="loading" border stripe>
|
||||||
@ -262,7 +263,7 @@
|
|||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { ref, reactive, onMounted } from 'vue'
|
import { ref, reactive, onMounted } from 'vue'
|
||||||
import { ElMessage, ElMessageBox, type FormInstance, type FormRules } from 'element-plus'
|
import { ElMessage, ElMessageBox, type FormInstance, type FormRules } from 'element-plus'
|
||||||
import { Search, Refresh, Plus, Edit, Delete, View, Check, Document } from '@element-plus/icons-vue'
|
import { Search, Refresh, Plus, Edit, Delete, View, Check, Document, Download } from '@element-plus/icons-vue'
|
||||||
import {
|
import {
|
||||||
getExpenseList,
|
getExpenseList,
|
||||||
createExpense,
|
createExpense,
|
||||||
@ -270,7 +271,8 @@ import {
|
|||||||
deleteExpense,
|
deleteExpense,
|
||||||
submitExpense,
|
submitExpense,
|
||||||
approveExpense,
|
approveExpense,
|
||||||
rejectExpense
|
rejectExpense,
|
||||||
|
exportExpense
|
||||||
} from '@/api/expense'
|
} from '@/api/expense'
|
||||||
import { getExpenseTypeTree } from '@/api/expense'
|
import { getExpenseTypeTree } from '@/api/expense'
|
||||||
import { getProjectList } from '@/api/project'
|
import { getProjectList } from '@/api/project'
|
||||||
@ -285,6 +287,7 @@ const fileList = ref<any[]>([])
|
|||||||
|
|
||||||
const loading = ref(false)
|
const loading = ref(false)
|
||||||
const submitLoading = ref(false)
|
const submitLoading = ref(false)
|
||||||
|
const exporting = ref(false)
|
||||||
const tableData = ref<any[]>([])
|
const tableData = ref<any[]>([])
|
||||||
const total = ref(0)
|
const total = ref(0)
|
||||||
const expenseTypeList = ref<any[]>([])
|
const expenseTypeList = ref<any[]>([])
|
||||||
@ -558,6 +561,34 @@ const resetForm = () => {
|
|||||||
formRef.value?.clearValidate()
|
formRef.value?.clearValidate()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 导出Excel
|
||||||
|
const handleExport = async () => {
|
||||||
|
exporting.value = true
|
||||||
|
try {
|
||||||
|
const params: any = {}
|
||||||
|
if (queryParams.title) params.title = queryParams.title
|
||||||
|
if (queryParams.expenseTypeId) params.expenseType = queryParams.expenseTypeId
|
||||||
|
if (queryParams.approvalStatus) params.approvalStatus = parseInt(queryParams.approvalStatus)
|
||||||
|
if (queryParams.payStatus) params.payStatus = parseInt(queryParams.payStatus)
|
||||||
|
|
||||||
|
const { blob, filename } = await exportExpense(params)
|
||||||
|
const url = window.URL.createObjectURL(blob)
|
||||||
|
const link = document.createElement('a')
|
||||||
|
link.href = url
|
||||||
|
link.download = filename
|
||||||
|
document.body.appendChild(link)
|
||||||
|
link.click()
|
||||||
|
document.body.removeChild(link)
|
||||||
|
window.URL.revokeObjectURL(url)
|
||||||
|
ElMessage.success('导出成功')
|
||||||
|
} catch (error) {
|
||||||
|
console.error('导出失败:', error)
|
||||||
|
ElMessage.error('导出失败')
|
||||||
|
} finally {
|
||||||
|
exporting.value = false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
fetchData()
|
fetchData()
|
||||||
fetchExpenseTypes()
|
fetchExpenseTypes()
|
||||||
|
|||||||
@ -27,6 +27,7 @@
|
|||||||
<div style="margin-bottom: 15px">
|
<div style="margin-bottom: 15px">
|
||||||
<el-button type="primary" :icon="Plus" @click="handleAdd">新增应收款</el-button>
|
<el-button type="primary" :icon="Plus" @click="handleAdd">新增应收款</el-button>
|
||||||
<el-button type="success" :icon="Money">批量收款</el-button>
|
<el-button type="success" :icon="Money">批量收款</el-button>
|
||||||
|
<el-button type="success" :icon="Download" @click="handleExport" :loading="exporting">导出Excel</el-button>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<el-table :data="tableData" v-loading="loading" border stripe>
|
<el-table :data="tableData" v-loading="loading" border stripe>
|
||||||
@ -262,14 +263,15 @@
|
|||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { ref, reactive, onMounted } from 'vue'
|
import { ref, reactive, onMounted } from 'vue'
|
||||||
import { ElMessage, ElMessageBox, type FormInstance, type FormRules } from 'element-plus'
|
import { ElMessage, ElMessageBox, type FormInstance, type FormRules } from 'element-plus'
|
||||||
import { Search, Refresh, Plus, Edit, Delete, View, Money } from '@element-plus/icons-vue'
|
import { Search, Refresh, Plus, Edit, Delete, View, Money, Download } from '@element-plus/icons-vue'
|
||||||
import {
|
import {
|
||||||
getReceivableList,
|
getReceivableList,
|
||||||
createReceivable,
|
createReceivable,
|
||||||
updateReceivable,
|
updateReceivable,
|
||||||
deleteReceivable,
|
deleteReceivable,
|
||||||
recordReceipt,
|
recordReceipt,
|
||||||
getReceiptRecords
|
getReceiptRecords,
|
||||||
|
exportReceivable
|
||||||
} from '@/api/receivable'
|
} from '@/api/receivable'
|
||||||
import { getProjectList } from '@/api/project'
|
import { getProjectList } from '@/api/project'
|
||||||
import { getCustomerList } from '@/api/customer'
|
import { getCustomerList } from '@/api/customer'
|
||||||
@ -277,6 +279,7 @@ import { getCustomerList } from '@/api/customer'
|
|||||||
const loading = ref(false)
|
const loading = ref(false)
|
||||||
const submitLoading = ref(false)
|
const submitLoading = ref(false)
|
||||||
const receiptLoading = ref(false)
|
const receiptLoading = ref(false)
|
||||||
|
const exporting = ref(false)
|
||||||
const tableData = ref<any[]>([])
|
const tableData = ref<any[]>([])
|
||||||
const total = ref(0)
|
const total = ref(0)
|
||||||
const projectList = ref<any[]>([])
|
const projectList = ref<any[]>([])
|
||||||
@ -500,6 +503,31 @@ const resetForm = () => {
|
|||||||
formRef.value?.clearValidate()
|
formRef.value?.clearValidate()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 导出Excel
|
||||||
|
const handleExport = async () => {
|
||||||
|
exporting.value = true
|
||||||
|
try {
|
||||||
|
const params: any = {}
|
||||||
|
if (queryParams.receiptStatus) params.status = queryParams.receiptStatus
|
||||||
|
|
||||||
|
const { blob, filename } = await exportReceivable(params)
|
||||||
|
const url = window.URL.createObjectURL(blob)
|
||||||
|
const link = document.createElement('a')
|
||||||
|
link.href = url
|
||||||
|
link.download = filename
|
||||||
|
document.body.appendChild(link)
|
||||||
|
link.click()
|
||||||
|
document.body.removeChild(link)
|
||||||
|
window.URL.revokeObjectURL(url)
|
||||||
|
ElMessage.success('导出成功')
|
||||||
|
} catch (error) {
|
||||||
|
console.error('导出失败:', error)
|
||||||
|
ElMessage.error('导出失败')
|
||||||
|
} finally {
|
||||||
|
exporting.value = false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
fetchData()
|
fetchData()
|
||||||
fetchProjects()
|
fetchProjects()
|
||||||
|
|||||||
@ -2,12 +2,18 @@ package com.fundplatform.exp.controller;
|
|||||||
|
|
||||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||||
import com.fundplatform.common.core.Result;
|
import com.fundplatform.common.core.Result;
|
||||||
|
import com.fundplatform.common.util.ExcelUtil;
|
||||||
|
import com.fundplatform.exp.dto.ExpenseExcel;
|
||||||
import com.fundplatform.exp.dto.FundExpenseDTO;
|
import com.fundplatform.exp.dto.FundExpenseDTO;
|
||||||
import com.fundplatform.exp.service.FundExpenseService;
|
import com.fundplatform.exp.service.FundExpenseService;
|
||||||
import com.fundplatform.exp.vo.FundExpenseVO;
|
import com.fundplatform.exp.vo.FundExpenseVO;
|
||||||
|
import jakarta.servlet.http.HttpServletResponse;
|
||||||
import jakarta.validation.Valid;
|
import jakarta.validation.Valid;
|
||||||
import org.springframework.web.bind.annotation.*;
|
import org.springframework.web.bind.annotation.*;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 支出管理Controller
|
* 支出管理Controller
|
||||||
*
|
*
|
||||||
@ -164,4 +170,32 @@ public class FundExpenseController {
|
|||||||
public Result<java.util.List<java.util.Map<String, Object>>> getTypeDistribution() {
|
public Result<java.util.List<java.util.Map<String, Object>>> getTypeDistribution() {
|
||||||
return Result.success(expenseService.getTypeDistribution());
|
return Result.success(expenseService.getTypeDistribution());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 导出支出明细Excel
|
||||||
|
*/
|
||||||
|
@GetMapping("/export")
|
||||||
|
public void exportExcel(
|
||||||
|
@RequestParam(required = false) String title,
|
||||||
|
@RequestParam(required = false) Long expenseType,
|
||||||
|
@RequestParam(required = false) Integer payStatus,
|
||||||
|
@RequestParam(required = false) Integer approvalStatus,
|
||||||
|
HttpServletResponse response) {
|
||||||
|
List<FundExpenseVO> list = expenseService.listExpenses(title, expenseType, payStatus, approvalStatus);
|
||||||
|
List<ExpenseExcel> excelData = list.stream().map(vo -> {
|
||||||
|
ExpenseExcel excel = new ExpenseExcel();
|
||||||
|
excel.setExpenseNo(vo.getExpenseNo());
|
||||||
|
excel.setTitle(vo.getTitle());
|
||||||
|
excel.setExpenseTypeName(vo.getExpenseTypeName());
|
||||||
|
excel.setAmount(vo.getAmount());
|
||||||
|
excel.setExpenseDate(vo.getExpenseDate());
|
||||||
|
excel.setPayeeName(vo.getPayeeName());
|
||||||
|
excel.setApprovalStatus(vo.getApprovalStatus());
|
||||||
|
excel.setPayStatus(vo.getPayStatus());
|
||||||
|
excel.setPurpose(vo.getPurpose());
|
||||||
|
excel.setCreatedTime(vo.getCreatedTime());
|
||||||
|
return excel;
|
||||||
|
}).collect(Collectors.toList());
|
||||||
|
ExcelUtil.exportExcel(excelData, "支出明细", "支出明细", ExpenseExcel.class, response, "支出明细.xlsx");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -0,0 +1,122 @@
|
|||||||
|
package com.fundplatform.exp.dto;
|
||||||
|
|
||||||
|
import cn.afterturn.easypoi.excel.annotation.Excel;
|
||||||
|
|
||||||
|
import java.math.BigDecimal;
|
||||||
|
import java.time.LocalDateTime;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 支出明细Excel导出实体
|
||||||
|
*/
|
||||||
|
public class ExpenseExcel {
|
||||||
|
|
||||||
|
@Excel(name = "支出编号", width = 15)
|
||||||
|
private String expenseNo;
|
||||||
|
|
||||||
|
@Excel(name = "支出标题", width = 25)
|
||||||
|
private String title;
|
||||||
|
|
||||||
|
@Excel(name = "支出类型", width = 12)
|
||||||
|
private String expenseTypeName;
|
||||||
|
|
||||||
|
@Excel(name = "支出金额", width = 12, type = 10)
|
||||||
|
private BigDecimal amount;
|
||||||
|
|
||||||
|
@Excel(name = "支出日期", width = 12, format = "yyyy-MM-dd")
|
||||||
|
private LocalDateTime expenseDate;
|
||||||
|
|
||||||
|
@Excel(name = "收款人", width = 12)
|
||||||
|
private String payeeName;
|
||||||
|
|
||||||
|
@Excel(name = "审批状态", width = 10, replace = {"草稿_0", "待审批_1", "已通过_2", "已拒绝_3", "已撤回_4"})
|
||||||
|
private Integer approvalStatus;
|
||||||
|
|
||||||
|
@Excel(name = "支付状态", width = 10, replace = {"未支付_0", "已支付_1", "支付失败_2"})
|
||||||
|
private Integer payStatus;
|
||||||
|
|
||||||
|
@Excel(name = "用途说明", width = 30)
|
||||||
|
private String purpose;
|
||||||
|
|
||||||
|
@Excel(name = "创建时间", width = 18, format = "yyyy-MM-dd HH:mm:ss")
|
||||||
|
private LocalDateTime createdTime;
|
||||||
|
|
||||||
|
public String getExpenseNo() {
|
||||||
|
return expenseNo;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setExpenseNo(String expenseNo) {
|
||||||
|
this.expenseNo = expenseNo;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getTitle() {
|
||||||
|
return title;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setTitle(String title) {
|
||||||
|
this.title = title;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getExpenseTypeName() {
|
||||||
|
return expenseTypeName;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setExpenseTypeName(String expenseTypeName) {
|
||||||
|
this.expenseTypeName = expenseTypeName;
|
||||||
|
}
|
||||||
|
|
||||||
|
public BigDecimal getAmount() {
|
||||||
|
return amount;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setAmount(BigDecimal amount) {
|
||||||
|
this.amount = amount;
|
||||||
|
}
|
||||||
|
|
||||||
|
public LocalDateTime getExpenseDate() {
|
||||||
|
return expenseDate;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setExpenseDate(LocalDateTime expenseDate) {
|
||||||
|
this.expenseDate = expenseDate;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getPayeeName() {
|
||||||
|
return payeeName;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setPayeeName(String payeeName) {
|
||||||
|
this.payeeName = payeeName;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Integer getApprovalStatus() {
|
||||||
|
return approvalStatus;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setApprovalStatus(Integer approvalStatus) {
|
||||||
|
this.approvalStatus = approvalStatus;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Integer getPayStatus() {
|
||||||
|
return payStatus;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setPayStatus(Integer payStatus) {
|
||||||
|
this.payStatus = payStatus;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getPurpose() {
|
||||||
|
return purpose;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setPurpose(String purpose) {
|
||||||
|
this.purpose = purpose;
|
||||||
|
}
|
||||||
|
|
||||||
|
public LocalDateTime getCreatedTime() {
|
||||||
|
return createdTime;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setCreatedTime(LocalDateTime createdTime) {
|
||||||
|
this.createdTime = createdTime;
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -14,6 +14,11 @@ public interface FundExpenseService {
|
|||||||
|
|
||||||
Page<FundExpenseVO> pageExpenses(int pageNum, int pageSize, String title, Long expenseType, Integer payStatus, Integer approvalStatus);
|
Page<FundExpenseVO> pageExpenses(int pageNum, int pageSize, String title, Long expenseType, Integer payStatus, Integer approvalStatus);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 查询支出列表(不分页,用于导出)
|
||||||
|
*/
|
||||||
|
java.util.List<FundExpenseVO> listExpenses(String title, Long expenseType, Integer payStatus, Integer approvalStatus);
|
||||||
|
|
||||||
boolean deleteExpense(Long id);
|
boolean deleteExpense(Long id);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@ -135,6 +135,19 @@ public class FundExpenseServiceImpl implements FundExpenseService {
|
|||||||
return voPage;
|
return voPage;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<FundExpenseVO> listExpenses(String title, Long expenseType, Integer payStatus, Integer approvalStatus) {
|
||||||
|
LambdaQueryWrapper<FundExpense> wrapper = new LambdaQueryWrapper<>();
|
||||||
|
wrapper.eq(FundExpense::getDeleted, 0);
|
||||||
|
if (StringUtils.hasText(title)) wrapper.like(FundExpense::getTitle, title);
|
||||||
|
if (expenseType != null) wrapper.eq(FundExpense::getExpenseType, expenseType);
|
||||||
|
if (payStatus != null) wrapper.eq(FundExpense::getPayStatus, payStatus);
|
||||||
|
if (approvalStatus != null) wrapper.eq(FundExpense::getApprovalStatus, approvalStatus);
|
||||||
|
wrapper.orderByDesc(FundExpense::getCreatedTime);
|
||||||
|
List<FundExpense> list = expenseDataService.list(wrapper);
|
||||||
|
return list.stream().map(this::convertToVO).toList();
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@Transactional(rollbackFor = Exception.class)
|
@Transactional(rollbackFor = Exception.class)
|
||||||
public boolean deleteExpense(Long id) {
|
public boolean deleteExpense(Long id) {
|
||||||
|
|||||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@ -12,6 +12,7 @@
|
|||||||
/home/along/MyCode/wanjiabuluo/fundplatform/fund-exp/src/main/java/com/fundplatform/exp/ExpApplication.java
|
/home/along/MyCode/wanjiabuluo/fundplatform/fund-exp/src/main/java/com/fundplatform/exp/ExpApplication.java
|
||||||
/home/along/MyCode/wanjiabuluo/fundplatform/fund-exp/src/main/java/com/fundplatform/exp/controller/ExpenseTypeController.java
|
/home/along/MyCode/wanjiabuluo/fundplatform/fund-exp/src/main/java/com/fundplatform/exp/controller/ExpenseTypeController.java
|
||||||
/home/along/MyCode/wanjiabuluo/fundplatform/fund-exp/src/main/java/com/fundplatform/exp/vo/FundExpenseVO.java
|
/home/along/MyCode/wanjiabuluo/fundplatform/fund-exp/src/main/java/com/fundplatform/exp/vo/FundExpenseVO.java
|
||||||
|
/home/along/MyCode/wanjiabuluo/fundplatform/fund-exp/src/main/java/com/fundplatform/exp/dto/ExpenseExcel.java
|
||||||
/home/along/MyCode/wanjiabuluo/fundplatform/fund-exp/src/main/java/com/fundplatform/exp/controller/HealthController.java
|
/home/along/MyCode/wanjiabuluo/fundplatform/fund-exp/src/main/java/com/fundplatform/exp/controller/HealthController.java
|
||||||
/home/along/MyCode/wanjiabuluo/fundplatform/fund-exp/src/main/java/com/fundplatform/exp/vo/ExpenseTypeVO.java
|
/home/along/MyCode/wanjiabuluo/fundplatform/fund-exp/src/main/java/com/fundplatform/exp/vo/ExpenseTypeVO.java
|
||||||
/home/along/MyCode/wanjiabuluo/fundplatform/fund-exp/src/main/java/com/fundplatform/exp/dto/ExpenseTypeDTO.java
|
/home/along/MyCode/wanjiabuluo/fundplatform/fund-exp/src/main/java/com/fundplatform/exp/dto/ExpenseTypeDTO.java
|
||||||
|
|||||||
@ -2,15 +2,19 @@ package com.fundplatform.receipt.controller;
|
|||||||
|
|
||||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||||
import com.fundplatform.common.core.Result;
|
import com.fundplatform.common.core.Result;
|
||||||
|
import com.fundplatform.common.util.ExcelUtil;
|
||||||
import com.fundplatform.receipt.dto.ReceivableDTO;
|
import com.fundplatform.receipt.dto.ReceivableDTO;
|
||||||
|
import com.fundplatform.receipt.dto.ReceivableExcel;
|
||||||
import com.fundplatform.receipt.service.ReceivableService;
|
import com.fundplatform.receipt.service.ReceivableService;
|
||||||
import com.fundplatform.receipt.vo.FundReceiptVO;
|
import com.fundplatform.receipt.vo.FundReceiptVO;
|
||||||
import com.fundplatform.receipt.vo.ReceivableVO;
|
import com.fundplatform.receipt.vo.ReceivableVO;
|
||||||
|
import jakarta.servlet.http.HttpServletResponse;
|
||||||
import jakarta.validation.Valid;
|
import jakarta.validation.Valid;
|
||||||
import org.springframework.web.bind.annotation.*;
|
import org.springframework.web.bind.annotation.*;
|
||||||
|
|
||||||
import java.math.BigDecimal;
|
import java.math.BigDecimal;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 应收款管理Controller
|
* 应收款管理Controller
|
||||||
@ -146,4 +150,33 @@ public class ReceivableController {
|
|||||||
public Result<Integer> getOverdueCount() {
|
public Result<Integer> getOverdueCount() {
|
||||||
return Result.success(receivableService.getOverdueCount());
|
return Result.success(receivableService.getOverdueCount());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 导出应收款明细Excel
|
||||||
|
*/
|
||||||
|
@GetMapping("/export")
|
||||||
|
public void exportExcel(
|
||||||
|
@RequestParam(required = false) Long projectId,
|
||||||
|
@RequestParam(required = false) Long customerId,
|
||||||
|
@RequestParam(required = false) String status,
|
||||||
|
@RequestParam(required = false) Integer confirmStatus,
|
||||||
|
HttpServletResponse response) {
|
||||||
|
List<ReceivableVO> list = receivableService.listReceivables(projectId, customerId, status, confirmStatus);
|
||||||
|
List<ReceivableExcel> excelData = list.stream().map(vo -> {
|
||||||
|
ReceivableExcel excel = new ReceivableExcel();
|
||||||
|
excel.setReceivableCode(vo.getReceivableCode());
|
||||||
|
excel.setProjectName(vo.getProjectName());
|
||||||
|
excel.setCustomerName(vo.getCustomerName());
|
||||||
|
excel.setTotalAmount(vo.getTotalAmount());
|
||||||
|
excel.setReceivedAmount(vo.getReceivedAmount());
|
||||||
|
excel.setRemainingAmount(vo.getRemainingAmount());
|
||||||
|
excel.setDueDate(vo.getDueDate());
|
||||||
|
excel.setReceiptStatus(vo.getReceiptStatus());
|
||||||
|
excel.setConfirmStatus(vo.getConfirmStatus());
|
||||||
|
excel.setRemark(vo.getRemark());
|
||||||
|
excel.setCreatedTime(vo.getCreatedTime());
|
||||||
|
return excel;
|
||||||
|
}).collect(Collectors.toList());
|
||||||
|
ExcelUtil.exportExcel(excelData, "应收款明细", "应收款明细", ReceivableExcel.class, response, "应收款明细.xlsx");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -0,0 +1,134 @@
|
|||||||
|
package com.fundplatform.receipt.dto;
|
||||||
|
|
||||||
|
import cn.afterturn.easypoi.excel.annotation.Excel;
|
||||||
|
|
||||||
|
import java.math.BigDecimal;
|
||||||
|
import java.time.LocalDate;
|
||||||
|
import java.time.LocalDateTime;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 应收款明细Excel导出实体
|
||||||
|
*/
|
||||||
|
public class ReceivableExcel {
|
||||||
|
|
||||||
|
@Excel(name = "应收款编号", width = 15)
|
||||||
|
private String receivableCode;
|
||||||
|
|
||||||
|
@Excel(name = "项目名称", width = 20)
|
||||||
|
private String projectName;
|
||||||
|
|
||||||
|
@Excel(name = "客户名称", width = 15)
|
||||||
|
private String customerName;
|
||||||
|
|
||||||
|
@Excel(name = "应收金额", width = 12, type = 10)
|
||||||
|
private BigDecimal totalAmount;
|
||||||
|
|
||||||
|
@Excel(name = "已收金额", width = 12, type = 10)
|
||||||
|
private BigDecimal receivedAmount;
|
||||||
|
|
||||||
|
@Excel(name = "未收金额", width = 12, type = 10)
|
||||||
|
private BigDecimal remainingAmount;
|
||||||
|
|
||||||
|
@Excel(name = "应收日期", width = 12, format = "yyyy-MM-dd")
|
||||||
|
private LocalDate dueDate;
|
||||||
|
|
||||||
|
@Excel(name = "收款状态", width = 10, replace = {"未收款_UNPAID", "部分收款_PARTIAL", "已收款_PAID", "已逾期_OVERDUE"})
|
||||||
|
private String receiptStatus;
|
||||||
|
|
||||||
|
@Excel(name = "确认状态", width = 10, replace = {"待确认_0", "已确认_1"})
|
||||||
|
private Integer confirmStatus;
|
||||||
|
|
||||||
|
@Excel(name = "备注", width = 25)
|
||||||
|
private String remark;
|
||||||
|
|
||||||
|
@Excel(name = "创建时间", width = 18, format = "yyyy-MM-dd HH:mm:ss")
|
||||||
|
private LocalDateTime createdTime;
|
||||||
|
|
||||||
|
public String getReceivableCode() {
|
||||||
|
return receivableCode;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setReceivableCode(String receivableCode) {
|
||||||
|
this.receivableCode = receivableCode;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getProjectName() {
|
||||||
|
return projectName;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setProjectName(String projectName) {
|
||||||
|
this.projectName = projectName;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getCustomerName() {
|
||||||
|
return customerName;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setCustomerName(String customerName) {
|
||||||
|
this.customerName = customerName;
|
||||||
|
}
|
||||||
|
|
||||||
|
public BigDecimal getTotalAmount() {
|
||||||
|
return totalAmount;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setTotalAmount(BigDecimal totalAmount) {
|
||||||
|
this.totalAmount = totalAmount;
|
||||||
|
}
|
||||||
|
|
||||||
|
public BigDecimal getReceivedAmount() {
|
||||||
|
return receivedAmount;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setReceivedAmount(BigDecimal receivedAmount) {
|
||||||
|
this.receivedAmount = receivedAmount;
|
||||||
|
}
|
||||||
|
|
||||||
|
public BigDecimal getRemainingAmount() {
|
||||||
|
return remainingAmount;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setRemainingAmount(BigDecimal remainingAmount) {
|
||||||
|
this.remainingAmount = remainingAmount;
|
||||||
|
}
|
||||||
|
|
||||||
|
public LocalDate getDueDate() {
|
||||||
|
return dueDate;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setDueDate(LocalDate dueDate) {
|
||||||
|
this.dueDate = dueDate;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getReceiptStatus() {
|
||||||
|
return receiptStatus;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setReceiptStatus(String receiptStatus) {
|
||||||
|
this.receiptStatus = receiptStatus;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Integer getConfirmStatus() {
|
||||||
|
return confirmStatus;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setConfirmStatus(Integer confirmStatus) {
|
||||||
|
this.confirmStatus = confirmStatus;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getRemark() {
|
||||||
|
return remark;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setRemark(String remark) {
|
||||||
|
this.remark = remark;
|
||||||
|
}
|
||||||
|
|
||||||
|
public LocalDateTime getCreatedTime() {
|
||||||
|
return createdTime;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setCreatedTime(LocalDateTime createdTime) {
|
||||||
|
this.createdTime = createdTime;
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -33,6 +33,11 @@ public interface ReceivableService {
|
|||||||
*/
|
*/
|
||||||
Page<ReceivableVO> pageReceivables(int pageNum, int pageSize, Long projectId, Long customerId, String status, Integer confirmStatus);
|
Page<ReceivableVO> pageReceivables(int pageNum, int pageSize, Long projectId, Long customerId, String status, Integer confirmStatus);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 查询应收款列表(不分页,用于导出)
|
||||||
|
*/
|
||||||
|
List<ReceivableVO> listReceivables(Long projectId, Long customerId, String status, Integer confirmStatus);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 确认应收款
|
* 确认应收款
|
||||||
*/
|
*/
|
||||||
|
|||||||
@ -137,6 +137,19 @@ public class ReceivableServiceImpl implements ReceivableService {
|
|||||||
return voPage;
|
return voPage;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<ReceivableVO> listReceivables(Long projectId, Long customerId, String status, Integer confirmStatus) {
|
||||||
|
LambdaQueryWrapper<Receivable> wrapper = new LambdaQueryWrapper<>();
|
||||||
|
wrapper.eq(Receivable::getDeleted, 0);
|
||||||
|
if (projectId != null) wrapper.eq(Receivable::getProjectId, projectId);
|
||||||
|
if (customerId != null) wrapper.eq(Receivable::getCustomerId, customerId);
|
||||||
|
if (status != null && !status.isEmpty()) wrapper.eq(Receivable::getStatus, status);
|
||||||
|
if (confirmStatus != null) wrapper.eq(Receivable::getConfirmStatus, confirmStatus);
|
||||||
|
wrapper.orderByDesc(Receivable::getCreatedTime);
|
||||||
|
List<Receivable> list = receivableDataService.list(wrapper);
|
||||||
|
return list.stream().map(this::convertToVO).toList();
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@Transactional(rollbackFor = Exception.class)
|
@Transactional(rollbackFor = Exception.class)
|
||||||
public boolean confirmReceivable(Long id, Long confirmBy) {
|
public boolean confirmReceivable(Long id, Long confirmBy) {
|
||||||
|
|||||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@ -1,19 +1,13 @@
|
|||||||
com/fundplatform/receipt/data/entity/Receivable.class
|
com/fundplatform/receipt/data/entity/Receivable.class
|
||||||
com/fundplatform/receipt/dto/FundReceiptDTO.class
|
com/fundplatform/receipt/dto/FundReceiptDTO.class
|
||||||
com/fundplatform/receipt/controller/FundReceiptController.class
|
|
||||||
com/fundplatform/receipt/data/mapper/ReceivableMapper.class
|
com/fundplatform/receipt/data/mapper/ReceivableMapper.class
|
||||||
com/fundplatform/receipt/service/impl/FundReceiptServiceImpl.class
|
|
||||||
com/fundplatform/receipt/vo/ReceivableVO.class
|
com/fundplatform/receipt/vo/ReceivableVO.class
|
||||||
com/fundplatform/receipt/vo/FundReceiptVO.class
|
com/fundplatform/receipt/vo/FundReceiptVO.class
|
||||||
com/fundplatform/receipt/data/service/FundReceiptDataService.class
|
com/fundplatform/receipt/data/service/FundReceiptDataService.class
|
||||||
com/fundplatform/receipt/controller/HealthController.class
|
|
||||||
com/fundplatform/receipt/data/service/ReceivableDataService.class
|
com/fundplatform/receipt/data/service/ReceivableDataService.class
|
||||||
com/fundplatform/receipt/data/mapper/FundReceiptMapper.class
|
com/fundplatform/receipt/data/mapper/FundReceiptMapper.class
|
||||||
com/fundplatform/receipt/service/impl/ReceivableServiceImpl.class
|
|
||||||
com/fundplatform/receipt/data/entity/FundReceipt.class
|
com/fundplatform/receipt/data/entity/FundReceipt.class
|
||||||
com/fundplatform/receipt/ReceiptApplication.class
|
com/fundplatform/receipt/ReceiptApplication.class
|
||||||
com/fundplatform/receipt/service/FundReceiptService.class
|
|
||||||
com/fundplatform/receipt/aop/ApiLogAspect.class
|
com/fundplatform/receipt/aop/ApiLogAspect.class
|
||||||
com/fundplatform/receipt/dto/ReceivableDTO.class
|
com/fundplatform/receipt/dto/ReceivableDTO.class
|
||||||
com/fundplatform/receipt/controller/ReceivableController.class
|
|
||||||
com/fundplatform/receipt/service/ReceivableService.class
|
com/fundplatform/receipt/service/ReceivableService.class
|
||||||
|
|||||||
@ -4,6 +4,7 @@
|
|||||||
/home/along/MyCode/wanjiabuluo/fundplatform/fund-receipt/src/main/java/com/fundplatform/receipt/ReceiptApplication.java
|
/home/along/MyCode/wanjiabuluo/fundplatform/fund-receipt/src/main/java/com/fundplatform/receipt/ReceiptApplication.java
|
||||||
/home/along/MyCode/wanjiabuluo/fundplatform/fund-receipt/src/main/java/com/fundplatform/receipt/data/service/FundReceiptDataService.java
|
/home/along/MyCode/wanjiabuluo/fundplatform/fund-receipt/src/main/java/com/fundplatform/receipt/data/service/FundReceiptDataService.java
|
||||||
/home/along/MyCode/wanjiabuluo/fundplatform/fund-receipt/src/main/java/com/fundplatform/receipt/dto/ReceivableDTO.java
|
/home/along/MyCode/wanjiabuluo/fundplatform/fund-receipt/src/main/java/com/fundplatform/receipt/dto/ReceivableDTO.java
|
||||||
|
/home/along/MyCode/wanjiabuluo/fundplatform/fund-receipt/src/main/java/com/fundplatform/receipt/dto/ReceivableExcel.java
|
||||||
/home/along/MyCode/wanjiabuluo/fundplatform/fund-receipt/src/main/java/com/fundplatform/receipt/data/entity/FundReceipt.java
|
/home/along/MyCode/wanjiabuluo/fundplatform/fund-receipt/src/main/java/com/fundplatform/receipt/data/entity/FundReceipt.java
|
||||||
/home/along/MyCode/wanjiabuluo/fundplatform/fund-receipt/src/main/java/com/fundplatform/receipt/service/ReceivableService.java
|
/home/along/MyCode/wanjiabuluo/fundplatform/fund-receipt/src/main/java/com/fundplatform/receipt/service/ReceivableService.java
|
||||||
/home/along/MyCode/wanjiabuluo/fundplatform/fund-receipt/src/main/java/com/fundplatform/receipt/vo/ReceivableVO.java
|
/home/along/MyCode/wanjiabuluo/fundplatform/fund-receipt/src/main/java/com/fundplatform/receipt/vo/ReceivableVO.java
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user