发表于: 2017-10-20 21:50:37
1 768
一、今天完成的主要事情
1.完成用户投资产品详情接口和查询还款计划接口
用户投资产品详情接口比较简单,这里就不贴出来了
以下是查询还款计划接口
如果用户查询自己投资的产品的回款计划,那么直接就去回款计划表中查询即可
如果是用户为了查看要投资的产品,模拟投资情况计算回款计划,那么就通过产品Id,投资金额计算回款计划
/**
* 23.查询还款计划
*
* @param
* @return
* @throws ServiceException
* @throws ServiceDaoException
*/
@RequestMapping(value = "/a/u/repayment", method = RequestMethod.GET)
public String getRepaymentList(HttpServletRequest request,
HttpServletResponse response, ModelMap model, Long userId, Long productId,
Integer repaymentStatus, BigDecimal investAmount) throws Exception {
log.info("getRepaymentList() parameters : userId : " + userId + ", repaymentStatus : " +
repaymentStatus + ", investAmount : " + investAmount + ", productId : " + productId);
if (DataUtils.isNullOrEmpty(userId) || DataUtils.isNullOrEmpty(repaymentStatus)) {
log.info("Parameters userId and repaymentStatus can not be NULL!");
model.addAttribute("code", -1000);
return "/common/failure";
}
if (userId < 0 && DataUtils.isNullOrEmpty(investAmount) && DataUtils.isNullOrEmpty(productId)) {
log.info("Parameter investAmount and productId can not be NULL when userId = -1");
model.addAttribute("code", -1000);
return "/common/failure";
}
List<Repayment> repayments = null;
try {
if (userId > 0) {
//获取还款计划表ID
List<Long> repaymentIds = repaymentService.getRepaymentIdsByUserIdAndStatus(userId, 1, 0,
Integer.MAX_VALUE);
log.info("get countRepaymentIdsByUserIdAndStatus size is : " + repaymentIds.size());
//获取还款计划表对象
if (CollectionUtils.isNotEmpty(repaymentIds)) {
repayments = repaymentService.getObjectsByIds(repaymentIds);
log.info("get repayments data size is : " + repayments.size());
}
} else {
//获取产品对象
Product product = productService.getObjectById(productId);
log.info("get product data is : " + product);
if (DataUtils.isNullOrEmpty(product)) {
log.info("Couldn't find product by productId, productId is : " + productId);
model.addAttribute("code", -4);
return "/common/failure";
}
//获取年化收益率
BigDecimal annualYield = product.getAnnualYield();
//获取还款方式
Integer paymentBackWay = product.getPaymentBackWay();
//获取投资期限
Integer financialPeriod = product.getFinancialPeriod();
//获取起息方式
Integer chargingInterestWay = product.getChargingInterestWay();
log.info("get fields annualYield,paymentBackWay,financialPeriod,chargingInterestWay" +
"from product. annualYield : " + annualYield + ", paymentBackWay: " + paymentBackWay +
", financialPeriod: " + financialPeriod + ", chargingInterestWay: " + chargingInterestWay);
//验证参数
Integer validateResult = ProductUtil.validateProductFields(annualYield, paymentBackWay,
financialPeriod, chargingInterestWay);
if (validateResult < 0) {
model.addAttribute("code", validateResult);
return "/common/failure";
}
//假设投资日期为当天
Long nowTime = System.currentTimeMillis();
//计算起息日期Long startDays = nowTime + chargingInterestWay * 1000 * 3600 * 24;
//重点是这个方法,该方法将起息日期,投资金额,年化收益率,投资期限,回款方式传递进去,返回的就是完整的回款计划
repayments = InvestUtil.getRepaymentPlanList(startDays, investAmount, annualYield,
financialPeriod, paymentBackWay);
}
model.addAttribute("code", 0);
model.addAttribute("repaymentList", repayments);
} catch (Throwable t) {
t.printStackTrace();
log.info(t.getMessage());
log.info("getRepaymentList() error, userId is : " + userId);
model.addAttribute("code", -1);
return "/common/failure";
}
return "/polyFinance-business-service/repayment/json/repaymentListJson";
}
上述方法是在Investment功能类中实现
/**
* 根据起息日期,投资金额,年化收益率,起息方式计算还款计划
*
* @param
* @return
*/
public static List<Repayment> getRepaymentPlanList(Long startDays, BigDecimal investAmount, BigDecimal yield,
Integer financialPeriod, Integer paymentBackWay) {
List<Repayment> repayments = new ArrayList<Repayment>();
if (paymentBackWay == 0) {
//按月付息,到期还本
repayments = getRepaymentPlanPhase(startDays, investAmount, yield, financialPeriod);
log.info("get repayment list size is : " + repayments.size());
} else if (paymentBackWay == 1) {
//一次性还本付息
//计算总利息
BigDecimal interest = getInterest(investAmount, yield, financialPeriod);
//计算还款时间
Long endTime = startDays + financialPeriod * 1000 * 3600 * 24;
Repayment repayment = new Repayment();
repayment.setRepaymentDate(endTime);
repayment.setRepaymentAmount(interest);
repayment.setStatus(1);
repayments.add(repayment);
//将本金也加入还款计划
Repayment lastRepayment = new Repayment();
lastRepayment.setStatus(1);
lastRepayment.setRepaymentDate(endTime);
lastRepayment.setRepaymentAmount(investAmount);
repayments.add(lastRepayment);
log.info("get repayment list size is : " + repayments.size());
} else {
log.info("Error parameter value. Error paymentBackWay is: " + paymentBackWay);
}
return repayments;
}
/**
* 计算当还款方式为按月付息,到期还本时的还款计划
*
* @param
* @return
*/
private static List<Repayment> getRepaymentPlanPhase(Long startDays, BigDecimal investAmount, BigDecimal yield,
Integer financialPeriod) {
//获取每次还款的时间
List<Long> longList = getRepaymentPlan(startDays, financialPeriod);
List<Repayment> repayments = new ArrayList<Repayment>();
for (int i=1; i<longList.size(); i++){
Repayment repayment = new Repayment();
repayment.setStatus(1);
repayment.setRepaymentDate(longList.get(i));
//计算还款天数
int days = (int) ((longList.get(i) - longList.get(i-1)) / 1000 / 3600 / 24);
//获取每一期要还的金额
BigDecimal interest = getInterest(investAmount, yield, days);
repayment.setRepaymentAmount(interest);
repayments.add(repayment);
}
//将本金也加入还款计划
Repayment lastRepayment = new Repayment();
lastRepayment.setStatus(1);
lastRepayment.setRepaymentDate(longList.get(longList.size()-1));
lastRepayment.setRepaymentAmount(investAmount);
repayments.add(lastRepayment);
return repayments;
}
/**
* 根据投资金额,年化收益率,期限计算利息
*
* @param
* @return
*/
private static BigDecimal getInterest(BigDecimal investAmount, BigDecimal yield,
Integer financialPeriod) {
//计算年化利息
BigDecimal interest = investAmount.multiply(yield);
//计算每天的利息
interest = interest.divide(new BigDecimal("360"), 6);
//计算总利息
interest = interest.multiply(new BigDecimal(financialPeriod + ""));
return interest;
}
/**
* 根据起始时间和投资期限,计算每次还款的日期时间戳
*
* @param
* @return
*/
private static List<Long> getRepaymentPlan(long startTime, int days) {
List<Long> list = new ArrayList<Long>();
long endTime = startTime + days * 1000 * 3600 * 24L;
//将初始时间戳转换为格式化时间
SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyyMMdd");
String formatStartDate = simpleDateFormat.format(new Date(startTime));
try {
//将开始时间转换为标准时间格式加入结果集
list.add(simpleDateFormat.parse(formatStartDate).getTime());
} catch (ParseException e) {
e.printStackTrace();
log.error(e.getMessage());
log.error("Time conversion exception");
return null;
}
Date date = null;
//将格式化时间转化为整形数字,方便计算
Integer startDateNumber = Integer.valueOf(formatStartDate);
while (true) {
//月份加1后再转换为字符串,如果有0230,0231这种特例,将其转换为0301
startDateNumber += 100;
String newFormatDate = startDateNumber.toString();
String tempStr = newFormatDate.substring(4);
if (tempStr.equals("0230") || tempStr.equals("0231")) {
newFormatDate = newFormatDate.substring(0, 4) + "0301";
}
try {
//将生成的格式化时间再解析成时间戳放入结果集
date = simpleDateFormat.parse(newFormatDate);
long repaymentTime = date.getTime();
if (repaymentTime < endTime) {
list.add(repaymentTime);
} else {
list.add(endTime);
break;
}
} catch (ParseException e) {
e.printStackTrace();
log.error(e.getMessage());
log.error("Time conversion exception");
return null;
}
}
return list;
}
该类中的方法包括计算每次还款的日期,计算每次还款的金额等等,通过这个功能类,就能实现计算回款计划的功能
该类还会在投资接口和跑批service中用到测试结果是:
二.明天计划完成的事情
1.继续投资列表story,编写查询合同接口,然后再趁热打铁,完成一部分用户投资接口
三.遇到的问题
暂无
四.收获
以上
五.项目进度情况
有延期风险
评论