A股项目迁移

This commit is contained in:
dengli
2023-11-27 16:10:15 +08:00
parent b19c6ec31d
commit 53039f9055
259 changed files with 19419 additions and 0 deletions

View File

@@ -0,0 +1,67 @@
package cn.stock.market.web;
import java.util.List;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import cn.qutaojing.common.PageInfo;
import cn.stock.market.domain.basic.entity.SiteArticle;
import cn.stock.market.domain.basic.service.SiteArticleService;
import cn.stock.market.utils.ServerResponse;
@Controller
@RequestMapping({"/api/market/art/", "/api/hq/art/"})
@Api(tags = "公告信息")
public class ArticleApiController extends BaseController {
@Autowired
SiteArticleService siteArticleService;
//查询企业公告信息
@ApiOperation(value = "查询企业公告信息",httpMethod = "GET")
@RequestMapping(value = {"list.do"},method = RequestMethod.GET)
@ResponseBody
@ApiImplicitParams({
@ApiImplicitParam(value = "公告标题", name = "artTitle", dataType = "String"),
@ApiImplicitParam(value = "公告类型", name = "artType", dataType = "String")
})
public ServerResponse<PageInfo<SiteArticle>> list(@RequestParam(value = "artTitle", required = false) String artTitle,
@RequestParam(value = "artType", required = false) String artType,
@RequestParam(value = "pageNum", defaultValue = "1") int pageNum,
@RequestParam(value = "pageSize", defaultValue = "12") int pageSize) {
Page<SiteArticle> page = siteArticleService.list(artTitle, artType, pageNum, pageSize);
return ServerResponse.createBySuccess(PageInfo.with(page));
}
//查询指定企业公告信息
@ApiOperation(value = "查询指定企业公告信息",httpMethod = "GET")
@RequestMapping(value = {"detail.do"},method = RequestMethod.GET)
@ResponseBody
@ApiImplicitParams({
@ApiImplicitParam(value = "公告id", name = "artId", dataType = "Integer")
})
public ServerResponse<SiteArticle> detail(Integer artId) {
SiteArticle article = siteArticleService.repository().find(artId);
return ServerResponse.createBySuccess(article);
}
//top最新公告
@ApiOperation(value = "top最新公告",httpMethod = "GET")
@RequestMapping(value = {"getTopArt.do"},method = RequestMethod.GET)
@ResponseBody
public ServerResponse<List<SiteArticle>> getTopArtList(@RequestParam(value = "pageSize", defaultValue = "15") int pageSize) {
List<SiteArticle> list = siteArticleService.getTopArtList(pageSize);
return ServerResponse.createBySuccess(list);
}
}

View File

@@ -0,0 +1,24 @@
package cn.stock.market.web;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.ag.exception.VisitLimitException;
import com.ag.utils.AgAssert;
import cn.stock.market.web.openapi.model.AuthOpenApiModel;
/**
* @author xlfd
* @email xlfd@gmail.com
* @version 1.0
* @created Jun 18, 2021 11:17:43 AM
*/
public class BaseController {
protected final Logger log = LoggerFactory.getLogger(this.getClass().getSimpleName());
public void checkSimpleCredentials(AuthOpenApiModel model) {
AgAssert.isTrue("simpleCredentials".equals(model.getSimpleCredentials()), VisitLimitException.class);
}
}

View File

@@ -0,0 +1,67 @@
package cn.stock.market.web;
import java.util.Map;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import com.google.common.collect.Maps;
import cn.qutaojing.common.web.response.SuccessView;
import cn.stock.market.utils.PropertiesUtil;
import springfox.documentation.annotations.ApiIgnore;
/**
*
* title: InfoController.java
* description
*
* @author rplees
* @email rplees.i.ly@gmail.com
* @version 1.0
* @created Dec 4, 2018 10:22:44 PM
*/
@RestController
@RequestMapping("/api/hq/")
@ApiIgnore
public class InfoController {
@Value("${spring.application.name}")
String name;
@Value("${server.port}")
Integer port;
@Value("${spring.datasource.stock-market.url}")
String stockMarketDbUrl;
@RequestMapping(value="test.do")
public Map<String, Object> test(@RequestParam(required = false) String key) {
Map<String, Object> map = Maps.newHashMap();
map.put("stockMarketDbUrl", stockMarketDbUrl);
if(StringUtils.isNotBlank(key)) {
map.put("key", PropertiesUtil.getProperty(key));
}
return map;
}
@RequestMapping(value="info")
public Map<String, Object> info(@RequestParam(required = false) String key) {
Map<String, Object> map = Maps.newHashMap();
map.put("name", name);
map.put("port", port);
map.put("redisIp", PropertiesUtil.getProperty("redis1.ip"));
if(StringUtils.isNotBlank(key)) {
map.put("key", PropertiesUtil.getProperty(key));
}
return map;
}
@RequestMapping(value="sleep")
public SuccessView sleep(@RequestParam(defaultValue = "3") Integer sleep) throws InterruptedException {
Thread.sleep(sleep * 1000);
return SuccessView.create();
}
}

View File

@@ -0,0 +1,70 @@
package cn.stock.market.web;
import javax.servlet.http.HttpServletRequest;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
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 cn.stock.market.domain.basic.service.SiteNewsService;
import cn.stock.market.utils.ServerResponse;
@Controller
@RequestMapping({"/api/market/news/", "/api/hq/news/"})
@Api(tags="新闻资讯")
public class SiteNewsController {
private static final Logger log = LoggerFactory.getLogger(SiteNewsController.class);
@Autowired
SiteNewsService iSiteNewsService;
//新闻资讯-列表查询
@RequestMapping({"getNewsList.do"})
@ResponseBody
@ApiOperation(value = "列表查询",httpMethod = "GET")
@ApiImplicitParams({
@ApiImplicitParam(name="type",value = "类型"),
@ApiImplicitParam(name="sort",value = "排序"),
@ApiImplicitParam(name="keyword",value = "搜索关键字"),
})
public ServerResponse getNewsList(@RequestParam(value = "pageNum", defaultValue = "1") int pageNum,
@RequestParam(value = "pageSize", defaultValue = "15") int pageSize,
@RequestParam(value = "type", defaultValue = "0") Integer type,
@RequestParam(value = "sort", defaultValue = "time1") String sort,
@RequestParam(value = "keyword", required = false) String keyword, HttpServletRequest request) {
return this.iSiteNewsService.getList(pageNum, pageSize, type, sort, keyword, request);
}
//新闻资讯-详情
@RequestMapping({"getDetail.do"})
@ResponseBody
@ApiOperation(value = "详情",httpMethod = "GET")
@ApiImplicitParam(name="id",value = "详情id")
public ServerResponse getDetail(int id) {
return this.iSiteNewsService.getDetail(id);
}
//新闻资讯-修改新闻浏览量
@RequestMapping({"updateViews.do"})
@ResponseBody
@ApiOperation(value = "修改新闻浏览量",httpMethod = "GET")
@ApiImplicitParam(name="id",value = "详情id")
public ServerResponse updateViews(Integer id) {
return this.iSiteNewsService.updateViews(id);
}
//新闻资讯-列表查询
@RequestMapping({"getTopNews.do"})
@ResponseBody
@ApiOperation(value = "新闻资讯-列表查询",httpMethod = "GET")
public ServerResponse getTopNewsList(@RequestParam(value = "pageSize", defaultValue = "15") int pageSize) {
return this.iSiteNewsService.getTopNewsList(pageSize);
}
}

