如何设置定时任务自动处理银行账户的利息收益?

2026-04-19 12:052阅读0评论SEO问题
  • 内容介绍
  • 文章标签
  • 相关推荐

本文共计3427个文字,预计阅读时间需要14分钟。

如何设置定时任务自动处理银行账户的利息收益?

1. 服务概述:介绍150+2.corn表达式151+资源在E:\java学习\海绵宝宝\资料\资料\08-spring-task格式:SecondsMinutesHoursDayofMonthMonthDayofWeekYear或Seconds:可能出现、-、*、/、四个字符。

1.服务概述150

2.corn表达式151

资料在E:\java学习\盈利宝\资料\资料\08-spring-task

格式:

SecondsMinutesHoursDayofMonthMonthDayofWeekYear或

SecondsMinutesHoursDayofMonthMonthDayofWeek

Seconds:可出现,-*/四个字符,有效范围为0-59的整数

Minutes:可出现,-*/四个字符,有效范围为0-59的整数

Hours:可出现,-*/四个字符,有效范围为0-23的整数

DayofMonth:可出现,-*/?LWC八个字符,有效范围为1-31的整数

Month:可出现,-*/四个字符,有效范围为1-12的整数或JAN-DEC

DayofWeek:可出现,-*/?LC#四个字符,有效范围为1-7的整数或SUN-SAT两个范围。1表示星期天,2表示星期一,依次类推

Year:可出现,-*/四个字符,有效范围为1970-2099年


2.1含义152

每一个域都使用数字,但还可以出现如下特殊字符,它们的含义是:


(1)*:表示匹配该域的任意值,假如在Minutes域使用*,即表示每分钟都会触发事件。


(2)?:只能用在DayofMonth和DayofWeek两个域。它也匹配域的任意值,但实际不会。因为DayofMonth和DayofWeek会相互影响。

例如想在每月的20日触发调度,不管20日到底是星期几,则只能使用如下写法:13131520*?,其中最后一位只能用?,而不能使用*,

如果使用*表示不管星期几都会触发,实际上并不是这样。


(3)-:表示范围,例如在Minutes域使用5-20,表示从5分到20分钟每分钟触发一次


(4)/:表示起始时间开始触发,然后每隔固定时间触发一次,例如在Minutes域使用5/20,则意味着5分钟触发一次,而25,45等分别触发一次.


(5), :表示列出枚举值值。例如:在Minutes域使用5,20,则意味着在5和20分每分钟触发一次。


(6)L:表示最后,只能出现在DayofWeek和DayofMonth域,如果在DayofWeek域使用5L,意味着在最后的一个星期四触发。


(7)W:表示有效工作日(周一到周五),只能出现在DayofMonth域,系统将在离指定日期的最近的有效工作日触发事件。

例如:在DayofMonth使用5W,如果5日是星期六,则将在最近的工作日:星期五,即4日触发。如果5日是星期天,则在6日触发;

如果5日在星期一到星期五中的一天,则就在5日触发。另外一点,W的最近寻找不会跨过月份

(8)LW:这两个字符可以连用,表示在某个月最后一个工作日,即最后一个星期五。

(9)#:用于确定每个月第几个星期几,只能出现在DayofMonth域。例如在4#2,表示某月的第二个星期三。

2.2举几个例子:152

0021*?*表示在每月的1日的凌晨2点调度任务

01510?*MON-FRI表示周一到周五每天上午10:15执行作业

01510?6L2002-2006表示2002-2006年的每个月的最后一个星期五上午10:15执行作业

3.创建一个新的模块153

直接放在course目录下即可

4.处理定时任务153

4.1举例153

启动类

TaskManager

micr-task

//每天的16点59分30秒执行 153 @Scheduled(cron = "30 59 16 * * ?") public void testCron(){ System.out.println("执行了定时任务的方法:"+ new Date()); }

//每天的每小时得每分钟每隔5秒执行一次 153 @Scheduled(cron = "*/5 * * * * ?") public void testCron2(){ System.out.println("执行了定时任务的方法:"+ new Date()); }

5.项目环境搭建153

5.1pom.xml

micr-task

