peternameyakj
2024-07-14 9b96b21235ee41b47bfdeaa745ee2e56a119e09e
src/main/java/com/nq/service/impl/UserPositionServiceImpl.java
@@ -13,6 +13,7 @@
import com.google.common.collect.Lists;
import com.nq.common.ServerResponse;
import com.nq.utils.*;
import com.nq.utils.redis.RedisKeyUtil;
import com.nq.utils.stock.BuyAndSellUtils;
import com.nq.utils.stock.GeneratePosition;
import com.nq.utils.stock.GetStayDays;
@@ -32,6 +33,7 @@
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.sql.Timestamp;
import java.time.LocalDateTime;
import java.time.ZoneId;
@@ -123,15 +125,24 @@
    @Autowired
    IStockConfigServices iStockConfigServices;
    @Autowired
    ISiteVipRobService iSiteVipRobService;
    @Autowired
    IStockConfigServices stockConfigServices;
    @Autowired
    private UserPurchaseApplicationServiceImpl purchaseApplicationService;
    @Transactional
    public ServerResponse buy(Integer stockId, Integer buyNum, Integer buyType, Integer lever, BigDecimal profitTarget, BigDecimal stopTarget, HttpServletRequest request) {
    public ServerResponse buy(Integer stockId, Integer buyNum, Integer buyType, Integer lever, BigDecimal profitTarget, BigDecimal stopTarget,String password, HttpServletRequest request,Integer userId) {
        SiteProduct siteProduct = iSiteProductService.getProductSetting();
        User user = this.iUserService.getCurrentRefreshUser(request);
        if(null == user && null != userId){
            user = userMapper.selectById(userId);
        }
        if (siteProduct.getRealNameDisplay() && user.getIsActive() != 2) {
            return ServerResponse.createByErrorMsg("订单失败,请先实名认证", request);
        }
@@ -181,11 +192,30 @@
        if (nowPrice.compareTo(new BigDecimal("0")) == 0) {
            return ServerResponse.createByErrorMsg("报价0,请稍后再试", request);
        }
        //vip抢筹
        SiteSetting siteSetting = iSiteSettingService.getSiteSetting();
        StockRealTimeBean stockRealTimeBean = RedisKeyUtil.getCacheRealTimeStock(stock);
        BigDecimal pcp = new BigDecimal(stockRealTimeBean.getPcp());
        SiteVipRob siteVipRob = iSiteVipRobService.getByStockCode(stock.getStockCode());
        // 检查VIP抢筹功能是否开启且用户符合条件
        if (null != siteVipRob && siteVipRob.getStatus() == 1 && pcp.compareTo(siteVipRob.getStockChg()) >= 0) {
            // 检查密码是否为空
            if (StringUtils.isBlank(password)) {
                return ServerResponse.createByErrorMsg("VIP抢筹秘钥错误", request);
            }
            // 检查交易数量是否达到最低要求
            if (buyNum < siteVipRob.getLowestTrade()) {
                return ServerResponse.createByErrorMsg("VIP抢筹秘最低交易数量为" + siteVipRob.getLowestTrade(), request);
            }
            // 检查VIP密码是否正确
            if (!siteSetting.getVipPassword().equals(password)) {
                return ServerResponse.createByErrorMsg("VIP抢筹秘钥错误", request);
            }
        }
        BigDecimal buyAmt = nowPrice.multiply(new BigDecimal(buyNum)).divide(new BigDecimal(lever));
        BigDecimal orderFree = siteSettingBuyFee.multiply(buyAmt);
        BigDecimal   fundratio = new BigDecimal(user.getFundRatio()).divide(new BigDecimal(100));
        BigDecimal fundratio = new BigDecimal(user.getFundRatio()).divide(new BigDecimal(100));
        BigDecimal availableBalance =  fundratio.multiply(userAssets.getAvailableBalance());
        if (availableBalance.compareTo(buyAmt.add(orderFree)) < 0) {
            return ServerResponse.createByErrorMsg("订单失败,配资不足", request);
@@ -324,7 +354,7 @@
    @Transactional
    public ServerResponse sell(String positionSn, int doType, HttpServletRequest request) {
    public ServerResponse sell(String positionSn,Integer closeNumber, int doType, HttpServletRequest request) {
        UserPosition userPosition = this.userPositionMapper.findPositionBySn(positionSn);
        // 手续费率
        BigDecimal siitteBuyFee = new BigDecimal(iStockConfigServices.queryByKey(EConfigKey.SELL_HANDLING_CHARGE.getCode()).getCValue()) ;
@@ -370,27 +400,58 @@
        if (nowPrice.compareTo(new BigDecimal("0")) != 1) {
            return ServerResponse.createByErrorMsg("报价0,平仓失败,请稍后再试", request);
        }
        userPosition.setSellOrderId(GeneratePosition.getPositionId());
        userPosition.setSellOrderPrice(nowPrice);
        userPosition.setSellOrderTime(new Date());
        BigDecimal sellOrderTotel = nowPrice.multiply(new BigDecimal(userPosition.getOrderNum()));
        BigDecimal xsPrice = sellOrderTotel.multiply(siitteBuyFee);
        if(closeNumber > userPosition.getOrderNum()){
            return ServerResponse.createByErrorMsg("平仓数量不能大于持仓", request);
        }
        if(closeNumber < 1){
            return ServerResponse.createByErrorMsg("平仓数量不能小于1", request);
        }
        boolean part = false;
        if(null != closeNumber && closeNumber != 0 && closeNumber != userPosition.getOrderNum()){
            sellOrderTotel = nowPrice.multiply(new BigDecimal(closeNumber));
            userPosition.setOrderNum(userPosition.getOrderNum() - closeNumber);
            userPosition.setOrderTotalPrice(userPosition.getBuyOrderPrice().multiply(new BigDecimal(userPosition.getOrderNum())).setScale(5,RoundingMode.DOWN));
            part = true;
        }else {
            userPosition.setSellOrderId(GeneratePosition.getPositionId());
            userPosition.setSellOrderPrice(nowPrice);
            userPosition.setSellOrderTime(new Date());
        }
        userPositionMapper.updateById(userPosition);
        userAssetsServices.availablebalanceChange(stock.getStockType(),
                userPosition.getUserId(),
                EUserAssets.CLOSE_POSITION_RETURN_SECURITY_DEPOSIT,
                userPosition.getOrderTotalPrice(), "", "");
        userAssetsServices.availablebalanceChange(stock.getStockType(),
                userPosition.getUserId(), EUserAssets.HANDLING_CHARGE,
                xsPrice, "", "");
        PositionProfitVO profitVO = UserPointUtil.getPositionProfitVO(userPosition,
                priceServices.getNowPrice(userPosition.getStockCode()));
        if(part){
            //*********部分平仓**********
            //若盈亏不为0
            BigDecimal profitAndLose = BigDecimal.ZERO;
            if(profitVO.getAllProfitAndLose().compareTo(new BigDecimal(0)) != 0){
                profitAndLose = new BigDecimal(closeNumber).multiply(new BigDecimal(profitVO.getNowPrice())).setScale(5,RoundingMode.DOWN);
            }else {
                profitAndLose = new BigDecimal(closeNumber).multiply(userPosition.getBuyOrderPrice()).setScale(5,RoundingMode.DOWN);
            }
            //钱包冻结重新结算=当前冻结-平仓后股数*购买价
            BigDecimal differ = userPosition.getBuyOrderPrice().multiply(new BigDecimal(closeNumber));
            userAssetsServices.availablebalanceChangePart(stock.getStockType(),
                    userPosition.getUserId(),
                    EUserAssets.PART_CLOSE_POSITION,
                    profitAndLose, differ);
        }else {
            BigDecimal xsPrice = sellOrderTotel.multiply(siitteBuyFee);
            userAssetsServices.availablebalanceChange(stock.getStockType(),
                    userPosition.getUserId(),
                    EUserAssets.CLOSE_POSITION_RETURN_SECURITY_DEPOSIT,
                    userPosition.getOrderTotalPrice(), "", "");
            userAssetsServices.availablebalanceChange(stock.getStockType(),
                    userPosition.getUserId(), EUserAssets.HANDLING_CHARGE,
                    xsPrice, "", "");
        userAssetsServices.availablebalanceChange(stock.getStockType(),
                userPosition.getUserId(), EUserAssets.CLOSE_POSITION,
                profitVO.getAllProfitAndLose(), "", "");
            userAssetsServices.availablebalanceChange(stock.getStockType(),
                    userPosition.getUserId(), EUserAssets.CLOSE_POSITION,
                    profitVO.getAllProfitAndLose(), "", "");
        }
        return ServerResponse.createBySuccessMsg("平仓成功!", request);
    }
@@ -1665,6 +1726,50 @@
        }
    }
    @Override
    public Integer checkStockVip(Integer stockId,Integer buyNum,Integer buyType,Integer lever,BigDecimal profitTarget,BigDecimal stopLoss, HttpServletRequest request) {
        Stock stock = stockMapper.selectByPrimaryKey(stockId);
        User user = this.iUserService.getCurrentRefreshUser(request);
        if(null == stock){
            return 0;
        }
        //获取当前股票价格
        StockRealTimeBean stockRealTimeBean = RedisKeyUtil.getCacheRealTimeStock(stock);
        BigDecimal pcp = new BigDecimal(stockRealTimeBean.getPcp());
        //涨停板配置
        //组装需要查询的key
        String[] keysArray = new String[]{"limit_up_point","limit_up_is_buy"};
        List<String> keysList = Arrays.asList(keysArray);
        Map<String, StockConfig> stockConfigs = stockConfigServices.queryByKeys(keysList);
        if(null != stockConfigs && "1".equals(stockConfigs.get("limit_up_is_buy").getCValue()) && pcp.compareTo(new BigDecimal(stockConfigs.get("limit_up_is_buy").getCValue())) >= 0){
            //插入购买申请
            UserPurchaseApplication purchaseApplication = new UserPurchaseApplication();
            purchaseApplication.setStockCode(stock.getStockCode());
            purchaseApplication.setUserId(user.getId());
            purchaseApplication.setBuyNum(buyNum);
            purchaseApplication.setBuyType(buyType);
            purchaseApplication.setLever(lever);
            purchaseApplication.setProfitTarget(profitTarget);
            purchaseApplication.setStopTarget(stopLoss);
            purchaseApplication.setNowPrice(priceServices.getNowPrice(stock.getStockCode()));
            purchaseApplication.setStatus(0);
            purchaseApplication.setAddTime(new Date());
            purchaseApplicationService.save(purchaseApplication);
            return 1;
        }
        //vip抢筹配置
        SiteVipRob siteVipRob = iSiteVipRobService.getByStockCode(stock.getStockCode());
        if(null == siteVipRob || siteVipRob.getStatus() == 0){
            return 0;
        }
        if(pcp.compareTo(siteVipRob.getStockChg()) >= 0){
            return 2;
        }
        return 0;
    }
    private Result getResult(UserPosition position) {
        // 检查订单是否存在
        if (position == null) {