View File

@@ -0,0 +1,602 @@
package cn.stock.market.web;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ExecutionException;
import java.util.stream.Collectors;
import javax.servlet.http.HttpServletRequest;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import org.apache.commons.lang.StringUtils;
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 com.ag.utils.DateUtils;
import com.ag.utils.Jsons;
import com.alibaba.fastjson.JSONObject;
import com.google.common.base.Joiner;
import com.google.common.cache.Cache;
import com.google.common.collect.Lists;
import cn.qutaojing.common.PageInfo;
import cn.qutaojing.common.utils.BigDecimals;
import cn.stock.market.application.CommonApis;
import cn.stock.market.domain.basic.entity.SiteArticle;
import cn.stock.market.domain.basic.entity.Stock;
import cn.stock.market.domain.basic.service.RealtimeService;
import cn.stock.market.domain.basic.service.SiteArticleService;
import cn.stock.market.domain.basic.service.StockService;
import cn.stock.market.dto.model.StockCode;
import cn.stock.market.dto.model.StockVO;
import cn.stock.market.infrastructure.api.EastmoneyApi;
import cn.stock.market.infrastructure.api.qq.QqStockApi;
import cn.stock.market.infrastructure.api.sina.SinaStockApi;
import cn.stock.market.utils.RequestCacheUtils;
import cn.stock.market.utils.ServerResponse;
import springfox.documentation.annotations.ApiIgnore;
@Controller
@Api(value = "/StockApiController", tags = "股票行情")
@RequestMapping({"/api/market/stock/", "/api/hq/stock/"})
public class StockApiController {
private static final Logger log = LoggerFactory.getLogger(StockApiController.class);
@Autowired
SiteArticleService siteArticleService;
@Autowired
RealtimeService realTimeService;
@Autowired
StockService stockService;
@RequestMapping({"getRawSinaStock.do"})
@ResponseBody
@ApiIgnore
public ServerResponse<?> getRawSinaStock(String stockGid) {
return RequestCacheUtils.cache("getRawSinaStock.do", stockGid, (string) -> {
String sina = SinaStockApi.getRawSinaStock(stockGid);
return ServerResponse.createBySuccess(sina);
});
}
//查询 股票指数、大盘指数信息
@RequestMapping({"getMarket.do"})
@ApiOperation(value = "查询股票指数", httpMethod = "GET")
@ResponseBody
public ServerResponse getMarket() {
return RequestCacheUtils.cache("getMarket.do", "_UNI_", (string) -> {
return this.stockService.getMarket();
});
}
//查询 热门股票
@RequestMapping({"getHotSearch.do"})
@ApiOperation(value = "查询热门股票", httpMethod = "GET")
@ResponseBody
public ServerResponse getHotSearch() {
return RequestCacheUtils.cache("getHotSearch.do", "_HOT_", (string) -> {
return this.stockService.getHotSearch();
});
}
//查询北向净流入
@RequestMapping({"getNorthIn.do"})
@ApiOperation(value = "查询北向净流入", httpMethod = "GET")
@ResponseBody
public ServerResponse getNorthIn() {
return this.stockService.getNorthIn();
}
// 查询主力净流入
@RequestMapping({"getMainIn.do"})
@ApiOperation(value = "查询主力净流入", httpMethod = "GET")
@ResponseBody
public ServerResponse getMainIn() {
return this.stockService.getMainIn();
}
//查询 新股上市信息
@RequestMapping({"getNewStock.do"})
@ApiOperation(value = "查询新股", httpMethod = "GET")
@ResponseBody
public ServerResponse getNewStock() {
return this.stockService.getNewStock();
}
//根据股票id查询 股票指数、大盘指数信息
@RequestMapping({"getMarketByStockGid.do"})
@ApiOperation(value = "根据股票id查询 股票指数、大盘指数信息", httpMethod = "GET")
@ResponseBody
public ServerResponse getMarketByStockGid(@RequestParam("stockGid") String stockGid) {
return RequestCacheUtils.cache("getMarketByStockGid.do", stockGid, (string) -> {
return this.stockService.getMarketByStockGid(stockGid);
});
}
//查询官网PC端交易 所有股票信息及指定股票信息
// @RequestMapping({"getStock.do"})
// @ResponseBody
// public ServerResponse getStock(@RequestParam(value = "pageNum", defaultValue = "1") int pageNum, @RequestParam(value = "pageSize", defaultValue = "10") int pageSize, @RequestParam(value = "stockPlate", required = false) String stockPlate, @RequestParam(value = "stockType", required = false) String stockType, @RequestParam(value = "keyWords", required = false) String keyWords, HttpServletRequest request) {
// return this.stockService.getStock(pageNum, pageSize, keyWords, stockPlate, stockType, request);
// }
//通过股票代码查询股票信息
@RequestMapping({"getSingleStock.do"})
@ApiOperation(value = "通过股票代码查询股票信息", httpMethod = "GET")
@ResponseBody
@ApiImplicitParams({
@ApiImplicitParam(name = "code",value = "股票对应代码symbol",dataType ="String",required = true),
})
public ServerResponse getSingleStock(@RequestParam("code") String code) {
return RequestCacheUtils.cache("getSingleStock.do", code, (string) -> {
return this.stockService.getSingleStock(code);
});
}
@RequestMapping({"getMinK.do"})
@ApiOperation(value = "查询股票分线", httpMethod = "GET")
@ResponseBody
@ApiImplicitParams({
@ApiImplicitParam(name = "code",value = "股票对应代码symbol",dataType ="String",required = true),
@ApiImplicitParam(name = "time",value = "时间间隔",dataType ="Integer",required = true),
})
public ServerResponse getMinK(@RequestParam("code") String code, @RequestParam("time") Integer time, @RequestParam("ma") Integer ma, @RequestParam("size") Integer size) {
String key = Joiner.on("_").skipNulls().join(code, time, ma, size);
return RequestCacheUtils.cache("getMinK.do", key, (string) -> {
return this.stockService.getMinK(code, time, ma, size);
});
}
@RequestMapping({"getKLine.do"})
@ApiOperation(value = "查询股票K线", httpMethod = "GET")
@ResponseBody
@ApiImplicitParams({
@ApiImplicitParam(name = "code",value = "股票对应代码symbol",dataType ="String",required = true),
})
public ServerResponse getKLine(@RequestParam("code") String code) {
return RequestCacheUtils.cache("getKLine.do", code, (string) -> {
return this.stockService.getKLine(code);
});
}
/*查询股票日线*/
@RequestMapping({"getDayK.do"})
@ApiOperation(value = "查询股票日线", httpMethod = "GET")
@ResponseBody
@ApiImplicitParams({
@ApiImplicitParam(name = "code",value = "股票对应代码symbol",dataType ="String",required = true),
})
public ServerResponse getDayK(@RequestParam("code") String code) {
return RequestCacheUtils.cache("getDayK.do", code, (string) -> {
return this.stockService.getDayK_Echarts(code);
});
}
/*查询股票周线*/
@RequestMapping({"getWeekK.do"})
@ApiOperation(value = "查询股票周线", httpMethod = "GET")
@ResponseBody
@ApiImplicitParams({
@ApiImplicitParam(name = "code",value = "股票对应代码symbol",dataType ="String",required = true),
})
public ServerResponse getWeekK(@RequestParam("code") String code) {
return RequestCacheUtils.cache("getWeekK.do", code, (string) -> {
return this.stockService.getWeekK_Echarts(code);
});
}
/*查询股票月线*/
@RequestMapping({"getMonthK.do"})
@ApiOperation(value = "查询股票月线", httpMethod = "GET")
@ResponseBody
@ApiImplicitParams({
@ApiImplicitParam(name = "code",value = "股票对应代码symbol",dataType ="String",required = true),
})
public ServerResponse getMonthK(@RequestParam("code") String code) {
return RequestCacheUtils.cache("getMonthK.do", code, (string) -> {
return this.stockService.getMonthK_Echarts(code);
});
}
//查询股票历史数据数据
@RequestMapping({"getMinK_Echarts.do"})
@ApiOperation(value = "查询股票历史数据数据", httpMethod = "GET")
@ResponseBody
@ApiImplicitParams({
@ApiImplicitParam(name = "code",value = "股票对应代码symbol",dataType ="String",required = true),
})
public ServerResponse getMinK_Echarts(@RequestParam("code") String code, @RequestParam("time") Integer time, @RequestParam("size") Integer size) {
String key = Joiner.on("_").skipNulls().join(code, time, size);
return RequestCacheUtils.cache("getMinK_Echarts.do", key, (string) -> {
return this.stockService.getMinK_Echarts(code, time, 15, size);
});
}
// /*期货分时-k线*/
// @RequestMapping({"getFuturesMinK_Echarts.do"})
// @ResponseBody
// public ServerResponse getFuturesMinK_Echarts(@RequestParam("code") String code, @RequestParam("time") Integer time, @RequestParam("size") Integer size) {
// return this.iStockService.getFuturesMinK_Echarts(code, time, size);
// }
/*指数分时-k线*/
@RequestMapping({"getIndexMinK_Echarts.do"})
@ApiOperation(value = "查询指数分时-k线", httpMethod = "GET")
@ResponseBody
@ApiImplicitParams({
@ApiImplicitParam(name = "code",value = "股票对应代码symbol",dataType ="String",required = true),
@ApiImplicitParam(name = "time",value = "时间间隔",dataType ="String",required = true),
})
public ServerResponse getIndexMinK_Echarts(@RequestParam("code") String code, @RequestParam("time") Integer time, @RequestParam("size") Integer size) {
String key = Joiner.on("_").skipNulls().join(code, time, size);
return RequestCacheUtils.cache("getIndexMinK_Echarts.do", key, (string) -> {
return this.stockService.getIndexMinK_Echarts(code, time, size);
});
}
// /*查询期货日线*/
// @RequestMapping({"getFuturesDayK.do"})
// @ResponseBody
// public ServerResponse getFuturesDayK(@RequestParam("code") String code) {
// return this.iStockService.getFuturesDayK(code);
// }
/*指数日线*/
@RequestMapping({"getIndexDayK.do"})
@ApiOperation(value = "查询指数日线", httpMethod = "GET")
@ResponseBody
@ApiImplicitParams({
@ApiImplicitParam(name = "code",value = "股票对应代码symbol",dataType ="String",required = true),
})
public ServerResponse getIndexDayK(@RequestParam("code") String code) {
return RequestCacheUtils.cache("getIndexDayK.do", code, (string) -> {
return this.stockService.getIndexDayK(code);
});
}
/*指数日线*/
@RequestMapping({"getIndexWeekK.do"})
@ApiOperation(value = "查询指数周线", httpMethod = "GET")
@ResponseBody
@ApiImplicitParams({
@ApiImplicitParam(name = "code",value = "股票对应代码symbol",dataType ="String",required = true),
})
public ServerResponse getIndexWeekK(@RequestParam("code") String code) {
return RequestCacheUtils.cache("getIndexWeekK.do", code, (string) -> {
return this.stockService.getIndexWeekK(code);
});
}
/*指数日线*/
@RequestMapping({"getIndexMonthK.do"})
@ApiOperation(value = "查询指数月线", httpMethod = "GET")
@ResponseBody
@ApiImplicitParams({
@ApiImplicitParam(name = "code",value = "股票对应代码symbol",dataType ="String",required = true),
})
public ServerResponse getIndexMonthK(@RequestParam("code") String code) {
return RequestCacheUtils.cache("getIndexMonthK.do", code, (string) -> {
return this.stockService.getIndexMonthK(code);
});
}
/*跌幅榜单*/
@RequestMapping({"getChangePercentDrop.do"})
@ApiOperation(value = "查询跌幅榜单", httpMethod = "GET")
@ResponseBody
@ApiImplicitParams({
@ApiImplicitParam(name = "pageNum",value = "分页页数",dataType ="int",required = true),
@ApiImplicitParam(name = "pageSize",value = "每页数量",dataType ="int",required = true),
})
public ServerResponse<List<JSONObject>> getChangePercentDrop(@RequestParam(defaultValue = "1") int pageNum, @RequestParam(defaultValue = "10") int pageSize) {
String key = Joiner.on("_").skipNulls().join(pageNum, pageSize);
return RequestCacheUtils.cache("getChangePercentDrop.do", key, (string) -> {
List<JSONObject> list = SinaStockApi.getHQNodeData(1, pageNum, pageSize);
Map<String, Stock> stockMap = this.stockService.repository().cacheCodeMap();
return ServerResponse.createBySuccess(list
.stream()
.filter(val -> {
String code = val.getString("code");
return stockMap.containsKey(code);
})
.collect(Collectors.toList()));
});
}
/*涨幅榜单*/
@RequestMapping({"getChangePercentRise.do"})
@ApiOperation(value = "查询涨幅榜单", httpMethod = "GET")
@ResponseBody
@ApiImplicitParams({
@ApiImplicitParam(name = "pageNum",value = "分页页数",dataType ="int",required = true),
@ApiImplicitParam(name = "pageSize",value = "每页数量",dataType ="int",required = true),
})
public ServerResponse<List<JSONObject>> getChangePercentRise(@RequestParam(defaultValue = "1") int pageNum, @RequestParam(defaultValue = "10") int pageSize) {
String key = Joiner.on("_").skipNulls().join(pageNum, pageSize);
return RequestCacheUtils.cache("getChangePercentRise.do", key, (string) -> {
List<JSONObject> list = SinaStockApi.getHQNodeData(0, pageNum, pageSize);
Map<String, Stock> stockMap = this.stockService.repository().cacheCodeMap();
return ServerResponse.createBySuccess(list
.stream()
.filter(val -> {
String code = val.getString("code");
return stockMap.containsKey(code);
})
.collect(Collectors.toList()));
});
}
/*新股日历*/
@RequestMapping({"getIpoApplyDate.do"})
@ApiOperation(value = "查询新股日历", httpMethod = "GET")
@ResponseBody
@ApiImplicitParams({
@ApiImplicitParam(name = "pageNum",value = "分页页数",dataType ="int",required = true),
@ApiImplicitParam(name = "pageSize",value = "每页数量",dataType ="int",required = true),
})
public ServerResponse<?> getIpoApplyDate(@RequestParam(defaultValue = "1") int pageNum, @RequestParam(defaultValue = "10") int pageSize) {
String key = Joiner.on("_").skipNulls().join(pageNum, pageSize);
return RequestCacheUtils.cache("getIpoApplyDate.do", key, (string) -> {
PageInfo<JSONObject> pageInfo = EastmoneyApi.ipoApplyDate(pageNum, pageSize);
return ServerResponse.createBySuccess(pageInfo);
});
}
/*新股日历_今日申购_即将发布*/
@RequestMapping({"getIpoApplyDateAndClassify.do"})
@ApiOperation(value = "查询新股日历_今日申购_即将发布", httpMethod = "GET")
@ResponseBody
public ServerResponse<?> getIpoApplyDateAndClassify() {
String key = "_UNI_";
return RequestCacheUtils.cache("getIpoApplyDateAndClassify.do", key, (string) -> {
PageInfo<JSONObject> pageInfo = EastmoneyApi.ipoApplyDate(1, 50);
String nowDate = DateUtils.nowDate(DateUtils.YYYY_MM_DD);
List<JSONObject> todayList = pageInfo.getItems()
.stream()
.filter(val -> {
return StringUtils.startsWith(val.getString("APPLY_DATE"), nowDate);
})
.collect(Collectors.toList());
List<JSONObject> futureList = pageInfo.getItems()
.stream()
.filter(val -> {
return ! StringUtils.startsWith(val.getString("APPLY_DATE"), nowDate);
})
.sorted(Comparator.comparing(val -> val.getString("APPLY_DATE")))
.collect(Collectors.toList());
JSONObject json = new JSONObject();
json.put("todayList", todayList);
json.put("futureList", futureList);
return ServerResponse.createBySuccess(json);
});
}
/*沪深300*/
@RequestMapping({"a300List.do"})
@ApiOperation(value = "查询沪深300", httpMethod = "GET")
@ResponseBody
public ServerResponse<?> a300List() {
String key = "_UNI_";
return RequestCacheUtils.cache("a300List.do", key, (string) -> {
Map<String, Stock> stockMap = this.stockService.repository().cacheCodeMap();
List<JSONObject> list = EastmoneyApi.a300List();
Map<String, StockVO> stockDetailMap = CommonApis.of().stockDetailMap(Lists.transform(list, val -> StockCode.a(val.getString("f12"))));
List<StockVO> retList = EastmoneyApi.a300List().stream()
.map(val -> {
String code = val.getString("f12");
Stock stock = stockMap.get(code);
if(stock == null) {
log.warn("stock无code:{} 数据.", code);
return null;
}
return stockDetailMap.get(code);
})
.filter(val -> val != null)
.collect(Collectors.toList());
return ServerResponse.createBySuccess(retList);
});
}
/*沪深指数*/
@RequestMapping({"aIndexList.do"})
@ApiOperation(value = "查询沪深指数", httpMethod = "GET")
@ResponseBody
public ServerResponse<?> aIndexList() {
String key = "_UNI_";
return RequestCacheUtils.cache("aIndexList.do", key, (string) -> {
List<JSONObject> list = EastmoneyApi.aIndexList();
// Map<String, StockVO> stockDetailMap = CommonApis.of().stockDetailMap(Lists.transform(list, val -> StockCode.a(val.getString("f12"))));
List<JSONObject> retList = list.stream()
.map(val -> {
String code = val.getString("f12");
// Stock stock = stockMap.get(code);
// if(stock == null) {
// log.warn("stock无code:{} 数据.", code);
// return null;
// }
JSONObject json = new JSONObject();
json.put("name", val.getString("f14"));
json.put("code", code);
json.put("gid", code);
json.put("hcrate", val.get("f3"));
json.put("nowPrice", val.get("f2"));
return json;
// return stockDetailMap.get(code);
})
.filter(val -> val != null)
.collect(Collectors.toList());
return ServerResponse.createBySuccess(retList);
});
}
/*热门股票*/
@RequestMapping({"gethotgubalist.do"})
@ApiOperation(value = "查询热门股票", httpMethod = "GET")
@ResponseBody
public ServerResponse<?> gethotgubalist() {
String key = "_UNI_";
return RequestCacheUtils.cache("gethotgubalist.do", key, (string) -> {
Map<String, Stock> stockMap = this.stockService.repository().cacheCodeMap();
List<JSONObject> list = EastmoneyApi.gethotgubalist();
Map<String, StockVO> stockDetailMap = CommonApis.of().stockDetailMap(Lists.transform(list, val -> StockCode.a(val.getString("guba_code"))));
List<JSONObject> retList = list
.stream()
.map(val -> {
String code = val.getString("guba_code");
Stock stock = stockMap.get(code);
if(stock == null) {
return null;
}
StockVO stockVO = stockDetailMap.get(code);
if(stockVO == null) {
return null;
}
val.put("hcrate", stockVO.getHcrate());
val.put("hcPrice", BigDecimals.multiplys(stockVO.getNowPrice(), stockVO.getHcrate()));
val.put("nowPrice",stockVO.getNowPrice());
return val;
})
.filter(val -> val != null)
.collect(Collectors.toList());
return ServerResponse.createBySuccess(retList);
});
}
/*上涨下跌家数统计*/
@RequestMapping({"bkqtRank.do"})
@ApiOperation(value = "上涨下跌家数统计", httpMethod = "GET")
@ResponseBody
public ServerResponse<?> bkqtRank() {
String key = "_UNI_";
return RequestCacheUtils.cache("bkqtRank.do", key, (string) -> {
JSONObject json = QqStockApi.bkqtRank();
return ServerResponse.createBySuccess(json);
});
}
/*新股日历_最新公告*/
@RequestMapping({"getIpoApplyDateAndTopArt.do"})
@ApiOperation(value = "新股日历_最新公告", httpMethod = "GET")
@ResponseBody
public ServerResponse<?> getIpoApplyDateAndTopArt() {
String key = "_UNI_";
return RequestCacheUtils.cache("getIpoApplyDateAndTopArt.do", key, (string) -> {
PageInfo<JSONObject> pageInfo = EastmoneyApi.ipoApplyDate(1, 50);
String nowDate = DateUtils.nowDate(DateUtils.YYYY_MM_DD);
List<JSONObject> todayList = pageInfo.getItems()
.stream()
.filter(val -> {
return StringUtils.startsWith(val.getString("APPLY_DATE"), nowDate);
})
.limit(2)
.collect(Collectors.toList());
JSONObject json = new JSONObject();
json.put("ipoApplyDateList", todayList);
List<SiteArticle> topArtList = siteArticleService.getTopArtList(20);
final Map<String, Stock> stockNameMap = this.stockService.repository().cacheNameMap();
List<StockCode> codeList = Lists.transform(topArtList, val -> {
Stock s = stockNameMap.get(val.getAuthor());
if(s == null) {
return null;
}
return StockCode.a(s.getStockCode());
});
Map<String, StockVO> stockDetailMap = CommonApis.of().stockDetailMap(codeList);
final List<String> stockNameList = new ArrayList<>();
com.github.pagehelper.PageInfo<?> artListPageInfo = new com.github.pagehelper.PageInfo<>(topArtList);
List list = artListPageInfo.getList().stream()
.filter(val -> stockNameMap.containsKey(((SiteArticle) val).getAuthor()) && !stockNameList.contains(((SiteArticle) val).getAuthor()))
.limit(2)
.map(val -> {
String name = ((SiteArticle) val).getAuthor();
Stock stockByCode = stockNameMap.get(name);
stockNameList.add(name);
JSONObject j = Jsons.toJSON(val);
if (stockByCode != null) {
StockVO stockVO = stockDetailMap.get(stockByCode.getStockCode());
if(stockVO != null) {
j.put("hcrate", stockVO.getHcrate());
j.put("nowPrice", stockVO.getNowPrice());
}
}
return j;
})
.collect(Collectors.toList());
artListPageInfo.setList(list);
json.put("artList", artListPageInfo);
return ServerResponse.createBySuccess(json);
});
}
/**
* 分时线
* 描述
* @param stockCode
* @return
*/
@RequestMapping({"/realTime/findStock.do"})
@ApiOperation(value = "分时线", httpMethod = "GET")
@ResponseBody
@ApiImplicitParams({
@ApiImplicitParam(name = "stockCode",value = "股票对应代码symbol",dataType ="String",required = true),
})
public ServerResponse findStock(@RequestParam(value = "stockCode", required = false) String stockCode) {
return RequestCacheUtils.cache("/realTime/findStock.do", stockCode, (string) -> {
Map<String, Object> findStock = this.realTimeService.findStock(stockCode);
return ServerResponse.createBySuccess(findStock);
});
}
@ApiOperation(value = "新股待上市接口",httpMethod = "GET", response = ServerResponse.class)
@RequestMapping({"getNewStockList.do"})
@ResponseBody
public
ServerResponse getNewStockList() {
return this.stockService.getNewStockList();
}
}