<?xml version="1.0" encoding="UTF-8"?> <project xmlns="maven.apache.org/POM/4.0.0" xmlns:xsi="www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="maven.apache.org/POM/4.0.0 maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <!--自己的父项目--> <parent> <groupId>com.bjpowernode</groupId> <artifactId>micr-parent</artifactId> <version>1.0.0</version> <relativePath/> </parent> <groupId>com.bjpowernode</groupId> <artifactId>micr-task</artifactId> <version>1.0.0</version> <properties> <java.version>1.8</java.version> </properties> <dependencies> <!--dubbo公共项目依赖 153--> <dependency> <groupId>com.bjpowernode</groupId> <artifactId>micr-api</artifactId> <version>1.0.0</version> </dependency> <!--dubbo起步依赖--> <dependency> <groupId>org.apache.dubbo</groupId> <artifactId>dubbo-spring-boot-starter</artifactId> </dependency> <!--zookeeper起步依赖--> <dependency> <groupId>org.apache.dubbo</groupId> <artifactId>dubbo-dependencies-zookeeper</artifactId> <type>pom</type> </dependency> <dependency> <groupId>com.bjpowernode</groupId> <artifactId>micr-common</artifactId> <version>1.0.0</version> <scope>compile</scope> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency> </dependencies> <build> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> </plugin> </plugins> </build> </project>

5.2配置文件153

micr-task

application.yml

spring: application: name: micr-task # 153 dubbo: scan: base-packages: com.bjpowernode.task registry: address: zookeeper://localhost:2181 consumer: timeout: 50000 check: false retries: 0

5.3启动类153

micr-task

package com.bjpowernode; import org.apache.dubbo.config.spring.context.annotation.EnableDubbo; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.scheduling.annotation.EnableScheduling; @EnableDubbo //启动dubbo 153 @EnableScheduling //启用定时任务 153 @SpringBootApplication public class MicrTaskApplication { public static void main(String[] args) { SpringApplication.run(MicrTaskApplication.class, args); } }

6.计算时间测试类155

MyTest

micr-common

package com.bjpowernode; import org.apache.commons.lang3.time.DateUtils; import org.junit.Test; import java.util.Calendar; import java.util.Date; //测试计算时间 155 public class MyTest { @Test public void test01(){ Date cur = new Date(); System.out.println("cur="+cur);//当前时间 //开始 14 : 00 :00:00 Date yes = DateUtils.addDays(cur, -1); //当前时间减一天 System.out.println("yes="+yes); //昨天时间 //需要零点时间 //开始时间 Date truncate = DateUtils.truncate(DateUtils.addDays(cur, -1), Calendar.DATE); System.out.println("truncate = " + truncate); //truncate截断时间 //比如 cur=Tue Aug 01 17:46:28 CST 2023 //截断为cur=Tue Aug 01 00:00:00 CST 2023 //截止时间 Date end = DateUtils.truncate(cur, Calendar.DATE); System.out.println("end = " + end); } }

7.实现产生收益计划功能155

7.1业务接口155

IncomeService

micr-api

package com.bjpowernode.api.service; //关于收益的业务接口 155 public interface IncomeService { //收益计划 155 void generateIncomePlan(); }

7.2业务接口实现类155

7.2.1定义常量类157

micr-common

7.2.2再mapper中定义放方法

micr-dataservice

满标的理财产品列表156

ProductInfoMapper

//满标的理财产品列表 156 List<ProductInfo> selectFullTimeProducts(@Param("beginTime") Date beginTime, @Param("endTime") Date endTime);

查询某个产品的投资记录156

BidInfoMapper

//查询某个产品的投资记录 156 List<BidInfo> selectByProdId(@Param("productId") Integer productId);

更新产品状态157

ProductInfoMapper

//更新产品状态 157 int updateStatus(@Param("id") Integer id, @Param("newStatus") int newStatus);

7.2.3编写sql

micr-dataservice

满标的理财产品列表156

ProductInfoMapper.xml

<!--满标的理财产品列表 156--> <select id="selectFullTimeProducts" resultMap="BaseResultMap"> SELECT <include refid="Base_Column_List" /> FROM b_product_info WHERE product_status = 1 AND product_full_time >= #{beginTime} AND product_full_time < #{endTime} order by id </select>

查询某个产品的投资记录156

BidInfoMapper.xml

<!-- 查询某个产品的投资记录 156--> <select id="selectByProdId" resultMap="BaseResultMap"> SELECT <include refid="Base_Column_List" /> FROM b_bid_info WHERE prod_id = #{productId} AND bid_status = 1 ORDER BY id </select>

更新产品状态157

ProductInfoMapper.xml

<!--更新产品状态 157--> <update id="updateStatus"> update b_product_info set product_status = #{newStatus} where id = #{id} </update>

7.2.4实现类IncomeServiceImpl155

