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,78 @@
package cn.stock.market.application;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.TreeSet;
import java.util.function.Function;
import java.util.stream.Collector;
import java.util.stream.Collectors;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.ag.utils.CollectionUtils;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import cn.qutaojing.common.utils.SpringUtils;
import cn.stock.market.constant.StockSource;
import cn.stock.market.domain.basic.entity.Stock;
import cn.stock.market.domain.basic.repository.StockRepository;
import cn.stock.market.dto.model.StockCode;
import cn.stock.market.dto.model.StockDetail;
import cn.stock.market.dto.model.StockVO;
import cn.stock.market.infrastructure.api.AStockApis;
import lombok.RequiredArgsConstructor;
@Service
@RequiredArgsConstructor(onConstructor = @__(@Autowired))
public class CommonApis {
public StockDetail aStockDetail(String code) {
return AStockApis.qq(code);
}
public StockVO stockDetail(StockCode code) {
Map<String, StockVO> map = stockDetailMap(Lists.newArrayList(code));
return map.get(code.getCode());
}
public List<StockDetail> aStockDetail(List<String> code) {
return AStockApis.qq(code);
}
public Map<String, StockVO> stockDetailMap(List<StockCode> code) {
Function<StockSource, List<StockCode>> func = (source) -> {
return code.stream()
.filter(val -> val != null && source == val.getSource())
.collect(Collectors.collectingAndThen(Collectors.toCollection(() -> new TreeSet<>(Comparator.comparing(StockCode::getCode))), ArrayList::new));
};
List<StockCode> aList = func.apply(StockSource.A);
// List<StockCode> hkList = func.apply(StockSource.HK);
// List<StockCode> usList = func.apply(StockSource.US);
Map<String, StockVO> map = Maps.newHashMap();
Collector<StockVO, ?, Map<String, StockVO>> collectorMap = Collectors.toMap(StockVO::getCode, Function.identity(), (u,v) -> { return v;}, HashMap::new);
Map<String, Stock> stockMap = StockRepository.of().cacheCodeMap();
if(CollectionUtils.isNotEmpty(aList)) {
Map<String, StockVO> m = aStockDetail(Lists.transform(aList, val -> val.getCode()))
.stream()
.map(val -> StockVO.from(val, stockMap.get(val.getCode())))
.collect(collectorMap);
map.putAll(m);
}
return map;
}
public static CommonApis of() {
return SpringUtils.getBean(CommonApis.class);
}
}

View File

