peter
2025-10-29 f3b9e9f5024c13c6e70711a3ec98b4538378bd85
10.24二开,场外买入卖出,挂单
14 files modified
214 ■■■■ changed files
src/main/java/com/nq/controller/protol/UserController.java 5 ●●●●● patch | view | raw | blame | history
src/main/java/com/nq/enums/EUserAssets.java 1 ●●●● patch | view | raw | blame | history
src/main/java/com/nq/pojo/UserPendingorder.java 2 ●●●●● patch | view | raw | blame | history
src/main/java/com/nq/service/ITradingHourService.java 4 ●●●● patch | view | raw | blame | history
src/main/java/com/nq/service/IUserPositionService.java 2 ●●● patch | view | raw | blame | history
src/main/java/com/nq/service/UserPendingorderService.java 2 ●●●●● patch | view | raw | blame | history
src/main/java/com/nq/service/impl/StockServiceImpl.java 7 ●●●●● patch | view | raw | blame | history
src/main/java/com/nq/service/impl/TradingHourServiceImpl.java 47 ●●●●● patch | view | raw | blame | history
src/main/java/com/nq/service/impl/UserPendingorderServiceImpl.java 43 ●●●●● patch | view | raw | blame | history
src/main/java/com/nq/service/impl/UserPositionServiceImpl.java 85 ●●●●● patch | view | raw | blame | history
src/main/java/com/nq/utils/task/stock/StockTask.java 9 ●●●●● patch | view | raw | blame | history
src/main/java/com/nq/vo/stock/StockVO.java 2 ●●●●● patch | view | raw | blame | history
src/main/resources/application.properties 3 ●●●● patch | view | raw | blame | history
src/main/resources/application.yml 2 ●●● patch | view | raw | blame | history
src/main/java/com/nq/controller/protol/UserController.java
@@ -129,14 +129,15 @@
                              @RequestParam("buyType") Integer buyType,
                              @RequestParam("lever") Integer lever,
                              @RequestParam(value = "profitTarget",required = false)
                                  BigDecimal profitTarget,@RequestParam(value = "stopLoss",required = false) BigDecimal stopLoss, HttpServletRequest request) {
                                  BigDecimal profitTarget,@RequestParam(value = "stopLoss",required = false) BigDecimal stopLoss,
                              @RequestParam(value = "preMarketPrice",required = false) BigDecimal preMarketPrice,HttpServletRequest request) {
        buyLock.lock();
        try {
            if (buyOrderCreated.get()) {
                return ServerResponse.createByErrorMsg("当前下单人数过多,请稍后重试", request);
            }
            buyOrderCreated.set(true);
            return this.iUserPositionService.buy(stockId, buyNum, buyType, lever,profitTarget,stopLoss, request);
            return this.iUserPositionService.buy(stockId, buyNum, buyType, lever,profitTarget,stopLoss,preMarketPrice, request);
        } catch (Exception e) {
            e.printStackTrace();
            return ServerResponse.createByErrorMsg("订单异常,请稍后重试", request);
src/main/java/com/nq/enums/EUserAssets.java
@@ -15,6 +15,7 @@
    CONSTRAINT_CLOSE_POSITION("CONSTRAINT_CLOSE_POSITION","强制平仓"),
    BUY("BUY","购买"),
    WITHDRAW("WITHDRAW","提现"),
    BUY_REFUND("BUY_REFUND","挂单退回"),
    TRANSFER("TRANSFER","转换"),
    TOP_UP("TOP_UP","充值");
src/main/java/com/nq/pojo/UserPendingorder.java
@@ -40,5 +40,7 @@
    private Integer status;
    private BigDecimal buyAmt;
    private static final long serialVersionUID = 1L;
}
src/main/java/com/nq/service/ITradingHourService.java
@@ -1,7 +1,11 @@
package com.nq.service;
import com.nq.pojo.StockSetting;
public interface ITradingHourService {
    Boolean timeCheck(String stockCode);
    StockSetting preMarketPrice(String stockCode);
    Boolean isPreMarket(String stockCode);
    Boolean timeCheck();
}
src/main/java/com/nq/service/IUserPositionService.java
@@ -13,7 +13,7 @@
public interface IUserPositionService {
  ServerResponse buy(Integer paramInteger1, Integer paramInteger2, Integer paramInteger3,
                     Integer paramInteger4,BigDecimal paramInteger5,BigDecimal paramInteger6, HttpServletRequest paramHttpServletRequest) ;
                     Integer paramInteger4,BigDecimal paramInteger5,BigDecimal paramInteger6,BigDecimal preMarketPrice, HttpServletRequest paramHttpServletRequest) ;
  
  ServerResponse sell(String paramString, int paramInt);
  ServerResponse sell(String paramString, int paramInt,Integer number,  HttpServletRequest request);
src/main/java/com/nq/service/UserPendingorderService.java
@@ -21,6 +21,8 @@
    void orderTask();
    void delUserPendingorderTask();
    ServerResponse delOrder(Integer id, HttpServletRequest request);
src/main/java/com/nq/service/impl/StockServiceImpl.java
@@ -97,6 +97,8 @@
    @Autowired
    IPriceServices iPriceServices;
    @Autowired
    ITradingHourService tradingHourService;
    public ServerResponse getMarket() {
@@ -240,6 +242,11 @@
            stockVO.setOpen_px(cacheBaseStock.getOpen());
            stockVO.setPreclose_px(cacheBaseStock.getPrevClose());
        }
        if(tradingHourService.isPreMarket(stock.getStockCode())){
            stockVO.setPreMarket(1);
        }else {
            stockVO.setPreMarket(0);
        }
        Map map = Maps.newHashMap();
        map.put("introduction", introduction);
        map.put("stock", stockVO);
src/main/java/com/nq/service/impl/TradingHourServiceImpl.java
@@ -68,6 +68,53 @@
    }
    @Override
    public StockSetting preMarketPrice(String stockCode) {
        StockSetting stockSetting = stockSettingMapper.selectOne(new QueryWrapper<StockSetting>().eq("stock_code",stockCode));
        if(stockSetting!= null){
            // 说明进入盘前交易或者盘后交易时间
            Date newDate = new Date();
            DateTime startTime = DateUtil.parseDateTime(stockSetting.getStartTime());
            DateTime endTime = DateUtil.parseDateTime(stockSetting.getEndTime());
            if(newDate.after(startTime) && newDate.before(endTime)){
                return  stockSetting;
            }
        }
        return  null;
    }
    @Override
    public Boolean isPreMarket(String stockCode) {
        // 查询该股票的特定时间设置
        StockSetting stockSetting = stockSettingMapper.selectOne(new QueryWrapper<StockSetting>().eq("stock_code",stockCode));
        boolean res = timeCheckNoPreMarket();
        if(!res){
            if(stockSetting!= null){
                // 说明进入盘前交易或者盘后交易时间
                Date newDate = new Date();
                DateTime startTime = DateUtil.parseDateTime(stockSetting.getStartTime());
                DateTime endTime = DateUtil.parseDateTime(stockSetting.getEndTime());
                if(newDate.after(startTime) && newDate.before(endTime)){
                    return true;
                }
            }
        }
        return false;
    }
    public Boolean timeCheckNoPreMarket() {
        StockTimeSetting stockTimeSetting = stockTimeSettingMapper.selectOne(new QueryWrapper<StockTimeSetting>().eq("accets_type","US"));
        if(stockTimeSetting == null){
            return  false;
        }
        if(!stockTimeSetting.getWeekDay().contains(String.valueOf(LocalDate.now().getDayOfWeek().getValue()))){
            return false;
        }
        return TimeUtil.isTradingHour(stockTimeSetting.getAmStartTime(),stockTimeSetting.getAmEndTime(),stockTimeSetting.getPmStartTime(),stockTimeSetting.getPmEndTime());
    }
    @Override
    public Boolean timeCheck() {
        return true;
    }