我来详细解释一下这个类的功能,目的就是产生收益计划,将数据存入收益表中,它是会对过去一天且满标的产品产生收益计划,不会影响其他未满标或者已经满标得产品有影响,他也不会因为产品的类型不同而重复对此产品产生收益,因为它只在每天凌晨一点执行一次

micr-dataservice

package com.bjpowernode.dataservice.service; import com.bjpowernode.api.model.BidInfo; import com.bjpowernode.api.model.IncomeRecord; import com.bjpowernode.api.model.ProductInfo; import com.bjpowernode.api.service.IncomeService; import com.bjpowernode.common.constants.YLBConstant; import com.bjpowernode.dataservice.mapper.BidInfoMapper; import com.bjpowernode.dataservice.mapper.IncomeRecordMapper; import com.bjpowernode.dataservice.mapper.ProductInfoMapper; import org.apache.commons.lang3.time.DateUtils; import org.apache.dubbo.config.annotation.DubboService; import org.springframework.transaction.annotation.Transactional; import javax.annotation.Resource; import java.math.BigDecimal; import java.math.RoundingMode; import java.util.Calendar; import java.util.Date; import java.util.List; //收益业务实现类 155 @DubboService(interfaceClass = IncomeService.class,version = "1.0") public class IncomeServiceImpl implements IncomeService { @Resource private ProductInfoMapper productInfoMapper; @Resource private BidInfoMapper bidInfoMapper; @Resource private IncomeRecordMapper incomeMapper; //157 /*收益计划 156 */ @Transactional(rollbackFor = Exception.class) //158 @Override public synchronized void generateIncomePlan() { //1.获取要处理的理财产品记录(满标的) 156 Date currentDate = new Date(); //开始时间 Date beginTime = DateUtils.truncate(DateUtils.addDays(currentDate, -1), Calendar.DATE); //截止时间 Date endTime = DateUtils.truncate(currentDate, Calendar.DATE); //获取要处理的理财产品记录(满标的) 156 List<ProductInfo> productInfoList = productInfoMapper.selectFullTimeProducts(beginTime,endTime); //2.查询每个理财产品的多个投资记录 156 int rows = 0 ; BigDecimal income = null;//利息 BigDecimal dayRate = null;//日利率 BigDecimal cycle = null; //周期 Date incomeDate = null;//到期时间 for(ProductInfo product:productInfoList){ //日利率 157 //new BigDecimal("360"),10, RoundingMode.HALF_UP(计算出来时百分比) 除以360天 保留10为小数 RoundingMode.HALF_UP四舍五入 //继续除 变成小数 .divide(new BigDecimal("100"),10, RoundingMode.HALF_UP); dayRate = product.getRate().divide(new BigDecimal("360"),10, RoundingMode.HALF_UP) .divide(new BigDecimal("100"),10, RoundingMode.HALF_UP); //产品类型不同,周期不同 天 ,月 //新手包按天算 if( product.getProductType() == YLBConstant.PRODUCT_TYPE_XINSHOUBAO){ //天为单位 //周期 157 cycle = new BigDecimal(product.getCycle()); //到期时间 157 //到期时间=产品满标时间开始+周期 举例14号满标要从15号开始算 incomeDate = DateUtils.addDays(product.getProductFullTime(),(1+product.getCycle())); } else {//其他的按月算 cycle = new BigDecimal(product.getCycle() * 30); incomeDate = DateUtils.addDays(product.getProductFullTime(),(1+ product.getCycle() * 30 )); } //查询某个产品的投资记录 156 //我们的产品每一条投资记录独立且都会产生利息 List<BidInfo> bidList = bidInfoMapper.selectByProdId(product.getId()); //3.计算每笔投资的 利息 和 到期时间 157 for(BidInfo bid : bidList){ //利息 = 本金 * 周期 * 利率 income = bid.getBidMoney().multiply(cycle).multiply(dayRate); // 创建收益记录 IncomeRecord incomeRecord = new IncomeRecord(); incomeRecord.setBidId(bid.getId());//投资id incomeRecord.setBidMoney(bid.getBidMoney());//投资金额 incomeRecord.setIncomeDate(incomeDate);//到期时间 incomeRecord.setIncomeStatus(YLBConstant.INCOME_STATUS_PLAN);//收益状态 incomeRecord.setProdId(product.getId());//产品id incomeRecord.setIncomeMoney(income);//利息 incomeRecord.setUid(bid.getUid());//投资人id //将数据添加进收益表 157 incomeMapper.insertSelective(incomeRecord); } //更新产品的状态 157 rows = productInfoMapper.updateStatus(product.getId(),YLBConstant.PRODUCT_STATUS_PLAN); if(rows < 1 ){ throw new RuntimeException("生成收益计划,更新产品状态为2失败"); } } } }