@@ -0,0 +1,198 @@
//package cn.stock.market.application;
//
//import java.util.Date;
//import java.util.List;
//import java.util.Map;
//import java.util.concurrent.TimeUnit;
//import java.util.stream.Collectors;
//
//import org.apache.commons.lang.StringUtils;
//import org.springframework.beans.factory.annotation.Autowired;
//import org.springframework.data.redis.core.RedisTemplate;
//import org.springframework.stereotype.Service;
//import org.springframework.transaction.annotation.Transactional;
//
//import com.ag.utils.CollectionUtils;
//import com.ag.utils.NumberUtils;
//import com.google.common.base.Joiner;
//import com.google.common.collect.Maps;
//import com.querydsl.core.types.dsl.CaseBuilder;
//import com.querydsl.core.types.dsl.CaseBuilder.Cases;
//import com.querydsl.core.types.dsl.NumberExpression;
//import com.querydsl.jpa.impl.JPAUpdateClause;
//
//import cn.qutaojing.common.utils.DslUtils;
//import cn.qutaojing.common.utils.SpringUtils;
//import cn.stock.market.infrastructure.db.po.Counter;
//import cn.stock.market.infrastructure.db.repo.CounterRepo;
//import cn.stock.market.infrastructure.db.po.QCounter;
//import lombok.extern.slf4j.Slf4j;
//
///**
// * 计数器
// *
// * @author xlfd
// * @email xlfd@gmail.com
// * @version 1.0
// * @created Apr 22, 2021 4:21:07 PM
// */
//@Service
//@SuppressWarnings("rawtypes")
//@Slf4j
//public class Counters {
// public static final String TYPE_USER = "USER";
// public static final String TYPE_SYS = "SYS";
//
// /**
// * 用户购买商品
// */
// public static final String USER_BUY_GOODS_COUNT_TMP = "USER_BUY_GOODS_COUNT_%s_%s";
// public static final String USER_EVERYDAY_BUY_GOODS_COUNT_TMP = "USER_EVERYDAY_BUY_GOODS_COUNT_%s_%s_%s";
// public static final String USER_STORE_BUY_COUNT_TMP = "USER_STORE_BUY_COUNT_%s_%s_%s";
//
// static final long EXPIRE_SEC = 60 * 60 * 24; // 默认一天
// @Autowired RedisTemplate redisTemplate;
// @Autowired CounterRepo repo;
//
// String COUNTER_OPERCOUNT_MAP = "counter::opercount::map";
// String COUNTER_MAP_PRE = "counter::count::";
//
// @SuppressWarnings("unchecked")
// public long getCount(String k) {
// Object obj = redisTemplate.opsForValue().get(key(k));
// if(obj != null) {
// if(obj instanceof Number) {
// return ((Number) obj).longValue();
// } else {
// log.error("获取的到值{}非数字类型, 删除", obj);
// redisTemplate.delete(key(k));
// }
// }
//
// Counter counter = repo.findById(k).orElse(null);
// if(counter != null) {
// redisTemplate.opsForValue().set(key(k), counter.getCount(), EXPIRE_SEC, TimeUnit.SECONDS);
// return counter.getCount();
// }
//
// return 0;
// }
//
// String key(String k) {
// return COUNTER_MAP_PRE + k;
// }
//
// /**
// * 返回add后的值
// * @return
// */
// @SuppressWarnings("unchecked")
// public long add(String k, long delta, String type, String fkId) {
// String key = key(k);
// if (redisTemplate.hasKey(key)) {
// Long increment = redisTemplate.opsForValue().increment(key, delta);
//
// if(redisTemplate.opsForHash().hasKey(COUNTER_OPERCOUNT_MAP, key)) {
// redisTemplate.opsForHash().increment(COUNTER_OPERCOUNT_MAP, key, 1);
// } else {
// redisTemplate.opsForHash().putIfAbsent(COUNTER_OPERCOUNT_MAP, key, 1);
// }
// return increment == null ? 0 : increment.longValue();
// }
//
// Counter counter = repo.findById(k).orElse(null);
// if(counter != null) {
// counter.setCount(counter.getCount() + delta);
// } else {
// counter = Counter.builder()
// .k(k)
// .count(delta)
// .type(type)
// .fkId(fkId)
// .build();
// }
// repo.save(counter);
// redisTemplate.opsForValue().set(key, counter.getCount(), EXPIRE_SEC, TimeUnit.SECONDS);
// return counter.getCount();
// }
//
// @SuppressWarnings("unchecked")
// public List<String> getStockOperList() {
// Map<Object, Object> map = redisTemplate.opsForHash().entries(COUNTER_OPERCOUNT_MAP);
// return
// map.entrySet()
// .stream()
// .filter(entry -> {
// return ((int) entry.getValue()) > 0;
// }).map(entry -> entry.getKey())
// .map(String::valueOf)
// .collect(Collectors.toList());
// }
//
// /**
// * 库存从redis回写到DB
// */
// @SuppressWarnings({ "unchecked"})
// @Transactional
// public long writebackToDB() {
// List<String> list = getStockOperList();
// if(CollectionUtils.isEmpty(list)) {
// return 0;
// }
//
// log.info("准备回写库存到DB, size:{}, {}", list.size(), Joiner.on(",").join(list));
// Map<String, Long> map = Maps.newConcurrentMap();
//
// List<Object> valueList = redisTemplate.opsForValue().multiGet(list);
// for (int i = 0; i < list.size(); i++) {
// String keyWithPre = list.get(i);
// Object value = valueList.get(i);
// if(value == null || ! (value instanceof Number)) {
// log.warn("{}-无效", keyWithPre, value);
// continue;
// }
//
// Long count = ((Number) valueList.get(i)).longValue();
// if(NumberUtils.isNotValidWithoutZero(count)) {
// log.warn("{}-无效值", keyWithPre, count);
// continue;
// }
//
// String k = StringUtils.replace(keyWithPre, COUNTER_MAP_PRE, "");
// if(StringUtils.isBlank(k)) {
// log.warn("{}-key-{}无效值", keyWithPre, k);
// continue;
// }
//
// map.put(k, count);
// }
//
// if(CollectionUtils.isNotEmpty(map)) {
// QCounter q = QCounter.counter;
//
// Cases<Long, NumberExpression<Long>> cases = null;
// for (Map.Entry<String, Long> entry : map.entrySet()) {
// if(cases == null) {
// cases = new CaseBuilder().when(q.k.eq(entry.getKey())).then(entry.getValue());
// } else {
// cases = cases.when(q.k.eq(entry.getKey())).then(entry.getValue());
// }
// }
//
// JPAUpdateClause updateClause = DslUtils.update(q)
// .set(q.count, cases.otherwise(-1L))
// .set(q.updateTime, new Date())
// .where(q.k.in(map.keySet()));
//
// long row = updateClause.execute();
// log.info("返回行数:{}, 执行SQL: {}", row, updateClause);
// }
//
// redisTemplate.delete(COUNTER_OPERCOUNT_MAP);
// return list.size();
// }
//
// public static Counters of() {
// return SpringUtils.getBean(Counters.class);
// }
//}