src/main/java/com/nq/service/impl/UserPendingorderServiceImpl.java
@@ -12,6 +12,8 @@
import com.github.pagehelper.PageInfo;
import com.nq.common.ServerResponse;
import com.nq.dao.*;
import com.nq.enums.EStockType;
import com.nq.enums.EUserAssets;
import com.nq.pojo.*;
import com.nq.service.*;
import com.nq.utils.timeutil.DateTimeUtil;
@@ -65,6 +67,12 @@
    private ISiteSettingService iSiteSettingService;
    @Autowired
    private UserPositionMapper userPositionMapper;
    @Autowired
    private UserAssetsServices userAssetsServices;
    @Autowired
    private MoneyLogMapper  moneyLogMapper;
    @Autowired
    private UserAssetsMapper userAssetsMapper;
    @Override
    public ServerResponse addOrder(String stockId, Integer buyNum, Integer buyType, Integer lever, BigDecimal profitTarget, BigDecimal stopTarget, BigDecimal targetPrice, HttpServletRequest request) {
@@ -118,7 +126,7 @@
            User user = (User) JsonUtil.string2Obj(userJson, User.class);
//            log.info("user:{}",user);
            if (user != null) {
                List<UserPendingorder> userPendingorders = userPendingorderMapper.selectList(new QueryWrapper<UserPendingorder>().eq("user_id", user.getId()));
                List<UserPendingorder> userPendingorders = userPendingorderMapper.selectList(new QueryWrapper<UserPendingorder>().eq("user_id", user.getId()).orderByDesc("add_time"));
                List UserPendingorderList = new ArrayList();
@@ -136,7 +144,8 @@
                        nowPrice = String.valueOf(0);
                    }
                    userPendingorderVO.setNowPrice(new BigDecimal(nowPrice));
                    userPendingorderVO.setStockName(stock.getStockName());
//                    userPendingorderVO.setStockName(stock.getStockName());
                    userPendingorderVO.setStockName(stock.getStockSpell());
                    userPendingorderVO.setStockId(stock.getStockCode());
                    userPendingorderVO.setBuyNum(userPendingorder.getBuyNum());
                    userPendingorderVO.setBuyType(userPendingorder.getBuyType());
@@ -311,6 +320,36 @@
        return ServerResponse.createByErrorMsg("Please log in");
    }
    public void delUserPendingorderTask() {
        log.info("===========删除挂单任务开始==========");
        List<UserPendingorder> userPendingorderList = this.userPendingorderMapper.selectList(new QueryWrapper<UserPendingorder>().eq("status",0));
        for (UserPendingorder userPendingorder : userPendingorderList) {
            //修改状态
            userPendingorder.setStatus(2);
            userPendingorderMapper.updateById(userPendingorder);
            //退款
            QueryWrapper<UserAssets>  queryWrapper = new QueryWrapper<>();
            queryWrapper.eq("accect_type","US");
            queryWrapper.eq("user_id",userPendingorder.getUserId());
            UserAssets userAssets =  userAssetsMapper.selectOne(queryWrapper);
            String before = userAssets.getAvailableBalance().toString();
            userAssets.setAvailableBalance(userAssets.getAvailableBalance().add(userPendingorder.getBuyAmt()));
            userAssetsMapper.updateById(userAssets);
            MoneyLog moneyLog = new MoneyLog();
            moneyLog.setDescs(EUserAssets.BUY_REFUND.getDesc());
            moneyLog.setBeFore(before);
            moneyLog.setAfter(userAssets.getAvailableBalance().toString());
            moneyLog.setAmount(userAssets.getAvailableBalance().toString());
            moneyLog.setAccectType("US");
            moneyLog.setType(EUserAssets.BUY_REFUND.getCode());
            moneyLog.setUserId(userPendingorder.getUserId()+"");
            moneyLog.setSymbol(EStockType.getEStockTypeByCode("US").getSymbol());
            moneyLog.setCreateTime(new Date());
            moneyLogMapper.insert(moneyLog);
        }
        log.info("===========删除挂单任务结束==========");
    }
    @Override
    public ServerResponse orderListByAdmin(int pageNum, int pageSize, String keywords, String status, HttpServletRequest request) {
src/main/java/com/nq/service/impl/UserPositionServiceImpl.java
@@ -128,11 +128,13 @@
    @Autowired
    UserPositionCheckDzService userPositionCheckDzService;
    @Autowired
    UserPendingorderMapper userPendingorderMapper;
    @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,BigDecimal preMarketPrice, HttpServletRequest request) {
        SiteProduct siteProduct = iSiteProductService.getProductSetting();
@@ -203,37 +205,58 @@
            if (stopTarget != null && stopTarget.compareTo(new BigDecimal("0")) > 0) {
                userPosition.setStopTargetPrice(stopTarget);
            }
            userPosition.setPositionType(user.getAccountType());
            userPosition.setPositionSn(KeyUtils.getUniqueKey());
            userPosition.setUserId(user.getId());
            userPosition.setNickName(user.getRealName());
            userPosition.setAgentId(user.getAgentId());
            userPosition.setStockCode(stock.getStockCode());
            userPosition.setStockName(stock.getStockName());
            userPosition.setStockGid(stock.getStockType());
            userPosition.setStockSpell(stock.getStockSpell());
            userPosition.setBuyOrderId(GeneratePosition.getPositionId());
            userPosition.setBuyOrderTime(new Date());
            userPosition.setBuyOrderPrice(nowPrice);
            userPosition.setOrderDirection((buyType.intValue() == 0) ? "买涨" : "买跌");
            userPosition.setOrderNum(buyNum);
            if (stock.getStockPlate() != null) {
                userPosition.setStockPlate(stock.getStockPlate());
            }
            userPosition.setIsLock(Integer.valueOf(0));
            userPosition.setOrderLever(lever);
            userPosition.setOrderTotalPrice(buyAmt);
            // 手续费
            //判断是否盘前,和价格
            StockSetting stockSetting = tradingHourService.preMarketPrice(stock.getStockCode());
            if(null != preMarketPrice && preMarketPrice.compareTo(new BigDecimal(0)) > 0 && null != stockSetting && preMarketPrice.compareTo(new BigDecimal(stockSetting.getPrice())) != 0){
                //挂单
                UserPendingorder userPendingorder = new UserPendingorder();
                userPendingorder.setUserId(user.getId());
                userPendingorder.setStockId(String.valueOf(stockId));
                userPendingorder.setBuyNum(buyNum);
                userPendingorder.setBuyType(buyType);
                userPendingorder.setLever(lever);
                userPendingorder.setProfitTarget(profitTarget);
                userPendingorder.setStopTarget(stopTarget);
                userPendingorder.setNowPrice(new BigDecimal(0));
                userPendingorder.setTargetPrice(preMarketPrice);
                userPendingorder.setAddTime(new Date());
                userPendingorder.setStatus(0);
                userPendingorder.setBuyAmt(buyAmt);
                int ret = userPendingorderMapper.insert(userPendingorder);
            }else {
                userPosition.setPositionType(user.getAccountType());
                userPosition.setPositionSn(KeyUtils.getUniqueKey());
                userPosition.setUserId(user.getId());
                userPosition.setNickName(user.getRealName());
                userPosition.setAgentId(user.getAgentId());
                userPosition.setStockCode(stock.getStockCode());
                userPosition.setStockName(stock.getStockName());
                userPosition.setStockGid(stock.getStockType());
                userPosition.setStockSpell(stock.getStockSpell());
                userPosition.setBuyOrderId(GeneratePosition.getPositionId());
                userPosition.setBuyOrderTime(new Date());
                userPosition.setBuyOrderPrice(nowPrice);
                userPosition.setOrderDirection((buyType.intValue() == 0) ? "买涨" : "买跌");
                userPosition.setOrderNum(buyNum);
                if (stock.getStockPlate() != null) {
                    userPosition.setStockPlate(stock.getStockPlate());
                }
                userPosition.setIsLock(Integer.valueOf(0));
                userPosition.setOrderLever(lever);
                userPosition.setOrderTotalPrice(buyAmt);
                // 手续费
            userPosition.setOrderFee(orderFree);
            userPosition.setOrderSpread(BigDecimal.ZERO);
            userPosition.setSpreadRatePrice(BigDecimal.ZERO);
            BigDecimal profit_and_lose = new BigDecimal("0");
            userPosition.setProfitAndLose(profit_and_lose);
            userPosition.setAllProfitAndLose(profit_and_lose.add(orderFree));
            userPosition.setOrderStayDays(Integer.valueOf(0));
            userPosition.setOrderStayFee(BigDecimal.ZERO);
            userPositionMapper.insert(userPosition);
                userPosition.setOrderFee(orderFree);
                userPosition.setOrderSpread(BigDecimal.ZERO);
                userPosition.setSpreadRatePrice(BigDecimal.ZERO);
                BigDecimal profit_and_lose = new BigDecimal("0");
                userPosition.setProfitAndLose(profit_and_lose);
                userPosition.setAllProfitAndLose(profit_and_lose.add(orderFree));
                userPosition.setOrderStayDays(Integer.valueOf(0));
                userPosition.setOrderStayFee(BigDecimal.ZERO);
                userPositionMapper.insert(userPosition);
            }
            iUserAssetsServices.availablebalanceChange(stock.getStockType(), user.getId(), EUserAssets.BUY, buyAmt.negate(), "", "");
            iUserAssetsServices.availablebalanceChange(stock.getStockType(), user.getId(), EUserAssets.HANDLING_CHARGE, orderFree, "", "");
            return ServerResponse.createBySuccessMsg("下单成功", request);
src/main/java/com/nq/utils/task/stock/StockTask.java
@@ -14,6 +14,7 @@
import com.nq.service.IMandatoryLiquidationService;
import com.nq.service.IStockService;
import com.nq.service.IUserPositionService;
import com.nq.service.UserPendingorderService;
import com.nq.utils.http.HttpClientRequest;
import com.nq.utils.redis.RedisKeyUtil;
import org.slf4j.Logger;
@@ -39,6 +40,8 @@
    @Autowired
    IUserPositionService userPositionService;
    @Autowired
    UserPendingorderService userPendingorderService;
    @Autowired
    UserPositionMapper userPositionMapper;
@@ -77,6 +80,12 @@
        }
    }