7.3先做个小调试158

TaskManager

micr-task

//测试生成收益计划 158 @DubboReference(interfaceClass = IncomeService.class, version = "1.0") private IncomeService incomeService; @Scheduled(cron = "0 0 1 * * ?")//每天凌晨1点 public void invokeGenerateIncomePlan() { incomeService.generateIncomePlan(); }

改造一下micr-task得启动类方便我们测试158

先改个名

package com.bjpowernode; import com.bjpowernode.task.TaskManager; import org.apache.dubbo.config.spring.context.annotation.EnableDubbo; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.context.ApplicationContext; import org.springframework.scheduling.annotation.EnableScheduling; @EnableDubbo //启动dubbo 153 @EnableScheduling //启用定时任务 153 @SpringBootApplication public class MicrTaskApplication { public static void main(String[] args) { //测试收益计划 158 ApplicationContext ctx = SpringApplication.run(MicrTaskApplication.class, args); TaskManager tm = (TaskManager) ctx.getBean("taskManager"); tm.invokeGenerateIncomePlan(); } }

debug模式启动micr-dataservice

正常模式启动micr-task

修改新手宝的数据方便我们测试

新手宝的原始数据

如何设置定时任务自动处理银行账户的利息收益?

执行程序

查看收益表,成功

产品表,状态为2代表开始产生收益

8.收益返还159

8.1业务接口159

IncomeService

micr-api

//收益返还 159 void generateIncomeBack();

8.2业务接口实现类159

8.2.1在mapper中定义方法159

到期收益记录159

IncomeRecordMapper

micr-dataservice

//到期收益记录 159 List<IncomeRecord> selectExpiredIncome(@Param("expiredDate") Date expiredDate);

收益返还,更新资金160

FinanceAccountMapper

//收益返还,更新资金 160 int ujapdateAvailableMoneyByIncomeBack(@Param("uid") Integer uid, @Param("bidMoney") BigDecimal bidMoney, @Param("incomeMoney") BigDecimal incomeMoney);

8.2.2编写sql159

到期收益记录159

IncomeRecordMapper.xml

micr-dataservice

<!--到期收益记录 159--> <select id="selectExpiredIncome" resultMap="BaseResultMap"> SELECT <include refid="Base_Column_List" /> FROM b_income_record WHERE income_status = 0 AND income_date = #{expiredDate} </select>

收益返还,更新资金160

FinanceAccountMapper.xml

<!--收益返还,更新资金 160--> <update id="updateAvailableMoneyByIncomeBack"> update u_finance_account set available_money = available_money + #{bidMoney} + #{incomeMoney} where uid = #{uid} </update>

8.2.3实现类159

IncomeServiceImpl

micr-dataservice

//实现收益返还 159 @Transactional(rollbackFor = Exception.class) @Override public synchronized void generateIncomeBack() { //1.获取要处理的到期的收益记录 159 Date curDate = new Date(); Date expiredDate = DateUtils.truncate(DateUtils.addDays(curDate, -1),Calendar.DATE); System.out.println("expiredDate="+expiredDate); List<IncomeRecord> incomeRecordList = incomeMapper.selectExpiredIncome(expiredDate); int rows = 0; //2.把每个收益,进行返还, 本金 + 利息 160 for(IncomeRecord ir : incomeRecordList){ rows = accountMapper.updateAvailableMoneyByIncomeBack(ir.getUid(),ir.getBidMoney(),ir.getIncomeMoney()); if( rows < 1 ){ throw new RuntimeException("收益返还,更新账号资金失败"); } //3.更新收益记录的状态为 1代表收益返还 160 ir.setIncomeStatus(YLBConstant.INCOME_STATUS_BACK); rows = incomeMapper.updateByPrimaryKey(ir); if( rows <1) { throw new RuntimeException("收益返还,更新收益记录的状态失败"); } } }

8.3做个小测试160

TaskManager

micr-task

//测试生成收益返还 160 @Scheduled(cron = "0 0 2 * * ?")//每天凌晨2点 public void invokeGenerateIncomeBack() { incomeService.generateIncomeBack(); }

改造一下micr-task得启动类方便我们测试160

debug模式启动micr-dataservice

正常模式启动micr-task

