package com.yami.trading.api.controller;
|
|
import cn.hutool.core.collection.CollectionUtil;
|
import cn.hutool.core.date.DateTime;
|
import cn.hutool.http.HttpRequest;
|
import com.alibaba.fastjson2.JSONArray;
|
import com.alibaba.fastjson2.JSON;
|
import com.alibaba.fastjson2.JSONObject;
|
import com.yami.trading.api.model.RegisterMobile;
|
import com.yami.trading.api.model.RegisterModel;
|
import com.yami.trading.api.model.UserLoginModel;
|
import com.yami.trading.bean.constans.UserConstants;
|
import com.yami.trading.bean.item.domain.Item;
|
import com.yami.trading.bean.model.RiskClient;
|
import com.yami.trading.bean.model.User;
|
import com.yami.trading.common.domain.Result;
|
import com.yami.trading.common.exception.BusinessException;
|
import com.yami.trading.common.exception.YamiShopBindException;
|
import com.yami.trading.common.util.IPHelper;
|
import com.yami.trading.common.util.LockFilter;
|
import com.yami.trading.common.util.StringUtils;
|
import com.yami.trading.common.web.ResultObject;
|
import com.yami.trading.security.common.bo.UserInfoInTokenBO;
|
import com.yami.trading.security.common.enums.SysTypeEnum;
|
import com.yami.trading.security.common.manager.PasswordCheckManager;
|
import com.yami.trading.security.common.manager.TokenStore;
|
import com.yami.trading.security.common.util.RiskClientUtil;
|
import com.yami.trading.security.common.util.SecurityUtils;
|
import com.yami.trading.security.common.vo.TokenInfoVO;
|
import com.yami.trading.service.IdentifyingCodeTimeWindowService;
|
import com.yami.trading.service.item.ItemService;
|
import com.yami.trading.service.syspara.SysparaService;
|
import com.yami.trading.service.user.UserService;
|
import com.yami.trading.service.user.UserSimRelationService;
|
import io.swagger.annotations.Api;
|
import io.swagger.annotations.ApiOperation;
|
import org.apache.commons.compress.utils.Lists;
|
import org.slf4j.Logger;
|
import org.slf4j.LoggerFactory;
|
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.security.crypto.password.PasswordEncoder;
|
import org.springframework.web.bind.annotation.*;
|
|
import javax.servlet.http.HttpServletRequest;
|
import javax.servlet.http.HttpServletResponse;
|
import javax.validation.Valid;
|
import java.io.IOException;
|
import java.math.BigDecimal;
|
import java.util.*;
|
import java.util.function.Function;
|
import java.util.stream.Collectors;
|
|
@RestController
|
@CrossOrigin
|
@RequestMapping("api/")
|
@Api(tags = "非登录接口")
|
public class ApiIndexController {
|
|
private Logger logger = LoggerFactory.getLogger(ApiIndexController.class);
|
|
@Autowired
|
private TokenStore tokenStore;
|
@Autowired
|
private PasswordCheckManager passwordCheckManager;
|
@Autowired
|
UserService userService;
|
@Autowired
|
UserSimRelationService userSimRelationService;
|
@Autowired
|
private PasswordEncoder passwordEncoder;
|
@Autowired
|
SysparaService sysparaService;
|
@Autowired
|
private IdentifyingCodeTimeWindowService identifyingCodeTimeWindowService;
|
|
@Autowired
|
ItemService itemService;
|
|
|
/**
|
* 采集富图美国ETF入库
|
* indices
|
* @return
|
*/
|
@GetMapping("/syncData")
|
public String syncData(){
|
// API地址
|
String url = "https://www.futunn.com/quote-api/quote-v2/get-etf-list";
|
try {
|
// 构建请求参数
|
String params = "routeType=1&plateId=10002799&rankType=5&leverage=&page=1&pageSize=50";
|
// 发起GET请求
|
String result = HttpRequest.get(url + "?" + params)
|
.header("User-Agent",
|
"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36")
|
.header("quote-token","6ae11951e0")
|
.header("Referer","https://www.futunn.com/en/quote/etf-us/most-active-etfs?global_content=%7B%22promote_id%22%3A13766,%22sub_promote_id%22%3A24%7D")
|
.timeout(20000)
|
.execute()
|
.body();
|
List<Item> itemSave = Lists.newArrayList();
|
// 解析JSON响应
|
JSONObject jsonObject = JSON.parseObject(result);
|
// 检查响应状态
|
int code = jsonObject.getIntValue("code");
|
if (code == 0) {
|
// 获取data对象
|
JSONObject dataObj = jsonObject.getJSONObject("data");
|
|
// 获取list数组
|
JSONArray list = dataObj.getJSONArray("list");
|
// 遍历第一个对象的所有字段
|
if (list.size() > 0) {
|
for (int i = 0; i < list.size(); i++) {
|
JSONObject data = list.getJSONObject(i);
|
Item item = new Item();
|
String name = data.getString("name");
|
String stockCode = data.getString("stockCode");
|
String stockId = data.getString("stockId");
|
item.setEnName(name);
|
item.setName(name);
|
item.setSymbol(stockCode);
|
item.setSymbolData(stockCode);
|
item.setRemarks(stockCode);
|
item.setSymbolFullName(name);
|
item.setPips(BigDecimal.valueOf(0.01).doubleValue());
|
item.setPipsAmount(BigDecimal.valueOf(0.02).doubleValue());
|
item.setAdjustmentValue(BigDecimal.ZERO.doubleValue());
|
item.setUnitAmount(BigDecimal.valueOf(1000).doubleValue());
|
item.setUnitFee(BigDecimal.valueOf(30).doubleValue());
|
item.setMarket(Item.US_ETF);
|
item.setDecimals(2);
|
item.setMultiple(BigDecimal.ZERO.doubleValue());
|
item.setBorrowingRate(BigDecimal.ZERO.doubleValue());
|
item.setCreateTime(DateTime.now());
|
item.setDelFlag(0);
|
item.setType("indices");
|
item.setCategory("indices");
|
item.setUnitPercentage(0.01);
|
item.setCrawlStatus("default_active");
|
item.setSorted("100");
|
item.setOpenCloseType(Item.US_STOCKS);
|
item.setFake("0");
|
item.setShowStatus("1");
|
item.setTradeStatus("1");
|
item.setQuoteCurrency("USDT");
|
item.setStockCode(stockId);
|
itemSave.add(item);
|
}
|
itemService.saveBatch(itemSave);
|
}
|
} else {
|
System.out.println("请求失败: " + jsonObject.getString("message"));
|
}
|
|
} catch (Exception e) {
|
System.out.println("发生错误:");
|
e.printStackTrace();
|
}
|
|
return "ok";
|
}
|
|
|
/**
|
* 同步股票ID
|
*
|
* @return
|
*/
|
@GetMapping("/syncMyStockKlineId")
|
public String syncMyStockKlineId() {
|
String url = "https://klse.i3investor.com/wapi/web/stock/listing/datatables";
|
String params = "{\"dtDraw\":1,\"start\":0,\"order\":[{\"column\":1,\"dir\":\"asc\"}],\"page\":0,\"size\":10000,\"marketList\":[],\"sectorList\":[],\"subsectorList\":[],\"type\":\"\",\"stockType\":\"\"}";
|
String body = HttpRequest.post(url).setHttpProxy("127.0.0.1", 7890).body(params).execute().body();
|
JSONObject jsonObject = JSON.parseObject(body);
|
JSONArray listArray = jsonObject.getJSONArray("data");
|
List<Item> myItems = itemService.findByType(Item.MY_STOCKS);
|
Map<String, Item> itemMap = myItems.stream()
|
.collect(Collectors.toMap(Item::getName, Function.identity()));
|
if (listArray != null) {
|
for (int k = 0; k < listArray.size(); k++) {
|
JSONArray item = listArray.getJSONArray(k);
|
String stockId = item.getString(14);
|
String name = item.getString(13);
|
if (!itemMap.containsKey(name)) {
|
continue;
|
}
|
Item dbItem = itemMap.get(name);
|
dbItem.setStockCode(String.valueOf(stockId));
|
itemService.updateById(dbItem);
|
}
|
}
|
return "ok";
|
}
|
|
/**
|
* 采集TradingView 外汇主要,次要外汇 数据入库
|
*
|
* @return
|
*/
|
@GetMapping("/initTwForexItem")
|
public String initTwForexItem() {
|
String url = "https://scanner.tradingview.com/forex/scan?label-product=screener-forex-old";
|
String params = "{\"filter\":[{\"left\":\"sector\",\"operation\":\"in_range\",\"right\":[\"Major\",\"Minor\"]}],\"options\":{\"lang\":\"zh_TW\"},\"markets\":[\"forex\"],\"symbols\":{\"query\":{\"types\":[\"forex\"]},\"tickers\":[]},\"columns\":[\"base_currency_logoid\",\"currency_logoid\",\"name\",\"close\",\"change\",\"change_abs\",\"bid\",\"ask\",\"high\",\"low\",\"Recommend.All\",\"description\",\"type\",\"subtype\",\"update_mode\",\"pricescale\",\"minmov\",\"fractional\",\"minmove2\"],\"sort\":{\"sortBy\":\"name\",\"sortOrder\":\"asc\"},\"range\":[0,150]}";
|
String body = HttpRequest.post(url).setHttpProxy("127.0.0.1", 7890).body(params).execute().body();
|
List<Item> itemSave = Lists.newArrayList();
|
com.alibaba.fastjson2.JSONObject bodyJson = com.alibaba.fastjson2.JSON.parseObject(body);
|
com.alibaba.fastjson2.JSONArray dataArr = bodyJson.getJSONArray("data");
|
if (dataArr != null) {
|
for (int i = 0; i < dataArr.size(); i++) {
|
com.alibaba.fastjson2.JSONObject stockData = dataArr.getJSONObject(i);
|
String symbol = stockData.getString("s");
|
com.alibaba.fastjson2.JSONArray data = stockData.getJSONArray("d");
|
Item item = new Item();
|
String name = (String) data.get(2);
|
item.setEnName(name);
|
item.setName(name);
|
item.setSymbol(symbol);
|
item.setSymbolData(symbol);
|
item.setPips(BigDecimal.valueOf(0.01).doubleValue());
|
item.setPipsAmount(BigDecimal.valueOf(0.02).doubleValue());
|
item.setAdjustmentValue(BigDecimal.ZERO.doubleValue());
|
item.setUnitAmount(BigDecimal.valueOf(1000).doubleValue());
|
item.setUnitFee(BigDecimal.valueOf(30).doubleValue());
|
item.setMarket("FOREVER");
|
item.setDecimals(2);
|
item.setMultiple(BigDecimal.ZERO.doubleValue());
|
item.setBorrowingRate(BigDecimal.ZERO.doubleValue());
|
item.setDelFlag(0);
|
item.setType("forex");
|
item.setCategory("forex");
|
item.setSorted("100");
|
item.setOpenCloseType("forex");
|
item.setFake("0");
|
item.setShowStatus("1");
|
item.setTradeStatus("1");
|
item.setQuoteCurrency("USDT");
|
itemSave.add(item);
|
}
|
itemService.saveBatch(itemSave);
|
}
|
return "ok";
|
}
|
|
|
/**
|
* 采集TradingView美国ETF 数据入库
|
*
|
* @return
|
*/
|
@GetMapping("/initUsEtfStockItem")
|
public String initUsEtfStockItem() {
|
String url = "https://scanner.tradingview.com/america/scan?label-product=screener-etf";
|
String body = HttpRequest.post(url).setHttpProxy("127.0.0.1", 7890).body(getUsEtfQuotesParams()).execute().body();
|
List<Item> itemSave = Lists.newArrayList();
|
JSONObject bodyJson = JSON.parseObject(body);
|
JSONArray dataArr = bodyJson.getJSONArray("data");
|
if (dataArr != null) {
|
for (int i = 0; i < dataArr.size(); i++) {
|
JSONObject stockData = dataArr.getJSONObject(i);
|
String symbol = stockData.getString("s");
|
JSONArray data = stockData.getJSONArray("d");
|
Item item = new Item();
|
String name = (String) data.get(1);
|
item.setEnName(name);
|
item.setName(name);
|
item.setSymbol((String) data.get(0));
|
item.setSymbolData((String) data.get(0));
|
item.setRemarks(symbol);
|
item.setSymbolFullName(name);
|
item.setPips(BigDecimal.valueOf(0.01).doubleValue());
|
item.setPipsAmount(BigDecimal.valueOf(0.02).doubleValue());
|
item.setAdjustmentValue(BigDecimal.ZERO.doubleValue());
|
item.setUnitAmount(BigDecimal.valueOf(1000).doubleValue());
|
item.setUnitFee(BigDecimal.valueOf(30).doubleValue());
|
item.setMarket(Item.US_STOCKS);
|
item.setDecimals(2);
|
item.setMultiple(BigDecimal.ZERO.doubleValue());
|
item.setBorrowingRate(BigDecimal.ZERO.doubleValue());
|
item.setCreateTime(DateTime.now());
|
item.setDelFlag(0);
|
item.setType(Item.indices);
|
item.setCategory((String) data.get(26));
|
item.setUnitPercentage(0.01);
|
item.setCrawlStatus("default_active");
|
item.setSorted("100");
|
item.setOpenCloseType(Item.US_STOCKS);
|
item.setFake("0");
|
item.setShowStatus("1");
|
item.setTradeStatus("1");
|
item.setQuoteCurrency("USDT");
|
itemSave.add(item);
|
}
|
itemService.saveBatch(itemSave);
|
}
|
return "ok";
|
}
|
|
/**
|
* 采集TradingView马来股票数据入库
|
*
|
* @return
|
*/
|
@GetMapping("/initMyStockItem")
|
public String initMyStockItem() {
|
String url = "https://scanner.tradingview.com/malaysia/scan";
|
String body = HttpRequest.post(url).setHttpProxy("127.0.0.1", 7890).body(getAllQuotesParams(2000)).execute().body();
|
List<Item> itemSave = Lists.newArrayList();
|
JSONObject bodyJson = JSON.parseObject(body);
|
JSONArray dataArr = bodyJson.getJSONArray("data");
|
if (dataArr != null) {
|
for (int i = 0; i < dataArr.size(); i++) {
|
JSONObject stockData = dataArr.getJSONObject(i);
|
String symbol = stockData.getString("s");
|
JSONArray data = stockData.getJSONArray("d");
|
Item item = new Item();
|
String name = (String) data.get(1);
|
item.setEnName((String) data.get(1));
|
item.setName((String) data.get(0));
|
item.setSymbol((String) data.get(0));
|
item.setSymbolData((String) data.get(0));
|
item.setRemarks(symbol);
|
item.setSymbolFullName((String) data.get(1));
|
item.setPips(BigDecimal.valueOf(0.01).doubleValue());
|
item.setPipsAmount(BigDecimal.valueOf(0.02).doubleValue());
|
item.setAdjustmentValue(BigDecimal.ZERO.doubleValue());
|
item.setUnitAmount(BigDecimal.valueOf(1000).doubleValue());
|
item.setUnitFee(BigDecimal.valueOf(30).doubleValue());
|
item.setMarket("FOREVER");
|
item.setDecimals(2);
|
item.setMultiple(BigDecimal.ZERO.doubleValue());
|
item.setBorrowingRate(BigDecimal.ZERO.doubleValue());
|
item.setCreateTime(DateTime.now());
|
item.setDelFlag(0);
|
item.setType("MY-stocks");
|
item.setCategory((String) data.get(26));
|
item.setUnitPercentage(0.01);
|
item.setCrawlStatus("default_active");
|
item.setSorted("100");
|
item.setOpenCloseType("MY-stocks");
|
item.setFake("0");
|
item.setShowStatus("1");
|
item.setTradeStatus("1");
|
item.setQuoteCurrency("USDT");
|
itemSave.add(item);
|
}
|
itemService.saveBatch(itemSave);
|
}
|
return "ok";
|
}
|
|
|
/**
|
* 采集TradingView美股股票数据入库
|
*
|
* @return
|
*/
|
@GetMapping("/initUsStockItem")
|
public String initUsStockItem() {
|
String url = "https://scanner.tradingview.com/america/scan?label-product=screener-stock";
|
String body = HttpRequest.post(url).setHttpProxy("127.0.0.1", 7890).body(getUsQuotesParams(4575)).execute().body();
|
List<Item> itemSave = Lists.newArrayList();
|
JSONObject bodyJson = JSON.parseObject(body);
|
JSONArray dataArr = bodyJson.getJSONArray("data");
|
if (dataArr != null) {
|
for (int i = 0; i < dataArr.size(); i++) {
|
JSONObject stockData = dataArr.getJSONObject(i);
|
String symbol = stockData.getString("s");
|
JSONArray data = stockData.getJSONArray("d");
|
Item item = new Item();
|
String name = (String) data.get(1);
|
item.setEnName((String) data.get(1));
|
item.setName(symbol);
|
item.setSymbol(symbol);
|
item.setSymbolData((String) data.get(0));
|
item.setRemarks(symbol);
|
item.setSymbolFullName((String) data.get(1));
|
item.setPips(BigDecimal.valueOf(0.01).doubleValue());
|
item.setPipsAmount(BigDecimal.valueOf(0.02).doubleValue());
|
item.setAdjustmentValue(BigDecimal.ZERO.doubleValue());
|
item.setUnitAmount(BigDecimal.valueOf(1000).doubleValue());
|
item.setUnitFee(BigDecimal.valueOf(30).doubleValue());
|
item.setMarket(Item.US_STOCKS);
|
item.setDecimals(2);
|
item.setMultiple(BigDecimal.ZERO.doubleValue());
|
item.setBorrowingRate(BigDecimal.ZERO.doubleValue());
|
item.setCreateTime(DateTime.now());
|
item.setDelFlag(0);
|
item.setType("US-stocks");
|
item.setCategory((String) data.get(26));
|
item.setUnitPercentage(0.01);
|
item.setCrawlStatus("default_active");
|
item.setSorted("100");
|
item.setOpenCloseType("US-stocks");
|
item.setFake("0");
|
item.setShowStatus("1");
|
item.setTradeStatus("1");
|
item.setQuoteCurrency("USDT");
|
itemSave.add(item);
|
}
|
itemService.saveBatch(itemSave);
|
}
|
return "ok";
|
}
|
|
|
@GetMapping("/initUsStockItem100")
|
public String initUsStockItem100() {
|
String url = "https://scanner.tradingview.com/america/scan?label-product=screener-stock";
|
String params = "{\"columns\":[\"name\",\"description\",\"logoid\",\"update_mode\",\"type\",\"typespecs\",\"close\",\"pricescale\",\"minmov\",\"fractional\",\"minmove2\",\"currency\",\"change\",\"volume\",\"relative_volume_10d_calc\",\"market_cap_basic\",\"fundamental_currency_code\",\"price_earnings_ttm\",\"earnings_per_share_diluted_ttm\",\"earnings_per_share_diluted_yoy_growth_ttm\",\"dividends_yield_current\",\"sector.tr\",\"market\",\"sector\",\"recommendation_mark\",\"exchange\"],\"filter\":[{\"left\":\"market_cap_basic\",\"operation\":\"egreater\",\"right\":200000000000},{\"left\":\"is_primary\",\"operation\":\"equal\",\"right\":true}],\"ignore_unknown_fields\":false,\"options\":{\"lang\":\"zh_TW\"},\"range\":[0,300],\"sort\":{\"sortBy\":\"market_cap_basic\",\"sortOrder\":\"desc\"},\"symbols\":{},\"markets\":[\"america\"],\"filter2\":{\"operator\":\"and\",\"operands\":[{\"operation\":{\"operator\":\"or\",\"operands\":[{\"operation\":{\"operator\":\"and\",\"operands\":[{\"expression\":{\"left\":\"type\",\"operation\":\"equal\",\"right\":\"stock\"}},{\"expression\":{\"left\":\"typespecs\",\"operation\":\"has\",\"right\":[\"common\"]}}]}},{\"operation\":{\"operator\":\"and\",\"operands\":[{\"expression\":{\"left\":\"type\",\"operation\":\"equal\",\"right\":\"stock\"}},{\"expression\":{\"left\":\"typespecs\",\"operation\":\"has\",\"right\":[\"preferred\"]}}]}},{\"operation\":{\"operator\":\"and\",\"operands\":[{\"expression\":{\"left\":\"type\",\"operation\":\"equal\",\"right\":\"dr\"}}]}},{\"operation\":{\"operator\":\"and\",\"operands\":[{\"expression\":{\"left\":\"type\",\"operation\":\"equal\",\"right\":\"fund\"}},{\"expression\":{\"left\":\"typespecs\",\"operation\":\"has_none_of\",\"right\":[\"etf\"]}}]}}]}}]}}";
|
String body = HttpRequest.post(url).setHttpProxy("127.0.0.1", 7890).body(params).execute().body();
|
List<Item> itemSave = Lists.newArrayList();
|
JSONObject bodyJson = JSON.parseObject(body);
|
JSONArray dataArr = bodyJson.getJSONArray("data");
|
if (dataArr != null) {
|
for (int i = 0; i < dataArr.size(); i++) {
|
JSONObject stockData = dataArr.getJSONObject(i);
|
String symbol = stockData.getString("s");
|
JSONArray data = stockData.getJSONArray("d");
|
Item item = new Item();
|
String name = (String) data.get(1);
|
item.setEnName((String) data.get(1));
|
item.setName((String) data.get(0));
|
item.setSymbol((String) data.get(0));
|
item.setSymbolData((String) data.get(0));
|
item.setRemarks(symbol);
|
item.setSymbolFullName((String) data.get(1));
|
item.setPips(BigDecimal.valueOf(0.01).doubleValue());
|
item.setPipsAmount(BigDecimal.valueOf(0.02).doubleValue());
|
item.setAdjustmentValue(BigDecimal.ZERO.doubleValue());
|
item.setUnitAmount(BigDecimal.valueOf(1000).doubleValue());
|
item.setUnitFee(BigDecimal.valueOf(30).doubleValue());
|
item.setMarket(Item.US_STOCKS);
|
item.setDecimals(2);
|
item.setMultiple(BigDecimal.ZERO.doubleValue());
|
item.setBorrowingRate(BigDecimal.ZERO.doubleValue());
|
item.setCreateTime(DateTime.now());
|
item.setDelFlag(0);
|
item.setType("US-stocks");
|
item.setCategory((String) data.get(23));
|
item.setUnitPercentage(0.01);
|
item.setCrawlStatus("default_active");
|
item.setSorted("100");
|
item.setOpenCloseType("US-stocks");
|
item.setFake("0");
|
item.setShowStatus("1");
|
item.setTradeStatus("1");
|
item.setQuoteCurrency("USDT");
|
itemSave.add(item);
|
}
|
itemService.saveBatch(itemSave);
|
}
|
return "ok";
|
}
|
|
private static String getUsEtfQuotesParams() {
|
// 创建并填充 JSON 对象
|
com.alibaba.fastjson2.JSONObject jsonObject = new com.alibaba.fastjson2.JSONObject();
|
|
jsonObject.put("columns", new com.alibaba.fastjson2.JSONArray()
|
.fluentAdd("name")
|
.fluentAdd("description")
|
.fluentAdd("logoid")
|
.fluentAdd("update_mode")
|
.fluentAdd("type")
|
.fluentAdd("typespecs")
|
.fluentAdd("open")
|
.fluentAdd("close")
|
.fluentAdd("high")
|
.fluentAdd("low")
|
.fluentAdd("pricescale")
|
.fluentAdd("minmov")
|
.fluentAdd("fractional")
|
.fluentAdd("minmove2")
|
.fluentAdd("currency")
|
.fluentAdd("change")
|
.fluentAdd("volume")
|
.fluentAdd("relative_volume_10d_calc")
|
.fluentAdd("market_cap_basic")
|
.fluentAdd("fundamental_currency_code")
|
.fluentAdd("price_earnings_ttm")
|
.fluentAdd("earnings_per_share_diluted_ttm")
|
.fluentAdd("earnings_per_share_diluted_yoy_growth_ttm")
|
.fluentAdd("dividends_yield_current")
|
.fluentAdd("sector.tr")
|
.fluentAdd("market")
|
.fluentAdd("sector")
|
.fluentAdd("recommendation_mark"));
|
|
jsonObject.put("ignore_unknown_fields", false);
|
|
jsonObject.put("options", new com.alibaba.fastjson2.JSONObject().fluentPut("lang", "zh"));
|
|
jsonObject.put("range", new com.alibaba.fastjson2.JSONArray().fluentAdd(0).fluentAdd(400));
|
|
jsonObject.put("sort", new com.alibaba.fastjson2.JSONObject()
|
.fluentPut("sortBy", "aum")
|
.fluentPut("sortOrder", "desc"));
|
|
jsonObject.put("symbols", new com.alibaba.fastjson2.JSONObject());
|
|
jsonObject.put("markets", new com.alibaba.fastjson2.JSONArray().fluentAdd("america"));
|
|
jsonObject.put("filter", new com.alibaba.fastjson2.JSONArray()
|
.fluentAdd(new com.alibaba.fastjson2.JSONObject()
|
.fluentPut("left", "aum")
|
.fluentPut("operation", "egreater")
|
.fluentPut("right", 10000000000L)
|
));
|
|
jsonObject.put("filter2", new com.alibaba.fastjson2.JSONObject()
|
.fluentPut("operator", "and")
|
.fluentPut("operands", new com.alibaba.fastjson2.JSONArray()
|
.fluentAdd(new com.alibaba.fastjson2.JSONObject()
|
.fluentPut("operation", new com.alibaba.fastjson2.JSONObject()
|
.fluentPut("operator", "or")
|
.fluentPut("operands", new com.alibaba.fastjson2.JSONArray()
|
.fluentAdd(new com.alibaba.fastjson2.JSONObject()
|
.fluentPut("operation", new com.alibaba.fastjson2.JSONObject()
|
.fluentPut("operator", "and")
|
.fluentPut("operands", new com.alibaba.fastjson2.JSONArray()
|
.fluentAdd(new com.alibaba.fastjson2.JSONObject()
|
.fluentPut("expression", new com.alibaba.fastjson2.JSONObject()
|
.fluentPut("left", "typespecs")
|
.fluentPut("operation", "has")
|
.fluentPut("right", new com.alibaba.fastjson2.JSONArray().fluentAdd("etf"))
|
)
|
)
|
)
|
)
|
)
|
.fluentAdd(new com.alibaba.fastjson2.JSONObject()
|
.fluentPut("operation", new com.alibaba.fastjson2.JSONObject()
|
.fluentPut("operator", "and")
|
.fluentPut("operands", new com.alibaba.fastjson2.JSONArray()
|
.fluentAdd(new com.alibaba.fastjson2.JSONObject()
|
.fluentPut("expression", new com.alibaba.fastjson2.JSONObject()
|
.fluentPut("left", "type")
|
.fluentPut("operation", "equal")
|
.fluentPut("right", "structured")
|
)
|
)
|
)
|
)
|
)
|
)
|
)
|
)
|
)
|
);
|
|
return jsonObject.toJSONString();
|
}
|
|
private static String getUsQuotesParams(int count) {
|
return "{\"columns\":[\"name\",\"description\",\"logoid\",\"update_mode\",\"type\",\"typespecs\",\"open\",\"close\",\"high\",\"low\",\"pricescale\",\"minmov\",\"fractional\",\"minmove2\",\"currency\",\"change\",\"volume\",\"relative_volume_10d_calc\",\"market_cap_basic\",\"fundamental_currency_code\",\"price_earnings_ttm\",\"earnings_per_share_diluted_ttm\",\"earnings_per_share_diluted_yoy_growth_ttm\",\"dividends_yield_current\",\"sector.tr\",\"market\",\"sector\",\"recommendation_mark\",\"exchange\"],\"filter\":[{\"left\":\"is_primary\",\"operation\":\"equal\",\"right\":true}],\"ignore_unknown_fields\":false,\"options\":{\"lang\":\"zh\"},\"range\":[0,8200],\"sort\":{\"sortBy\":\"market_cap_basic\",\"sortOrder\":\"desc\"},\"symbols\":{},\"markets\":[\"america\"],\"filter2\":{\"operator\":\"and\",\"operands\":[{\"operation\":{\"operator\":\"or\",\"operands\":[{\"operation\":{\"operator\":\"and\",\"operands\":[{\"expression\":{\"left\":\"type\",\"operation\":\"equal\",\"right\":\"stock\"}},{\"expression\":{\"left\":\"typespecs\",\"operation\":\"has\",\"right\":[\"common\"]}}]}},{\"operation\":{\"operator\":\"and\",\"operands\":[{\"expression\":{\"left\":\"type\",\"operation\":\"equal\",\"right\":\"stock\"}},{\"expression\":{\"left\":\"typespecs\",\"operation\":\"has\",\"right\":[\"preferred\"]}}]}},{\"operation\":{\"operator\":\"and\",\"operands\":[{\"expression\":{\"left\":\"type\",\"operation\":\"equal\",\"right\":\"dr\"}}]}},{\"operation\":{\"operator\":\"and\",\"operands\":[{\"expression\":{\"left\":\"type\",\"operation\":\"equal\",\"right\":\"fund\"}},{\"expression\":{\"left\":\"typespecs\",\"operation\":\"has_none_of\",\"right\":[\"etf\"]}}]}}]}}]}}";
|
}
|
|
private static String getAllQuotesParams(int count) {
|
// 创建并填充 JSON 对象
|
com.alibaba.fastjson2.JSONObject jsonObject = new com.alibaba.fastjson2.JSONObject();
|
jsonObject.put("columns", new com.alibaba.fastjson2.JSONArray()
|
.fluentAdd("name")
|
.fluentAdd("description")
|
.fluentAdd("logoid")
|
.fluentAdd("update_mode")
|
.fluentAdd("type")
|
.fluentAdd("typespecs")
|
.fluentAdd("open")
|
.fluentAdd("close")
|
.fluentAdd("high")
|
.fluentAdd("low")
|
.fluentAdd("pricescale")
|
.fluentAdd("minmov")
|
.fluentAdd("fractional")
|
.fluentAdd("minmove2")
|
.fluentAdd("currency")
|
.fluentAdd("change")
|
.fluentAdd("volume")
|
.fluentAdd("relative_volume_10d_calc")
|
.fluentAdd("market_cap_basic")
|
.fluentAdd("fundamental_currency_code")
|
.fluentAdd("price_earnings_ttm")
|
.fluentAdd("earnings_per_share_diluted_ttm")
|
.fluentAdd("earnings_per_share_diluted_yoy_growth_ttm")
|
.fluentAdd("dividends_yield_current")
|
.fluentAdd("sector.tr")
|
.fluentAdd("market")
|
.fluentAdd("sector")
|
.fluentAdd("recommendation_mark"));
|
jsonObject.put("ignore_unknown_fields", false);
|
jsonObject.put("options", new com.alibaba.fastjson2.JSONObject().fluentPut("lang", "zh"));
|
jsonObject.put("range", new com.alibaba.fastjson2.JSONArray().fluentAdd(0).fluentAdd(count));
|
jsonObject.put("sort", new com.alibaba.fastjson2.JSONObject()
|
.fluentPut("sortBy", "name")
|
.fluentPut("sortOrder", "asc")
|
.fluentPut("nullsFirst", false));
|
return jsonObject.toJSONString();
|
}
|
|
|
@PostMapping("/login")
|
@ApiOperation(value = "账号密码(用于前端登录)", notes = "通过账号/手机号/用户名密码登录,还要携带用户的类型,也就是用户所在的系统")
|
public Result login(@Valid UserLoginModel model, HttpServletResponse httpResponse) {
|
String mobileOrUserName = model.getUserName();
|
User user = null;
|
if (model.getType() == 1) {
|
user = userService.findByUserName(mobileOrUserName);
|
}
|
if (model.getType() == 2) {
|
user = userService.findByUserName(mobileOrUserName);
|
}
|
if (model.getType() == 3) {
|
user = userService.findByUserName(mobileOrUserName);
|
}
|
if (user == null) {
|
if (model.getLanguage().equals("en")) {
|
throw new YamiShopBindException("Incorrect account or password");
|
}
|
throw new YamiShopBindException("账号或密码不正确");
|
}
|
// 模拟账户不能直接登录,只能通过主账户登录后切换
|
if (user.getAccountType() != null && user.getAccountType() == 1) {
|
if (model.getLanguage().equals("en")) {
|
throw new YamiShopBindException("Sim account cannot login directly, please switch after main account login");
|
}
|
throw new YamiShopBindException("模拟账户不能直接登录,请使用主账户登录后切换");
|
}
|
|
if (!user.isLoginAuthority()) {
|
if (model.getLanguage().equals("en")) {
|
throw new YamiShopBindException("login fail");
|
}
|
throw new YamiShopBindException("登录失败");
|
}
|
|
// 半小时内密码输入错误十次,已限制登录30分钟
|
passwordCheckManager.checkPassword(SysTypeEnum.ORDINARY, model.getUserName(), model.getPassWord(), user.getLoginPassword(), model.getLanguage());
|
UserInfoInTokenBO userInfoInToken = new UserInfoInTokenBO();
|
userInfoInToken.setUserId(user.getUserId());
|
userInfoInToken.setSysType(SysTypeEnum.ORDINARY.value());
|
userInfoInToken.setEnabled(user.getStatus() == 1);
|
user.setUserLastip(IPHelper.getIpAddr());
|
user.setUserLasttime(new Date());
|
userService.online(user.getUserId());
|
userService.updateById(user);
|
tokenStore.deleteAllToken(String.valueOf(SysTypeEnum.ORDINARY.value()), String.valueOf(user.getUserId()));
|
String simUserIdForLogin = userSimRelationService.getSimUserId(user.getUserId());
|
if (simUserIdForLogin != null) {
|
tokenStore.deleteAllToken(String.valueOf(SysTypeEnum.ORDINARY.value()), simUserIdForLogin);
|
}
|
// 存储token返回vo
|
TokenInfoVO tokenInfoVO = tokenStore.storeAndGetVo(userInfoInToken);
|
tokenInfoVO.setToken(tokenInfoVO.getAccessToken());
|
Map<String, Object> accountInfo = new HashMap<>();
|
accountInfo.put("accountType", user.getAccountType() != null ? user.getAccountType() : 0);
|
accountInfo.put("mainUserId", userSimRelationService.getMainUserId(user.getUserId()));
|
accountInfo.put("simUserId", simUserIdForLogin);
|
tokenInfoVO.setInfo(accountInfo);
|
List<RiskClient> riskList = RiskClientUtil.getRiskInfoByUserCode(user.getUserCode(), "badnetwork");
|
if (CollectionUtil.isNotEmpty(riskList)) {
|
logger.info("uid:{} Network Unavailable", user.getUserId());
|
// 断网效果
|
return null;
|
}
|
riskList = RiskClientUtil.getRiskInfoByUserCode(user.getUserCode(), "black");
|
if (CollectionUtil.isNotEmpty(riskList)) {
|
// 黑名单禁止登录效果
|
Result result = Result.failed("Forbidden");
|
result.setCode(1);
|
return result;
|
}
|
return Result.succeed(tokenInfoVO);
|
}
|
|
@PostMapping("/registerNoVerifcode")
|
@ApiOperation(value = "手机/邮箱/用户名注册(无验证码)")
|
public Result register(@Valid RegisterModel model) {
|
|
String username = model.getUserName();
|
String password = model.getPassword();
|
String usercode = model.getUserCode();
|
// 注册类型:1/手机;2/邮箱;3/用户名;
|
int type = model.getType();
|
|
User user = userService.register(model.getUserName(),
|
passwordEncoder.encode(password)
|
, model.getUserCode(), model.getType(), false);
|
UserInfoInTokenBO userInfoInToken = new UserInfoInTokenBO();
|
userInfoInToken.setUserId(user.getUserId());
|
userService.online(user.getUserId());
|
userInfoInToken.setSysType(SysTypeEnum.ORDINARY.value());
|
userInfoInToken.setEnabled(user.getStatus() == 1);
|
// userDataService.saveRegister(user.getUserId());
|
tokenStore.deleteAllToken(String.valueOf(SysTypeEnum.ORDINARY.value()), String.valueOf(user.getUserId()));
|
String simUserIdReg = userSimRelationService.getSimUserId(user.getUserId());
|
if (simUserIdReg != null) {
|
tokenStore.deleteAllToken(String.valueOf(SysTypeEnum.ORDINARY.value()), simUserIdReg);
|
}
|
// 存储token返回vo
|
TokenInfoVO tokenInfoVO = tokenStore.storeAndGetVo(userInfoInToken);
|
tokenInfoVO.setToken(tokenInfoVO.getAccessToken());
|
Map<String, Object> accountInfo = new HashMap<>();
|
accountInfo.put("accountType", 0);
|
accountInfo.put("mainUserId", user.getUserId());
|
accountInfo.put("simUserId", simUserIdReg);
|
tokenInfoVO.setInfo(accountInfo);
|
user.setUserLastip(IPHelper.getIpAddr());
|
user.setUserLasttime(new Date());
|
user.setUserMobile(username);
|
user.setUserMobileBind(Boolean.TRUE);
|
userService.updateById(user);
|
return Result.succeed(tokenInfoVO);
|
}
|
|
@PostMapping("/registerVerifcode")
|
@ApiOperation(value = "手机(有验证码)")
|
public Result registerVerifcode(@Valid RegisterMobile model) {
|
|
String username = model.getUserName();
|
String password = model.getPassword();
|
String authCode = identifyingCodeTimeWindowService.getAuthCode(username);
|
if (!model.getVerifcode().equalsIgnoreCase(authCode)) {
|
throw new YamiShopBindException("无效验证码");
|
}
|
|
User user = userService.register(username,
|
passwordEncoder.encode(password)
|
, model.getUserCode(), model.getType(), false);
|
UserInfoInTokenBO userInfoInToken = new UserInfoInTokenBO();
|
userInfoInToken.setUserId(user.getUserId());
|
userService.online(user.getUserId());
|
userInfoInToken.setSysType(SysTypeEnum.ORDINARY.value());
|
userInfoInToken.setEnabled(user.getStatus() == 1);
|
// userDataService.saveRegister(user.getUserId());
|
tokenStore.deleteAllToken(String.valueOf(SysTypeEnum.ORDINARY.value()), String.valueOf(user.getUserId()));
|
String simUserIdVerif = userSimRelationService.getSimUserId(user.getUserId());
|
if (simUserIdVerif != null) {
|
tokenStore.deleteAllToken(String.valueOf(SysTypeEnum.ORDINARY.value()), simUserIdVerif);
|
}
|
// 存储token返回vo
|
TokenInfoVO tokenInfoVO = tokenStore.storeAndGetVo(userInfoInToken);
|
tokenInfoVO.setToken(tokenInfoVO.getAccessToken());
|
Map<String, Object> accountInfo = new HashMap<>();
|
accountInfo.put("accountType", 0);
|
accountInfo.put("mainUserId", user.getUserId());
|
accountInfo.put("simUserId", simUserIdVerif);
|
tokenInfoVO.setInfo(accountInfo);
|
user.setUserLastip(IPHelper.getIpAddr());
|
user.setUserLasttime(new Date());
|
userService.updateById(user);
|
return Result.succeed(tokenInfoVO);
|
}
|
|
/**
|
* 创建虚拟账户信息
|
*/
|
@RequestMapping("/addVirtualAccount.action")
|
public Object addVirtualAccount(HttpServletRequest request) {
|
|
String loginPartyId = SecurityUtils.getCurrentUserId();
|
if (loginPartyId == null) {
|
throw new BusinessException("重复提交");
|
}
|
String username = loginPartyId;
|
ResultObject resultObject = new ResultObject();
|
|
boolean lock = false;
|
|
try {
|
if (!LockFilter.add(username)) {
|
throw new BusinessException("重复提交");
|
}
|
|
lock = true;
|
|
RegisterModel reg = new RegisterModel();
|
reg.setUserName(username);
|
reg.setPassword("8973At456");
|
reg.setType(4);
|
|
User user = userService.findByUserName(reg.getUserName());
|
if (user == null) {
|
user = userService.register(reg.getUserName(),
|
passwordEncoder.encode(reg.getPassword())
|
, reg.getUserCode(), reg.getType(), false);
|
user.setWithdrawAuthority(false);
|
user.setRoleName(UserConstants.SECURITY_ROLE_TEST);
|
}
|
|
Date now = new Date();
|
UserInfoInTokenBO userInfoInToken = new UserInfoInTokenBO();
|
userInfoInToken.setUserId(user.getUserId());
|
userService.online(user.getUserId());
|
userInfoInToken.setSysType(SysTypeEnum.ORDINARY.value());
|
userInfoInToken.setEnabled(user.getStatus() == 1);
|
// userDataService.saveRegister(user.getUserId());
|
tokenStore.deleteAllToken(String.valueOf(SysTypeEnum.ORDINARY.value()), String.valueOf(user.getUserId()));
|
|
// 存储token返回vo
|
TokenInfoVO tokenInfoVO = tokenStore.storeAndGetVo(userInfoInToken);
|
tokenInfoVO.setToken(tokenInfoVO.getAccessToken());
|
user.setUserLastip(IPHelper.getIpAddr());
|
user.setUserLasttime(now);
|
user.setUpdateTime(now);
|
user.setRoleName(UserConstants.SECURITY_ROLE_TEST);
|
userService.updateById(user);
|
|
String realUserName = userService.findByUserId(username).getUserName();
|
|
Map<String, Object> map = new HashMap<>();
|
map.put("userCode", user.getUserCode());
|
map.put("userName", realUserName + "-virtual");
|
tokenInfoVO.setInfo(map);
|
|
return Result.succeed(tokenInfoVO);
|
} catch (BusinessException e) {
|
resultObject.setCode("1");
|
resultObject.setMsg(e.getMessage());
|
} catch (Throwable t) {
|
logger.error("UserAction.register error ", t);
|
resultObject.setCode("1");
|
resultObject.setMsg("[ERROR] " + t.getMessage());
|
} finally {
|
if (lock) {
|
LockFilter.remove(username);
|
}
|
}
|
return resultObject;
|
}
|
|
/**
|
* 重置虚拟账号信息
|
*/
|
@RequestMapping("/recharge.action")
|
public Object recharge(HttpServletRequest request) {
|
ResultObject resultObject = new ResultObject();
|
resultObject = this.readSecurityContextFromSession(resultObject);
|
if (!"0".equals(resultObject.getCode())) {
|
return resultObject;
|
}
|
|
String loginPartyId = SecurityUtils.getCurrentUserId();
|
if (loginPartyId == null) {
|
throw new BusinessException("重复提交");
|
}
|
|
boolean lock = false;
|
|
try {
|
if (!LockFilter.add(loginPartyId)) {
|
throw new BusinessException("重复提交");
|
}
|
|
lock = true;
|
User user = userService.findByUserId(loginPartyId);
|
double money_wallet = 0;
|
if (user != null && user.getUserName().length() > 8) {
|
money_wallet = this.userService.recharge(loginPartyId);
|
} else {
|
logger.error("error:虚拟账号重置失败,UserName:" + user.getUserName());
|
}
|
Map<String, Object> data = new HashMap<String, Object>();
|
data.put("money_wallet", money_wallet);
|
resultObject.setData(data);
|
} catch (BusinessException e) {
|
resultObject.setCode("1");
|
resultObject.setMsg(e.getMessage());
|
} catch (Throwable t) {
|
resultObject.setCode("1");
|
resultObject.setMsg("Program Error");
|
logger.error("error:", t);
|
} finally {
|
if (lock) {
|
LockFilter.remove(loginPartyId);
|
}
|
}
|
|
return resultObject;
|
}
|
|
public ResultObject readSecurityContextFromSession(ResultObject resultObject) {
|
String partyId = SecurityUtils.getCurrentUserId();
|
if (StringUtils.isNullOrEmpty(partyId)) {
|
resultObject.setCode("403");
|
resultObject.setMsg("请重新登录");
|
return resultObject;
|
}
|
return resultObject;
|
}
|
|
}
|