View File

@@ -0,0 +1,13 @@
package cn.stock.market.web;
/**
* ThreadLocal 多线程会造成内存泄漏 请使用
* https://github.com/alibaba/transmittable-thread-local
*
* @author xlfd
* @email xlfd@gmail.com
* @version 1.0
* @created Jun 3, 2021 4:23:35 PM
*/
public class TTLHolder {
}

View File

@@ -0,0 +1,56 @@
package cn.stock.market.web;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import cn.qutaojing.common.utils.SpringUtils;
import cn.stock.market.infrastructure.job.RealTimeTask;
import cn.stock.market.infrastructure.job.StockTask;
import cn.stock.market.utils.RequestCacheUtils;
import cn.stock.market.utils.ServerResponse;
import springfox.documentation.annotations.ApiIgnore;
@Controller
@RequestMapping({"/api/hq/tool/", "/api/market/tool/"})
@ApiIgnore
public class ToolController {
@RequestMapping({"/syncAStockList.do"})
@ResponseBody
public ServerResponse<?> syncAStockList() {
StockTask stockTask = SpringUtils.getBean(StockTask.class);
stockTask.syncAStockList();
return ServerResponse.createBySuccess("已经执行");
}
@RequestMapping({"/syncBjsStockList.do"})
@ResponseBody
public ServerResponse<?> syncBjsStockList() {
StockTask stockTask = SpringUtils.getBean(StockTask.class);
stockTask.syncBjsStockList();
return ServerResponse.createBySuccess("已经执行");
}
@RequestMapping({"/syncAFutureStockList.do"})
@ResponseBody
public ServerResponse<?> syncAFutureStockList() {
StockTask stockTask = SpringUtils.getBean(StockTask.class);
stockTask.syncAFutureStockList();
return ServerResponse.createBySuccess("已经执行");
}
@RequestMapping({"/cache/stat.do"})
@ResponseBody
public ServerResponse<?> cache_stat() {
return ServerResponse.createBySuccess(RequestCacheUtils.stat());
}
@RequestMapping({"/deleteStockCode.do"})
@ResponseBody
public ServerResponse<?> deleteStockCode() {
RealTimeTask task = SpringUtils.getBean(RealTimeTask.class);
task.deleteStockCode();
return ServerResponse.createBySuccess("已经执行");
}
}

