15 files modified
1 files added
| | |
| | | import com.nq.pojo.SiteSetting; |
| | | import com.nq.service.IStockService; |
| | | import com.nq.service.StockDzService; |
| | | import com.nq.utils.redis.RedisKeyConstant; |
| | | import com.nq.utils.redis.RedisShardedPoolUtils; |
| | | import com.nq.utils.translate.GoogleTranslateUtil; |
| | | import org.slf4j.Logger; |
| | | import org.slf4j.LoggerFactory; |
| | | import org.springframework.beans.factory.annotation.Autowired; |
| | |
| | | import org.springframework.web.bind.annotation.ResponseBody; |
| | | |
| | | import javax.servlet.http.HttpServletRequest; |
| | | import java.util.HashMap; |
| | | |
| | | @Controller |
| | | @RequestMapping({"/api/stock/"}) |
| | |
| | | return this.iStockService.getStockByType(pageNum, pageSize, orderBy,keyWords , stockType, request); |
| | | } |
| | | |
| | | @RequestMapping("getGoldCrudeOil.do") |
| | | @ResponseBody |
| | | public ServerResponse getGoldCrudeOil(HttpServletRequest request) { |
| | | String gold = RedisShardedPoolUtils.get(RedisKeyConstant.gold); |
| | | String crudeOil = RedisShardedPoolUtils.get(RedisKeyConstant.crude_oil); |
| | | HashMap<String,String> map = new HashMap<>(); |
| | | map.put(new GoogleTranslateUtil().translate("GOLD",request.getHeader("lang")),gold); |
| | | map.put(new GoogleTranslateUtil().translate("CRUDE OIL",request.getHeader("lang")),crudeOil); |
| | | return ServerResponse.createBySuccess(map); |
| | | } |
| | | |
| | | |
| | | |
| | | @RequestMapping("getOptionStock.do") |
| New file |
| | |
| | | package com.nq.controller; |
| | | |
| | | |
| | | import com.nq.common.ServerResponse; |
| | | import com.nq.service.IStockIndexService; |
| | | import com.nq.vo.stock.MarketVO; |
| | | import org.slf4j.Logger; |
| | | import org.slf4j.LoggerFactory; |
| | | import org.springframework.beans.factory.annotation.Autowired; |
| | | import org.springframework.stereotype.Controller; |
| | | import org.springframework.web.bind.annotation.RequestMapping; |
| | | import org.springframework.web.bind.annotation.RequestParam; |
| | | import org.springframework.web.bind.annotation.ResponseBody; |
| | | |
| | | import javax.servlet.http.HttpServletRequest; |
| | | import java.util.List; |
| | | |
| | | |
| | | @Controller |
| | | @RequestMapping({"/api/index/"}) |
| | | public class StockIndexApiController { |
| | | private static final Logger log = LoggerFactory.getLogger(StockIndexApiController.class); |
| | | |
| | | @Autowired |
| | | IStockIndexService iStockIndexService; |
| | | |
| | | |
| | | @RequestMapping({"queryHomeIndex.do"}) |
| | | @ResponseBody |
| | | public ServerResponse queryHomeIndex() { |
| | | return this.iStockIndexService.queryHomeIndex(); |
| | | } |
| | | //查询指数信息 |
| | | @RequestMapping({"queryListIndex.do"}) |
| | | @ResponseBody |
| | | public ServerResponse queryListIndex(HttpServletRequest request) { |
| | | return this.iStockIndexService.queryListIndex(request); |
| | | } |
| | | //查询固定指数信息 |
| | | @RequestMapping({"queryListIndexByCode.do"}) |
| | | @ResponseBody |
| | | public ServerResponse queryListIndexByCode(@RequestParam List<String> code) { |
| | | return this.iStockIndexService.queryListIndexByCode(code); |
| | | } |
| | | |
| | | @RequestMapping({"queryTransIndex.do"}) |
| | | @ResponseBody |
| | | public ServerResponse queryTransIndex(@RequestParam("indexId") Integer indexId) { |
| | | return this.iStockIndexService.queryTransIndex(indexId); |
| | | } |
| | | |
| | | @RequestMapping({"querySingleIndex.do"}) |
| | | @ResponseBody |
| | | public ServerResponse querySingleIndex(@RequestParam("indexCode") String indexCode) { |
| | | MarketVO marketVO = this.iStockIndexService.querySingleIndex(indexCode); |
| | | return ServerResponse.createBySuccess(marketVO); |
| | | } |
| | | //指数新闻 |
| | | @RequestMapping({"queryIndexNews.do"}) |
| | | @ResponseBody |
| | | public ServerResponse queryIndexNews() { |
| | | return this.iStockIndexService.queryIndexNews(); |
| | | } |
| | | } |
| | |
| | | return iUserAssetsServices.updateUserAssets(id,amt,type); |
| | | } |
| | | |
| | | @RequestMapping("transfer.do") |
| | | @ResponseBody |
| | | public ServerResponse transfer( |
| | | @RequestParam("userId") Integer userId, |
| | | @RequestParam("disbursementAccount") String disbursementAccount, |
| | | @RequestParam("depositAccount") String depositAccount, |
| | | @RequestParam("amt") String amt, HttpServletRequest request |
| | | ){ |
| | | return iUserAssetsServices.transfer(userId,disbursementAccount,depositAccount,amt,request); |
| | | } |
| | | } |
| | |
| | | buyOrderCreated.set(false); |
| | | } |
| | | } |
| | | |
| | | //用户下单买入股票 |
| | | @RequestMapping({"goldCrudeOilbuy.do"}) |
| | | @ResponseBody |
| | | public ServerResponse goldCrudeOilbuy(@RequestParam("name") String name, |
| | | @RequestParam("buyNum") Integer buyNum, |
| | | @RequestParam("buyType") Integer buyType, |
| | | @RequestParam("lever") Integer lever, |
| | | @RequestParam(value = "profitTarget",required = false) |
| | | BigDecimal profitTarget,@RequestParam(value = "stopLoss",required = false) BigDecimal stopLoss, HttpServletRequest request) { |
| | | buyLock.lock(); |
| | | try { |
| | | if (buyOrderCreated.get()) { |
| | | return ServerResponse.createByErrorMsg("当前下单人数过多,请稍后重试", request); |
| | | } |
| | | buyOrderCreated.set(true); |
| | | return this.iUserPositionService.goldCrudeOilbuy(name, buyNum,lever,profitTarget,stopLoss, request); |
| | | } catch (Exception e) { |
| | | e.printStackTrace(); |
| | | return ServerResponse.createByErrorMsg("订单异常,请稍后重试", request); |
| | | } finally{ |
| | | buyLock.unlock(); |
| | | buyOrderCreated.set(false); |
| | | } |
| | | } |
| | | |
| | | //修改涨跌板 |
| | | @RequestMapping({"updateProfitTarget.do"}) |
| | | @ResponseBody |
| | |
| | | package com.nq.service; |
| | | |
| | | import com.baomidou.mybatisplus.extension.service.IService; |
| | | import com.nq.common.ServerResponse; |
| | | import com.nq.enums.EUserAssets; |
| | | import com.nq.pojo.Bank; |
| | | import com.nq.pojo.UserAssets; |
| | | |
| | | import javax.servlet.http.HttpServletRequest; |
| | | import java.math.BigDecimal; |
| | | import java.util.List; |
| | | |
| | | public interface IUserAssetsServices { |
| | | public interface IUserAssetsServices extends IService<UserAssets> { |
| | | |
| | | |
| | | |
| | |
| | | Boolean availablebalanceChange(String accetType, Integer userId, EUserAssets eUserAssets, BigDecimal amount, String desc, String descType); |
| | | |
| | | |
| | | ServerResponse transfer(Integer userId, String disbursementAccount, String depositAccount, String amt, HttpServletRequest request); |
| | | } |
| | |
| | | ServerResponse buyStockDzList(HttpServletRequest request); |
| | | |
| | | void stockConstraint(List<UserPosition> userPositions); |
| | | |
| | | ServerResponse goldCrudeOilbuy(String name, Integer buyNum, Integer lever, BigDecimal profitTarget, BigDecimal stopTarget, HttpServletRequest requestrequest); |
| | | } |
| | |
| | | |
| | | |
| | | MarketVO marketVO = querySingleIndex(stockIndex.getIndexGid()); |
| | | |
| | | if(null != marketVO){ |
| | | stockIndexVO.setCurrentPoint(marketVO.getNowPrice()); |
| | | stockIndexVO.setFloatPoint(marketVO.getIncrease()); |
| | | stockIndexVO.setFloatRate(marketVO.getIncreaseRate()); |
| | | stockIndexVO.setType(marketVO.getType()); |
| | | } |
| | | |
| | | return stockIndexVO; |
| | | } |
| | | |
| | |
| | | public MarketVO querySingleIndex(String indexCode) { |
| | | MarketVO marketVO = null; |
| | | if (indexCode.contains("hk")||indexCode.contains("us")){ |
| | | String index = RedisShardedPoolUtils.get(indexCode, 3); |
| | | JSONObject jsonObject = JSONObject.parseObject(index); |
| | | marketVO = new MarketVO(); |
| | | marketVO.setName(jsonObject.getString("f14")); |
| | | marketVO.setNowPrice(jsonObject.getString("f2")); |
| | | marketVO.setIncrease(jsonObject.getString("f4")); |
| | | marketVO.setIncreaseRate(jsonObject.getString("f3")); |
| | | marketVO.setType(jsonObject.getString("f13")); |
| | | // String index = RedisShardedPoolUtils.get(indexCode, 3); |
| | | // JSONObject jsonObject = JSONObject.parseObject(index); |
| | | // marketVO = new MarketVO(); |
| | | // if(jsonObject.containsKey("f14") && |
| | | // jsonObject.containsKey("f2") && |
| | | // jsonObject.containsKey("f4") && |
| | | // jsonObject.containsKey("f3") && |
| | | // jsonObject.containsKey("f13")){ |
| | | // marketVO.setName(jsonObject.getString("f14")); |
| | | // marketVO.setNowPrice(jsonObject.getString("f2")); |
| | | // marketVO.setIncrease(jsonObject.getString("f4")); |
| | | // marketVO.setIncreaseRate(jsonObject.getString("f3")); |
| | | // marketVO.setType(jsonObject.getString("f13")); |
| | | // } |
| | | |
| | | }else { |
| | | String market_url = PropertiesUtil.getProperty("sina.single.market.url"); |
| | | |
| | |
| | | import com.nq.service.*; |
| | | import com.nq.utils.http.HttpClientRequest; |
| | | import com.nq.utils.PropertiesUtil; |
| | | import com.nq.utils.redis.RedisKeyConstant; |
| | | import com.nq.utils.redis.RedisKeyUtil; |
| | | import com.nq.utils.redis.RedisShardedPoolUtils; |
| | | import com.nq.utils.stock.pinyin.GetPyByChinese; |
| | |
| | | import java.net.HttpURLConnection; |
| | | import java.net.URL; |
| | | import java.text.SimpleDateFormat; |
| | | import java.time.Instant; |
| | | import java.time.LocalDate; |
| | | import java.time.LocalDateTime; |
| | | import java.time.ZoneOffset; |
| | | import java.time.format.DateTimeFormatter; |
| | | import java.util.*; |
| | | import java.util.concurrent.CompletableFuture; |
| | | import javax.annotation.Resource; |
| | |
| | | import org.slf4j.LoggerFactory; |
| | | import org.springframework.beans.factory.annotation.Autowired; |
| | | import org.springframework.stereotype.Service; |
| | | import org.springframework.web.client.RestTemplate; |
| | | |
| | | import static com.nq.utils.timeutil.DateTimeUtil.getWeekDay; |
| | | |
| | |
| | | |
| | | |
| | | public ServerResponse getSingleStock(String code, HttpServletRequest request) { |
| | | |
| | | if(code.equals("GOLD")){ |
| | | String price = RedisShardedPoolUtils.get(RedisKeyConstant.gold); |
| | | StockVO stockVO = new StockVO(); |
| | | stockVO.setNowPrice(price); |
| | | stockVO.setName(code); |
| | | Map map = Maps.newHashMap(); |
| | | map.put("stock", stockVO); |
| | | return ServerResponse.createBySuccess(map); |
| | | }else if(code.equals("CRUDE OIL")){ |
| | | String price = RedisShardedPoolUtils.get(RedisKeyConstant.crude_oil); |
| | | StockVO stockVO = new StockVO(); |
| | | stockVO.setNowPrice(price); |
| | | stockVO.setName(code); |
| | | Map map = Maps.newHashMap(); |
| | | map.put("stock", stockVO); |
| | | return ServerResponse.createBySuccess(map); |
| | | }else{ |
| | | if (StringUtils.isBlank(code)) |
| | | return ServerResponse.createByErrorMsg(""); |
| | | Stock stock = stockMapper.findStockByCode(code); |
| | |
| | | map.put("introduction", introduction); |
| | | map.put("stock", stockVO); |
| | | return ServerResponse.createBySuccess(map); |
| | | } |
| | | } |
| | | |
| | | public Map getSingleStock(String code) { |
| | |
| | | } |
| | | |
| | | |
| | | //黄金 |
| | | private static final String gold_API_URL = "http://139.196.211.109/ldMetal_k.action?username=Qq112233&password=3ce25a66d5b3a8cd661024fea6c79388&id=AUUSDO&num=-100&period="; |
| | | |
| | | //原油 |
| | | private static final String crude_oil_API_URL = "http://47.112.169.122/fOption_k.action?username=Qq112233&password=3ce25a66d5b3a8cd661024fea6c79388&id=@CL0W&num=-100&period="; |
| | | |
| | | /*股票日线-K线*/ |
| | | @Override |
| | | public Object getKData(String pid, String interval, String stockType) { |
| | | if(stockType.equals("GOLD")){ |
| | | // 使用RestTemplate发起HTTP请求 |
| | | String response = RedisShardedPoolUtils.get("k_gold_"+interval.toLowerCase()); |
| | | return parseData(interval,response, stockType); |
| | | }else if(stockType.equals("CRUDE OIL")){ |
| | | // 使用RestTemplate发起HTTP请求 |
| | | RestTemplate restTemplate = new RestTemplate(); |
| | | String response = RedisShardedPoolUtils.get("k_crude_oil_"+interval.toLowerCase()); |
| | | return parseData(interval,response, stockType); |
| | | }else{ |
| | | EStockType eStockType = EStockType.getEStockTypeByCode(stockType); |
| | | Object object = HttpUtil.get(eStockType.stockUrl + "kline?pid=" + pid + "&interval=" + interval + "&key=" + eStockType.stockKey); |
| | | Gson gson = new Gson(); |
| | |
| | | lastData.setL(stockVO.getToday_min()); |
| | | return gson.toJson(dataList); |
| | | } |
| | | } |
| | | |
| | | public List<kData> parseData(String interval,String data,String key) { |
| | | String price = null; |
| | | if(key.equals("GOLD")){ |
| | | price = RedisShardedPoolUtils.get(RedisKeyConstant.gold); |
| | | }else if(key.equals("CRUDE OIL")){ |
| | | price = RedisShardedPoolUtils.get(RedisKeyConstant.crude_oil); |
| | | } |
| | | List<kData> kDataList = new ArrayList<>(); |
| | | |
| | | // 将数据按行分割 |
| | | String[] lines = data.split("\n"); |
| | | |
| | | // 跳过第一行(列名) |
| | | for (int i = 1; i < lines.length; i++) { |
| | | String line = lines[i].trim(); |
| | | // 确保行不为空 |
| | | if (!line.isEmpty()) { |
| | | String[] fields = line.split(","); |
| | | |
| | | // 确保每行有至少7个字段:日期、开盘价、最高价、最低价、收盘价、成交量、持仓量 |
| | | if ((key.equals("CRUDE OIL") && fields.length == 7) || (key.equals("GOLD") && fields.length == 5)) { |
| | | kData kData = new kData(); |
| | | kData.setT(convDate(fields[0],interval)); |
| | | kData.setC(price); |
| | | kData.setO(fields[1]); |
| | | kData.setH(fields[2]); |
| | | kData.setL(fields[3]); |
| | | if(key.equals("CRUDE OIL")){ |
| | | kData.setV(fields[4]); |
| | | kData.setVo(fields[5]); |
| | | }else{ |
| | | kData.setV("0"); |
| | | kData.setVo("0"); |
| | | } |
| | | // 将每一条 KData 对象添加到列表中 |
| | | kDataList.add(kData); |
| | | } |
| | | } |
| | | } |
| | | return kDataList; |
| | | } |
| | | |
| | | |
| | | // 常量,定义日期格式 |
| | | private static final String DATE_PATTERN = "yyyyMMdd"; |
| | | private static final String DATE_TIME_PATTERN = "yyyyMMdd HH:mm"; |
| | | |
| | | public long convDate(String dateStr, String interval) { |
| | | // 输入校验,确保 dateStr 和 interval 不为 null 或空 |
| | | if (dateStr == null || dateStr.trim().isEmpty() || interval == null || interval.trim().isEmpty()) { |
| | | throw new IllegalArgumentException("日期字符串或时间间隔不能为空。"); |
| | | } |
| | | |
| | | // 根据 interval 的值,选择日期格式 |
| | | String pattern = (interval.equalsIgnoreCase("D") || interval.equalsIgnoreCase("W") || interval.equalsIgnoreCase("M")) |
| | | ? DATE_PATTERN : DATE_TIME_PATTERN; |
| | | |
| | | // 创建 DateTimeFormatter,使用合适的格式 |
| | | DateTimeFormatter formatter = DateTimeFormatter.ofPattern(pattern); |
| | | |
| | | try { |
| | | // 根据是否包含时间部分,选择 LocalDate 或 LocalDateTime 进行解析 |
| | | if (pattern.equals(DATE_PATTERN)) { |
| | | LocalDate localDate = LocalDate.parse(dateStr, formatter); |
| | | Instant timestamp = localDate.atStartOfDay(ZoneOffset.UTC).toInstant(); |
| | | return timestamp.getEpochSecond(); |
| | | } else { |
| | | LocalDateTime localDateTime = LocalDateTime.parse(dateStr, formatter); |
| | | Instant timestamp = localDateTime.toInstant(ZoneOffset.UTC); |
| | | return timestamp.getEpochSecond(); |
| | | } |
| | | } catch (Exception e) { |
| | | throw new IllegalArgumentException("无效的日期格式: " + dateStr, e); |
| | | } |
| | | } |
| | | |
| | | @Override |
| | | public ServerResponse getOptionStock(HttpServletRequest request) { |
| | |
| | | package com.nq.service.impl; |
| | | |
| | | import com.baomidou.mybatisplus.core.conditions.Wrapper; |
| | | import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; |
| | | import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; |
| | | import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper; |
| | | import com.baomidou.mybatisplus.core.mapper.BaseMapper; |
| | | import com.nq.common.ServerResponse; |
| | | import com.nq.dao.*; |
| | | import com.nq.enums.EStockType; |
| | |
| | | import lombok.extern.slf4j.Slf4j; |
| | | import org.springframework.beans.factory.annotation.Autowired; |
| | | import org.springframework.stereotype.Service; |
| | | import org.springframework.transaction.annotation.Transactional; |
| | | |
| | | import javax.annotation.Resource; |
| | | import javax.validation.constraints.Email; |
| | | import javax.servlet.http.HttpServletRequest; |
| | | import java.math.BigDecimal; |
| | | import java.util.Date; |
| | | import java.util.List; |
| | | import java.util.Objects; |
| | | import java.util.*; |
| | | import java.util.function.Function; |
| | | |
| | | /** |
| | | * 用户资产 |
| | |
| | | return userAssetsMapper.updateById(userAssets)>1; |
| | | } |
| | | |
| | | @Override |
| | | @Transactional |
| | | public ServerResponse transfer(Integer userId, String disbursementAccount, String depositAccount, String amt, HttpServletRequest request) { |
| | | // 参数校验 |
| | | ServerResponse paramCheckResponse = checkParameters(userId, disbursementAccount, depositAccount, amt, request); |
| | | if (paramCheckResponse != null) { |
| | | return paramCheckResponse; |
| | | } |
| | | |
| | | // 转账金额合法性检查 |
| | | BigDecimal transferAmount = validateTransferAmount(amt, request); |
| | | if (transferAmount == null) { |
| | | return ServerResponse.createByErrorMsg("无效的转账金额", request); |
| | | } |
| | | |
| | | // 查询转出账户和转入账户的资产信息 |
| | | UserAssets disbursement = getUserAssets(userId, disbursementAccount); |
| | | UserAssets deposit = getUserAssets(userId, depositAccount); |
| | | |
| | | // 账户检查 |
| | | if (disbursement == null) { |
| | | return ServerResponse.createByErrorMsg("转出账户不存在", request); |
| | | } |
| | | if (deposit == null) { |
| | | return ServerResponse.createByErrorMsg("转入账户不存在", request); |
| | | } |
| | | |
| | | // 检查转出账户余额是否足够 |
| | | if (isBalanceSufficient(disbursement.getAvailableBalance(), transferAmount)) { |
| | | return ServerResponse.createByErrorMsg("转出账户余额不足", request); |
| | | } |
| | | |
| | | // 执行转账操作 |
| | | try { |
| | | synchronized (userId){ |
| | | performTransfer(disbursement, deposit, transferAmount); |
| | | } |
| | | return ServerResponse.createBySuccess("划转成功", request); |
| | | } catch (Exception e) { |
| | | log.error("划转失败: " + e.getMessage(), e); |
| | | return ServerResponse.createByErrorMsg("划转失败", request); |
| | | } |
| | | } |
| | | |
| | | // 参数校验 |
| | | private ServerResponse checkParameters(Integer userId, String disbursementAccount, String depositAccount, String amt, HttpServletRequest request) { |
| | | if (userId == null || disbursementAccount == null || depositAccount == null || amt == null) { |
| | | return ServerResponse.createByErrorMsg("输入参数不能为空", request); |
| | | } |
| | | return null; |
| | | } |
| | | |
| | | // 转账金额校验 |
| | | private BigDecimal validateTransferAmount(String amt, HttpServletRequest request) { |
| | | try { |
| | | BigDecimal transferAmount = BigDecimal.valueOf(Double.valueOf(amt)); |
| | | if (transferAmount.compareTo(BigDecimal.ZERO) <= 0) { |
| | | ServerResponse.createByErrorMsg("转账金额必须大于零", request); |
| | | return null; |
| | | } |
| | | return transferAmount; |
| | | } catch (NumberFormatException e) { |
| | | return null; |
| | | } |
| | | } |
| | | |
| | | // 获取账户资产信息 |
| | | private UserAssets getUserAssets(Integer userId, String accountType) { |
| | | return userAssetsMapper.selectOne(new LambdaQueryWrapper<>(UserAssets.class) |
| | | .eq(UserAssets::getAccectType, accountType) |
| | | .eq(UserAssets::getUserId, userId)); |
| | | } |
| | | |
| | | // 判断余额是否足够 |
| | | private boolean isBalanceSufficient(BigDecimal balance, BigDecimal transferAmount) { |
| | | return balance.compareTo(transferAmount) < 0; |
| | | } |
| | | |
| | | // 执行转账操作 |
| | | private void performTransfer(UserAssets disbursement, UserAssets deposit, BigDecimal transferAmount) { |
| | | // 更新转出账户余额 |
| | | disbursement.setAvailableBalance(disbursement.getAvailableBalance().subtract(transferAmount)); |
| | | userAssetsMapper.updateById(disbursement); |
| | | |
| | | // 更新转入账户余额 |
| | | deposit.setAvailableBalance(deposit.getAvailableBalance().add(transferAmount)); |
| | | userAssetsMapper.updateById(deposit); |
| | | } |
| | | |
| | | //只要涉及到cumulativeProfitAndLoss变动重新设置状态 |
| | | private static void extracted(UserAssets userAssets) { |
| | | if(userAssets.getCumulativeProfitAndLoss().compareTo(BigDecimal.ZERO) >= 0){ |
| | |
| | | } |
| | | extracted(userAssets); |
| | | } |
| | | |
| | | @Override |
| | | public boolean saveBatch(Collection<UserAssets> entityList, int batchSize) { |
| | | return false; |
| | | } |
| | | |
| | | @Override |
| | | public boolean saveOrUpdateBatch(Collection<UserAssets> entityList, int batchSize) { |
| | | return false; |
| | | } |
| | | |
| | | @Override |
| | | public boolean updateBatchById(Collection<UserAssets> entityList, int batchSize) { |
| | | return false; |
| | | } |
| | | |
| | | @Override |
| | | public boolean saveOrUpdate(UserAssets entity) { |
| | | return false; |
| | | } |
| | | |
| | | @Override |
| | | public UserAssets getOne(Wrapper<UserAssets> queryWrapper, boolean throwEx) { |
| | | return null; |
| | | } |
| | | |
| | | @Override |
| | | public Map<String, Object> getMap(Wrapper<UserAssets> queryWrapper) { |
| | | return null; |
| | | } |
| | | |
| | | @Override |
| | | public <V> V getObj(Wrapper<UserAssets> queryWrapper, Function<? super Object, V> mapper) { |
| | | return null; |
| | | } |
| | | |
| | | @Override |
| | | public BaseMapper<UserAssets> getBaseMapper() { |
| | | return null; |
| | | } |
| | | |
| | | @Override |
| | | public Class<UserAssets> getEntityClass() { |
| | | return null; |
| | | } |
| | | } |
| | |
| | | import com.google.common.collect.Lists; |
| | | import com.nq.common.ServerResponse; |
| | | import com.nq.utils.*; |
| | | import com.nq.utils.redis.RedisKeyConstant; |
| | | import com.nq.utils.redis.RedisKeyUtil; |
| | | import com.nq.utils.redis.RedisShardedPoolUtils; |
| | | import com.nq.utils.stock.BuyAndSellUtils; |
| | | import com.nq.utils.stock.GeneratePosition; |
| | | import com.nq.utils.stock.GetStayDays; |
| | |
| | | } |
| | | } |
| | | |
| | | @Transactional |
| | | public ServerResponse goldCrudeOilbuy(String name, Integer buyNum, Integer lever, BigDecimal profitTarget, BigDecimal stopTarget, HttpServletRequest request) { |
| | | |
| | | SiteProduct siteProduct = iSiteProductService.getProductSetting(); |
| | | |
| | | User user = this.iUserService.getCurrentRefreshUser(request); |
| | | synchronized (user.getId()){ |
| | | if (siteProduct.getRealNameDisplay() && user.getIsActive() != 2) { |
| | | return ServerResponse.createByErrorMsg("订单失败,请先实名认证", request); |
| | | } |
| | | // 手续费率 |
| | | BigDecimal siteSettingBuyFee = new BigDecimal(iStockConfigServices.queryByKey(EConfigKey.BUY_HANDLING_CHARGE.getCode()).getCValue()) ; |
| | | |
| | | if (siteProduct.getRealNameDisplay() && user.getIsLock().intValue() == 1) { |
| | | return ServerResponse.createByErrorMsg("订单失败,帐户已被锁定", request); |
| | | } |
| | | |
| | | String s = RedisShardedPoolUtils.get(name); |
| | | BigDecimal price = new BigDecimal(s); |
| | | if (price == null) { |
| | | return ServerResponse.createByErrorMsg("下单失败,请稍候再试!", request); |
| | | } |
| | | |
| | | |
| | | UserAssets userAssets = iUserAssetsServices.assetsByTypeAndUserId("USDT", user.getId()); |
| | | |
| | | if(userAssets.getAmountToBeCovered().compareTo(BigDecimal.ZERO) > 0){ |
| | | return ServerResponse.createByErrorMsg("请先缴清待补资金", request); |
| | | } |
| | | |
| | | if (price.compareTo(new BigDecimal("0")) == 0) { |
| | | return ServerResponse.createByErrorMsg("报价0,请稍后再试", request); |
| | | } |
| | | |
| | | BigDecimal buyAmt = price.multiply(new BigDecimal(buyNum)).divide(new BigDecimal(lever)); |
| | | BigDecimal orderFree = siteSettingBuyFee.multiply(buyAmt); |
| | | |
| | | 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); |
| | | } |
| | | UserPosition userPosition = new UserPosition(); |
| | | if (profitTarget != null && profitTarget.compareTo(new BigDecimal("0")) > 0) { |
| | | userPosition.setProfitTargetPrice(profitTarget); |
| | | } |
| | | 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(name); |
| | | userPosition.setStockName(name); |
| | | userPosition.setStockGid(name); |
| | | userPosition.setStockSpell(name); |
| | | userPosition.setBuyOrderId(GeneratePosition.getPositionId()); |
| | | userPosition.setBuyOrderTime(new Date()); |
| | | userPosition.setBuyOrderPrice(price); |
| | | userPosition.setOrderDirection("买涨"); |
| | | userPosition.setOrderNum(buyNum); |
| | | 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); |
| | | iUserAssetsServices.availablebalanceChange("USDT", user.getId(), EUserAssets.BUY, buyAmt.negate(), "", ""); |
| | | iUserAssetsServices.availablebalanceChange("USDT", user.getId(), EUserAssets.HANDLING_CHARGE, orderFree, "", ""); |
| | | return ServerResponse.createBySuccessMsg("下单成功", request); |
| | | } |
| | | } |
| | | |
| | | |
| | | /** |
| | | * 用户修改止盈止损 |
| | |
| | | return ServerResponse.createByErrorMsg("登录失败。账户锁定",request); |
| | | } |
| | | userAssetsServices.assetsByTypeAndUserId(EStockType.ST.getCode(),user.getId()); |
| | | QueryWrapper<UserAssets> usdtQueryWrapper = new QueryWrapper<>(); |
| | | usdtQueryWrapper.eq("accect_type","USDT"); |
| | | usdtQueryWrapper.eq("user_id",user.getId()); |
| | | UserAssets usdtUserAssets = userAssetsServices.getOne(usdtQueryWrapper); |
| | | if(usdtUserAssets == null){ |
| | | usdtUserAssets.setAccectType("USDT"); |
| | | usdtUserAssets.setUserId(user.getId()); |
| | | userAssetsServices.save(usdtUserAssets); |
| | | } |
| | | this.iSiteLoginLogService.saveLog(user, request); |
| | | return ServerResponse.createBySuccess(user); |
| | | } |
| | |
| | | public static final String verification_code= "verification_code"; |
| | | |
| | | |
| | | /** |
| | | * 黄金行情 |
| | | */ |
| | | public static final String gold= "gold"; |
| | | |
| | | |
| | | /** |
| | | * 原油行情 |
| | | */ |
| | | public static final String crude_oil= "crude_oil"; |
| | | } |
| | |
| | | import com.alibaba.fastjson2.JSONObject; |
| | | import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; |
| | | import com.baomidou.mybatisplus.core.toolkit.CollectionUtils; |
| | | import com.fasterxml.jackson.databind.JsonNode; |
| | | import com.fasterxml.jackson.databind.ObjectMapper; |
| | | import com.google.gson.Gson; |
| | | import com.nq.dao.StockMapper; |
| | | import com.nq.dao.UserPositionMapper; |
| | |
| | | import com.nq.service.IStockService; |
| | | import com.nq.service.IUserPositionService; |
| | | import com.nq.utils.http.HttpClientRequest; |
| | | import com.nq.utils.redis.RedisKeyConstant; |
| | | import com.nq.utils.redis.RedisKeyUtil; |
| | | import com.nq.utils.redis.RedisShardedPoolUtils; |
| | | 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 org.springframework.web.client.RestTemplate; |
| | | |
| | | import java.util.ArrayList; |
| | | import java.util.Date; |
| | |
| | | } |
| | | } |
| | | |
| | | //黄金 |
| | | private static final String gold_API_URL = "http://139.196.211.109/exchange_curr.action?username=Qq112233&password=3ce25a66d5b3a8cd661024fea6c79388&id=AUUSDO"; |
| | | |
| | | //原油 |
| | | private static final String crude_oil_API_URL = "http://47.112.169.122/fOption_curr.action?username=Qq112233&password=3ce25a66d5b3a8cd661024fea6c79388&id=@CL0W"; |
| | | |
| | | @Scheduled(cron = "0/10 * * * * ?") // 每6秒执行一次 |
| | | public void gold() { |
| | | try { |
| | | // 使用RestTemplate发起HTTP请求 |
| | | RestTemplate restTemplate = new RestTemplate(); |
| | | String response = restTemplate.getForObject(gold_API_URL, String.class); |
| | | |
| | | // 解析返回的CSV格式数据,去除可能存在的换行符 |
| | | if (response != null) { |
| | | // 清除换行符并按逗号分割数据 |
| | | String[] parts = response.trim().split(","); |
| | | String price = parts[2].trim(); // "3348.4" |
| | | // 转换价格为Double类型 |
| | | // 保存价格到Redis |
| | | RedisShardedPoolUtils.set(RedisKeyConstant.gold, String.valueOf(price)); |
| | | log.info("黄金定时任务------成功"); |
| | | } else { |
| | | log.info("黄金定时任务------没有接收到数据"); |
| | | } |
| | | } catch (Exception e) { |
| | | e.printStackTrace(); |
| | | log.error("黄金定时任务------请求或数据解析失败:" + e.getMessage()); |
| | | } |
| | | } |
| | | |
| | | @Scheduled(cron = "0/15 * * * * ?") // 每6秒执行一次 |
| | | public void crudeOil() { |
| | | try { |
| | | // 使用RestTemplate发起HTTP请求 |
| | | RestTemplate restTemplate = new RestTemplate(); |
| | | String response = restTemplate.getForObject(crude_oil_API_URL, String.class); |
| | | |
| | | // 解析返回的CSV格式数据,去除可能存在的换行符 |
| | | if (response != null) { |
| | | // 清除换行符并按逗号分割数据 |
| | | String[] parts = response.trim().split(","); |
| | | String price = parts[2].trim(); // "3348.4" |
| | | // 转换价格为Double类型 |
| | | // 保存价格到Redis |
| | | RedisShardedPoolUtils.set(RedisKeyConstant.crude_oil, String.valueOf(price)); |
| | | log.info("原油定时任务------没有接收到数据"); |
| | | } else { |
| | | log.info("原油定时任务------没有接收到数据"); |
| | | } |
| | | } catch (Exception e) { |
| | | e.printStackTrace(); |
| | | log.error("原油定时任务------请求或数据解析失败:" + e.getMessage()); |
| | | } |
| | | } |
| | | |
| | | |
| | | //黄金 |
| | | private static final String k_gold_API_URL = "http://139.196.211.109/ldMetal_k.action?username=Qq112233&password=3ce25a66d5b3a8cd661024fea6c79388&id=AUUSDO&num=-100&period="; |
| | | |
| | | //原油 |
| | | private static final String k_crude_oil_API_URL = "http://47.112.169.122/fOption_k.action?username=Qq112233&password=3ce25a66d5b3a8cd661024fea6c79388&id=@CL0W&num=-100&period="; |
| | | |
| | | @Scheduled(cron = "0/6 * * * * ?") // 每6秒执行一次 |
| | | public void getKDate() throws InterruptedException { |
| | | RestTemplate restTemplate = new RestTemplate(); |
| | | String[] arr = {"d", "w", "m", "1", "5", "30"}; |
| | | for (String str : arr) { |
| | | String g = restTemplate.getForObject(k_gold_API_URL+str, String.class); |
| | | RedisShardedPoolUtils.set("k_gold_"+str, g); |
| | | Thread.sleep(6000); |
| | | String c = restTemplate.getForObject(k_crude_oil_API_URL+str, String.class); |
| | | RedisShardedPoolUtils.set("k_crude_oil_"+str, c); |
| | | Thread.sleep(6000); |
| | | } |
| | | } |
| | | /** |
| | | * 同步美国股票 |
| | | */ |
| | |
| | | public String translate(String langFrom, String langTo, |
| | | String word) throws Exception { |
| | | |
| | | |
| | | langTo = "ar-SA"; |
| | | //不为空则设置代理 |
| | | // String proxyHost = PropertiesUtil.getProperty("https.proxyHost"); |
| | | // String proxyPort = PropertiesUtil.getProperty("https.proxyPort"); |
| | |
| | | private String indexGid; |
| | | private Integer homeShow; |
| | | private Integer listShow; |
| | | private Integer random; |
| | | private Integer transState; |
| | | private Integer depositAmt; |
| | | |
| | |
| | | |
| | | ST_HTTP_API = http://api-sa.js-stock.top/ |
| | | ST_WS_URL = ws://api-sa-ws.js-stock.top |
| | | ST_KEY = eiFMWvMcKgVlCYKD7S4y |
| | | ST_KEY = DP6jTI2ow7unfakP0fRM |
| | | |
| | | |
| | | #HK_HTTP_API = http://api-v1.js-stock.top/ |