修改几条记录方便我们测试返还利息

状态变为1表示已返还

资金表加了金额,成功

本文共计3427个文字,预计阅读时间需要14分钟。

如何设置定时任务自动处理银行账户的利息收益?

1. 服务概述:介绍150+2.corn表达式151+资源在E:\java学习\海绵宝宝\资料\资料\08-spring-task格式:SecondsMinutesHoursDayofMonthMonthDayofWeekYear或Seconds:可能出现、-、*、/、四个字符。

1.服务概述150

2.corn表达式151

资料在E:\java学习\盈利宝\资料\资料\08-spring-task

格式:

SecondsMinutesHoursDayofMonthMonthDayofWeekYear或

SecondsMinutesHoursDayofMonthMonthDayofWeek

Seconds:可出现,-*/四个字符,有效范围为0-59的整数

Minutes:可出现,-*/四个字符,有效范围为0-59的整数

Hours:可出现,-*/四个字符,有效范围为0-23的整数

DayofMonth:可出现,-*/?LWC八个字符,有效范围为1-31的整数

Month:可出现,-*/四个字符,有效范围为1-12的整数或JAN-DEC

DayofWeek:可出现,-*/?LC#四个字符,有效范围为1-7的整数或SUN-SAT两个范围。1表示星期天,2表示星期一,依次类推

Year:可出现,-*/四个字符,有效范围为1970-2099年


2.1含义152

每一个域都使用数字,但还可以出现如下特殊字符,它们的含义是:


(1)*:表示匹配该域的任意值,假如在Minutes域使用*,即表示每分钟都会触发事件。


(2)?:只能用在DayofMonth和DayofWeek两个域。它也匹配域的任意值,但实际不会。因为DayofMonth和DayofWeek会相互影响。

例如想在每月的20日触发调度,不管20日到底是星期几,则只能使用如下写法:13131520*?,其中最后一位只能用?,而不能使用*,

如果使用*表示不管星期几都会触发,实际上并不是这样。


(3)-:表示范围,例如在Minutes域使用5-20,表示从5分到20分钟每分钟触发一次


(4)/:表示起始时间开始触发,然后每隔固定时间触发一次,例如在Minutes域使用5/20,则意味着5分钟触发一次,而25,45等分别触发一次.


(5), :表示列出枚举值值。例如:在Minutes域使用5,20,则意味着在5和20分每分钟触发一次。


(6)L:表示最后,只能出现在DayofWeek和DayofMonth域,如果在DayofWeek域使用5L,意味着在最后的一个星期四触发。


(7)W:表示有效工作日(周一到周五),只能出现在DayofMonth域,系统将在离指定日期的最近的有效工作日触发事件。

例如:在DayofMonth使用5W,如果5日是星期六,则将在最近的工作日:星期五,即4日触发。如果5日是星期天,则在6日触发;

如果5日在星期一到星期五中的一天,则就在5日触发。另外一点,W的最近寻找不会跨过月份

(8)LW:这两个字符可以连用,表示在某个月最后一个工作日,即最后一个星期五。

(9)#:用于确定每个月第几个星期几,只能出现在DayofMonth域。例如在4#2,表示某月的第二个星期三。

2.2举几个例子:152

0021*?*表示在每月的1日的凌晨2点调度任务

01510?*MON-FRI表示周一到周五每天上午10:15执行作业

01510?6L2002-2006表示2002-2006年的每个月的最后一个星期五上午10:15执行作业

3.创建一个新的模块153

直接放在course目录下即可

4.处理定时任务153

4.1举例153

启动类

TaskManager

micr-task

//每天的16点59分30秒执行 153 @Scheduled(cron = "30 59 16 * * ?") public void testCron(){ System.out.println("执行了定时任务的方法:"+ new Date()); }

//每天的每小时得每分钟每隔5秒执行一次 153 @Scheduled(cron = "*/5 * * * * ?") public void testCron2(){ System.out.println("执行了定时任务的方法:"+ new Date()); }

5.项目环境搭建153

5.1pom.xml

micr-task