View File

@@ -0,0 +1,42 @@
/*
*
* * Copyright (C) 2018 Wanghaobin<463540703@qq.com>
*
* * AG-Enterprise 企业版源码
* * 郑重声明:
* * 如果你从其他途径获取到请告知老A传播人奖励1000。
* * 老A将追究授予人和传播人的法律责任!
*
* * This program is free software; you can redistribute it and/or modify
* * it under the terms of the GNU General Public License as published by
* * the Free Software Foundation; either version 2 of the License, or
* * (at your option) any later version.
*
* * This program is distributed in the hope that it will be useful,
* * but WITHOUT ANY WARRANTY; without even the implied warranty of
* * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* * GNU General Public License for more details.
*
* * You should have received a copy of the GNU General Public License along
* * with this program; if not, write to the Free Software Foundation, Inc.,
* * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*
*/
package cn.stock.market.web.config;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Configuration;
import lombok.Data;
@Data
@Configuration
@ConfigurationProperties()
public class Config {
String ig507Licence;
String gugudataAppKey;
String aliyunAccessKeyId;
String aliyunAccessKeySecret;
String aliyunAppCode;
}

View File

@@ -0,0 +1,12 @@
package cn.stock.market.web.config;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.annotation.EnableScheduling;
@Configuration
@EnableScheduling
@ConditionalOnProperty(prefix = "enable", name = "scheduled", havingValue = "true")
public class ControlSchedulingConfiguration {
}