View File

@@ -0,0 +1,264 @@
package cn.stock.market.application;
import java.util.Comparator;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.ag.utils.CollectionUtils;
import com.ag.utils.JsonUtils;
import com.ag.utils.Jsons;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.parser.ParserConfig;
import com.alibaba.fastjson.util.TypeUtils;
import com.google.common.base.Joiner;
import com.google.common.cache.CacheBuilder;
import com.google.common.cache.CacheLoader;
import com.google.common.cache.LoadingCache;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import cn.qutaojing.common.utils.SpringUtils;
import cn.stock.market.infrastructure.db.po.Dic;
import cn.stock.market.infrastructure.db.po.QDic;
import cn.stock.market.infrastructure.db.repo.DicRepo;
import lombok.extern.slf4j.Slf4j;
/**
* title: Dics.java
*
* @author xlfd
* @version 1.0
* @email xlfd@gmail.com
* @created Oct 15, 2020 11:00:46 AM
*/
@Slf4j
@Service
public class Dics {
@Autowired
DicRepo repository;
final static String SPLIT = "."; //分隔符
LoadingCache<String, Optional<Object>> keyCahce = CacheBuilder.newBuilder()
.maximumSize(20000)
.expireAfterWrite(60, TimeUnit.SECONDS)
.build(CacheLoader.from((prefix) -> {
return Optional.ofNullable(findByPrefix(prefix));
}));
public void refreshCache(String key) {
try {
keyCahce.refresh(key);
} catch(Exception e) {
log.warn("refreshCache error: {}", e.getLocalizedMessage());
}
}
@SuppressWarnings("unchecked")
public <T> T getFromCache(String prefix) {
try {
return (T) keyCahce.get(prefix).orElse(null);
} catch (ExecutionException e) {
e.printStackTrace();
}
return null;
}
@SuppressWarnings("unchecked")
public <T> T getFromCache(String prefix, Class<T> clazz) {
Object o = getFromCache(prefix);
if(o != null && clazz == null) {
return (T) o;
}
return Jsons.typeCast(o, clazz);
}
@SuppressWarnings("unchecked")
public <T> T getFromCache(String prefix, T defalutValue) {
Object o = getFromCache(prefix);
if (o == null) {
return defalutValue;
}
return (T) Jsons.typeCast(o, defalutValue.getClass());
// return (T) TypeUtils.cast(o, defalutValue.getClass(), ParserConfig.getGlobalInstance());
}
public static String pack(Object... strings) {
return Joiner.on(SPLIT).skipNulls().join(strings);
}
public static Dics of() {
return SpringUtils.getBean(Dics.class);
}
/**
* 降map的每键值对记录刷到DB中, 每组记录为一列
*
* @param prefix 键的前缀
* @param map
* @return
*/
public List<Dic> save(final String prefix, Object obj) {
JSONObject map = JsonUtils.formObject(obj);
return save(prefix, map);
}
/**
* 降map的每组记录刷到DB中, 每组记录为一列
*
* @param prefix 键的前缀
* @param map
* @return
*/
public List<Dic> save(final String prefix, Map<String, Object> map) {
Map<String, Object> m = Maps.newHashMap();
map.keySet().stream().forEach(k -> {
m.put(prefix + SPLIT + k, map.get(k));
});
return save(m);
}
public Dic saveOne(final String key, Object value) {
Map<String, Object> m = Maps.newHashMap();
m.put(key, value);
return save(m).get(0);
}
public List<Dic> save(Map<String, Object> map) {
List<Dic> list = Lists.newArrayList();
map.forEach((k, v) -> {
Dic dic = Dic.builder()
.k(k)
.val(String.valueOf(v))
.build();
list.add(dic);
});
repository.saveAll(list);
return list;
}
static String[] split(String str) {
return StringUtils.split(str, SPLIT);
}
/**
* 根据前缀查询到列表, 然后每列的k-val对应的 class.v=val封装成对象返回
* 适用于 key -> Object
*
* @param prefix 前缀
* @param clazz
* @return
*/
public <T> T findByPrefix(String prefix, Class<T> clazz) {
Object o = findByPrefix(prefix);
return TypeUtils.cast(o, clazz, ParserConfig.getGlobalInstance());
// return JsonUtils.convert(JsonUtils.formObject(o), clazz);
}
/**
* 根据前缀查询到列表
* 根据传入的prefix返回对应的保存数据库的结构
* 1, prefix -> Object
* 2, prefix -> Map<String, K> K可以是String也可以是Map
*
* @param prefix 前缀
* @return
*/
public <T> T findByPrefix(String prefix) {
return findByPrefix(prefix, Comparator.comparing(Dic::getCreateTime));
}
@SuppressWarnings("unchecked")
public <T> T findByPrefix(String prefix, Comparator<Dic> comparator) {
List<Dic> list = repository.findAll(QDic.dic.k.like(prefix + "%"));
list.sort(comparator);
Map<String, String> map = list.stream().collect(HashMap::new, (m, v) -> m.put(v.getK(), v.getVal()), HashMap::putAll);
Map<String, Object> structureMap = buildStructureMap(map);
return (T) getParameter(structureMap, split(prefix));
}
@SuppressWarnings("rawtypes")
static Object getParameter(Map<String, Object> map, String... settings) {
if (settings == null || settings.length < 1)
return null;
if (settings.length == 1) {
settings = StringUtils.split(settings[0], ".");
}
if (settings.length == 1)
return map.get(settings[0]);
Map tempMap = (Map) map.get(settings[0]);
for (int i = 1; i < settings.length - 1; i++) {
if (tempMap == null) {
return null;
}
tempMap = (Map) tempMap.get(settings[i]);
if (tempMap == null) {
return null;
}
}
if (tempMap == null) {
return null;
}
return tempMap.get(settings[settings.length - 1]);
}
@SuppressWarnings({"unchecked", "rawtypes"})
static Map<String, Object> buildStructureMap(Map<String, String> assembleMap) {
Map<String, Object> map = Maps.newLinkedHashMap();
if (CollectionUtils.isEmpty(assembleMap)) {
return map;
}
for (Map.Entry<String, String> set : assembleMap.entrySet()) {
String variable = set.getKey();
String value = set.getValue();
if (StringUtils.isBlank(variable)) {
continue;
}
String[] keys = StringUtils.split(variable, '.');
Map<String, Object> supMap = null;
Map<String, Object> subMap = null;
Object obj = null;
int len = keys.length - 1;
if (len < 1) { // only root node
map.put(variable, value);
continue;
}
supMap = (Map<String, Object>) map.get(keys[0]);
if (supMap == null) { // new root node
supMap = new LinkedHashMap<String, Object>();
map.put(keys[0], supMap);
}
for (int i = 1; i < len; i++) {
String key = keys[i];
obj = supMap.get(key);
if (obj != null && obj instanceof Map) {
supMap = (Map) obj;
} else {
subMap = Maps.newLinkedHashMap();
supMap.put(key, subMap);
supMap = subMap;
}
}
supMap.put(keys[len], value);
}
return map;
}
}