<?xml version="1.0" encoding="UTF-8"?> <project xmlns="maven.apache.org/POM/4.0.0" xmlns:xsi="www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="maven.apache.org/POM/4.0.0 maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <!--自己的父项目--> <parent> <groupId>com.bjpowernode</groupId> <artifactId>micr-parent</artifactId> <version>1.0.0</version> <relativePath/> </parent> <groupId>com.bjpowernode</groupId> <artifactId>micr-task</artifactId> <version>1.0.0</version> <properties> <java.version>1.8</java.version> </properties> <dependencies> <!--dubbo公共项目依赖 153--> <dependency> <groupId>com.bjpowernode</groupId> <artifactId>micr-api</artifactId> <version>1.0.0</version> </dependency> <!--dubbo起步依赖--> <dependency> <groupId>org.apache.dubbo</groupId> <artifactId>dubbo-spring-boot-starter</artifactId> </dependency> <!--zookeeper起步依赖--> <dependency> <groupId>org.apache.dubbo</groupId> <artifactId>dubbo-dependencies-zookeeper</artifactId> <type>pom</type> </dependency> <dependency> <groupId>com.bjpowernode</groupId> <artifactId>micr-common</artifactId> <version>1.0.0</version> <scope>compile</scope> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency> </dependencies> <build> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> </plugin> </plugins> </build> </project>

5.2配置文件153

micr-task

application.yml

spring: application: name: micr-task # 153 dubbo: scan: base-packages: com.bjpowernode.task registry: address: zookeeper://localhost:2181 consumer: timeout: 50000 check: false retries: 0

5.3启动类153

micr-task

package com.bjpowernode; import org.apache.dubbo.config.spring.context.annotation.EnableDubbo; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.scheduling.annotation.EnableScheduling; @EnableDubbo //启动dubbo 153 @EnableScheduling //启用定时任务 153 @SpringBootApplication public class MicrTaskApplication { public static void main(String[] args) { SpringApplication.run(MicrTaskApplication.class, args); } }

6.计算时间测试类155

MyTest

micr-common

package com.bjpowernode; import org.apache.commons.lang3.time.DateUtils; import org.junit.Test; import java.util.Calendar; import java.util.Date; //测试计算时间 155 public class MyTest { @Test public void test01(){ Date cur = new Date(); System.out.println("cur="+cur);//当前时间 //开始 14 : 00 :00:00 Date yes = DateUtils.addDays(cur, -1); //当前时间减一天 System.out.println("yes="+yes); //昨天时间 //需要零点时间 //开始时间 Date truncate = DateUtils.truncate(DateUtils.addDays(cur, -1), Calendar.DATE); System.out.println("truncate = " + truncate); //truncate截断时间 //比如 cur=Tue Aug 01 17:46:28 CST 2023 //截断为cur=Tue Aug 01 00:00:00 CST 2023 //截止时间 Date end = DateUtils.truncate(cur, Calendar.DATE); System.out.println("end = " + end); } }

7.实现产生收益计划功能155

7.1业务接口155

IncomeService

micr-api

package com.bjpowernode.api.service; //关于收益的业务接口 155 public interface IncomeService { //收益计划 155 void generateIncomePlan(); }

7.2业务接口实现类155

7.2.1定义常量类157

micr-common

7.2.2再mapper中定义放方法

micr-dataservice

满标的理财产品列表156

ProductInfoMapper

//满标的理财产品列表 156 List<ProductInfo> selectFullTimeProducts(@Param("beginTime") Date beginTime, @Param("endTime") Date endTime);

查询某个产品的投资记录156

BidInfoMapper

//查询某个产品的投资记录 156 List<BidInfo> selectByProdId(@Param("productId") Integer productId);

更新产品状态157

ProductInfoMapper

//更新产品状态 157 int updateStatus(@Param("id") Integer id, @Param("newStatus") int newStatus);

7.2.3编写sql

micr-dataservice

满标的理财产品列表156

ProductInfoMapper.xml

<!--满标的理财产品列表 156--> <select id="selectFullTimeProducts" resultMap="BaseResultMap"> SELECT <include refid="Base_Column_List" /> FROM b_product_info WHERE product_status = 1 AND product_full_time >= #{beginTime} AND product_full_time < #{endTime} order by id </select>

查询某个产品的投资记录156

BidInfoMapper.xml

<!-- 查询某个产品的投资记录 156--> <select id="selectByProdId" resultMap="BaseResultMap"> SELECT <include refid="Base_Column_List" /> FROM b_bid_info WHERE prod_id = #{productId} AND bid_status = 1 ORDER BY id </select>

更新产品状态157

ProductInfoMapper.xml

<!--更新产品状态 157--> <update id="updateStatus"> update b_product_info set product_status = #{newStatus} where id = #{id} </update>

7.2.4实现类IncomeServiceImpl155