View File

@@ -0,0 +1,53 @@
package cn.stock.market.web.config;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.PropertySource;
import org.springframework.context.annotation.PropertySources;
import org.springframework.core.env.Environment;
import cn.qutaojing.common.utils.SpringUtils;
/**
* 环境变量
*
* @author xlfd
* @email xlfd@gmail.com
* @version 1.0
* @created Jun 2, 2020 10:00:59 AM
*/
@Configuration
@PropertySources({
@PropertySource("classpath:stock2guo.properties"),
})
public class Env {
@Autowired
Environment environment;
static Env env;
public static Env of() {
if (env == null) {
env = SpringUtils.getBean(Env.class);
}
return env;
}
public String domain() {
return environment.getProperty("domain");
}
public String springProfilesActive() {
return environment.getProperty("spring.profiles.active");
}
public boolean isProd() {
return "prod".equals(springProfilesActive());
}
public Environment environment() {
return environment;
}
}

View File

@@ -0,0 +1,23 @@
package cn.stock.market.web.config;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.client.ClientHttpRequestFactory;
import org.springframework.http.client.SimpleClientHttpRequestFactory;
import org.springframework.web.client.RestTemplate;
@Configuration
public class RestTemplateConfig {
@Bean
public RestTemplate restTemplate(ClientHttpRequestFactory factory) {
return new RestTemplate(factory);
}
@Bean
public ClientHttpRequestFactory simpleClientHttpRequestFactory() {
SimpleClientHttpRequestFactory factory = new SimpleClientHttpRequestFactory();
factory.setReadTimeout(5000);// ms
factory.setConnectTimeout(15000);// ms
return factory;
}
}

View File