View File

@@ -0,0 +1,28 @@
package cn.stock.market.application.assembler;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Component;
import cn.qutaojing.common.utils.Beans;
import cn.qutaojing.common.utils.SpringUtils;
import cn.stock.market.domain.basic.entity.City;
import cn.stock.market.dto.CityDTO;
/**
* CityAssembler
*
* @author xlfd
* @email xlfd@gmail.com
* @created 2021/06/16
*/
@Component
@Lazy
public class CityAssembler {
public CityDTO toDTO(City entity) {
return Beans.mapper(entity, CityDTO.class);
}
public static CityAssembler of() {
return SpringUtils.getBean(CityAssembler.class);
}
}

View File

@@ -0,0 +1,36 @@
package cn.stock.market.application.assembler;
import cn.qutaojing.common.utils.Beans;
import cn.qutaojing.common.utils.SpringUtils;
import cn.stock.market.domain.basic.entity.JsonInfo;
import cn.stock.market.dto.JsonInfoDTO;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Component;
/**
* JsonInfoAssembler
*
* @author rplees
* @email rplees.i.ly@gmail.com
* @created 2022/08/16
*/
@Component
@Lazy
public class JsonInfoAssembler {
public JsonInfoDTO toDTO(JsonInfo e) {
JsonInfoDTO dto = Beans.mapper(e, JsonInfoDTO.class);
if(dto == null) return dto;
fill(e, dto);
return dto;
}
protected void fill(JsonInfo e, JsonInfoDTO dto) {
if(dto == null) return;
return;
}
public static JsonInfoAssembler of() {
return SpringUtils.getBean(JsonInfoAssembler.class);
}
}

