|
|
@@ -14,6 +14,8 @@ import me.chanjar.weixin.cp.bean.message.WxCpMessage;
|
|
|
import me.chanjar.weixin.cp.bean.message.WxCpMessageSendResult;
|
|
|
import me.chanjar.weixin.cp.config.impl.WxCpDefaultConfigImpl;
|
|
|
import org.jsoup.Connection;
|
|
|
+import org.redisson.api.RLock;
|
|
|
+import org.redisson.api.RedissonClient;
|
|
|
import org.springframework.beans.factory.annotation.Autowired;
|
|
|
import org.springframework.scheduling.annotation.Async;
|
|
|
import org.springframework.stereotype.Service;
|
|
|
@@ -105,6 +107,12 @@ public class CoinServiceImpl implements CoinService {
|
|
|
@Resource
|
|
|
private CoinApiConfigMapper coinApiConfigMapper;
|
|
|
|
|
|
+ @Resource
|
|
|
+ private RedissonClient redissonClient;
|
|
|
+
|
|
|
+ @Resource
|
|
|
+ private RedisUtils redisUtils;
|
|
|
+
|
|
|
static {
|
|
|
// API KEY作为一个字符串。
|
|
|
basicHeaderMap.put("ACCESS-KEY", "bg_433d37306df0e8901c6d107c6d9e9111");
|
|
|
@@ -120,13 +128,13 @@ public class CoinServiceImpl implements CoinService {
|
|
|
basicHeaderMap.put("locale", "zh-CN");
|
|
|
|
|
|
// 字符串类型的APIKey
|
|
|
- basicHeaderMap4OKX.put("OK-ACCESS-KEY","25e4f515-5efd-4bb9-a934-3949b21d9f10");
|
|
|
+ basicHeaderMap4OKX.put("OK-ACCESS-KEY", "25e4f515-5efd-4bb9-a934-3949b21d9f10");
|
|
|
// 使用HMAC SHA256哈希函数获得哈希值,再使用Base-64编码(请参阅签名)
|
|
|
- basicHeaderMap4OKX.put("OK-ACCESS-SIGN","");
|
|
|
+ basicHeaderMap4OKX.put("OK-ACCESS-SIGN", "");
|
|
|
// 发起请求的时间(UTC),如:2020-12-08T09:08:57.715Z
|
|
|
- basicHeaderMap4OKX.put("OK-ACCESS-TIMESTAMP","");
|
|
|
+ basicHeaderMap4OKX.put("OK-ACCESS-TIMESTAMP", "");
|
|
|
// 您在创建API密钥时指定的Passphrase
|
|
|
- basicHeaderMap4OKX.put("OK-ACCESS-PASSPHRASE","tmvxeGY#Q#Y2qm8");
|
|
|
+ basicHeaderMap4OKX.put("OK-ACCESS-PASSPHRASE", "tmvxeGY#Q#Y2qm8");
|
|
|
// 统一设置为application/json
|
|
|
basicHeaderMap4OKX.put("Content-Type", "application/json");
|
|
|
|
|
|
@@ -451,6 +459,10 @@ public class CoinServiceImpl implements CoinService {
|
|
|
public String monitorJob() {
|
|
|
// BITGET开仓平仓监控报警
|
|
|
scheduler.scheduleWithFixedDelay(() -> {
|
|
|
+ if (!"1".equals(getMonitorJobStatus("bitget-mix-order"))) {
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
LocalDateTime endTime = LocalDateTime.now();
|
|
|
// 全部历史委托列表
|
|
|
Map<String, String> paramMap = new LinkedHashMap<>();
|
|
|
@@ -493,6 +505,10 @@ public class CoinServiceImpl implements CoinService {
|
|
|
|
|
|
// OKX开仓平仓监控报警
|
|
|
scheduler.scheduleWithFixedDelay(() -> {
|
|
|
+ if (!"1".equals(getMonitorJobStatus("okx-mix-order"))) {
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
LocalDateTime endTime = LocalDateTime.now();
|
|
|
// 查看历史持仓信息
|
|
|
Map<String, String> paramMap = new LinkedHashMap<>();
|
|
|
@@ -524,7 +540,11 @@ public class CoinServiceImpl implements CoinService {
|
|
|
}
|
|
|
}, 0, 10, TimeUnit.SECONDS);
|
|
|
|
|
|
- scheduler.scheduleAtFixedRate(() -> {
|
|
|
+ scheduler.scheduleWithFixedDelay(() -> {
|
|
|
+ if (!"1".equals(getMonitorJobStatus("bitget-mix-returnrate"))) {
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
// BITGET全部合约仓位信息V2
|
|
|
Map<String, String> paramMap = new HashMap<>();
|
|
|
paramMap.put("productType", "umcbl");
|
|
|
@@ -616,6 +636,10 @@ public class CoinServiceImpl implements CoinService {
|
|
|
|
|
|
// BITGET跟单员监控报警
|
|
|
scheduler.scheduleWithFixedDelay(() -> {
|
|
|
+ if (!"1".equals(getMonitorJobStatus("bitget-mix-trader"))) {
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
List<String> monitorTraderList = coinMapper.findMonitorTraderList();
|
|
|
forkJoinPool5.submit(() -> monitorTraderList.parallelStream().forEach(e -> {
|
|
|
LocalDateTime endTime = LocalDateTime.now();
|
|
|
@@ -660,7 +684,10 @@ public class CoinServiceImpl implements CoinService {
|
|
|
}, 0, 3, TimeUnit.SECONDS);
|
|
|
|
|
|
// 星球日报新闻快讯监控报警
|
|
|
- /*scheduler.scheduleWithFixedDelay(() -> {
|
|
|
+ scheduler.scheduleWithFixedDelay(() -> {
|
|
|
+ if (!"1".equals(getMonitorJobStatus("news-odaily"))) {
|
|
|
+ return;
|
|
|
+ }
|
|
|
try {
|
|
|
Connection.Response response = JsoupUtil.requestBody("https://www.odaily.news/v1/openapi/feeds", JsoupUtil.HTTP_GET, InitRunner.proxy, null, null);
|
|
|
JSONObject result = JSONObject.parseObject(response.body());
|
|
|
@@ -709,10 +736,13 @@ public class CoinServiceImpl implements CoinService {
|
|
|
}
|
|
|
} catch (Exception e) {
|
|
|
}
|
|
|
- }, 0, 3, TimeUnit.SECONDS);*/
|
|
|
+ }, 0, 3, TimeUnit.SECONDS);
|
|
|
|
|
|
// 律动日报新闻快讯监控报警
|
|
|
scheduler.scheduleWithFixedDelay(() -> {
|
|
|
+ if (!"1".equals(getMonitorJobStatus("news-theblockbeats"))) {
|
|
|
+ return;
|
|
|
+ }
|
|
|
try {
|
|
|
Map<String, String> paramMap = new HashMap<>();
|
|
|
paramMap.put("size", "10");
|
|
|
@@ -789,6 +819,10 @@ public class CoinServiceImpl implements CoinService {
|
|
|
|
|
|
// coingecko
|
|
|
scheduler.scheduleAtFixedRate(() -> {
|
|
|
+ if (!"1".equals(getMonitorJobStatus("watchlist-coingecko-cmc"))) {
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
Map<String, Object> params = new HashMap<>();
|
|
|
params.put("sortField", "create_time");
|
|
|
params.put("sort", "desc");
|
|
|
@@ -803,6 +837,9 @@ public class CoinServiceImpl implements CoinService {
|
|
|
|
|
|
// Upbit交易所监控报警
|
|
|
scheduler.scheduleWithFixedDelay(() -> {
|
|
|
+ if (!"1".equals(getMonitorJobStatus("upbit-digitalasset-notices"))) {
|
|
|
+ return;
|
|
|
+ }
|
|
|
try {
|
|
|
Map<String, String> paramMap = new HashMap<>();
|
|
|
paramMap.put("page", "1");
|
|
|
@@ -1288,7 +1325,7 @@ public class CoinServiceImpl implements CoinService {
|
|
|
|
|
|
renderMainSearch4CmcMap(cmcMapList);
|
|
|
return cmcMapPageInfo;
|
|
|
- }else if (params.getString("nameEn").equals("monitorCurrency")) {
|
|
|
+ } else if (params.getString("nameEn").equals("monitorCurrency")) {
|
|
|
List<CoinMonitorCurrency> monitorCurrencyList = coinMapper.findMonitorCurrencyList();
|
|
|
|
|
|
Map<String, JSONArray> resultMulti = new ConcurrentHashMap<>();
|
|
|
@@ -1569,16 +1606,16 @@ public class CoinServiceImpl implements CoinService {
|
|
|
String symbol = jsonObject.getString("symbol").replace("USDT_UMCBL", "");
|
|
|
jsonObject.put("symbol", "<strong style=\"background-color:#F1B90d;\"><font color=\"#242A30\">" + symbol + "</font></strong>USDT_UMCBL");
|
|
|
// 标记价格
|
|
|
- jsonObject.put("close",jsonObject.getString("last"));
|
|
|
+ jsonObject.put("close", jsonObject.getString("last"));
|
|
|
jsonObject.put("closeStyle", " style=\"color:#252B31;background-color:#C4ADE9;font-weight:bold;\"");
|
|
|
// 基础币量 计价币量 usdt币量
|
|
|
jsonObject.put("baseVol", readableFileSize(jsonObject.getDouble("baseVolume")));
|
|
|
jsonObject.put("quoteVol", readableFileSize(jsonObject.getDouble("quoteVolume")));
|
|
|
jsonObject.put("usdtVol", readableFileSize(jsonObject.getDouble("quoteVolume")));
|
|
|
// 其他字段兼容
|
|
|
- jsonObject.put("openUtc0",jsonObject.getString("openUtc"));
|
|
|
- jsonObject.put("buyOne",jsonObject.getString("bestBid"));
|
|
|
- jsonObject.put("sellOne",jsonObject.getString("bestAsk"));
|
|
|
+ jsonObject.put("openUtc0", jsonObject.getString("openUtc"));
|
|
|
+ jsonObject.put("buyOne", jsonObject.getString("bestBid"));
|
|
|
+ jsonObject.put("sellOne", jsonObject.getString("bestAsk"));
|
|
|
})).join();
|
|
|
|
|
|
array4Spot.addAll(array4Mix);
|
|
|
@@ -1788,4 +1825,55 @@ public class CoinServiceImpl implements CoinService {
|
|
|
int digitGroups = (int) (Math.log10(size) / Math.log10(1000));
|
|
|
return df1.format(size / Math.pow(1000, digitGroups)) + units[digitGroups];
|
|
|
}
|
|
|
+
|
|
|
+ public String getMonitorJobStatus(String jobName) {
|
|
|
+ Map<String, JSONObject> monitorJobConfig = getMonitorJobConfig();
|
|
|
+ if (null != monitorJobConfig && monitorJobConfig.containsKey(jobName)) {
|
|
|
+ return monitorJobConfig.get(jobName).getString("job_status");
|
|
|
+ }
|
|
|
+ return null;
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public Map<String, JSONObject> getMonitorJobConfig() {
|
|
|
+ String cacheKey = "coin:monitor:job:list";
|
|
|
+
|
|
|
+ // 1. 缓存有,直接返回
|
|
|
+ if (redisUtils.hasKey(cacheKey) && redisUtils.get(cacheKey) != null) {
|
|
|
+ return (Map<String, JSONObject>) redisUtils.get(cacheKey);
|
|
|
+ }
|
|
|
+
|
|
|
+ // 加锁防止同时对一个数据发送多次请求
|
|
|
+ RLock lock = redissonClient.getLock("lock:" + cacheKey);
|
|
|
+ try {
|
|
|
+ // 2. 尝试加分布式锁,最多等待30秒,上锁以后60秒自动解锁
|
|
|
+ boolean lockFlag = lock.tryLock(30, 60, TimeUnit.SECONDS);
|
|
|
+ if (lockFlag) {
|
|
|
+ // 3. 加锁成功,二次检查,缓存有,直接返回
|
|
|
+ if (redisUtils.hasKey(cacheKey) && redisUtils.get(cacheKey) != null) {
|
|
|
+ return (Map<String, JSONObject>) redisUtils.get(cacheKey);
|
|
|
+ }
|
|
|
+
|
|
|
+ // 4. 查数据库,并且按给定的时长加到缓存中
|
|
|
+ Map<String, JSONObject> monitorJobConfigMap = coinMapper.findMonitorJobConfig();
|
|
|
+
|
|
|
+ // 缓存监控任务配置信息
|
|
|
+ if (monitorJobConfigMap != null) {
|
|
|
+ redisUtils.set(cacheKey, monitorJobConfigMap, 60, TimeUnit.MINUTES);
|
|
|
+ }
|
|
|
+
|
|
|
+ return monitorJobConfigMap;
|
|
|
+ } else {
|
|
|
+ log.error("getMonitorJobConfig 加锁失败 error,lockFlag: false");
|
|
|
+ return null;
|
|
|
+ }
|
|
|
+ } catch (Exception e) {
|
|
|
+ log.error("getMonitorJobConfig Exception", e);
|
|
|
+ return null;
|
|
|
+ } finally {
|
|
|
+ if (lock.isLocked() && lock.isHeldByCurrentThread()) {
|
|
|
+ lock.unlock();
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
}
|