@@ -0,0 +1,135 @@
package cn.stock.market.web.config;
import static com.google.common.base.Predicates.not;
import static com.google.common.collect.Lists.newArrayList;
import java.util.List;
import java.util.Set;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.annotation.Order;
import com.ag.utils.AnnotationUtils;
import com.fasterxml.classmate.TypeResolver;
import com.github.xiaoymin.swaggerbootstrapui.annotations.EnableSwaggerBootstrapUI;
import com.github.xiaoymin.swaggerbootstrapui.model.SpringAddtionalModel;
import cn.stock.market.web.interceptor.AppInterceptor;
import io.swagger.annotations.ApiModel;
import springfox.documentation.annotations.ApiIgnore;
import springfox.documentation.builders.ApiInfoBuilder;
import springfox.documentation.builders.PathSelectors;
import springfox.documentation.builders.RequestHandlerSelectors;
import springfox.documentation.service.ApiKey;
import springfox.documentation.service.AuthorizationScope;
import springfox.documentation.service.SecurityReference;
import springfox.documentation.spi.DocumentationType;
import springfox.documentation.spi.service.contexts.SecurityContext;
import springfox.documentation.spring.web.plugins.Docket;
import springfox.documentation.swagger2.annotations.EnableSwagger2;
/**
*
* title: Swagger2Config.java
* Swagger2 的Api注解的配置
*
* @author xlfd
* @email xlfd@gmail.com
* @version 1.0
* @created Jan 26, 2018 3:55:02 PM
*/
@Configuration
@EnableSwagger2
@EnableSwaggerBootstrapUI
@ConditionalOnProperty(name = "enabled", prefix = "swagger", havingValue = "true", matchIfMissing = true)
public class Swagger2Config {
@Autowired
private TypeResolver typeResolver;
SpringAddtionalModel springAddtionalModel = null;
public synchronized SpringAddtionalModel springAddtionalModel() {
if(springAddtionalModel == null) {
SpringAddtionalModel springAddtionalModel = new SpringAddtionalModel();
Set<Class<?>> classSets = AnnotationUtils.getClazzFromAnnotation("cn.stock.trade.dto", ApiModel.class);
Set<Class<?>> classSetModels = AnnotationUtils.getClazzFromAnnotation("cn.stock.trade.model", ApiModel.class);
classSets.addAll(classSetModels);
int a = 0;
for (Class<?> clazz : classSets) {
if (a == 0) {
springAddtionalModel.setFirst(typeResolver.resolve(clazz));
} else {
springAddtionalModel.add(typeResolver.resolve(clazz));
}
a++;
}
this.springAddtionalModel = springAddtionalModel;
}
return springAddtionalModel;
}
@Bean
@Order(value = 4)
public Docket createAppApi() {
// Parameter headerTokenParameter = new ParameterBuilder().name(AppInterceptor.TOKEN_KEY)
// .description("appToken")
// .modelRef(new ModelRef("string")).parameterType("query")
// .required(false)
// .defaultValue("")
// .build();
SpringAddtionalModel springAddtionalModel = springAddtionalModel();
Docket docket = new Docket(DocumentationType.SWAGGER_2).apiInfo(commonApiInfoBuilder().title("鑫宝 - App Api RESTful APIs").build())
.groupName("前端 -app -api")
.select()
.apis(not(RequestHandlerSelectors.withClassAnnotation(ApiIgnore.class)))
.paths(PathSelectors.ant("/api/app/**"))
.build()
.additionalModels(springAddtionalModel.getFirst(), springAddtionalModel.getRemaining())
.ignoredParameterTypes(ApiIgnore.class)
// .securitySchemes(newArrayList(apiKey(AppInterceptor.TOKEN_KEY)))
// .securityContexts(newArrayList(SecurityContext.builder().securityReferences(defaultAuth(AppInterceptor.TOKEN_KEY)).forPaths(PathSelectors.regex("/anyPath.*")).build()))
// .globalOperationParameters(newArrayList(
// headerTokenParameter
// ))
;
return docket;
}
@Bean
@Order(value = 5)
public Docket createCommonApi() {
return new Docket(DocumentationType.SWAGGER_2)
.groupName("后端 -api")
.select()
.apis(RequestHandlerSelectors.basePackage("cn.stock.market.web"))
.paths(PathSelectors.any())
.build();
}
private ApiKey apiKey(String key) {
return new ApiKey(key, key, "header");
}
List<SecurityReference> defaultAuth(String key) {
AuthorizationScope authorizationScope = new AuthorizationScope("global", "accessEverything");
AuthorizationScope[] authorizationScopes = new AuthorizationScope[1];
authorizationScopes[0] = authorizationScope;
return newArrayList(new SecurityReference(key, authorizationScopes));
}
public ApiInfoBuilder commonApiInfoBuilder() {
return new ApiInfoBuilder()
.description("鑫宝 接口文档")
.termsOfServiceUrl("http://www.xxxx.cn/")
.licenseUrl("http://www.apache.org/licenses/LICENSE-2.0").version("v1.0");
}
}

View File

@@ -0,0 +1,57 @@
package cn.stock.market.web.config;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.HttpStatus;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import cn.qutaojing.common.config.WebAppBaseConfigurer;
import cn.qutaojing.common.web.HttpTraceLogFilter;
import cn.stock.market.utils.ExceptionHandler;
import cn.stock.market.web.interceptor.AppInterceptor;
import cn.stock.market.web.interceptor.GlobalInterceptor;
/**
* title: WebAppConfigurer.java
*
* @author xlfd
* @version 1.0
* @email xlfd@gmail.com
* @created Jan 26, 2018 3:56:53 PM
*/
@Configuration
public class WebAppConfigurer extends WebAppBaseConfigurer {
@Autowired AppInterceptor appInterceptor;
@Autowired GlobalInterceptor globalInterceptor;
protected String[] swaggerPath = new String[] {
"/error**",
"/v2/api-docs**",
"/swagger-resources**",
"/swagger-resources/**", "/configuration/**"
};
@Override
public void addInterceptors(InterceptorRegistry registry) {
super.addInterceptors(registry);
registry.addInterceptor(globalInterceptor)
.addPathPatterns("/api/**")
.excludePathPatterns(swaggerPath);
registry.addInterceptor(appInterceptor)
.addPathPatterns("/api/**")
.excludePathPatterns(swaggerPath);
}
@Bean
public HttpTraceLogFilter httpTraceLogFilter() {
return new HttpTraceLogFilter();
}
@Bean
public ExceptionHandler exceptionHandler() {
return new ExceptionHandler(HttpStatus.OK);
}
}

View File