我来详细解释一下这个类的功能,目的就是产生收益计划,将数据存入收益表中,它是会对过去一天且满标的产品产生收益计划,不会影响其他未满标或者已经满标得产品有影响,他也不会因为产品的类型不同而重复对此产品产生收益,因为它只在每天凌晨一点执行一次

micr-dataservice

package com.bjpowernode.dataservice.service; import com.bjpowernode.api.model.BidInfo; import com.bjpowernode.api.model.IncomeRecord; import com.bjpowernode.api.model.ProductInfo; import com.bjpowernode.api.service.IncomeService; import com.bjpowernode.common.constants.YLBConstant; import com.bjpowernode.dataservice.mapper.BidInfoMapper; import com.bjpowernode.dataservice.mapper.IncomeRecordMapper; import com.bjpowernode.dataservice.mapper.ProductInfoMapper; import org.apache.commons.lang3.time.DateUtils; import org.apache.dubbo.config.annotation.DubboService; import org.springframework.transaction.annotation.Transactional; import javax.annotation.Resource; import java.math.BigDecimal; import java.math.RoundingMode; import java.util.Calendar; import java.util.Date; import java.util.List; //收益业务实现类 155 @DubboService(interfaceClass = IncomeService.class,version = "1.0") public class IncomeServiceImpl implements IncomeService { @Resource private ProductInfoMapper productInfoMapper; @Resource private BidInfoMapper bidInfoMapper; @Resource private IncomeRecordMapper incomeMapper; //157 /*收益计划 156 */ @Transactional(rollbackFor = Exception.class) //158 @Override public synchronized void generateIncomePlan() { //1.获取要处理的理财产品记录(满标的) 156 Date currentDate = new Date(); //开始时间 Date beginTime = DateUtils.truncate(DateUtils.addDays(currentDate, -1), Calendar.DATE); //截止时间 Date endTime = DateUtils.truncate(currentDate, Calendar.DATE); //获取要处理的理财产品记录(满标的) 156 List<ProductInfo> productInfoList = productInfoMapper.selectFullTimeProducts(beginTime,endTime); //2.查询每个理财产品的多个投资记录 156 int rows = 0 ; BigDecimal income = null;//利息 BigDecimal dayRate = null;//日利率 BigDecimal cycle = null; //周期 Date incomeDate = null;//到期时间 for(ProductInfo product:productInfoList){ //日利率 157 //new BigDecimal("360"),10, RoundingMode.HALF_UP(计算出来时百分比) 除以360天 保留10为小数 RoundingMode.HALF_UP四舍五入 //继续除 变成小数 .divide(new BigDecimal("100"),10, RoundingMode.HALF_UP); dayRate = product.getRate().divide(new BigDecimal("360"),10, RoundingMode.HALF_UP) .divide(new BigDecimal("100"),10, RoundingMode.HALF_UP); //产品类型不同,周期不同 天 ,月 //新手包按天算 if( product.getProductType() == YLBConstant.PRODUCT_TYPE_XINSHOUBAO){ //天为单位 //周期 157 cycle = new BigDecimal(product.getCycle()); //到期时间 157 //到期时间=产品满标时间开始+周期 举例14号满标要从15号开始算 incomeDate = DateUtils.addDays(product.getProductFullTime(),(1+product.getCycle())); } else {//其他的按月算 cycle = new BigDecimal(product.getCycle() * 30); incomeDate = DateUtils.addDays(product.getProductFullTime(),(1+ product.getCycle() * 30 )); } //查询某个产品的投资记录 156 //我们的产品每一条投资记录独立且都会产生利息 List<BidInfo> bidList = bidInfoMapper.selectByProdId(product.getId()); //3.计算每笔投资的 利息 和 到期时间 157 for(BidInfo bid : bidList){ //利息 = 本金 * 周期 * 利率 income = bid.getBidMoney().multiply(cycle).multiply(dayRate); // 创建收益记录 IncomeRecord incomeRecord = new IncomeRecord(); incomeRecord.setBidId(bid.getId());//投资id incomeRecord.setBidMoney(bid.getBidMoney());//投资金额 incomeRecord.setIncomeDate(incomeDate);//到期时间 incomeRecord.setIncomeStatus(YLBConstant.INCOME_STATUS_PLAN);//收益状态 incomeRecord.setProdId(product.getId());//产品id incomeRecord.setIncomeMoney(income);//利息 incomeRecord.setUid(bid.getUid());//投资人id //将数据添加进收益表 157 incomeMapper.insertSelective(incomeRecord); } //更新产品的状态 157 rows = productInfoMapper.updateStatus(product.getId(),YLBConstant.PRODUCT_STATUS_PLAN); if(rows < 1 ){ throw new RuntimeException("生成收益计划,更新产品状态为2失败"); } } } }

