.idea/jarRepositories.xml
@@ -8,6 +8,11 @@ </remote-repository> <remote-repository> <option name="id" value="central" /> <option name="name" value="Central Repository" /> <option name="url" value="http://maven.aliyun.com/nexus/content/repositories/central/" /> </remote-repository> <remote-repository> <option name="id" value="central" /> <option name="name" value="Maven Central repository" /> <option name="url" value="https://repo1.maven.org/maven2" /> </remote-repository> pom.xml
@@ -41,6 +41,12 @@ <artifactId>mybatis-spring-boot-starter</artifactId> <version>2.2.2</version> </dependency> <!-- Spring Boot Data JPA --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-jpa</artifactId> </dependency> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> src/main/java/com/nq/Repository/StockRepository.java
New file @@ -0,0 +1,7 @@ package com.nq.Repository; import com.nq.pojo.Stock; import org.springframework.data.jpa.repository.JpaRepository; public interface StockRepository extends JpaRepository<Stock, Integer> { } src/main/java/com/nq/controller/UserPositionCheckDzController.java
@@ -107,7 +107,7 @@ StockDz stockDz = this.stockDzMapper.selectOne(new QueryWrapper<StockDz>().eq("id", userPositionCheckDz.getDzId())); UserAssets userAssets = userAssetsServices.assetsByTypeAndUserId("IN", user.getId()); UserAssets userAssets = userAssetsServices.assetsByTypeAndUserId(stockDz.getStockType(), user.getId()); if(userAssets.getAmountToBeCovered().compareTo(BigDecimal.ZERO) > 0){ return ServerResponse.createByErrorMsg("用户账户有待补资金未补齐,审核失败"); } @@ -132,7 +132,7 @@ userPosition.setId(null); userPosition.setDzId(stockDz.getId()); userPositionMapper.insert(userPosition); userAssetsServices.availablebalanceChange(EStockType.IN.getCode(), user.getId(), EUserAssets.BUY, buyAmt.negate(),"",""); userAssetsServices.availablebalanceChange(userAssets.getAccectType(), user.getId(), EUserAssets.BUY, buyAmt.negate(),"",""); return ServerResponse.createBySuccessMsg("审核成功,订单已转客户持仓"); } } src/main/java/com/nq/controller/echo/EChoController.java
@@ -62,14 +62,14 @@ } } User user = this.iUserService.getCurrentRefreshUser(request); UserAssets userAssets = userAssetsServices.assetsByTypeAndUserId("IN", user.getId()); UserAssets userAssets = userAssetsServices.assetsByTypeAndUserId("MX", user.getId()); if(userAssets.getAmountToBeCovered().compareTo(BigDecimal.ZERO) > 0){ return ServerResponse.createByErrorMsg("请先缴清待补资金", request); } if(userAssets.getAvailableBalance().compareTo(money) < 0){ return ServerResponse.createByErrorMsg("配资不足",request); } if (iEchoServices.buyECho(eid, money,request)) { if (iEchoServices.buyECho(eid, money, userAssets.getAccectType(), request)) { return ServerResponse.createBySuccess("购买成功",request); } else { return ServerResponse.createByErrorMsg("购买失败",request); src/main/java/com/nq/enums/EStockType.java
@@ -50,7 +50,7 @@ }else if(EStockType.MX.getCode().equals(code)){ return MX; }else{ return US; return MX; } } src/main/java/com/nq/pojo/Stock.java
@@ -6,12 +6,16 @@ import com.baomidou.mybatisplus.annotation.TableName; import lombok.Data; import javax.persistence.*; import java.math.BigDecimal; import java.util.Date; @Data @TableName("stock") @Entity public class Stock { @TableId(type = IdType.AUTO,value = "id") @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private Integer id; private String stockName; private String stockCode; src/main/java/com/nq/pojo/UserPosition.java
@@ -10,6 +10,10 @@ import java.io.Serializable; import java.math.BigDecimal; import java.util.Date; /** * 用户持仓表 */ @Data @TableName(value ="user_position") public class UserPosition implements Serializable { src/main/java/com/nq/service/IEchoServices.java
@@ -15,7 +15,7 @@ public List<EChoBean> queryList(); boolean buyECho(String eId, BigDecimal money, HttpServletRequest request); boolean buyECho(String eId, BigDecimal money, String accectType, HttpServletRequest request); List<OrderEchoOut> queryOrderEcho(HttpServletRequest request); src/main/java/com/nq/service/ITradingHourService.java
@@ -1,7 +1,7 @@ package com.nq.service; public interface ITradingHourService { Boolean timeCheck(String stockCode); Boolean timeCheck(String stockCode, String stockType); Boolean timeCheck(); } src/main/java/com/nq/service/impl/EchoServices.java
@@ -12,6 +12,7 @@ import com.nq.pojo.reponse.OrderEChoReponse; import com.nq.service.IEchoServices; import com.nq.service.IUserService; import com.nq.utils.PropertiesUtil; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; @@ -21,6 +22,8 @@ import java.math.RoundingMode; import java.util.ArrayList; import java.util.List; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; @Slf4j @Service @@ -50,7 +53,7 @@ } @Override public boolean buyECho(String eId, BigDecimal money, HttpServletRequest request) { public boolean buyECho(String eId, BigDecimal money, String accectType, HttpServletRequest request) { User user = this.iUserService.getCurrentRefreshUser(request); @@ -77,7 +80,7 @@ UserAssets userAssets = userAssetsMapper.selectOne(new LambdaQueryWrapper<UserAssets>() .eq(UserAssets::getUserId, orderEchoBean.getUserId()) .eq(UserAssets::getAccectType, "IN") .eq(UserAssets::getAccectType, accectType) ); userAssets.setAvailableBalance(userAssets.getAvailableBalance().subtract(money)); userAssets.setFreezeMoney(userAssets.getFreezeMoney().add(money)); @@ -102,6 +105,18 @@ @Override public void sendMoney() { // 创建固定大小的线程池,根据需求调整线程数量 ExecutorService executor = Executors.newFixedThreadPool(2); try { executor.submit(() -> sendMoney(EStockType.US.getCode())); executor.submit(() -> sendMoney(EStockType.MX.getCode())); } finally { // 关闭线程池 executor.shutdown(); } } private void sendMoney(String stockType) { try { QueryWrapper<OrderEchoBean> queryWrapper = new QueryWrapper<>(); queryWrapper.eq("state", 1); @@ -120,7 +135,7 @@ BigDecimal aml = incomeAmount.add(money); UserAssets userAssets = userAssetsMapper.selectOne(new LambdaQueryWrapper<UserAssets>() .eq(UserAssets::getUserId, orderEchoBean.getUserId()) .eq(UserAssets::getAccectType, "IN") .eq(UserAssets::getAccectType, stockType) ); if (userAssets.getAmountToBeCovered().compareTo(BigDecimal.ZERO) > 0) { continue; @@ -154,7 +169,6 @@ log.error("基金定时任务---失败: ", ex); } } @Override public int insertEcho(EChoBean eChoBean) { src/main/java/com/nq/service/impl/StockServiceImpl.java
@@ -134,7 +134,7 @@ List<Stock> stockList = new ArrayList<>(); if (stockType.equals("99")) { PageHelper.startPage(pageNum, pageSize); stockList.addAll(stockMapper.findZtStockListByKeyWords(keyWords, stockPlate, "IN", Integer.valueOf(0))); stockList.addAll(stockMapper.findZtStockListByKeyWords(keyWords, stockPlate, "MX", Integer.valueOf(0))); } else if (stockType.equals("100")) { User user = iUserService.getCurrentRefreshUser(request); if (user == null) { src/main/java/com/nq/service/impl/TradingHourServiceImpl.java
@@ -46,9 +46,9 @@ * @return */ @Override public Boolean timeCheck(String stockCode) { public Boolean timeCheck(String stockCode, String stockType) { StockSetting stockSetting = stockSettingMapper.selectOne(new QueryWrapper<StockSetting>().eq("stock_code",stockCode)); StockTimeSetting stockTimeSetting = stockTimeSettingMapper.selectOne(new QueryWrapper<StockTimeSetting>().eq("accets_type","IN")); StockTimeSetting stockTimeSetting = stockTimeSettingMapper.selectOne(new QueryWrapper<StockTimeSetting>().eq("accets_type",stockType)); if(stockSetting!= null){ // 说明进入盘前交易或者盘后交易时间 Date newDate = new Date(); src/main/java/com/nq/service/impl/UserPositionServiceImpl.java
@@ -43,6 +43,7 @@ import java.util.concurrent.atomic.AtomicBoolean; import java.util.concurrent.locks.Lock; import java.util.concurrent.locks.ReentrantLock; import java.util.stream.Collectors; import javax.annotation.Resource; import javax.servlet.http.HttpServletRequest; @@ -153,7 +154,7 @@ return ServerResponse.createByErrorMsg("订单失败,股票代码不存在", request); } //判断股票是否在可交易时间段 Boolean b = tradingHourService.timeCheck(stock.getStockCode()); Boolean b = tradingHourService.timeCheck(stock.getStockCode(), stock.getStockType()); if (!b) { return ServerResponse.createByErrorMsg("订单失败,不在交易时间之内", request); } @@ -234,8 +235,8 @@ 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, "", ""); iUserAssetsServices.availablebalanceChange(EStockType.MX.getCode(), user.getId(), EUserAssets.BUY, buyAmt.negate(), "", ""); iUserAssetsServices.availablebalanceChange(EStockType.MX.getCode(), user.getId(), EUserAssets.HANDLING_CHARGE, orderFree, "", ""); return ServerResponse.createBySuccessMsg("下单成功", request); } } @@ -286,20 +287,24 @@ @Transactional public ServerResponse sell(String positionSn, int doType) { UserPosition userPosition = this.userPositionMapper.findPositionBySn(positionSn); BigDecimal siitteBuyFee = iSiteSettingService.getSiteSetting().getBuyFee(); Boolean b = tradingHourService.timeCheck(userPosition.getStockCode()); if (!b) { return ServerResponse.createByErrorMsg("订单失败,不在交易时间之内"); } if (userPosition == null) { return ServerResponse.createByErrorMsg("平仓失败,订单不存在"); } User user = this.userMapper.selectById(userPosition.getUserId()); if (user.getIsLock() == 1) { return ServerResponse.createByErrorMsg("账户已被限制交易"); BigDecimal siitteBuyFee = iSiteSettingService.getSiteSetting().getBuyFee(); Stock stock = stockMapper.selectOne(new QueryWrapper<Stock>().eq("stock_code", userPosition.getStockCode())); if(null == stock){ return ServerResponse.createByErrorMsg("股票不存在,平仓失败"); } Boolean b = tradingHourService.timeCheck(userPosition.getStockCode(), stock.getStockType()); if (!b) { return ServerResponse.createByErrorMsg("订单失败,不在交易时间之内"); } User user = this.userMapper.selectById(userPosition.getUserId()); if (user == null) { return ServerResponse.createByErrorMsg("平仓失败,用户不存在"); } if (user.getIsLock() == 1) { return ServerResponse.createByErrorMsg("账户已被限制交易"); } if (userPosition.getSellOrderId() != null) { return ServerResponse.createByErrorMsg("平仓失败, 订单已平仓"); @@ -307,7 +312,7 @@ if (1 == userPosition.getIsLock().intValue()) { return ServerResponse.createByErrorMsg("this order is closed " + userPosition.getLockMsg()); } Stock stock = stockMapper.selectOne(new QueryWrapper<Stock>().eq("stock_code", userPosition.getStockCode())); //Stock stock = stockMapper.selectOne(new QueryWrapper<Stock>().eq("stock_code", userPosition.getStockCode())); BigDecimal nowPrice = priceServices.getNowPrice(userPosition.getStockCode()); if (nowPrice.compareTo(new BigDecimal("0")) != 1) { return ServerResponse.createByErrorMsg("报价0,平仓失败,请稍后再试"); @@ -336,15 +341,22 @@ @Transactional public ServerResponse sell(String positionSn, int doType, Integer number,HttpServletRequest request) { UserPosition userPosition = this.userPositionMapper.findPositionBySn(positionSn); if (userPosition == null) { return ServerResponse.createByErrorMsg("平仓失败,订单不存在", request); } if(null == number || number <= 0 || number > userPosition.getOrderNum()){ return ServerResponse.createByErrorMsg("请输入正确的平仓数", request); } // 手续费率 BigDecimal siitteBuyFee = new BigDecimal(iStockConfigServices.queryByKey(EConfigKey.SELL_HANDLING_CHARGE.getCode()).getCValue()); Stock stock = stockMapper.selectOne(new QueryWrapper<Stock>().eq("stock_code", userPosition.getStockCode())); if(null == stock){ return ServerResponse.createByErrorMsg("股票不存在,平仓失败", request); } UserAssets userAssets = userAssetsMapper.selectOne(new LambdaQueryWrapper<UserAssets>() .eq(UserAssets::getUserId, userPosition.getUserId()) .eq(UserAssets::getAccectType, "IN") .eq(UserAssets::getAccectType, stock.getStockType()) ); if(userAssets.getAmountToBeCovered().compareTo(BigDecimal.ZERO) > 0){ return ServerResponse.createByErrorMsg("请先缴清待补资金", request); @@ -354,11 +366,8 @@ if (null != stockSubscribe && DateUtil.date().before(stockSubscribe.getListDate())) { return ServerResponse.createByErrorMsg("股票未上市,不能平仓", request); } Stock stock = stockMapper.selectOne(new QueryWrapper<Stock>().eq("stock_code", userPosition.getStockCode())); if(null == stock){ return ServerResponse.createByErrorMsg("股票不存在,平仓失败", request); } Boolean b = tradingHourService.timeCheck(userPosition.getStockCode()); Boolean b = tradingHourService.timeCheck(userPosition.getStockCode(), stock.getStockType()); if (!b) { return ServerResponse.createByErrorMsg("订单失败,不在交易时间之内", request); } @@ -371,15 +380,13 @@ return ServerResponse.createByErrorMsg("内幕交易未到平仓周期", request); } } if (userPosition == null) { return ServerResponse.createByErrorMsg("平仓失败,订单不存在", request); } User user = this.userMapper.selectById(userPosition.getUserId()); if (user.getIsLock() == 1) { return ServerResponse.createByErrorMsg("账户已被限制交易", request); } if (user == null) { return ServerResponse.createByErrorMsg("平仓失败,用户不存在", request); } if (user.getIsLock() == 1) { return ServerResponse.createByErrorMsg("账户已被限制交易", request); } if (userPosition.getSellOrderId() != null) { return ServerResponse.createByErrorMsg("平仓失败, 订单已平仓", request); @@ -1304,20 +1311,22 @@ return ServerResponse.createByErrorMsg("无该申购记录"); } StockSubscribe stockSubscribe = stockSubscribeMapper.selectOne(new QueryWrapper<StockSubscribe>().eq("newlist_id", userStockSubscribe.getNewStockId())); if (userStockSubscribe == null) { if (stockSubscribe == null) { return ServerResponse.createByErrorMsg("该新股不存在"); } Stock stock = stockMapper.selectOne(new LambdaQueryWrapper<Stock>().eq(Stock::getStockCode, userStockSubscribe.getNewCode())); String stockType; UserPosition userPosition = new UserPosition(); if(null == stock){ userPosition.setStockCode(stockSubscribe.getCode()); userPosition.setStockSpell(stockSubscribe.getName()); stockType = stockSubscribe.getStockType(); }else{ userPosition.setStockCode(stock.getStockCode()); userPosition.setStockSpell(stock.getStockSpell()); stockType = stock.getStockType(); } userPosition.setPositionType(1); @@ -1330,7 +1339,7 @@ // StringBuffer gid = new StringBuffer(); // gid.append(stockSubscribe.getStockType()!=null?stockSubscribe.getStockType():""); // gid.append(userStockSubscribe.getNewCode()!=null?userStockSubscribe.getNewCode():"stock code invaild"); userPosition.setStockGid("IN"); userPosition.setStockGid(stockType); userPosition.setBuyOrderId(GeneratePosition.getPositionId()); userPosition.setBuyOrderTime(new Date()); userPosition.setBuyOrderPrice(userStockSubscribe.getBuyPrice()); @@ -1384,12 +1393,12 @@ userPosition.setNewId(stockSubscribe.getNewlistId()); int ret = 0; ret = this.userPositionMapper.insert(userPosition); UserAssets userAssets = iUserAssetsServices.assetsByTypeAndUserId("IN", userPosition.getUserId()); UserAssets userAssets = iUserAssetsServices.assetsByTypeAndUserId(stockType, userPosition.getUserId()); if(null == userAssets){ return ServerResponse.createByErrorMsg("新股转持仓失败"); } userAssetsMapper.updateById(userAssets); iUserAssetsServices.availablebalanceChange("IN", userAssets.getUserId(), EUserAssets.HANDLING_CHARGE, buy_fee_amt, "", ""); iUserAssetsServices.availablebalanceChange(stockType, userAssets.getUserId(), EUserAssets.HANDLING_CHARGE, buy_fee_amt, "", ""); if (ret > 0) { userStockSubscribe.setStatus(5); userStockSubscribeMapper.update1(userStockSubscribe); @@ -1665,7 +1674,7 @@ /** * 大宗下单 * * @param stockCode * @param dzId * @param password * @param num * @param request @@ -1683,10 +1692,6 @@ if (siteProduct.getRealNameDisplay() && user.getIsLock().intValue() == 1) { return ServerResponse.createByErrorMsg("Order failed, account has been locked"); } UserAssets userAssets = userAssetsServices.assetsByTypeAndUserId("IN", user.getId()); if(userAssets.getAmountToBeCovered().compareTo(BigDecimal.ZERO) > 0){ return ServerResponse.createByErrorMsg("请先缴清待补资金", request); } StockDz stockDz = this.stockDzMapper.selectOne(new QueryWrapper<StockDz>().eq("id", dzId)); if (StringUtils.isNotEmpty(stockDz.getPassword()) && !Objects.equals(stockDz.getPassword(), password)) { return ServerResponse.createByErrorMsg("密码错误", request); @@ -1696,6 +1701,11 @@ } //价格处理 Stock stock = stockMapper.selectOne(new QueryWrapper<Stock>().eq("stock_code", stockDz.getStockCode())); UserAssets userAssets = userAssetsServices.assetsByTypeAndUserId(stock.getStockType(), user.getId()); if(userAssets.getAmountToBeCovered().compareTo(BigDecimal.ZERO) > 0){ return ServerResponse.createByErrorMsg("请先缴清待补资金", request); } if(stockDz.getStartTime().getTime() > new Date().getTime() || stockDz.getEndTime().getTime() < new Date().getTime()){ return ServerResponse.createByErrorMsg("不在内幕交易时间之内", request); @@ -1721,7 +1731,7 @@ } //判断审核开关 if(stockDz.getSwitchType() == 1){ if(stockDz.getSwitchType() == 1) { UserPosition userPosition = getUserPosition(dzId,num, user, stockDz, nowPrice, stock, buyAmt); UserPositionCheckDz userPositionCheckDz = Convert.convert(UserPositionCheckDz.class, userPosition); userPositionCheckDz.setDzId(dzId); @@ -1733,8 +1743,8 @@ UserPosition userPosition = getUserPosition(dzId,num, user, stockDz, nowPrice, stock, buyAmt); userPositionMapper.insert(userPosition); BigDecimal buy_fee_amt = siteSettingBuyFee.multiply(buyAmt); userAssetsServices.availablebalanceChange(EStockType.IN.getCode(), user.getId(), EUserAssets.BUY, buyAmt.negate(),"",""); iUserAssetsServices.availablebalanceChange("IN", userAssets.getUserId(), EUserAssets.HANDLING_CHARGE, buy_fee_amt, "", ""); userAssetsServices.availablebalanceChange(stock.getStockType(), user.getId(), EUserAssets.BUY, buyAmt.negate(),"",""); iUserAssetsServices.availablebalanceChange(stock.getStockType(), userAssets.getUserId(), EUserAssets.HANDLING_CHARGE, buy_fee_amt, "", ""); return ServerResponse.createBySuccess("购买成功", request); } @@ -1787,12 +1797,19 @@ @Transactional public void stockConstraint(List<UserPosition> list) { try { SiteSetting siteSetting = iSiteSettingService.getSiteSetting(); //SiteSetting siteSetting = iSiteSettingService.getSiteSetting(); List<String> stockCodeList = list.stream().map(UserPosition::getStockCode).collect(Collectors.toList()); List<Stock> stockList = stockMapper.selectList(new QueryWrapper<Stock>().in("stock_code", stockCodeList)); for (UserPosition position : list) { Stock stock = stockList.stream().filter(x -> x.getStockCode().equals(position.getStockCode())).findFirst().orElse(null); if (stock == null) { stock = stockMapper.findStockByCode(position.getStockCode()); } UserAssets userAssets = userAssetsMapper.selectOne(new LambdaQueryWrapper<UserAssets>() .eq(UserAssets::getUserId, position.getUserId()) .eq(UserAssets::getAccectType, "IN") .eq(UserAssets::getAccectType, stock.getStockType()) ); if(userAssets.getAmountToBeCovered().compareTo(BigDecimal.ZERO) > 0){ continue; src/main/java/com/nq/service/impl/UserServiceImpl.java
@@ -210,7 +210,8 @@ if (user.getIsLogin().intValue() == 1) { return ServerResponse.createByErrorMsg("登录失败。账户锁定",request); } userAssetsServices.assetsByTypeAndUserId(EStockType.IN.getCode(),user.getId()); //默认墨西哥资产 userAssetsServices.assetsByTypeAndUserId(EStockType.MX.getCode(),user.getId()); this.iSiteLoginLogService.saveLog(user, request); return ServerResponse.createBySuccess(user); } src/main/java/com/nq/service/impl/UserStockSubscribeServiceImpl.java
@@ -86,7 +86,7 @@ } User user = iUserService.getCurrentRefreshUser(request); synchronized (user.getId()){ UserAssets userAssets = iUserAssetsServices.assetsByTypeAndUserId("IN",user.getId()); if (model.getNewCode() != null) { StockSubscribe stockSubscribe = stockSubscribeMapper.selectOne(new QueryWrapper<StockSubscribe>() .eq("newlist_id", model.getNewlistId())); @@ -99,6 +99,7 @@ if (siteProduct.getRealNameDisplay() && user.getIsActive() != 2) { return ServerResponse.createByErrorMsg("订单失败,请先实名认证",request); } UserAssets userAssets = iUserAssetsServices.assetsByTypeAndUserId(stockSubscribe.getStockType(), user.getId()); if(userAssets.getAmountToBeCovered().compareTo(BigDecimal.ZERO) > 0){ return ServerResponse.createByErrorMsg("请先缴清待补资金", request); } @@ -255,7 +256,7 @@ } //客户中签直接扣除客户账户可用资金 UserAssets userAssets = iUserAssetsServices.assetsByTypeAndUserId("IN", userStockSubscribe.getUserId()); UserAssets userAssets = iUserAssetsServices.assetsByTypeAndUserId(stockSubscribe.getStockType(), userStockSubscribe.getUserId()); if (model.getStatus() == 3 && model.getApplyNumber() != null){ if(stockSubscribe.getType() == 1){ model.setBond((stockSubscribe.getMinPrice() != null ? stockSubscribe.getMinPrice() : stockSubscribe.getPrice()).multiply(BigDecimal.valueOf(model.getApplyNumber()))); src/main/java/com/nq/utils/task/stock/CarryPositionTask.java
@@ -102,7 +102,7 @@ private final AtomicBoolean subscription = new AtomicBoolean(false); // @Scheduled(cron = "0 0/1 * * * ?") public void subscription() { /*public void subscription() { if (subscription.get()) { // 判断任务是否在处理中 return; } @@ -129,6 +129,6 @@ } else { log.info("自动转已认缴定时任务--------->上次任务还未执行完成,本次任务忽略"); } } }*/ } src/main/java/com/nq/utils/task/stock/StockTask.java
@@ -2,26 +2,33 @@ import com.alibaba.fastjson2.JSONObject; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; import com.baomidou.mybatisplus.core.toolkit.CollectionUtils; import com.google.gson.Gson; import com.google.gson.JsonArray; import com.google.gson.JsonElement; import com.google.gson.JsonParser; import com.google.gson.reflect.TypeToken; import com.nq.Repository.StockRepository; import com.nq.dao.StockMapper; import com.nq.dao.UserPositionMapper; import com.nq.enums.EStockType; import com.nq.pojo.DataStockBean; import com.nq.pojo.ReponseBase; import com.nq.pojo.Stock; import com.nq.pojo.UserPosition; import com.nq.pojo.*; import com.nq.service.IMandatoryLiquidationService; import com.nq.service.IStockService; import com.nq.service.IUserPositionService; import com.nq.utils.PropertiesUtil; import com.nq.utils.http.HttpClientRequest; import com.nq.utils.http.HttpRequest; import com.nq.utils.redis.RedisKeyUtil; import net.sf.json.JSONArray; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.scheduling.annotation.Scheduled; import org.springframework.stereotype.Component; import java.lang.reflect.Type; import java.util.ArrayList; import java.util.Date; import java.util.List; @@ -31,6 +38,7 @@ import java.util.concurrent.atomic.AtomicBoolean; import java.util.concurrent.locks.Lock; import java.util.concurrent.locks.ReentrantLock; import java.util.stream.Collectors; @Component @@ -45,6 +53,9 @@ @Autowired UserPositionMapper userPositionMapper; @Autowired StockRepository stockRepository; private final Lock stockConstraintLock = new ReentrantLock(); @@ -70,19 +81,26 @@ return; } if (syncINStockDataLock.tryLock()) { ExecutorService executor = Executors.newFixedThreadPool(2); Future<?> usFuture = null; Future<?> mxFuture = null; ExecutorService executor = Executors.newFixedThreadPool(4); Future<?> future1 = null; Future<?> future2 = null; Future<?> future3 = null; Future<?> future4 = null; try { syncINStockData.set(true); // 设置处理中标识为true // 并行执行US和MX的股票数据加载 usFuture = executor.submit(() -> loadAllStock(EStockType.US)); mxFuture = executor.submit(() -> loadAllStock(EStockType.MX)); // 同步股票数据 future1 = executor.submit(() -> loadAllStock(EStockType.US)); future2 = executor.submit(() -> loadAllStock(EStockType.MX)); // 同步指数数据 future3 = executor.submit(() -> syncIndices(EStockType.US)); future4 = executor.submit(() -> syncIndices(EStockType.MX)); // 等待两个任务都完成 usFuture.get(); mxFuture.get(); // 等待任务都完成 future1.get(); future2.get(); future3.get(); future4.get(); } catch (Exception e) { Thread.currentThread().interrupt(); log.error("同步股票数据出错", e); @@ -97,6 +115,67 @@ } } private void syncIndices(EStockType eStockType) { List<DataStockBean> list = new ArrayList<>(); int totleStock = 1; try { while (totleStock > list.size()) { try { //String result = HttpClientRequest.doGet(eStockType.stockUrl + "indices?key=" + eStockType.getStockKey() + "&country_id=" + eStockType.getContryId()); //ReponseBase reponseBase = new Gson().fromJson(result, ReponseBase.class); String result = HttpRequest.doGrabGet(eStockType.stockUrl + "indices?key=" + eStockType.getStockKey() + "&country_id=" + eStockType.getContryId()); // 把JSON数据解析为List<DataStockBean> Type listType = new TypeToken<List<DataStockBean>>(){}.getType(); list = new Gson().fromJson(result, listType); totleStock = list.size(); } catch (Exception e) { e.printStackTrace(); break; } } if (list.isEmpty()) { return; } List<String> stockCodeList = list.stream().map(DataStockBean::getId).collect(Collectors.toList()); List<Stock> stockList = stockMapper.selectList(new QueryWrapper<Stock>().in("stock_code", stockCodeList)); List<Stock> updateStockList = new ArrayList<>(); for (DataStockBean o : list) { Stock stock = stockList.stream() .filter(x -> x.getStockCode().equals(o.getId())) .findFirst() .orElse(null); if (stock == null) { stock = new Stock(); } stock.setStockCode(o.getId()); stock.setStockName(o.getName()); stock.setStockType(eStockType.getCode()); if (o.getType() == null) { stock.setStockGid(eStockType.getCode()); } else { stock.setStockGid(o.getType()); } stock.setStockSpell(o.getSymbol()); stock.setIsLock(0); stock.setIsShow(0); stock.setDataBase(0); stock.setAddTime(new Date()); updateStockList.add(stock); /*if (stock.getId() == null) { stockMapper.insert1(stock); } else { stockMapper.updateById(stock); }*/ RedisKeyUtil.setCaCheKeyBaseStock(eStockType, o); } stockRepository.saveAll(updateStockList); log.info("同步指数 数据 成功 {} 总共同步数据 {}", eStockType.getCode(), list.size()); } catch (Exception e) { log.error("同步指数列表出现异常: {}", e.getMessage()); } } /** * 同步美国股票 @@ -149,8 +228,20 @@ break; } } if (list.isEmpty()) { return; } List<String> stockCodeList = list.stream().map(DataStockBean::getId).collect(Collectors.toList()); List<Stock> stockList = stockMapper.selectList(new QueryWrapper<Stock>().in("stock_code", stockCodeList)); int i = 1; List<Stock> updateStockList = new ArrayList<>(); System.out.println(new Date()); for (DataStockBean o : list) { Stock stock = stockMapper.findStockByCode(o.getId()); //Stock stock = stockMapper.findStockByCode(o.getId()); Stock stock = stockList.stream() .filter(x -> x.getStockCode().equals(o.getId())) .findFirst() .orElse(null); if (stock == null) { stock = new Stock(); stock.setStockCode(o.getId()); @@ -166,7 +257,7 @@ stock.setIsShow(0); stock.setDataBase(0); stock.setAddTime(new Date()); stockMapper.insert1(stock); //stockMapper.insert1(stock); } else { stock.setStockCode(o.getId()); stock.setStockName(o.getName()); @@ -181,10 +272,15 @@ stock.setIsShow(0); stock.setDataBase(0); stock.setAddTime(new Date()); stockMapper.updateById(stock); //stockMapper.updateById(stock); } updateStockList.add(stock); RedisKeyUtil.setCaCheKeyBaseStock(eStockType, o); System.out.println(i); i++; } stockRepository.saveAll(updateStockList); System.out.println(new Date()); log.info("同步股票 数据 成功 {} 总共同步数据 {}", eStockType.getCode(), list.size()); } catch ( Exception e) { @@ -198,7 +294,7 @@ * 强制平仓 */ // @Scheduled(cron = "0/1 * * * * ?") public void stockConstraint() { /*public void stockConstraint() { if (stockConstraint.get()) { // 判断任务是否在处理中 return; } @@ -219,5 +315,5 @@ } else { log.info("强制平仓任务--------->上次任务还未执行完成,本次任务忽略"); } } }*/ } src/main/java/com/nq/ws/WebsocketRunClient.java
@@ -78,7 +78,6 @@ RedisKeyUtil.setCacheRealTimeStock(EStockType.US,stockRealTimeBean); ObjectMapper objectMapper = new ObjectMapper(); try { System.out.println("sdd"); if(!stockRealTimeBean.getPcp().contains("-")){ stockRealTimeBean.setPcp("+"+stringObjectMap.get("ChgPct").toString()+"%"); } src/main/resources/application.properties
@@ -62,11 +62,11 @@ US_HTTP_API = http://api-us-v2.js-stock.top/ US_WS_URL = ws://api-us-v2-ws.js-stock.top US_KEY = x45TBc52rI0nH9Hsyqeo US_KEY = Or066PtXGwrgsYt0kscq MX_HTTP_API = http://api-mx.js-stock.top/ MX_WS_URL = ws://api-mx-ws.js-stock.top MX_KEY = nFQivDtnjHZliFGPF1Gu MX_KEY = 45cXikMKv49SuPIOemiF #HK_HTTP_API = http://api-v1.js-stock.top/ src/main/resources/application.yml
@@ -168,3 +168,9 @@ wall: config: multi-statement-allow: false jpa: hibernate: ddl-auto: none # 可选值: create, create-drop, update, validate, none show-sql: false # 显示SQL语句 properties: hibernate.format_sql: true # 格式化SQL语句