@@ -0,0 +1,289 @@
package cn.stock.market.web.config.swagger2;
import static com.google.common.base.Objects.equal;
import static com.google.common.base.Predicates.and;
import static com.google.common.base.Predicates.not;
import static com.google.common.base.Predicates.or;
import static com.google.common.base.Strings.isNullOrEmpty;
import static com.google.common.collect.FluentIterable.from;
import static com.google.common.collect.Lists.newArrayList;
import static com.google.common.collect.Sets.newHashSet;
import static springfox.documentation.schema.Collections.collectionElementType;
import static springfox.documentation.schema.Collections.isContainerType;
import static springfox.documentation.schema.Types.typeNameFor;
import java.beans.Introspector;
import java.beans.PropertyDescriptor;
import java.lang.reflect.Field;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Primary;
import org.springframework.stereotype.Component;
import com.fasterxml.classmate.ResolvedType;
import com.fasterxml.classmate.members.ResolvedField;
import com.google.common.base.Function;
import com.google.common.base.Optional;
import com.google.common.base.Predicate;
import com.google.common.collect.FluentIterable;
import io.swagger.annotations.ApiModelProperty;
import springfox.documentation.builders.ParameterBuilder;
import springfox.documentation.schema.Maps;
import springfox.documentation.schema.Types;
import springfox.documentation.schema.property.field.FieldProvider;
import springfox.documentation.service.Parameter;
import springfox.documentation.spi.schema.AlternateTypeProvider;
import springfox.documentation.spi.service.contexts.DocumentationContext;
import springfox.documentation.spi.service.contexts.ParameterExpansionContext;
import springfox.documentation.spring.web.plugins.DocumentationPluginsManager;
import springfox.documentation.spring.web.readers.parameter.ExpansionContext;
import springfox.documentation.spring.web.readers.parameter.ModelAttributeField;
import springfox.documentation.spring.web.readers.parameter.ModelAttributeParameterExpander;
/**
*
* title: ModelAttributeParameterExpander.java
* springboot整合Swagger解决忽略属性不生效
*
* @author rplees
* @email rplees.i.ly@gmail.com
* @version 1.0
* @created Dec 9, 2022 11:21:13 AM
*/
@Component
@Primary
public class CustomizeModelAttributeParameterExpander extends ModelAttributeParameterExpander {
private static final Logger LOG = LoggerFactory.getLogger(CustomizeModelAttributeParameterExpander.class);
private final FieldProvider fieldProvider;
@Autowired
protected DocumentationPluginsManager pluginsManager;
@Autowired
public CustomizeModelAttributeParameterExpander(FieldProvider fields) {
super(fields);
this.fieldProvider = fields;
}
public List<Parameter> expand(ExpansionContext context) {
List<Parameter> parameters = newArrayList();
Set<String> beanPropNames = getBeanPropertyNames(context.getParamType().getErasedType());
Iterable<ResolvedField> fields = FluentIterable.from(fieldProvider.in(context.getParamType()))
.filter(onlyBeanProperties(beanPropNames));
LOG.debug("Expanding parameter type: {}", context.getParamType());
AlternateTypeProvider alternateTypeProvider = context.getDocumentationContext().getAlternateTypeProvider();
FluentIterable<ModelAttributeField> modelAttributes = from(fields)
.transform(toModelAttributeField(alternateTypeProvider));
FluentIterable<ModelAttributeField> expendables = modelAttributes.filter(not(simpleType()))
.filter(not(recursiveType(context)));
for (ModelAttributeField each : expendables) {
LOG.debug("Attempting to expand expandable field: {}", each.getField());
parameters.addAll(expand(context.childContext(nestedParentName(context.getParentName(), each.getField()),
each.getFieldType(), context.getDocumentationContext())));
}
FluentIterable<ModelAttributeField> collectionTypes = modelAttributes
.filter(and(isCollection(), not(recursiveCollectionItemType(context.getParamType()))));
for (ModelAttributeField each : collectionTypes) {
LOG.debug("Attempting to expand collection/array field: {}", each.getField());
ResolvedType itemType = collectionElementType(each.getFieldType());
if (Types.isBaseType(itemType) || itemType.getErasedType().isEnum()) {
parameters.add(simpleFields(context.getParentName(), context.getDocumentationContext(), each));
} else {
parameters
.addAll(expand(context.childContext(nestedParentName(context.getParentName(), each.getField()),
itemType, context.getDocumentationContext())));
}
}
FluentIterable<ModelAttributeField> simpleFields = modelAttributes.filter(simpleType());
for (ModelAttributeField each : simpleFields) {
parameters.add(simpleFields(context.getParentName(), context.getDocumentationContext(), each));
}
return FluentIterable.from(parameters).filter(not(hiddenParameters())).toList();
}
private Predicate<ModelAttributeField> recursiveCollectionItemType(final ResolvedType paramType) {
return new Predicate<ModelAttributeField>() {
@Override
public boolean apply(ModelAttributeField input) {
return equal(collectionElementType(input.getFieldType()), paramType);
}
};
}
private Predicate<Parameter> hiddenParameters() {
return new Predicate<Parameter>() {
@Override
public boolean apply(Parameter input) {
return input.isHidden();
}
};
}
private Parameter simpleFields(String parentName, DocumentationContext documentationContext,
ModelAttributeField each) {
LOG.debug("Attempting to expand field: {}", each);
String dataTypeName = Optional.fromNullable(typeNameFor(each.getFieldType().getErasedType()))
.or(each.getFieldType().getErasedType().getSimpleName());
LOG.debug("Building parameter for field: {}, with type: ", each, each.getFieldType());
ParameterExpansionContext parameterExpansionContext = new ParameterExpansionContext(dataTypeName, parentName,
each.getField(), documentationContext.getDocumentationType(), new ParameterBuilder());
return pluginsManager.expandParameter(parameterExpansionContext);
}
private Predicate<ModelAttributeField> recursiveType(final ExpansionContext context) {
return new Predicate<ModelAttributeField>() {
@Override
public boolean apply(ModelAttributeField input) {
return context.hasSeenType(input.getFieldType());
}
};
}
private Predicate<ModelAttributeField> simpleType() {
return and(not(isCollection()), not(isMap()), or(belongsToJavaPackage(), isBaseType(), isEnum()));
}
private Predicate<ModelAttributeField> isCollection() {
return new Predicate<ModelAttributeField>() {
@Override
public boolean apply(ModelAttributeField input) {
return isContainerType(input.getFieldType());
}
};
}
private Predicate<ModelAttributeField> isMap() {
return new Predicate<ModelAttributeField>() {
@Override
public boolean apply(ModelAttributeField input) {
return Maps.isMapType(input.getFieldType());
}
};
}
private Predicate<ModelAttributeField> isEnum() {
return new Predicate<ModelAttributeField>() {
@Override
public boolean apply(ModelAttributeField input) {
return input.getFieldType().getErasedType().isEnum();
}
};
}
private Predicate<ModelAttributeField> belongsToJavaPackage() {
return new Predicate<ModelAttributeField>() {
@Override
public boolean apply(ModelAttributeField input) {
return packageName(input.getFieldType().getErasedType()).startsWith("java.lang");
}
};
}
private Predicate<ModelAttributeField> isBaseType() {
return new Predicate<ModelAttributeField>() {
@Override
public boolean apply(ModelAttributeField input) {
return Types.isBaseType(input.getFieldType()) || input.getField().getType().isPrimitive();
}
};
}
private Function<ResolvedField, ModelAttributeField> toModelAttributeField(
final AlternateTypeProvider alternateTypeProvider) {
return new Function<ResolvedField, ModelAttributeField>() {
@Override
public ModelAttributeField apply(ResolvedField input) {
return new ModelAttributeField(fieldType(alternateTypeProvider, input), input);
}
};
}
private Predicate<ResolvedField> onlyBeanProperties(final Set<String> beanPropNames) {
return new Predicate<ResolvedField>() {
@Override
public boolean apply(ResolvedField input) {
return beanPropNames.contains(input.getName());
}
};
}
private String nestedParentName(String parentName, ResolvedField field) {
String name = field.getName();
ResolvedType fieldType = field.getType();
if (isContainerType(fieldType) && !Types.isBaseType(collectionElementType(fieldType))) {
name += "[0]";
}
if (isNullOrEmpty(parentName)) {
return name;
}
return String.format("%s.%s", parentName, name);
}
private ResolvedType fieldType(AlternateTypeProvider alternateTypeProvider, ResolvedField field) {
return alternateTypeProvider.alternateFor(field.getType());
}
private String packageName(Class<?> type) {
return Optional.fromNullable(type.getPackage()).transform(toPackageName()).or("java");
}
private Function<Package, String> toPackageName() {
return new Function<Package, String>() {
@Override
public String apply(Package input) {
return input.getName();
}
};
}
private Set<String> getBeanPropertyNames(final Class<?> clazz) {
try {
Set<String> beanProps = new HashSet<String>();
PropertyDescriptor[] propDescriptors = Introspector.getBeanInfo(clazz).getPropertyDescriptors();
for (PropertyDescriptor propDescriptor : propDescriptors) {
try {
Field field = clazz.getDeclaredField(propDescriptor.getName());
if(field != null) {
field.setAccessible(true);
ApiModelProperty property = field.getAnnotation(ApiModelProperty.class);
if(property != null && property.hidden()) {
continue;
}
}
} catch (Exception e) {
}
if (propDescriptor.getReadMethod() != null) {
beanProps.add(propDescriptor.getName());
}
}
return beanProps;
} catch (Exception e) {
LOG.warn(String.format("Failed to get bean properties on (%s)", clazz), e);
}
return newHashSet();
}
// @VisibleForTesting
// BeanInfo getBeanInfo(Class<?> clazz) throws IntrospectionException {
// return Introspector.getBeanInfo(clazz);
// }
}