//    @Scheduled(cron = "0 0/1 * * * ?")
    @Scheduled(cron = "0 30 21 * * ?")
    public void delUserPendingorder() {
        userPendingorderService.delUserPendingorderTask();
    }
    /**
     * 同步美国股票
src/main/java/com/nq/vo/stock/StockVO.java
@@ -59,6 +59,8 @@
    private Integer depositAmt;
    private Integer preMarket;
}
src/main/resources/application.properties
@@ -55,7 +55,8 @@
US_HTTP_API = http://api-us-v2.js-stock.top/
US_WS_URL = ws://api-us-v2-ws.js-stock.top
US_KEY = BUTiZZdBdiWejyiPpZQ2
#US_KEY = BUTiZZdBdiWejyiPpZQ2
US_KEY = RcVac8fzlkDj3wVbG2s3
HK_HTTP_API = http://test.js-stock.top/
HK_WS_URL = ws://test-ws.js-stock.top
src/main/resources/application.yml
@@ -129,7 +129,7 @@
    driverClassName: com.mysql.cj.jdbc.Driver
    url: jdbc:mysql://127.0.0.1:6306/us?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8
#    url: jdbc:mysql://127.0.0.1:6306us?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8
#    url: jdbc:mysql://127.0.0.1:3306/cgstock?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8
#    url: jdbc:mysql://127.0.0.1:3306/trading_order_1024?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8
    username: root
    password: Err;2[eoGFUriwdgr
    druid: