package project.loan.internal; import java.math.BigDecimal; import java.math.RoundingMode; import java.util.ArrayList; import java.util.Date; import java.util.HashMap; import java.util.List; import java.util.Map; import org.apache.commons.lang3.ObjectUtils; import org.springframework.jdbc.core.JdbcTemplate; import kernel.bo.RecordObjectMapper; import kernel.exception.BusinessException; import kernel.util.Arith; import kernel.util.DateUtils; import kernel.util.UUIDGenerator; import kernel.web.ApplicationUtil; import kernel.web.Page; import project.Constants; import project.data.DataService; import project.data.model.Realtime; import project.loan.LoanConstants; import project.loan.LoanOrder; import project.loan.LoanOrderService; import project.loan.LoanRelationOrder; import project.loan.LoanRelationOrderService; import project.log.MoneyLog; import project.log.MoneyLogService; import project.wallet.Wallet; import project.wallet.WalletExtend; import project.wallet.WalletService; public class LoanRelationOrderServiceImpl implements LoanRelationOrderService { private DataService dataService; private JdbcTemplate jdbcTemplate; private WalletService walletService; private MoneyLogService moneyLogService; private LoanOrderService loanOrderService; /** * 新增质押借币关联订单 */ public void saveLoanRelationOrder(LoanRelationOrder relationOrder) { relationOrder.setId(UUIDGenerator.getUUID()); relationOrder.setPledgeType(LoanConstants.PLEDGE_TYPE); relationOrder.setOrderType(LoanConstants.PLEDGE_ORDER_TYPE_LOAN); relationOrder.setLoanCurrency("usdt"); relationOrder.setCreateTime(new Date()); this.insertLoanRelationOrder(relationOrder); } /** * 质押记录 */ public List> pagedQueryPledge(int pageNo, int pageSize, String loanRelationOrderId) { if (pageNo <= 0) pageNo = 1; Page page = new Page(pageNo, pageSize, Integer.MAX_VALUE); List orders = ApplicationUtil.executeSelect(LoanRelationOrder.class,"WHERE LOAN_RELATION_ORDER_ID=? ORDER BY CREATE_TIME DESC LIMIT ?,?",new Object[] {loanRelationOrderId,page.getFirstElementNumber(),pageSize}); List> list = new ArrayList>(); for (LoanRelationOrder order : orders) { Map map = new HashMap<>(); // 借款 if (LoanConstants.PLEDGE_ORDER_TYPE_LOAN == order.getOrderType()) { map.put("orderType", order.getOrderType()); map.put("loanAmount", order.getLoanAmount()); map.put("pledgeType", order.getPledgeType()); map.put("pledgeAmount", order.getPledgeAmount()); map.put("pledgeCurrency", order.getPledgeCurrency()); map.put("createTime", DateUtils.format(order.getCreateTime(), DateUtils.DF_yyyyMMddHHmmss)); } // 续借、强平、还款 if (LoanConstants.PLEDGE_ORDER_TYPE_REFURBISH == order.getOrderType() || LoanConstants.PLEDGE_ORDER_TYPE_CLOSEOUT == order.getOrderType() || LoanConstants.PLEDGE_ORDER_TYPE_REPAY == order.getOrderType()) { map.put("orderType", order.getOrderType()); map.put("loanAmount", order.getLoanAmount()); map.put("createTime", DateUtils.format(order.getCreateTime(), DateUtils.DF_yyyyMMddHHmmss)); } // 补增质押 if (LoanConstants.PLEDGE_ORDER_TYPE_REPLENISH == order.getOrderType()) { map.put("orderType", order.getOrderType()); map.put("pledgeType", order.getPledgeType()); map.put("pledgeAmount", order.getPledgeAmount()); map.put("pledgeCurrency", order.getPledgeCurrency()); map.put("createTime", DateUtils.format(order.getCreateTime(), DateUtils.DF_yyyyMMddHHmmss)); } if(ObjectUtils.isNotEmpty(map)) { list.add(map); } } return list; } /** * 补增质押 */ public void saveReplenishOrder(String id, double pledgeAmount, String partyId) { LoanOrder order = loanOrderService.getLoanOrderParam(id); if (null == order) { throw new BusinessException(1, "order is unknown"); } if (LoanConstants.PLEDGE_ORDER_STATE_CALCULATE != order.getState()) { throw new BusinessException(1, "order state error"); } WalletExtend walletExtend = walletService.saveExtendByPara(partyId, order.getPledgeCurrency()); if (walletExtend.getAmount() < pledgeAmount) { throw new BusinessException(1, "Insufficient balance"); } double amountBeforeExtend = walletExtend.getAmount(); // 修改拓展钱包 余额 及冻结余额 walletService.updateExtend(partyId, walletExtend.getWallettype(), Arith.sub(0, pledgeAmount), pledgeAmount); // 保存资金日志 MoneyLog logExtend = new MoneyLog(); logExtend.setCategory(Constants.MONEYLOG_CATEGORY_LOAN); logExtend.setAmount_before(amountBeforeExtend); logExtend.setAmount(pledgeAmount); logExtend.setAmount_after(Arith.add(amountBeforeExtend, Arith.sub(0, pledgeAmount))); logExtend.setLog("补增质押,订单号[" + order.getOrderNo() + "]," + "冻结:" + pledgeAmount); logExtend.setPartyId(partyId); logExtend.setWallettype(order.getPledgeCurrency()); logExtend.setContent_type(Constants.MONEYLOG_CONTENT_LOAN_FROZEN); logExtend.setCreateTime(new Date()); moneyLogService.save(logExtend); // 保存质押记录 LoanRelationOrder replenish = new LoanRelationOrder(); replenish.setId(UUIDGenerator.getUUID()); replenish.setLoanRelationOrderId(id); replenish.setPartyId(partyId); replenish.setOrderType(LoanConstants.PLEDGE_ORDER_TYPE_REPLENISH); replenish.setPledgeType(LoanConstants.PLEDGE_TYPE); replenish.setPledgeCurrency(order.getPledgeCurrency()); replenish.setPledgeAmount(pledgeAmount); replenish.setCreateTime(new Date()); this.insertLoanRelationOrder(replenish); } /** * 续借 */ public void saveRefurbishOrder(String id, double loanAmountRq, String partyId) { LoanOrder order = loanOrderService.getLoanOrderParam(id); if (null == order) { throw new BusinessException(1, "order is unknown"); } if (LoanConstants.PLEDGE_ORDER_STATE_CALCULATE != order.getState()) { throw new BusinessException(1, "order state error"); } double pledgeAmount = order.getPledgeAmount(); String pledgeCurrency = order.getPledgeCurrency(); int loanCycle = order.getLoanCycle(); // 质押率 = (借款金额 + (借款金额 * 时利率 * 24 * 借款周期)) / 质押币的价格 / 质押数量 List realtimes = dataService.realtime(pledgeCurrency); double debtAmount = Arith.mul(realtimes.get(0).getClose(), pledgeAmount) * LoanConstants.PLEDGE_RATE_INITIAL; double rate = Arith.add(Arith.mul(order.getHourlyRate() * 24, loanCycle), 1); double loanAmountMax = Arith.div(debtAmount, rate, 2); double loanAmountSub = Arith.sub(loanAmountMax, order.getLoanAmount()); if (loanAmountSub < loanAmountRq) { throw new BusinessException(1, "Maximum Borrow: " + new BigDecimal(loanAmountSub).setScale(2, RoundingMode.DOWN)); } Wallet wallet = walletService.saveWalletByPartyId(partyId); double amountBefore = wallet.getMoney(); // 修改主钱包余额 walletService.update(partyId, loanAmountRq); // 保存资金日志 MoneyLog moneylog = new MoneyLog(); moneylog.setCategory(Constants.MONEYLOG_CATEGORY_LOAN); moneylog.setAmount_before(amountBefore); moneylog.setAmount(loanAmountRq); moneylog.setAmount_after(Arith.add(amountBefore, loanAmountRq)); moneylog.setLog("质押借币,订单号[" + order.getOrderNo() + "]," + "借款:" + loanAmountRq); moneylog.setPartyId(partyId); moneylog.setWallettype(Constants.WALLET); moneylog.setContent_type(Constants.MONEYLOG_CONTENT_LOAN_ADD); moneylog.setCreateTime(new Date()); moneyLogService.save(moneylog); LoanRelationOrder refurbish = new LoanRelationOrder(); refurbish.setId(UUIDGenerator.getUUID()); refurbish.setLoanRelationOrderId(id); refurbish.setPartyId(partyId); refurbish.setOrderType(LoanConstants.PLEDGE_ORDER_TYPE_REFURBISH); refurbish.setLoanAmount(loanAmountRq); refurbish.setCreateTime(new Date()); this.insertLoanRelationOrder(refurbish); // 修改质押借币单 order.setDebtAmount(Arith.add(order.getDebtAmount(), loanAmountRq)); order.setLoanAmount(Arith.add(order.getLoanAmount(), loanAmountRq)); loanOrderService.updateLoanOrder(order); // 更新缓存 loanOrderService.addCacheOrder(order); } /** * 还款 */ public void saveRepayOrder(String id, double repayAmount, String partyId) { LoanOrder order = loanOrderService.getLoanOrderParam(id); if (null == order) { throw new BusinessException(1, "order is unknown"); } if (LoanConstants.PLEDGE_ORDER_STATE_SETTLE == order.getState() || LoanConstants.PLEDGE_ORDER_STATE_CLOSEOUT == order.getState()) { throw new BusinessException(1, "order state error"); } if (repayAmount > order.getDebtAmount()) { throw new BusinessException(1, "wrong repayment amount"); } // 解冻 if (repayAmount >= order.getDebtAmount()) { WalletExtend walletExtend = walletService.saveExtendByPara(order.getPartyId(), order.getPledgeCurrency()); List list = queryOrders(id, LoanConstants.PLEDGE_ORDER_TYPE_REPLENISH); double pledgeAmount = order.getPledgeAmount(); for (LoanRelationOrder relationOrder : list) { pledgeAmount = Arith.add(pledgeAmount, relationOrder.getPledgeAmount()); } double amountBeforeExtend = walletExtend.getAmount(); // 修改拓展钱包 余额 及冻结余额 walletService.updateExtend(partyId, walletExtend.getWallettype(), pledgeAmount, Arith.sub(0, pledgeAmount)); // 保存资金日志 MoneyLog logExtend = new MoneyLog(); logExtend.setCategory(Constants.MONEYLOG_CATEGORY_LOAN); logExtend.setAmount_before(amountBeforeExtend); logExtend.setAmount(pledgeAmount); logExtend.setAmount_after(Arith.add(amountBeforeExtend, pledgeAmount)); logExtend.setLog("质押借币,订单号[" + order.getOrderNo() + "]," + "解冻:" + pledgeAmount); logExtend.setPartyId(partyId); logExtend.setWallettype(order.getPledgeCurrency()); logExtend.setContent_type(Constants.MONEYLOG_CONTENT_LOAN_THAW); logExtend.setCreateTime(new Date()); moneyLogService.save(logExtend); // 主动结清 order.setState(LoanConstants.PLEDGE_ORDER_STATE_SETTLE); } Wallet wallet = walletService.saveWalletByPartyId(partyId); double amountBefore = wallet.getMoney(); // 修改主钱包余额 walletService.update(partyId, Arith.sub(0, repayAmount)); // 保存资金日志 MoneyLog moneylog = new MoneyLog(); moneylog.setCategory(Constants.MONEYLOG_CATEGORY_LOAN); moneylog.setAmount_before(amountBefore); moneylog.setAmount(repayAmount); moneylog.setAmount_after(Arith.sub(amountBefore, repayAmount)); moneylog.setLog("借币还款,订单号[" + order.getOrderNo() + "]," + "还款:" + repayAmount); moneylog.setPartyId(partyId); moneylog.setWallettype(Constants.WALLET); moneylog.setContent_type(Constants.MONEYLOG_CONTENT_LOAN_REPAY); moneylog.setCreateTime(new Date()); moneyLogService.save(moneylog); LoanRelationOrder repay = new LoanRelationOrder(); repay.setId(UUIDGenerator.getUUID()); repay.setLoanRelationOrderId(id); repay.setPartyId(partyId); repay.setOrderType(LoanConstants.PLEDGE_ORDER_TYPE_REPAY); repay.setLoanAmount(repayAmount); repay.setCreateTime(new Date()); this.insertLoanRelationOrder(repay); // 修改质押借币单 order.setDebtAmount(Arith.sub(order.getDebtAmount(), repayAmount)); // order.setLoanAmount(Arith.sub(order.getLoanAmount(), repayAmount)); loanOrderService.updateLoanOrder(order); // 更新缓存 if (LoanConstants.PLEDGE_ORDER_STATE_SETTLE == order.getState()) { // 主动结清 loanOrderService.removeCacheOrder(order.getId()); } else { loanOrderService.addCacheOrder(order); } } /** * 后台质押记录 */ public List> queryLoanRelation(String loanRelationOrderId) { List> result = new ArrayList>(); List list = jdbcTemplate.query("SELECT * FROM T_LOAN_RELATION_ORDER WHERE LOAN_RELATION_ORDER_ID=? ORDER BY CREATE_TIME DESC", RecordObjectMapper.newInstance(LoanRelationOrder.class), loanRelationOrderId); for (LoanRelationOrder order : list) { Map data = new HashMap(); data.put("orderType", order.getOrderType()); data.put("loanAmount", order.getLoanAmount()); data.put("pledgeType", order.getPledgeType()); data.put("pledgeAmount", order.getPledgeAmount()); data.put("pledgeCurrency", order.getPledgeCurrency()); data.put("createTime", DateUtils.format(order.getCreateTime(), DateUtils.DF_yyyyMMddHHmmss)); result.add(data); } return result; } /** * 根据订单关联ID获取订单列表 */ public List queryOrders(String loanRelationOrderId, int orderType) { List list = jdbcTemplate.query("SELECT * FROM T_LOAN_RELATION_ORDER WHERE LOAN_RELATION_ORDER_ID=? AND ORDER_TYPE=?", RecordObjectMapper.newInstance(LoanRelationOrder.class), loanRelationOrderId, orderType); return list; } public void insertLoanRelationOrder(LoanRelationOrder order) { String insertSql = "INSERT INTO T_LOAN_RELATION_ORDER(UUID,LOAN_RELATION_ORDER_ID,PARTY_ID,ORDER_TYPE,LOAN_AMOUNT,LOAN_CURRENCY," + "PLEDGE_AMOUNT,PLEDGE_CURRENCY,PLEDGE_TYPE,CREATE_TIME) VALUES (?,?,?,?,?,?,?,?,?,?)"; jdbcTemplate.update(insertSql,order.getId(),order.getLoanRelationOrderId(),order.getPartyId(),order.getOrderType(), order.getLoanAmount(),order.getLoanCurrency(),order.getPledgeAmount(),order.getPledgeCurrency(), order.getPledgeType(),order.getCreateTime()); } public void setJdbcTemplate(JdbcTemplate jdbcTemplate) { this.jdbcTemplate = jdbcTemplate; } public void setWalletService(WalletService walletService) { this.walletService = walletService; } public void setMoneyLogService(MoneyLogService moneyLogService) { this.moneyLogService = moneyLogService; } public void setDataService(DataService dataService) { this.dataService = dataService; } public void setLoanOrderService(LoanOrderService loanOrderService) { this.loanOrderService = loanOrderService; } }