View File

@@ -0,0 +1,35 @@
package cn.stock.market.application.assembler;
import cn.qutaojing.common.utils.Beans;
import cn.qutaojing.common.utils.SpringUtils;
import cn.stock.market.domain.basic.entity.Realtime;
import cn.stock.market.dto.RealtimeDTO;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Component;
/**
* RealtimeAssembler
*
* @author rplees
* @email rplees.i.ly@gmail.com
* @created 2023/06/17
*/
@Component
@Lazy
public class RealtimeAssembler {
public RealtimeDTO toDTO(Realtime e) {
RealtimeDTO dto = Beans.mapper(e, RealtimeDTO.class);
if(dto == null) return dto;
fill(e, dto);
return dto;
}
protected void fill(Realtime e, RealtimeDTO dto) {
if(dto == null) return;
return;
}
public static RealtimeAssembler of() {
return SpringUtils.getBean(RealtimeAssembler.class);
}
}

View File

@@ -0,0 +1,35 @@
package cn.stock.market.application.assembler;
import cn.qutaojing.common.utils.Beans;
import cn.qutaojing.common.utils.SpringUtils;
import cn.stock.market.domain.basic.entity.SiteArticle;
import cn.stock.market.dto.SiteArticleDTO;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Component;
/**
* SiteArticleAssembler
*
* @author rplees
* @email rplees.i.ly@gmail.com
* @created 2023/06/17
*/
@Component
@Lazy
public class SiteArticleAssembler {
public SiteArticleDTO toDTO(SiteArticle e) {
SiteArticleDTO dto = Beans.mapper(e, SiteArticleDTO.class);
if(dto == null) return dto;
fill(e, dto);
return dto;
}
protected void fill(SiteArticle e, SiteArticleDTO dto) {
if(dto == null) return;
return;
}
public static SiteArticleAssembler of() {
return SpringUtils.getBean(SiteArticleAssembler.class);
}
}

View File

@@ -0,0 +1,35 @@
package cn.stock.market.application.assembler;
import cn.qutaojing.common.utils.Beans;
import cn.qutaojing.common.utils.SpringUtils;
import cn.stock.market.domain.basic.entity.SiteNews;
import cn.stock.market.dto.SiteNewsDTO;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Component;
/**
* SiteNewsAssembler
*
* @author rplees
* @email rplees.i.ly@gmail.com
* @created 2023/06/19
*/
@Component
@Lazy
public class SiteNewsAssembler {
public SiteNewsDTO toDTO(SiteNews e) {
SiteNewsDTO dto = Beans.mapper(e, SiteNewsDTO.class);
if(dto == null) return dto;
fill(e, dto);
return dto;
}
protected void fill(SiteNews e, SiteNewsDTO dto) {
if(dto == null) return;
return;
}
public static SiteNewsAssembler of() {
return SpringUtils.getBean(SiteNewsAssembler.class);
}
}

View File

@@ -0,0 +1,35 @@
package cn.stock.market.application.assembler;
import cn.qutaojing.common.utils.Beans;
import cn.qutaojing.common.utils.SpringUtils;
import cn.stock.market.domain.basic.entity.Stock;
import cn.stock.market.dto.StockDTO;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Component;
/**
* StockAssembler
*
* @author rplees
* @email rplees.i.ly@gmail.com
* @created 2023/06/17
*/
@Component
@Lazy
public class StockAssembler {
public StockDTO toDTO(Stock e) {
StockDTO dto = Beans.mapper(e, StockDTO.class);
if(dto == null) return dto;
fill(e, dto);
return dto;
}
protected void fill(Stock e, StockDTO dto) {
if(dto == null) return;
return;
}
public static StockAssembler of() {
return SpringUtils.getBean(StockAssembler.class);
}
}

View File

@@ -0,0 +1,28 @@
package cn.stock.market.application.assembler;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Component;
import cn.qutaojing.common.utils.Beans;
import cn.qutaojing.common.utils.SpringUtils;
import cn.stock.market.domain.basic.entity.SysLog;
import cn.stock.market.dto.SysLogDTO;
/**
* SysLogAssembler
*
* @author xlfd
* @email xlfd@gmail.com
* @created 2021/06/18
*/
@Component
@Lazy
public class SysLogAssembler {
public SysLogDTO toDTO(SysLog entity) {
return Beans.mapper(entity, SysLogDTO.class);
}
public static SysLogAssembler of() {
return SpringUtils.getBean(SysLogAssembler.class);
}
}