package com.gear.customer.swx.biz.impl; import com.alibaba.fastjson2.JSONArray; import com.alibaba.fastjson2.JSONObject; import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; import com.baomidou.mybatisplus.core.metadata.IPage; import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.gear.common.constant.SwxConstons; import com.gear.common.core.redis.RedisCache; import com.gear.common.exception.CustomerException; import com.gear.customer.swx.biz.SwxBizOrder; import com.gear.customer.swx.config.DelayQueueRabbitConfig; import com.gear.customer.swx.vo.request.SwxBuyOptionsVo; import com.gear.customer.swx.vo.request.SwxBuySmartVo; import com.gear.customer.swx.vo.response.SwxBuyOptionsInfo; import com.gear.customer.swx.vo.response.SwxUserInfoVo; import com.gear.swx.domain.*; import com.gear.swx.service.*; import lombok.extern.slf4j.Slf4j; import org.apache.logging.log4j.util.Strings; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.amqp.rabbit.core.RabbitTemplate; import org.springframework.beans.BeanUtils; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; import java.math.BigDecimal; import java.math.RoundingMode; import java.text.SimpleDateFormat; import java.time.LocalDateTime; import java.time.ZoneId; import java.util.*; import java.util.concurrent.TimeUnit; @Component @Slf4j public class SwxBizOrderImpl implements SwxBizOrder { private static final Logger lg = LoggerFactory.getLogger("orderFile"); private static final Logger logger = LoggerFactory.getLogger(SwxBizOrderImpl.class); @Autowired private ISwxSmartOrderService swxSmartOrderService; @Autowired private ISwxUserService swxUserService; @Autowired private ISwxMarketService swxMarketService; @Autowired private ISwxMarketSmartService swxMarketSmartService; @Autowired private ISwxMoneyLogService swxMoneyLogService; @Autowired private ISwxOrderService swxOrderService; @Autowired private ISwxOptionsOrderService swxOptionsOrderService; @Autowired private ISwxMarketOptionsService swxMarketOptionsService; @Autowired private RedisCache redisCache; @Autowired private ISwxSettingsService swxSettingsService; @Autowired RabbitTemplate rabbitTemplate; @Autowired private ISwxUserLevelService swxUserLevelService; @Override public String buySmart(SwxBuySmartVo vo, String userId, String virtually) throws CustomerException { if (!SwxConstons.SWX_CUSTOMER_USER_ORDER_TYPE_TRUE.equals(virtually)){ throw new CustomerException("10008"); } //获取用户信息 SwxUser swxUser = swxUserService.getById(userId); if (swxUser == null){ throw new CustomerException("10009"); } //获取产品 SwxMarketSmart swxMarketSmart = swxMarketSmartService.getById(vo.getMarketId()); if (swxMarketSmart == null || !Objects.equals(swxMarketSmart.getStatus(), SwxConstons.NOMARL_STATUS_YES)){ throw new CustomerException("10010"); } //当天是否存在相同订单 if (swxSmartOrderService.checkRepeatOrder(userId, vo.getMarketId(), vo.getAllDay())) { //已购买相同产品,请勿重复购买 throw new CustomerException("10024"); } //获取用户是否有足够钱购买,用户余额为用户余额减保证金占用 if((swxUser.getAmount().subtract(swxUser.getBondAmount())).compareTo(vo.getAmount()) < 0) { throw new CustomerException("10011"); } String rateInfoStr = swxMarketSmart.getSmartInfo(); BigDecimal rate = null; BigDecimal max = null; BigDecimal min = null; JSONArray jsonArray = JSONArray.parseArray(rateInfoStr); for(int i = 0; i < jsonArray.size(); i++){ JSONObject object = jsonArray.getJSONObject(i); Integer days = object.getInteger("days"); if (days.intValue() == vo.getAllDay().intValue()){ rate = new BigDecimal(object.getString("rate")); max = new BigDecimal(object.getString("max")); min = new BigDecimal(object.getString("min")); break; } } if (rate == null || max == null || min == null){ throw new CustomerException("10012"); } if(vo.getAmount().compareTo(max) >0 || vo.getAmount().compareTo(min) < 0){ throw new CustomerException("10013"); } LocalDateTime localDateTime = LocalDateTime.now(); LocalDateTime afterDays = localDateTime.plusDays(1); SwxSmartOrder swxSmartOrder = new SwxSmartOrder(); BeanUtils.copyProperties(vo,swxSmartOrder); swxSmartOrder.setUserId(userId); swxSmartOrder.setMarketId(swxMarketSmart.getId()); swxSmartOrder.setCurrentDay(0); swxSmartOrder.setBuyTime(new Date()); swxSmartOrder.setRate(rate); swxSmartOrder.setNextProfitTime(new SimpleDateFormat("yyyy-MM-dd HH:mm:00").format(Date.from(afterDays.atZone(ZoneId.systemDefault()).toInstant()))); swxSmartOrder.setProfitType(swxMarketSmart.getProfitType()); SwxMarket swxMarket = swxMarketService.getById(swxMarketSmart.getMId()); swxSmartOrder.setMarketName(swxMarket.getAppName()); swxSmartOrder.setMarketCode(swxMarket.getCode()); swxSmartOrder.setAddRate(BigDecimal.ZERO); //获取加息 if(!Strings.isEmpty(swxUser.getLevel())){ SwxUserLevel userLevel = swxUserLevelService.getById(swxUser.getLevel()); if (userLevel != null){ swxSmartOrder.setAddRate(userLevel.getEquity1()); } } lg.info("购买智能交易订单,产品id=‘{}’Rate=‘{}’", vo.getMarketId(), swxSmartOrder.getRate()); //计算当期收益 swxSmartOrder.setCurrentProfit(swxSmartOrder.getAmount().multiply(swxSmartOrder.getRate().add(swxSmartOrder.getAddRate())).divide(new BigDecimal(100)).multiply(BigDecimal.valueOf(swxSmartOrder.getAllDay())).setScale(2,BigDecimal.ROUND_HALF_UP)); swxSmartOrderService.save(swxSmartOrder); //修改用户余额,插入资金日志 SwxMoneyLog moneyLog = new SwxMoneyLog(); moneyLog.setInfo("购买智能交易,产品为:"+swxMarketSmart.getMId()+",总额为:"+vo.getAmount()+"日利率为:"+vo.getRate()); moneyLog.setStatus(SwxConstons.SWX_EXAMINE_STATUS_YES); moneyLog.setType(SwxConstons.SWX_MONEY_LOG_TYPE_BUY_SMART); moneyLog.setSymbol(SwxConstons.SWX_MONEY_TYPE_PAY); moneyLog.setTitle("购买智能交易"); moneyLog.setOldAmount(swxUser.getAmount()); swxUser.setAmount(swxUser.getAmount().subtract(vo.getAmount())); swxUserService.updateById(swxUser); moneyLog.setNowAmount(swxUser.getAmount()); moneyLog.setUserId(swxUser.getId()); moneyLog.setBusiId(vo.getId()); moneyLog.setMoney(vo.getAmount()); swxMoneyLogService.save(moneyLog); //插入订单总表 // SwxOrder swxOrder = new SwxOrder(); // swxOrder.setUserId(userId); // swxOrder.setType(SwxConstons.SWX_ORDER_TYPE_SMART); // swxOrder.setStatus(SwxConstons.SWX_ORDER_STATUS_SMART_WAIT); // swxOrder.setMId(swxMarketSmart.getMId()); // swxOrder.setBuyType(SwxConstons.SWX_ORDER_BUY_TYPE_HY); // swxOrderService.save(swxOrder); // return "购买成功"; return "20004"; } @Override public IPage listOrder(String userId, String virtually,Integer pageNo,Integer pageSize) throws CustomerException { SwxUser swxUser = swxUserService.getById(userId); if (swxUser == null){ throw new CustomerException("10009"); } Page page = new Page(pageNo, pageSize); IPage pageList = swxOrderService.page(page, new QueryWrapper().lambda().eq(SwxOrder::getUserId,userId)); return pageList; } @Override public IPage listSmartOrder(String userId, String virtually, Integer pageNo, Integer pageSize) { SwxUser swxUser = swxUserService.getById(userId); if (swxUser == null){ throw new CustomerException("10009"); } Page page = new Page(pageNo, pageSize); QueryWrapper queryWrapper = new QueryWrapper<>(); queryWrapper.lambda().eq(SwxSmartOrder::getUserId,userId); queryWrapper.lambda().orderByDesc(SwxSmartOrder::getCreateTime); IPage pageList = swxSmartOrderService.page(page, queryWrapper); return pageList; } @Override public String buyOptionsTrue(SwxBuyOptionsVo vo, String userId, String virtually) throws CustomerException { if (!SwxConstons.SWX_CUSTOMER_USER_ORDER_TYPE_TRUE.equals(virtually)){ throw new CustomerException("10008"); } //获取用户信息 SwxUser swxUser = swxUserService.getById(userId); if (swxUser == null){ throw new CustomerException("10009"); } SwxUserInfoVo infoVo = new SwxUserInfoVo(); BeanUtils.copyProperties(swxUser,infoVo); //获取订单 SwxOptionsOrder order = getSwxOptionsOrderBuyInfo(vo,swxUser); order.setOrderType(1); BigDecimal yue = infoVo.getAmount().subtract(infoVo.getBondAmount()).subtract(order.getTradeFee()); //判断资金是否足够 if ((yue).compareTo(vo.getAmount()) < 0){ throw new CustomerException("10011"); } swxUser.setAmount(swxUser.getAmount().subtract(vo.getAmount()).subtract(order.getTradeFee())); swxUserService.updateById(swxUser); swxOptionsOrderService.save(order); String id = order.getId(); //推送给消息队列 Map messageMap = new HashMap<>(); messageMap.put("id",id); messageMap.put("istrue",1); messageMap.put("userId",userId); Integer timeSeconds = vo.getLimitTime() * 1000; rabbitTemplate.convertAndSend(DelayQueueRabbitConfig.ORDER_EXCHANGE, DelayQueueRabbitConfig.ORDER_ROUTING_KEY, messageMap, message->{ message.getMessageProperties().setExpiration(timeSeconds+""); return message; }); return id; } private SwxOptionsOrder getSwxOptionsOrderBuyInfo(SwxBuyOptionsVo vo,SwxUser swxUser) throws CustomerException{ //获取产品 SwxMarketOptions swxMarketOptions = swxMarketOptionsService.getById(vo.getOptionsId()); if (swxMarketOptions == null || swxMarketOptions.getStatus() != SwxConstons.NOMARL_STATUS_YES){ throw new CustomerException("10014"); } //获取产品 SwxMarket swxMarket = swxMarketService.getById(swxMarketOptions.getMId()); if (swxMarket == null){ throw new CustomerException("10014"); } //获取可交易时间 if (!getCanTradeTime(swxMarketOptions.getCanTradeDateType(),swxMarketOptions.getCanTradeDate(),swxMarketOptions.getCanTradeTime())) { throw new CustomerException("10015"); } if (vo.getAmount() == null || vo.getAmount().compareTo(BigDecimal.ZERO) <= 0){ throw new CustomerException("10016"); } //获取利润 String rateInfoStr = swxMarketOptions.getOptionsInfo(); BigDecimal rate = null; JSONArray jsonArray = JSONArray.parseArray(rateInfoStr); for(int i = 0; i < jsonArray.size(); i++){ JSONObject object = jsonArray.getJSONObject(i); Integer days = object.getInteger("seconds"); if (days.intValue() == vo.getLimitTime().intValue()){ rate = new BigDecimal(object.getString("rate")); break; } } if (rate == null){ throw new CustomerException("10017"); } //获取概率 SwxSettings percentSettins = swxSettingsService.getOne(new QueryWrapper().lambda().eq(SwxSettings::getParamKey,"options_win_percent")); if(percentSettins == null){ throw new CustomerException("10018"); } //获取手续费 SwxSettings tradeFeeSettings = swxSettingsService.getOne(new QueryWrapper().lambda().eq(SwxSettings::getParamKey,"default_trade_fee")); if(percentSettins == null){ throw new CustomerException("10018"); } BigDecimal tradeFee = vo.getAmount().multiply(new BigDecimal(tradeFeeSettings.getParamValue())).divide(new BigDecimal(100)); //创建订单 SwxOptionsOrder swxOptionsOrder = new SwxOptionsOrder(); BeanUtils.copyProperties(vo,swxOptionsOrder); swxOptionsOrder.setMarketName(swxMarket.getAppName()); swxOptionsOrder.setMarketCode(swxMarket.getCode()); swxOptionsOrder.setMarketType(swxMarket.getType()); swxOptionsOrder.setRate(rate); //获取概率,存入是否会赢 swxOptionsOrder.setOptionsId(swxMarketOptions.getId()); swxOptionsOrder.setUserId(swxUser.getId()); swxOptionsOrder.setMarketId(swxMarketOptions.getMId()); swxOptionsOrder.setStatus(0); //判断用户是否设置包输包赢 boolean isWin; if (swxUser.getBw() != 0){ if (swxUser.getBw() == 1){ isWin = true; }else{ isWin = false; } }else{ isWin = checkWin(Integer.parseInt(percentSettins.getParamValue())); } //判断是否赢,来设置显示平仓价 BigDecimal endPrice = BigDecimal.ZERO; BigDecimal fd = (vo.getBuyPrice().multiply(getRandom(10)).divide(new BigDecimal(1000))).setScale(4, RoundingMode.HALF_UP); if (isWin){ if(vo.getType() == 1){ endPrice = vo.getBuyPrice().add(fd); }else{ endPrice = vo.getBuyPrice().subtract(fd); } }else{ if(vo.getType() == 1){ endPrice = vo.getBuyPrice().subtract(fd); }else{ endPrice = vo.getBuyPrice().add(fd); } } swxOptionsOrder.setResultType(isWin ? 1 : 2); swxOptionsOrder.setEndPrice(endPrice); swxOptionsOrder.setIncome(vo.getAmount().multiply(rate).divide(new BigDecimal(100))); swxOptionsOrder.setTradeFee(tradeFee); return swxOptionsOrder; } @Override public String buyOptionsVirtually(SwxBuyOptionsVo vo, String userId, String virtually) throws CustomerException { if (!SwxConstons.SWX_CUSTOMER_USER_ORDER_TYPE_VIRTRUAL.equals(virtually)){ throw new CustomerException("10008"); } //获取用户信息 SwxUser swxUser = swxUserService.getById(userId); if (swxUser == null){ throw new CustomerException("10009"); } SwxUserInfoVo infoVo; if (redisCache.hasKey("SWX-CUSTOMER-VERTURAL-"+userId)){ infoVo= redisCache.getCacheObject("SWX-CUSTOMER-VERTURAL-"+userId); }else{ infoVo = new SwxUserInfoVo(); BeanUtils.copyProperties(swxUser,infoVo); infoVo.setVirtuallyAmount(new BigDecimal(1000000)); infoVo.setVirtuallyBondAmount(new BigDecimal(0)); redisCache.setCacheObject("SWX-CUSTOMER-VERTURAL-"+swxUser.getId(),infoVo,604800L, TimeUnit.SECONDS); } //获取订单 SwxOptionsOrder order = getSwxOptionsOrderBuyInfo(vo,swxUser); order.setOrderType(2); BigDecimal yue = infoVo.getVirtuallyAmount().subtract(infoVo.getVirtuallyBondAmount()); //判断资金是否足够 if ((yue.subtract(order.getTradeFee())).compareTo(vo.getAmount()) < 0){ throw new CustomerException("10011"); } // String id = UUID.randomUUID().toString(); infoVo.setVirtuallyAmount(yue.subtract(vo.getAmount()).subtract(order.getTradeFee())); // //修改redis值 // order.setId(id); // order.setCreateTime(new Date()); Long exprise = redisCache.getExpire("SWX-CUSTOMER-VERTURAL-"+userId); if(exprise <= 0){ exprise = 604800L; } redisCache.setCacheObject("SWX-CUSTOMER-VERTURAL-"+userId,infoVo,exprise,TimeUnit.SECONDS); // //将订单信息加入缓存中 // Long orderExprise = redisCache.getExpire("SWX-CUSTOMER-VERTURAL-OPTIONS-"+userId); // List list = new ArrayList<>(); // list.add(order); // redisCache.setCacheList("SWX-CUSTOMER-VERTURAL-OPTIONS-"+userId,list); // if (orderExprise <= 0){ // orderExprise = 604800L; // } // redisCache.expire("SWX-CUSTOMER-VERTURAL-OPTIONS-"+userId,orderExprise,TimeUnit.SECONDS); swxOptionsOrderService.save(order); String id = order.getId(); //推送给消息队列 Map messageMap = new HashMap<>(); messageMap.put("id",id); messageMap.put("istrue",2); messageMap.put("userId",userId); Integer timeSeconds = vo.getLimitTime() * 1000; rabbitTemplate.convertAndSend(DelayQueueRabbitConfig.ORDER_EXCHANGE, DelayQueueRabbitConfig.ORDER_ROUTING_KEY, messageMap, message->{ message.getMessageProperties().setExpiration(timeSeconds+""); return message; }); return id; } @Override public IPage listOptionsOrder(String userId, String virtually, Integer pageNo, Integer pageSize) throws CustomerException { if (!SwxConstons.SWX_CUSTOMER_USER_ORDER_TYPE_TRUE.equals(virtually) && !SwxConstons.SWX_CUSTOMER_USER_ORDER_TYPE_VIRTRUAL.equals(virtually)){ throw new CustomerException("10008"); } //获取用户信息 SwxUser swxUser = swxUserService.getById(userId); if (swxUser == null){ throw new CustomerException("10009"); } Page result = new Page<>(); Page page = new Page<>(pageNo,pageSize); QueryWrapper swxOptionsOrderQueryWrapper = new QueryWrapper<>(); swxOptionsOrderQueryWrapper.lambda().eq(SwxOptionsOrder::getUserId,userId); swxOptionsOrderQueryWrapper.lambda().orderByDesc(SwxOptionsOrder::getCreateTime); if (SwxConstons.SWX_CUSTOMER_USER_ORDER_TYPE_VIRTRUAL.equals(virtually)){ swxOptionsOrderQueryWrapper.lambda().eq(SwxOptionsOrder::getOrderType,2); }else { swxOptionsOrderQueryWrapper.lambda().eq(SwxOptionsOrder::getOrderType,1); } IPage pageList = swxOptionsOrderService.page(page,swxOptionsOrderQueryWrapper); result.setTotal(pageList.getTotal()); List records = new ArrayList<>(); for (SwxOptionsOrder item : pageList.getRecords()){ SwxBuyOptionsInfo info = new SwxBuyOptionsInfo(); BeanUtils.copyProperties(item,info); if (item.getStatus() == 0){ info.setEndPrice(BigDecimal.ZERO); info.setResultType(null); } records.add(info); } result.setRecords(records); // if (SwxConstons.SWX_CUSTOMER_USER_ORDER_TYPE_VIRTRUAL.equals(virtually)){ //获取redis中缓存 // Integer size = redisCache.getCacheListSize("SWX-CUSTOMER-VERTURAL-OPTIONS-"+userId).intValue(); // result.setTotal(size); // if (size > 0){ // Integer begin = (size - (pageNo * pageSize)) <= 0 ? 0 : (size - (pageNo * pageSize)); // Integer end =size - ((pageNo-1) * pageSize) - 1; // List list = redisCache.getCacheList("SWX-CUSTOMER-VERTURAL-OPTIONS-"+userId,begin,end); // List records = new ArrayList<>(); // for (SwxOptionsOrder item : list){ // SwxBuyOptionsInfo info = new SwxBuyOptionsInfo(); // BeanUtils.copyProperties(item,info); // if (item.getStatus() == 0){ // info.setEndPrice(BigDecimal.ZERO); // info.setResultType(null); // } // records.add(info); // } // Collections.reverse(records); // result.setRecords(records); // } // // }else{ // Page page = new Page<>(pageNo,pageSize); // QueryWrapper swxOptionsOrderQueryWrapper = new QueryWrapper<>(); // swxOptionsOrderQueryWrapper.lambda().eq(SwxOptionsOrder::getUserId,userId); // swxOptionsOrderQueryWrapper.lambda().orderByDesc(SwxOptionsOrder::getCreateTime); // IPage pageList = swxOptionsOrderService.page(page,swxOptionsOrderQueryWrapper); // result.setTotal(pageList.getTotal()); // List records = new ArrayList<>(); // for (SwxOptionsOrder item : pageList.getRecords()){ // SwxBuyOptionsInfo info = new SwxBuyOptionsInfo(); // BeanUtils.copyProperties(item,info); // if (item.getStatus() == 0){ // info.setEndPrice(BigDecimal.ZERO); // info.setResultType(null); // } // records.add(info); // } // result.setRecords(records); // } return result; } @Override public SwxBuyOptionsInfo getOptionsOrderById(String userId, String virtually, String id) { SwxOptionsOrder swxOptionsOrder = null; if (SwxConstons.SWX_CUSTOMER_USER_ORDER_TYPE_VIRTRUAL.equals(virtually)){ List list = redisCache.getCacheList("SWX-CUSTOMER-VERTURAL-OPTIONS-"+userId); for (SwxOptionsOrder item : list){ if (item.getId().equals(id)){ swxOptionsOrder = item ; break; } } }else{ swxOptionsOrder= swxOptionsOrderService.getById(id); } if (swxOptionsOrder != null){ SwxBuyOptionsInfo info = new SwxBuyOptionsInfo(); BeanUtils.copyProperties(swxOptionsOrder,info); if (info.getStatus() == 0){ info.setEndPrice(BigDecimal.ZERO); info.setResultType(null); } return info; } return null; } private BigDecimal getRandom(Integer randomMax){ Random random = new Random(); Double randomFloat = random.nextDouble() * 10; return new BigDecimal(randomFloat).setScale(4, RoundingMode.HALF_UP); } private boolean checkWin(Integer persont){ Random random = new Random(); int randomNumber = random.nextInt(100); return persont >= randomNumber; } /** * 是否可交易时间 * @param tradeDateType 可交易日期类型 * @param tradeDate 可交易日期 * @param tradeTime 可交易时间 * @return */ private boolean getCanTradeTime(Integer tradeDateType,String tradeDate,String tradeTime){ logger.info("校验时间"); logger.info("tradeDateType"+tradeDateType); logger.info("tradeDate"+tradeDate); logger.info("tradeTime"+tradeTime); Date date = new Date(); boolean canTradeDayFlag = false; String[] cantrade = tradeDate.replace("[", "").replace("]", "").split(","); String currentDay = ""; logger.info("data"+date); if (tradeDateType == 1){ SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd"); // 定义日期格式 currentDay = dateFormat.format(date).split("-")[2]; // 将日期转换为字 }else if(tradeDateType == 2){ // 周 Calendar calendar = Calendar.getInstance(); calendar.setTime(date); currentDay = calendar.get(Calendar.DAY_OF_WEEK)+""; }else if(tradeDateType == 3){ //余额 SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd"); // 定义日期格式 currentDay = dateFormat.format(date).split("-")[1]; // 将日期转换为字 } logger.info("currentDay= "+currentDay); for (String item : cantrade){ if (item.equals("\""+currentDay+"\"")){ canTradeDayFlag = true; break; } } if (canTradeDayFlag){ String[] canTradeTime = tradeTime.replace("[", "").replace("]", "").split(","); Calendar calendar = Calendar.getInstance(); calendar.setTime(date); int hour = calendar.get(Calendar.HOUR_OF_DAY); String hourStr =hour < 10 ? "\"0"+hour+"\"" : "\""+hour+"\""; logger.info("hourStr= "+hourStr); for (String item : canTradeTime){ if (item.equals(hourStr)){ return true; } } } return false; } }