增加 StockStrategy 服务,数据表建立及批量更新方法重写。解决多数据源配置 mapper-locations
无法识别并读取到对应数据源的 mapper.xml 及其 statement 方法的问题
This commit is contained in:
58
src/main/java/quant/rich/emoney/util/DateUtils.java
Normal file
58
src/main/java/quant/rich/emoney/util/DateUtils.java
Normal file
@@ -0,0 +1,58 @@
|
||||
package quant.rich.emoney.util;
|
||||
|
||||
import java.time.LocalDate;
|
||||
import java.time.LocalDateTime;
|
||||
import java.time.format.DateTimeFormatter;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
public final class DateUtils {
|
||||
|
||||
// 缓存 formatter,行为接近 fastjson2
|
||||
private static final Map<String, DateTimeFormatter> FORMATTER_CACHE =
|
||||
new ConcurrentHashMap<>();
|
||||
|
||||
private DateUtils() {
|
||||
}
|
||||
|
||||
/**
|
||||
* 格式化 LocalDateTime
|
||||
*
|
||||
* @param dateTime LocalDateTime
|
||||
* @param pattern 日期格式,如 yyyy-MM-dd HH:mm:ss
|
||||
* @return 格式化后的字符串
|
||||
*/
|
||||
public static String format(LocalDateTime dateTime, String pattern) {
|
||||
if (dateTime == null) {
|
||||
return null;
|
||||
}
|
||||
if (pattern == null || pattern.isEmpty()) {
|
||||
throw new IllegalArgumentException("pattern must not be null or empty");
|
||||
}
|
||||
|
||||
DateTimeFormatter formatter =
|
||||
FORMATTER_CACHE.computeIfAbsent(pattern, DateTimeFormatter::ofPattern);
|
||||
|
||||
return dateTime.format(formatter);
|
||||
}
|
||||
|
||||
/**
|
||||
* 将给定字符串转换成 LocalDate
|
||||
* @param value 如 "20260101"
|
||||
* @param pattern 日期格式,如 yyyyMMdd
|
||||
* @return
|
||||
*/
|
||||
public static LocalDate parse(String value, String pattern) {
|
||||
if (value == null) {
|
||||
return null;
|
||||
}
|
||||
if (pattern == null || pattern.isEmpty()) {
|
||||
throw new IllegalArgumentException("pattern must not be null or empty");
|
||||
}
|
||||
DateTimeFormatter formatter =
|
||||
FORMATTER_CACHE.computeIfAbsent(pattern, DateTimeFormatter::ofPattern);
|
||||
|
||||
LocalDate date = LocalDate.parse(value, formatter);
|
||||
return date;
|
||||
}
|
||||
}
|
||||
90
src/main/java/quant/rich/emoney/util/StockCodeUtils.java
Normal file
90
src/main/java/quant/rich/emoney/util/StockCodeUtils.java
Normal file
@@ -0,0 +1,90 @@
|
||||
package quant.rich.emoney.util;
|
||||
|
||||
public class StockCodeUtils {
|
||||
|
||||
/**
|
||||
* 从 goodsId 转换为 tsCode
|
||||
* @param goodsId
|
||||
* @return
|
||||
*/
|
||||
public static String goodsIdToTsCode(Integer goodsId) {
|
||||
if (goodsId == null || goodsId < 0) {
|
||||
throw new IllegalArgumentException("goodsId 不能为空或为负数");
|
||||
}
|
||||
|
||||
final String s = goodsId.toString();
|
||||
final int len = s.length();
|
||||
|
||||
switch (len) {
|
||||
case 6:
|
||||
// 6 位默认 SH
|
||||
return s + ".SH";
|
||||
|
||||
case 7:
|
||||
// 7 位默认 SZ 或 BJ
|
||||
if (!s.startsWith("1")) {
|
||||
throw new IllegalArgumentException("无法将 goodsId " + s + " 转换为 tsCode");
|
||||
}
|
||||
|
||||
char second = s.charAt(1);
|
||||
String core = s.substring(1);
|
||||
|
||||
if (second == '9') {
|
||||
return core + ".BJ";
|
||||
}
|
||||
return core + ".SZ";
|
||||
|
||||
default:
|
||||
throw new IllegalArgumentException("无法将 goodsId " + s + " 转换为 tsCode");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 从 tsCode 转换成 goodsId
|
||||
* @param tsCode
|
||||
* @return
|
||||
*/
|
||||
public static Integer tsCodeToGoodsId(String tsCode) {
|
||||
if (tsCode == null || tsCode.isBlank()) {
|
||||
throw new IllegalArgumentException("tsCode 不能为空");
|
||||
}
|
||||
|
||||
String s = tsCode.trim().toUpperCase();
|
||||
|
||||
// 期望格式:XXX.SZ / XXX.SH / XXX.BJ
|
||||
int dot = s.indexOf('.');
|
||||
if (dot <= 0 || dot == s.length() - 1) {
|
||||
throw new IllegalArgumentException("tsCode 格式无效: " + tsCode);
|
||||
}
|
||||
|
||||
String code = s.substring(0, dot);
|
||||
String market = s.substring(dot + 1);
|
||||
|
||||
if (!code.matches("\\d+")) {
|
||||
throw new IllegalArgumentException("tsCode 数字部分无效: " + tsCode);
|
||||
}
|
||||
|
||||
switch (market) {
|
||||
case "SH":
|
||||
if (code.length() == 6) {
|
||||
return Integer.valueOf(code);
|
||||
}
|
||||
break;
|
||||
|
||||
case "SZ":
|
||||
if (code.length() == 6) {
|
||||
return Integer.valueOf("1" + code);
|
||||
}
|
||||
break;
|
||||
|
||||
case "BJ":
|
||||
if (code.length() == 6) {
|
||||
return Integer.valueOf("1" + code);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
throw new IllegalArgumentException("无法将 tsCode " + tsCode + " 转换为 goodsId");
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user