From decfc2ff7244cec365d3f32a5090edf5faeae861 Mon Sep 17 00:00:00 2001
From: zj <1772600164@qq.com>
Date: Wed, 23 Apr 2025 19:08:18 +0800
Subject: [PATCH] 1
---
src/main/java/com/nq/controller/StockIndexApiController.java | 64 +++++
src/main/java/com/nq/service/impl/UserAssetsServices.java | 145 +++++++++++
src/main/java/com/nq/service/impl/StockServiceImpl.java | 201 +++++++++++++---
src/main/java/com/nq/controller/StockApiController.java | 15 +
src/main/java/com/nq/controller/protol/UserController.java | 26 ++
src/main/java/com/nq/utils/task/stock/StockTask.java | 80 ++++++
src/main/java/com/nq/service/impl/UserPositionServiceImpl.java | 85 +++++++
src/main/java/com/nq/service/IUserPositionService.java | 2
src/main/java/com/nq/utils/redis/RedisKeyConstant.java | 9
src/main/java/com/nq/utils/translate/GoogleTranslateUtil.java | 2
src/main/java/com/nq/service/impl/UserServiceImpl.java | 9
src/main/resources/application.properties | 2
src/main/java/com/nq/service/IUserAssetsServices.java | 6
src/main/java/com/nq/controller/backend/AdminController.java | 10
src/main/java/com/nq/service/impl/StockIndexServiceImpl.java | 33 +-
src/main/java/com/nq/vo/stockindex/StockIndexVO.java | 1
16 files changed, 627 insertions(+), 63 deletions(-)
diff --git a/src/main/java/com/nq/controller/StockApiController.java b/src/main/java/com/nq/controller/StockApiController.java
index d265e7a..33fe10f 100644
--- a/src/main/java/com/nq/controller/StockApiController.java
+++ b/src/main/java/com/nq/controller/StockApiController.java
@@ -4,6 +4,9 @@
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;
@@ -14,6 +17,7 @@
import org.springframework.web.bind.annotation.ResponseBody;
import javax.servlet.http.HttpServletRequest;
+import java.util.HashMap;
@Controller
@RequestMapping({"/api/stock/"})
@@ -52,6 +56,17 @@
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")
diff --git a/src/main/java/com/nq/controller/StockIndexApiController.java b/src/main/java/com/nq/controller/StockIndexApiController.java
new file mode 100644
index 0000000..81c35ae
--- /dev/null
+++ b/src/main/java/com/nq/controller/StockIndexApiController.java
@@ -0,0 +1,64 @@
+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();
+ }
+}
diff --git a/src/main/java/com/nq/controller/backend/AdminController.java b/src/main/java/com/nq/controller/backend/AdminController.java
index aecd92a..49dd07e 100644
--- a/src/main/java/com/nq/controller/backend/AdminController.java
+++ b/src/main/java/com/nq/controller/backend/AdminController.java
@@ -384,4 +384,14 @@
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);
+ }
}
diff --git a/src/main/java/com/nq/controller/protol/UserController.java b/src/main/java/com/nq/controller/protol/UserController.java
index 0b720f5..e49f34a 100644
--- a/src/main/java/com/nq/controller/protol/UserController.java
+++ b/src/main/java/com/nq/controller/protol/UserController.java
@@ -130,6 +130,32 @@
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
diff --git a/src/main/java/com/nq/service/IUserAssetsServices.java b/src/main/java/com/nq/service/IUserAssetsServices.java
index ae7475a..98a3ebe 100644
--- a/src/main/java/com/nq/service/IUserAssetsServices.java
+++ b/src/main/java/com/nq/service/IUserAssetsServices.java
@@ -1,14 +1,15 @@
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> {
@@ -48,4 +49,5 @@
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);
}
diff --git a/src/main/java/com/nq/service/IUserPositionService.java b/src/main/java/com/nq/service/IUserPositionService.java
index 34ddad4..936134d 100644
--- a/src/main/java/com/nq/service/IUserPositionService.java
+++ b/src/main/java/com/nq/service/IUserPositionService.java
@@ -85,4 +85,6 @@
ServerResponse buyStockDzList(HttpServletRequest request);
void stockConstraint(List<UserPosition> userPositions);
+
+ ServerResponse goldCrudeOilbuy(String name, Integer buyNum, Integer lever, BigDecimal profitTarget, BigDecimal stopTarget, HttpServletRequest requestrequest);
}
diff --git a/src/main/java/com/nq/service/impl/StockIndexServiceImpl.java b/src/main/java/com/nq/service/impl/StockIndexServiceImpl.java
index 75b0b29..763b801 100644
--- a/src/main/java/com/nq/service/impl/StockIndexServiceImpl.java
+++ b/src/main/java/com/nq/service/impl/StockIndexServiceImpl.java
@@ -81,11 +81,13 @@
MarketVO marketVO = querySingleIndex(stockIndex.getIndexGid());
+ if(null != marketVO){
+ stockIndexVO.setCurrentPoint(marketVO.getNowPrice());
+ stockIndexVO.setFloatPoint(marketVO.getIncrease());
+ stockIndexVO.setFloatRate(marketVO.getIncreaseRate());
+ stockIndexVO.setType(marketVO.getType());
+ }
- stockIndexVO.setCurrentPoint(marketVO.getNowPrice());
- stockIndexVO.setFloatPoint(marketVO.getIncrease());
- stockIndexVO.setFloatRate(marketVO.getIncreaseRate());
- stockIndexVO.setType(marketVO.getType());
return stockIndexVO;
}
@@ -195,14 +197,21 @@
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");
diff --git a/src/main/java/com/nq/service/impl/StockServiceImpl.java b/src/main/java/com/nq/service/impl/StockServiceImpl.java
index 7b896d8..d6f7d9e 100644
--- a/src/main/java/com/nq/service/impl/StockServiceImpl.java
+++ b/src/main/java/com/nq/service/impl/StockServiceImpl.java
@@ -21,6 +21,7 @@
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;
@@ -38,6 +39,11 @@
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;
@@ -53,6 +59,7 @@
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;
@@ -190,33 +197,52 @@
public ServerResponse getSingleStock(String code, HttpServletRequest request) {
- if (StringUtils.isBlank(code))
- return ServerResponse.createByErrorMsg("");
- Stock stock = stockMapper.findStockByCode(code);
- DataStockBean cacheBaseStock = RedisKeyUtil.getCacheBaseStock(stock);
- Integer depositAmt = 0;
- String introduction = null;
- StockVO stockVO = StockApi.assembleInStockVO(stock);
- stockVO.setDepositAmt(depositAmt);
- stockVO.setNowPrice(iPriceServices.getNowPrice(stock.getStockCode()).toString());
- stockVO.setType(stock.getStockType());
- stockVO.setId(stock.getId().intValue());
- stockVO.setCode(stock.getStockCode());
- stockVO.setName(stock.getStockName());
- stockVO.setSpell(stock.getStockSpell());
- stockVO.setGid(stock.getStockGid().toUpperCase());
- Map<String, Object> newStock = iPriceServices.getNewStock(stock.getStockCode());
- stockVO.setHcrate(newStock.get("ChgPct").toString().replaceAll("%", ""));
- stockVO.setToday_max(newStock.get("High").toString());
- stockVO.setToday_min(newStock.get("Low").toString());
- if(null != cacheBaseStock){
- stockVO.setOpen_px(cacheBaseStock.getOpen());
- stockVO.setPreclose_px(cacheBaseStock.getPrevClose());
+
+ 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);
+ DataStockBean cacheBaseStock = RedisKeyUtil.getCacheBaseStock(stock);
+ Integer depositAmt = 0;
+ String introduction = null;
+ StockVO stockVO = StockApi.assembleInStockVO(stock);
+ stockVO.setDepositAmt(depositAmt);
+ stockVO.setNowPrice(iPriceServices.getNowPrice(stock.getStockCode()).toString());
+ stockVO.setType(stock.getStockType());
+ stockVO.setId(stock.getId().intValue());
+ stockVO.setCode(stock.getStockCode());
+ stockVO.setName(stock.getStockName());
+ stockVO.setSpell(stock.getStockSpell());
+ stockVO.setGid(stock.getStockGid().toUpperCase());
+ Map<String, Object> newStock = iPriceServices.getNewStock(stock.getStockCode());
+ stockVO.setHcrate(newStock.get("ChgPct").toString().replaceAll("%", ""));
+ stockVO.setToday_max(newStock.get("High").toString());
+ stockVO.setToday_min(newStock.get("Low").toString());
+ if(null != cacheBaseStock){
+ stockVO.setOpen_px(cacheBaseStock.getOpen());
+ stockVO.setPreclose_px(cacheBaseStock.getPrevClose());
+ }
+ Map map = Maps.newHashMap();
+ map.put("introduction", introduction);
+ map.put("stock", stockVO);
+ return ServerResponse.createBySuccess(map);
}
- Map map = Maps.newHashMap();
- map.put("introduction", introduction);
- map.put("stock", stockVO);
- return ServerResponse.createBySuccess(map);
}
public Map getSingleStock(String code) {
@@ -432,25 +458,118 @@
}
+ //黄金
+ 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) {
- EStockType eStockType = EStockType.getEStockTypeByCode(stockType);
- Object object = HttpUtil.get(eStockType.stockUrl + "kline?pid=" + pid + "&interval=" + interval + "&key=" + eStockType.stockKey);
- Gson gson = new Gson();
- List<kData> dataList = gson.fromJson(object.toString(), new TypeToken<List<kData>>(){}.getType());
+ 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();
+ List<kData> dataList = gson.fromJson(object.toString(), new TypeToken<List<kData>>(){}.getType());
- Stock stock = stockMapper.selectOne(new LambdaQueryWrapper<Stock>().eq(Stock::getStockCode, pid).eq(Stock::getStockType, EStockType.ST.getCode()));
- BigDecimal nowPrice = iPriceServices.getNowPrice(stock.getStockCode());
- Map singleStock = getSingleStock(stock.getStockCode());
- StockVO stockVO = (StockVO)singleStock.get("stock");
- // 修改 List 中的最后一条数据
- kData lastData = dataList.get(dataList.size() - 1);
- lastData.setC(nowPrice.toString());
- lastData.setO(stockVO.getOpen_px());
- lastData.setH(stockVO.getToday_max());
- lastData.setL(stockVO.getToday_min());
- return gson.toJson(dataList);
+ Stock stock = stockMapper.selectOne(new LambdaQueryWrapper<Stock>().eq(Stock::getStockCode, pid).eq(Stock::getStockType, EStockType.ST.getCode()));
+ BigDecimal nowPrice = iPriceServices.getNowPrice(stock.getStockCode());
+ Map singleStock = getSingleStock(stock.getStockCode());
+ StockVO stockVO = (StockVO)singleStock.get("stock");
+ // 修改 List 中的最后一条数据
+ kData lastData = dataList.get(dataList.size() - 1);
+ lastData.setC(nowPrice.toString());
+ lastData.setO(stockVO.getOpen_px());
+ lastData.setH(stockVO.getToday_max());
+ 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
diff --git a/src/main/java/com/nq/service/impl/UserAssetsServices.java b/src/main/java/com/nq/service/impl/UserAssetsServices.java
index e6fb068..88ec26c 100644
--- a/src/main/java/com/nq/service/impl/UserAssetsServices.java
+++ b/src/main/java/com/nq/service/impl/UserAssetsServices.java
@@ -1,8 +1,9 @@
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;
@@ -13,13 +14,13 @@
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;
/**
* 用户资产
@@ -259,6 +260,95 @@
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){
@@ -288,4 +378,49 @@
}
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;
+ }
}
diff --git a/src/main/java/com/nq/service/impl/UserPositionServiceImpl.java b/src/main/java/com/nq/service/impl/UserPositionServiceImpl.java
index d9cb1b3..0022bfb 100644
--- a/src/main/java/com/nq/service/impl/UserPositionServiceImpl.java
+++ b/src/main/java/com/nq/service/impl/UserPositionServiceImpl.java
@@ -15,7 +15,9 @@
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;
@@ -240,6 +242,89 @@
}
}
+ @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);
+ }
+ }
+
/**
* 用户修改止盈止损
diff --git a/src/main/java/com/nq/service/impl/UserServiceImpl.java b/src/main/java/com/nq/service/impl/UserServiceImpl.java
index 1cc5b55..6db3321 100644
--- a/src/main/java/com/nq/service/impl/UserServiceImpl.java
+++ b/src/main/java/com/nq/service/impl/UserServiceImpl.java
@@ -209,6 +209,15 @@
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);
}
diff --git a/src/main/java/com/nq/utils/redis/RedisKeyConstant.java b/src/main/java/com/nq/utils/redis/RedisKeyConstant.java
index 54cebd0..e6bb64f 100644
--- a/src/main/java/com/nq/utils/redis/RedisKeyConstant.java
+++ b/src/main/java/com/nq/utils/redis/RedisKeyConstant.java
@@ -32,6 +32,13 @@
public static final String verification_code= "verification_code";
+ /**
+ * 黄金行情
+ */
+ public static final String gold= "gold";
-
+ /**
+ * 原油行情
+ */
+ public static final String crude_oil= "crude_oil";
}
diff --git a/src/main/java/com/nq/utils/task/stock/StockTask.java b/src/main/java/com/nq/utils/task/stock/StockTask.java
index 97dc181..f7787b7 100644
--- a/src/main/java/com/nq/utils/task/stock/StockTask.java
+++ b/src/main/java/com/nq/utils/task/stock/StockTask.java
@@ -3,6 +3,8 @@
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;
@@ -15,12 +17,15 @@
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;
@@ -77,7 +82,82 @@
}
}
+ //黄金
+ 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);
+ }
+ }
/**
* 同步美国股票
*/
diff --git a/src/main/java/com/nq/utils/translate/GoogleTranslateUtil.java b/src/main/java/com/nq/utils/translate/GoogleTranslateUtil.java
index a9728d9..e9315e0 100644
--- a/src/main/java/com/nq/utils/translate/GoogleTranslateUtil.java
+++ b/src/main/java/com/nq/utils/translate/GoogleTranslateUtil.java
@@ -15,7 +15,7 @@
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");
diff --git a/src/main/java/com/nq/vo/stockindex/StockIndexVO.java b/src/main/java/com/nq/vo/stockindex/StockIndexVO.java
index 8551da4..cac716c 100644
--- a/src/main/java/com/nq/vo/stockindex/StockIndexVO.java
+++ b/src/main/java/com/nq/vo/stockindex/StockIndexVO.java
@@ -11,6 +11,7 @@
private String indexGid;
private Integer homeShow;
private Integer listShow;
+ private Integer random;
private Integer transState;
private Integer depositAmt;
diff --git a/src/main/resources/application.properties b/src/main/resources/application.properties
index 70dd692..ee90313 100644
--- a/src/main/resources/application.properties
+++ b/src/main/resources/application.properties
@@ -62,7 +62,7 @@
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/
--
Gitblit v1.9.3