7.3先做个小调试158

TaskManager

micr-task

//测试生成收益计划 158 @DubboReference(interfaceClass = IncomeService.class, version = "1.0") private IncomeService incomeService; @Scheduled(cron = "0 0 1 * * ?")//每天凌晨1点 public void invokeGenerateIncomePlan() { incomeService.generateIncomePlan(); }

改造一下micr-task得启动类方便我们测试158

先改个名

package com.bjpowernode; import com.bjpowernode.task.TaskManager; import org.apache.dubbo.config.spring.context.annotation.EnableDubbo; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.context.ApplicationContext; import org.springframework.scheduling.annotation.EnableScheduling; @EnableDubbo //启动dubbo 153 @EnableScheduling //启用定时任务 153 @SpringBootApplication public class MicrTaskApplication { public static void main(String[] args) { //测试收益计划 158 ApplicationContext ctx = SpringApplication.run(MicrTaskApplication.class, args); TaskManager tm = (TaskManager) ctx.getBean("taskManager"); tm.invokeGenerateIncomePlan(); } }

debug模式启动micr-dataservice

正常模式启动micr-task

修改新手宝的数据方便我们测试

新手宝的原始数据

如何设置定时任务自动处理银行账户的利息收益?

执行程序

查看收益表,成功

产品表,状态为2代表开始产生收益

8.收益返还159

8.1业务接口159

IncomeService

micr-api

//收益返还 159 void generateIncomeBack();

8.2业务接口实现类159

8.2.1在mapper中定义方法159

到期收益记录159

IncomeRecordMapper

micr-dataservice

//到期收益记录 159 List<IncomeRecord> selectExpiredIncome(@Param("expiredDate") Date expiredDate);

收益返还,更新资金160

FinanceAccountMapper

//收益返还,更新资金 160 int ujapdateAvailableMoneyByIncomeBack(@Param("uid") Integer uid, @Param("bidMoney") BigDecimal bidMoney, @Param("incomeMoney") BigDecimal incomeMoney);

8.2.2编写sql159

到期收益记录159

IncomeRecordMapper.xml

micr-dataservice

<!--到期收益记录 159--> <select id="selectExpiredIncome" resultMap="BaseResultMap"> SELECT <include refid="Base_Column_List" /> FROM b_income_record WHERE income_status = 0 AND income_date = #{expiredDate} </select>

收益返还,更新资金160

FinanceAccountMapper.xml

<!--收益返还,更新资金 160--> <update id="updateAvailableMoneyByIncomeBack"> update u_finance_account set available_money = available_money + #{bidMoney} + #{incomeMoney} where uid = #{uid} </update>

8.2.3实现类159

IncomeServiceImpl

micr-dataservice

//实现收益返还 159 @Transactional(rollbackFor = Exception.class) @Override public synchronized void generateIncomeBack() { //1.获取要处理的到期的收益记录 159 Date curDate = new Date(); Date expiredDate = DateUtils.truncate(DateUtils.addDays(curDate, -1),Calendar.DATE); System.out.println("expiredDate="+expiredDate); List<IncomeRecord> incomeRecordList = incomeMapper.selectExpiredIncome(expiredDate); int rows = 0; //2.把每个收益,进行返还, 本金 + 利息 160 for(IncomeRecord ir : incomeRecordList){ rows = accountMapper.updateAvailableMoneyByIncomeBack(ir.getUid(),ir.getBidMoney(),ir.getIncomeMoney()); if( rows < 1 ){ throw new RuntimeException("收益返还,更新账号资金失败"); } //3.更新收益记录的状态为 1代表收益返还 160 ir.setIncomeStatus(YLBConstant.INCOME_STATUS_BACK); rows = incomeMapper.updateByPrimaryKey(ir); if( rows <1) { throw new RuntimeException("收益返还,更新收益记录的状态失败"); } } }

8.3做个小测试160

TaskManager

micr-task

//测试生成收益返还 160 @Scheduled(cron = "0 0 2 * * ?")//每天凌晨2点 public void invokeGenerateIncomeBack() { incomeService.generateIncomeBack(); }

改造一下micr-task得启动类方便我们测试160

debug模式启动micr-dataservice

正常模式启动micr-task

修改几条记录方便我们测试返还利息

状态变为1表示已返还

资金表加了金额,成功