View File

@@ -0,0 +1,39 @@
package cn.stock.market.web.interceptor;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;
import lombok.extern.slf4j.Slf4j;
/**
*
* @author xlfd
* @email xlfd@gmail.com
* @version 1.0
* @created Mar 3, 2018 5:31:57 PM
*/
@Configuration
@Slf4j
public class AppInterceptor implements HandlerInterceptor {
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
throws Exception {
return true;
}
@Override
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler,
ModelAndView modelAndView) throws Exception {
}
@Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex)
throws Exception {
}
}

View File

@@ -0,0 +1,37 @@
package cn.stock.market.web.interceptor;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;
/**
*
* title: GlobalInterceptor.java
* 全局拦截器
* @author xlfd
* @email xlfd@gmail.com
* @version 1.0
* @created Nov 1, 2021 2:08:51 PM
*/
@Configuration
public class GlobalInterceptor implements HandlerInterceptor {
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
throws Exception {
return true;
}
@Override
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler,
ModelAndView modelAndView) throws Exception {
}
@Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex)
throws Exception {
}
}

View File

@@ -0,0 +1,32 @@
package cn.stock.market.web.interceptor;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;
/**
*
* @author xlfd
* @email xlfd@gmail.com
* @version 1.0
* @created Mar 3, 2018 5:31:57 PM
*/
public class OpenApiAuthInterceptor implements HandlerInterceptor {
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
throws Exception {
return true;
}
@Override
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler,
ModelAndView modelAndView) throws Exception {
}
@Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex)
throws Exception {
}
}

View File

@@ -0,0 +1,82 @@
//package cn.stock.market.web.interceptor;
//
//import java.util.Calendar;
//import java.util.Date;
//import java.util.List;
//
//import org.apache.commons.lang3.StringUtils;
//import org.springframework.data.redis.core.ListOperations;
//import org.springframework.data.redis.core.RedisTemplate;
//
//import com.ag.utils.CollectionUtils;
//
//import cn.qutaojing.common.utils.JwtUtils;
//import io.jsonwebtoken.Claims;
//import io.jsonwebtoken.Jws;
//
///**
// * 维护token列表
// *
// * @author xlfd
// * @email xlfd@gmail.com
// * @version 1.0
// * @created Jun 16, 2021 2:37:24 PM
// */
//@SuppressWarnings({ "rawtypes", "unchecked" })
//public class RedisTokenVerifyer {
// RedisTemplate redisTemplate;
// String redisKey;
// String secret;
//
// public RedisTokenVerifyer(RedisTemplate redisTemplate, String secret, String redisKey) {
// this.redisTemplate = redisTemplate;
// this.secret = secret;
// this.redisKey = redisKey;
// }
//
// public boolean verify(String token) {
// List list = redisTemplate.opsForList().range(redisKey, 0, -1);
// if (CollectionUtils.isEmpty(list)) {
// return false;
// }
//
// for (Object o : list) {
// String t = String.valueOf(o);
//
// try {
// Jws<Claims> jws = JwtUtils.parse(t, secret);
// Date expiration = jws.getBody().getExpiration();
// if(expiration != null && expiration.before(Calendar.getInstance().getTime())) {
// redisTemplate.opsForList().remove(redisKey, 0, t);
// continue;
// }
// } catch(Exception e) {
// }
//
// if (StringUtils.equals(token, t)) {
// return true;
// }
// }
//
// return false;
// }
//
// public void expireAt(Date date) {
// redisTemplate.expireAt(redisKey, date);
// }
//
// public void login(String token, Date expireAt) {
// redisTemplate.opsForList().leftPush(redisKey, token);
// expireAt(expireAt);
// }
//
// public void logout(String token) {
// redisTemplate.opsForList().remove(redisKey, 0, token);
// }
//
// public void clear() {
// ListOperations listOperations = redisTemplate.opsForList();
// listOperations.trim(redisKey, 0, 0);
// listOperations.leftPop(redisKey);
// }
//}

View File

@@ -0,0 +1,21 @@
package cn.stock.market.web.openapi;
import lombok.Data;
/**
* open-api 公用入参
*
* @author xlfd
* @email xlfd@gmail.com
* @version 1.0
* @created Jun 16, 2021 1:54:51 PM
*/
@Data
public class OpenApiParam {
String appId;
String teamToken;
String version;
String timestamp;
String nonce;
String sign;
}

View File

@@ -0,0 +1,36 @@
package cn.stock.market.web.openapi.impl;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
import java.util.stream.Stream;
import org.apache.commons.lang3.StringUtils;
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 com.ag.utils.param.ParamUtils;
import cn.stock.market.application.CommonApis;
import cn.stock.market.dto.model.StockCode;
import cn.stock.market.dto.model.StockVO;
import cn.stock.market.utils.ServerResponse;
import springfox.documentation.annotations.ApiIgnore;
@Controller
@RequestMapping({"/api/market/openapi/stock"})
@ApiIgnore
public class StockOpenApi {
@RequestMapping({"hq"})
@ResponseBody
public ServerResponse<?> getNewsList(@RequestParam(value = "codeList") String codeList) {
ParamUtils.verify("股票代码集", codeList, ParamUtils.STRING_NOT_EMPTY_VERIFY_AND_CONVERT_VALUE);
List<StockCode> list = Stream.of(StringUtils.split(codeList, ",")).map(val -> StockCode.a(val)).collect(Collectors.toList());
Map<String, StockVO> map = CommonApis.of().stockDetailMap(list);
return ServerResponse.createBySuccess(map);
}
}

View File

@@ -0,0 +1,17 @@
package cn.stock.market.web.openapi.model;
import javax.validation.constraints.NotBlank;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.NoArgsConstructor;
import lombok.experimental.SuperBuilder;
@Data
@NoArgsConstructor
@SuperBuilder
@EqualsAndHashCode(callSuper = false)
public class AuthOpenApiModel {
@NotBlank(message = "凭证不能为空")
String simpleCredentials;
}