feat: 定时任务与账期逾期管理功能

1. 定时任务框架:
   - 使用Spring @Scheduled实现定时任务(替代XXL-JOB简化部署)
   - @EnableScheduling启用定时任务
   - 条件配置: fund.schedule.enabled

2. 定时任务列表:
   - 逾期状态更新: 每天凌晨1点执行
   - 逾期提醒通知: 每天上午9点执行
   - 账期预警提醒: 每周一上午10点执行

3. 账期管理API:
   - GET /upcoming-due: 获取即将到期应收款列表
   - 支持指定天数内到期的应收款查询

4. 服务层增强:
   - ReceivableService.getUpcomingDueList(): 查询即将到期应收款
   - ReceivableServiceImpl: 完整实现逾期状态更新逻辑
This commit is contained in:
zhangjf 2026-02-20 09:06:40 +08:00
parent 06efab9596
commit eafb783e2b
18 changed files with 140 additions and 4 deletions

View File

@ -3,9 +3,11 @@ package com.fundplatform.receipt;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
import org.springframework.scheduling.annotation.EnableScheduling;
@SpringBootApplication
@EnableDiscoveryClient
@EnableScheduling
public class ReceiptApplication {
public static void main(String[] args) {

View File

@ -151,6 +151,16 @@ public class ReceivableController {
return Result.success(receivableService.getOverdueCount());
}
/**
* 获取即将到期的应收款列表
* @param daysWithin 未来多少天内到期默认7天
*/
@GetMapping("/upcoming-due")
public Result<List<ReceivableVO>> getUpcomingDue(
@RequestParam(defaultValue = "7") int daysWithin) {
return Result.success(receivableService.getUpcomingDueList(daysWithin));
}
/**
* 导出应收款明细Excel
*/
@ -167,11 +177,11 @@ public class ReceivableController {
excel.setReceivableCode(vo.getReceivableCode());
excel.setProjectName(vo.getProjectName());
excel.setCustomerName(vo.getCustomerName());
excel.setTotalAmount(vo.getTotalAmount());
excel.setTotalAmount(vo.getReceivableAmount());
excel.setReceivedAmount(vo.getReceivedAmount());
excel.setRemainingAmount(vo.getRemainingAmount());
excel.setDueDate(vo.getDueDate());
excel.setReceiptStatus(vo.getReceiptStatus());
excel.setRemainingAmount(vo.getUnpaidAmount());
excel.setDueDate(vo.getPaymentDueDate());
excel.setReceiptStatus(vo.getStatus());
excel.setConfirmStatus(vo.getConfirmStatus());
excel.setRemark(vo.getRemark());
excel.setCreatedTime(vo.getCreatedTime());

View File

@ -84,4 +84,10 @@ public interface ReceivableService {
* 获取逾期应收款数量
*/
Integer getOverdueCount();
/**
* 获取即将到期的应收款列表
* @param daysWithin 未来多少天内到期
*/
List<ReceivableVO> getUpcomingDueList(int daysWithin);
}

View File

@ -403,4 +403,21 @@ public class ReceivableServiceImpl implements ReceivableService {
.eq(Receivable::getStatus, STATUS_OVERDUE);
return (int) receivableDataService.count(wrapper);
}
@Override
public List<ReceivableVO> getUpcomingDueList(int daysWithin) {
LocalDate today = LocalDate.now();
LocalDate endDate = today.plusDays(daysWithin);
LambdaQueryWrapper<Receivable> wrapper = new LambdaQueryWrapper<>();
wrapper.eq(Receivable::getDeleted, 0)
.eq(Receivable::getConfirmStatus, CONFIRM_CONFIRMED)
.ne(Receivable::getStatus, STATUS_RECEIVED)
.isNotNull(Receivable::getPaymentDueDate)
.between(Receivable::getPaymentDueDate, today, endDate)
.orderByAsc(Receivable::getPaymentDueDate);
List<Receivable> list = receivableDataService.list(wrapper);
return list.stream().map(this::convertToVO).toList();
}
}

View File

@ -0,0 +1,74 @@
package com.fundplatform.receipt.task;
import com.fundplatform.receipt.service.ReceivableService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
/**
* 应收款定时任务
* 执行逾期状态更新和提醒
*/
@Component
@ConditionalOnProperty(name = "fund.schedule.enabled", havingValue = "true", matchIfMissing = true)
public class ReceivableScheduledTask {
private static final Logger log = LoggerFactory.getLogger(ReceivableScheduledTask.class);
private final ReceivableService receivableService;
public ReceivableScheduledTask(ReceivableService receivableService) {
this.receivableService = receivableService;
}
/**
* 每天凌晨1点执行逾期状态更新
* cron表达式:
*/
@Scheduled(cron = "0 0 1 * * ?")
public void updateOverdueStatus() {
log.info("开始执行逾期状态更新定时任务...");
try {
receivableService.updateOverdueStatus();
log.info("逾期状态更新定时任务执行完成");
} catch (Exception e) {
log.error("逾期状态更新定时任务执行失败", e);
}
}
/**
* 每天上午9点执行逾期提醒
* 发送逾期预警通知
*/
@Scheduled(cron = "0 0 9 * * ?")
public void sendOverdueReminder() {
log.info("开始执行逾期提醒定时任务...");
try {
// TODO: 集成消息通知服务后实现
// Integer overdueCount = receivableService.getOverdueCount();
// notificationService.sendOverdueAlert(overdueCount);
log.info("逾期提醒定时任务执行完成(待集成消息通知服务)");
} catch (Exception e) {
log.error("逾期提醒定时任务执行失败", e);
}
}
/**
* 每周一上午10点执行账期预警
* 提醒即将到期的应收款
*/
@Scheduled(cron = "0 0 10 ? * MON")
public void sendDueDateWarning() {
log.info("开始执行账期预警定时任务...");
try {
// TODO: 集成消息通知服务后实现
// List<ReceivableVO> upcomingDue = receivableService.getUpcomingDueList(7);
// notificationService.sendDueDateWarning(upcomingDue);
log.info("账期预警定时任务执行完成(待集成消息通知服务)");
} catch (Exception e) {
log.error("账期预警定时任务执行失败", e);
}
}
}

View File

@ -53,3 +53,14 @@ tenant:
tenant-header: X-Tenant-Id
default-tenant-id: "1"
fallback-to-shared: true
# 定时任务配置
fund:
schedule:
enabled: true
# 逾期状态更新每天凌晨1点
overdue-update-cron: "0 0 1 * * ?"
# 逾期提醒每天上午9点
overdue-reminder-cron: "0 0 9 * * ?"
# 账期预警每周一上午10点
due-date-warning-cron: "0 0 10 ? * MON"

View File

@ -53,3 +53,14 @@ tenant:
tenant-header: X-Tenant-Id
default-tenant-id: "1"
fallback-to-shared: true
# 定时任务配置
fund:
schedule:
enabled: true
# 逾期状态更新每天凌晨1点
overdue-update-cron: "0 0 1 * * ?"
# 逾期提醒每天上午9点
overdue-reminder-cron: "0 0 9 * * ?"
# 账期预警每周一上午10点
due-date-warning-cron: "0 0 10 ? * MON"

View File

@ -1,13 +1,17 @@
com/fundplatform/receipt/data/entity/Receivable.class
com/fundplatform/receipt/dto/FundReceiptDTO.class
com/fundplatform/receipt/controller/FundReceiptController.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/FundReceiptVO.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/mapper/FundReceiptMapper.class
com/fundplatform/receipt/data/entity/FundReceipt.class
com/fundplatform/receipt/ReceiptApplication.class
com/fundplatform/receipt/service/FundReceiptService.class
com/fundplatform/receipt/aop/ApiLogAspect.class
com/fundplatform/receipt/dto/ReceivableDTO.class
com/fundplatform/receipt/service/ReceivableService.class

View File

@ -1,6 +1,7 @@
/home/along/MyCode/wanjiabuluo/fundplatform/fund-receipt/src/main/java/com/fundplatform/receipt/data/mapper/FundReceiptMapper.java
/home/along/MyCode/wanjiabuluo/fundplatform/fund-receipt/src/main/java/com/fundplatform/receipt/aop/ApiLogAspect.java
/home/along/MyCode/wanjiabuluo/fundplatform/fund-receipt/src/main/java/com/fundplatform/receipt/data/mapper/ReceivableMapper.java
/home/along/MyCode/wanjiabuluo/fundplatform/fund-receipt/src/main/java/com/fundplatform/receipt/task/ReceivableScheduledTask.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/dto/ReceivableDTO.java