file-parse

This commit is contained in:
N1KO 2024-12-19 20:13:33 +08:00
parent bbc1258a40
commit 1b710c56d6
41 changed files with 646 additions and 622 deletions

View File

@ -81,18 +81,18 @@
</dependency> </dependency>
<!-- Sa-Token 权限认证在线文档https://sa-token.cc --> <!-- Sa-Token 权限认证在线文档https://sa-token.cc -->
<dependency> <!-- <dependency>-->
<groupId>cn.dev33</groupId> <!-- <groupId>cn.dev33</groupId>-->
<artifactId>sa-token-spring-boot-starter</artifactId> <!-- <artifactId>sa-token-spring-boot-starter</artifactId>-->
<version>1.34.0</version> <!-- <version>1.34.0</version>-->
</dependency> <!-- </dependency>-->
<!-- Sa-Token 插件整合SSO --> <!-- Sa-Token 插件整合SSO -->
<dependency> <!-- <dependency>-->
<groupId>cn.dev33</groupId> <!-- <groupId>cn.dev33</groupId>-->
<artifactId>sa-token-sso</artifactId> <!-- <artifactId>sa-token-sso</artifactId>-->
<version>1.34.0</version> <!-- <version>1.34.0</version>-->
</dependency> <!-- </dependency>-->
<dependency> <dependency>
<groupId>com.dtflys.forest</groupId> <groupId>com.dtflys.forest</groupId>

View File

@ -1,31 +1,31 @@
package top.baogutang.admin.config; //package top.baogutang.admin.config;
//
import cn.dev33.satoken.exception.NotLoginException; //import cn.dev33.satoken.exception.NotLoginException;
import lombok.extern.slf4j.Slf4j; //import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.ExceptionHandler; //import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice; //import org.springframework.web.bind.annotation.RestControllerAdvice;
import top.baogutang.common.domain.Results; //import top.baogutang.common.domain.Results;
//
/** ///**
* @description: 全局异常处理 // * @description: 全局异常处理
* @author: nikooh // * @author: nikooh
* @date: 2023/06/15 : 12:23 // * @date: 2023/06/15 : 12:23
*/ // */
@Slf4j //@Slf4j
@RestControllerAdvice //@RestControllerAdvice
public class SysGlobalExceptionHandler { //public class SysGlobalExceptionHandler {
//
//
public SysGlobalExceptionHandler() { // public SysGlobalExceptionHandler() {
// // //
} // }
//
//
@ExceptionHandler({NotLoginException.class}) // @ExceptionHandler({NotLoginException.class})
public Results<Object> businessNotLoginException(NotLoginException e) { // public Results<Object> businessNotLoginException(NotLoginException e) {
log.error("请求发生错误code:{},message:{}", e.getCode(), e.getMessage()); // log.error("请求发生错误code:{},message:{}", e.getCode(), e.getMessage());
return Results.failed(e.getCode(), e.getMessage()); // return Results.failed(e.getCode(), e.getMessage());
} // }
//
//
} //}

View File

@ -0,0 +1,18 @@
package top.baogutang.admin.config;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
@Configuration
public class WebConfig implements WebMvcConfigurer {
@Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
registry.addResourceHandler("/**")
.addResourceLocations("classpath:/static/");
registry.addResourceHandler("/file-parse/**")
.addResourceLocations("classpath:/static/");
}
}

View File

@ -1,24 +1,24 @@
package top.baogutang.admin.config; //package top.baogutang.admin.config;
//
import org.springframework.context.annotation.Configuration; //import org.springframework.context.annotation.Configuration;
import org.springframework.web.socket.config.annotation.EnableWebSocket; //import org.springframework.web.socket.config.annotation.EnableWebSocket;
import org.springframework.web.socket.config.annotation.WebSocketConfigurer; //import org.springframework.web.socket.config.annotation.WebSocketConfigurer;
import org.springframework.web.socket.config.annotation.WebSocketHandlerRegistry; //import org.springframework.web.socket.config.annotation.WebSocketHandlerRegistry;
import top.baogutang.admin.handlers.KlineWebSocketHandler; //import top.baogutang.admin.handlers.KlineWebSocketHandler;
//
import javax.annotation.Resource; //import javax.annotation.Resource;
//
@Configuration //@Configuration
@EnableWebSocket //@EnableWebSocket
public class WebSocketConfig implements WebSocketConfigurer { //public class WebSocketConfig implements WebSocketConfigurer {
//
@Resource // @Resource
private KlineWebSocketHandler klineWebSocketHandler; // private KlineWebSocketHandler klineWebSocketHandler;
//
@Override // @Override
public void registerWebSocketHandlers(WebSocketHandlerRegistry registry) { // public void registerWebSocketHandlers(WebSocketHandlerRegistry registry) {
registry.addHandler(klineWebSocketHandler, "/ws") // registry.addHandler(klineWebSocketHandler, "/ws")
// 配置 WebSocket 端点并允许跨域 // // 配置 WebSocket 端点并允许跨域
.setAllowedOrigins("*"); // .setAllowedOrigins("*");
} // }
} //}

View File

@ -1,73 +1,73 @@
package top.baogutang.admin.controller; //package top.baogutang.admin.controller;
//
import cn.dev33.satoken.annotation.SaCheckLogin; //import cn.dev33.satoken.annotation.SaCheckLogin;
import cn.dev33.satoken.stp.SaTokenInfo; //import cn.dev33.satoken.stp.SaTokenInfo;
import cn.hutool.core.lang.PatternPool; //import cn.hutool.core.lang.PatternPool;
import cn.hutool.core.lang.Validator; //import cn.hutool.core.lang.Validator;
import lombok.extern.slf4j.Slf4j; //import lombok.extern.slf4j.Slf4j;
import org.springframework.validation.annotation.Validated; //import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.PostMapping; //import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody; //import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping; //import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController; //import org.springframework.web.bind.annotation.RestController;
import top.baogutang.admin.domain.req.SysUserLoginReq; //import top.baogutang.admin.domain.req.SysUserLoginReq;
import top.baogutang.admin.domain.req.SysUserRegisterReq; //import top.baogutang.admin.domain.req.SysUserRegisterReq;
import top.baogutang.admin.services.ISysUserService; //import top.baogutang.admin.services.ISysUserService;
import top.baogutang.common.domain.Results; //import top.baogutang.common.domain.Results;
//
import javax.annotation.Resource; //import javax.annotation.Resource;
//
/** ///**
* @description: 后台用户控制器 // * @description: 后台用户控制器
* @author: nikooh // * @author: nikooh
* @date: 2023/06/19 : 11:57 // * @date: 2023/06/19 : 11:57
*/ // */
@Slf4j //@Slf4j
@RestController //@RestController
@RequestMapping("/api/v1/admin/sysUser") //@RequestMapping("/api/v1/admin/sysUser")
public class SysUserController { //public class SysUserController {
//
@Resource // @Resource
private ISysUserService sysUserService; // private ISysUserService sysUserService;
//
/** // /**
* 后台系统用户注册 // * 后台系统用户注册
* // *
* @param sysUserRegisterReq 注册请求参数 // * @param sysUserRegisterReq 注册请求参数
* @return 注册结果 // * @return 注册结果
*/ // */
@PostMapping("register") // @PostMapping("register")
public Results<Void> register(@Validated @RequestBody SysUserRegisterReq sysUserRegisterReq) { // public Results<Void> register(@Validated @RequestBody SysUserRegisterReq sysUserRegisterReq) {
if (!Validator.isMatchRegex(PatternPool.EMAIL, sysUserRegisterReq.getEmail())) { // if (!Validator.isMatchRegex(PatternPool.EMAIL, sysUserRegisterReq.getEmail())) {
return Results.failed("邮箱格式不正确!"); // return Results.failed("邮箱格式不正确!");
} // }
if (!Validator.isMatchRegex(PatternPool.MOBILE, sysUserRegisterReq.getMobile())) { // if (!Validator.isMatchRegex(PatternPool.MOBILE, sysUserRegisterReq.getMobile())) {
return Results.failed("手机号格式不正确!"); // return Results.failed("手机号格式不正确!");
} // }
sysUserService.register(sysUserRegisterReq); // sysUserService.register(sysUserRegisterReq);
return Results.ok(); // return Results.ok();
} // }
//
/** // /**
* 登陆接口 // * 登陆接口
* // *
* @param sysUserLoginReq 登陆请求参数 // * @param sysUserLoginReq 登陆请求参数
* @return 登陆用户信息 // * @return 登陆用户信息
*/ // */
@PostMapping("/login") // @PostMapping("/login")
public Results<SaTokenInfo> login(@RequestBody SysUserLoginReq sysUserLoginReq) { // public Results<SaTokenInfo> login(@RequestBody SysUserLoginReq sysUserLoginReq) {
return Results.ok(sysUserService.login(sysUserLoginReq)); // return Results.ok(sysUserService.login(sysUserLoginReq));
} // }
//
/** // /**
* 登出接口 // * 登出接口
*/ // */
@PostMapping("/logout") // @PostMapping("/logout")
@SaCheckLogin // @SaCheckLogin
public Results<Void> logout() { // public Results<Void> logout() {
sysUserService.logout(); // sysUserService.logout();
return Results.ok(); // return Results.ok();
} // }
//
//
} //}

View File

@ -1,48 +1,48 @@
package top.baogutang.admin.controller; //package top.baogutang.admin.controller;
//
import org.springframework.web.bind.annotation.GetMapping; //import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping; //import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam; //import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController; //import org.springframework.web.bind.annotation.RestController;
import top.baogutang.admin.domain.res.MarketCandlesRes; //import top.baogutang.admin.domain.res.MarketCandlesRes;
import top.baogutang.admin.services.IVirtualCoinService; //import top.baogutang.admin.services.IVirtualCoinService;
import top.baogutang.common.domain.Results; //import top.baogutang.common.domain.Results;
//
import javax.annotation.Resource; //import javax.annotation.Resource;
import java.text.SimpleDateFormat; //import java.text.SimpleDateFormat;
import java.util.Collections; //import java.util.Collections;
import java.util.Comparator; //import java.util.Comparator;
import java.util.List; //import java.util.List;
import java.util.stream.Collectors; //import java.util.stream.Collectors;
//
/** ///**
* @description: // * @description:
* @author: nikooh // * @author: nikooh
* @date: 2024/08/23 : 17:29 // * @date: 2024/08/23 : 17:29
*/ // */
@RestController //@RestController
@RequestMapping("/api/v1/admin/virtualCoin") //@RequestMapping("/api/v1/admin/virtualCoin")
public class VirtualCoinController { //public class VirtualCoinController {
//
@Resource // @Resource
private IVirtualCoinService virtualCoinService; // private IVirtualCoinService virtualCoinService;
//
private static final SimpleDateFormat DATE_FORMAT = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); // private static final SimpleDateFormat DATE_FORMAT = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
//
@GetMapping("/uiKline") // @GetMapping("/uiKline")
public Results<List<String[]>> uiKline(@RequestParam(name = "symbol") String symbol, // public Results<List<String[]>> uiKline(@RequestParam(name = "symbol") String symbol,
@RequestParam(name = "interval") String interval) { // @RequestParam(name = "interval") String interval) {
return Results.ok(virtualCoinService.uiKline(symbol, interval)); // return Results.ok(virtualCoinService.uiKline(symbol, interval));
} // }
//
@GetMapping("/uiKlineData") // @GetMapping("/uiKlineData")
public Results<List<MarketCandlesRes.KLineData>> uiKlineData(@RequestParam(name = "symbol") String symbol, // public Results<List<MarketCandlesRes.KLineData>> uiKlineData(@RequestParam(name = "symbol") String symbol,
@RequestParam(name = "interval") String interval) { // @RequestParam(name = "interval") String interval) {
List<MarketCandlesRes.KLineData> kLineDataList = virtualCoinService.uiKline(symbol, interval).stream() // List<MarketCandlesRes.KLineData> kLineDataList = virtualCoinService.uiKline(symbol, interval).stream()
.sorted(Collections.reverseOrder(Comparator.comparingLong(data -> Long.parseLong(data[0])))) // .sorted(Collections.reverseOrder(Comparator.comparingLong(data -> Long.parseLong(data[0]))))
.limit(5) // .limit(5)
.map(data -> MarketCandlesRes.KLineData.newInstance(data, DATE_FORMAT)) // .map(data -> MarketCandlesRes.KLineData.newInstance(data, DATE_FORMAT))
.collect(Collectors.toList()); // .collect(Collectors.toList());
return Results.ok(kLineDataList); // return Results.ok(kLineDataList);
} // }
} //}

View File

@ -1,98 +1,98 @@
package top.baogutang.admin.handlers; //package top.baogutang.admin.handlers;
//
import com.binance.connector.client.WebSocketStreamClient; //import com.binance.connector.client.WebSocketStreamClient;
import lombok.Data; //import lombok.Data;
import lombok.extern.slf4j.Slf4j; //import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component; //import org.springframework.stereotype.Component;
import org.springframework.util.CollectionUtils; //import org.springframework.util.CollectionUtils;
import org.springframework.web.socket.*; //import org.springframework.web.socket.*;
import top.baogutang.common.utils.JacksonUtil; //import top.baogutang.common.utils.JacksonUtil;
//
import javax.annotation.Resource; //import javax.annotation.Resource;
import java.io.IOException; //import java.io.IOException;
import java.io.Serializable; //import java.io.Serializable;
import java.util.Map; //import java.util.Map;
import java.util.Objects; //import java.util.Objects;
import java.util.concurrent.ConcurrentHashMap; //import java.util.concurrent.ConcurrentHashMap;
//
@Slf4j //@Slf4j
@Component //@Component
public class KlineWebSocketHandler implements WebSocketHandler { //public class KlineWebSocketHandler implements WebSocketHandler {
//
@Resource // @Resource
private WebSocketStreamClient webSocketStreamClient; // private WebSocketStreamClient webSocketStreamClient;
//
private final Map<String, WebSocketSession> webSocketMap = new ConcurrentHashMap<>(); // private final Map<String, WebSocketSession> webSocketMap = new ConcurrentHashMap<>();
//
private volatile Integer connectionId; // private volatile Integer connectionId;
//
@Override // @Override
public void afterConnectionEstablished(WebSocketSession webSocketSession) throws Exception { // public void afterConnectionEstablished(WebSocketSession webSocketSession) throws Exception {
//连接成功时调用该方法 // //连接成功时调用该方法
log.info(">>>>>>>>>>WebSocket connected:{}<<<<<<<<<<", webSocketSession.getId()); // log.info(">>>>>>>>>>WebSocket connected:{}<<<<<<<<<<", webSocketSession.getId());
webSocketMap.put(webSocketSession.getId(), webSocketSession); // webSocketMap.put(webSocketSession.getId(), webSocketSession);
} // }
//
@Override // @Override
public void handleMessage(WebSocketSession webSocketSession, WebSocketMessage<?> webSocketMessage) throws Exception { // public void handleMessage(WebSocketSession webSocketSession, WebSocketMessage<?> webSocketMessage) throws Exception {
// 获取客户端发送的消息 // // 获取客户端发送的消息
log.info(">>>>>>>>>>客户端ID:{} 发送消息:{}<<<<<<<<<<", webSocketSession.getId(), webSocketMessage.getPayload()); // log.info(">>>>>>>>>>客户端ID:{} 发送消息:{}<<<<<<<<<<", webSocketSession.getId(), webSocketMessage.getPayload());
KlineMessage message = JacksonUtil.fromJson(webSocketMessage.getPayload().toString(), KlineMessage.class); // KlineMessage message = JacksonUtil.fromJson(webSocketMessage.getPayload().toString(), KlineMessage.class);
if (Objects.nonNull(connectionId)) { // if (Objects.nonNull(connectionId)) {
webSocketStreamClient.closeConnection(connectionId); // webSocketStreamClient.closeConnection(connectionId);
} // }
// 使用 Binance Connector 开启 WebSocket 连接 // // 使用 Binance Connector 开启 WebSocket 连接
connectionId = webSocketStreamClient.klineStream(message.getSymbol(), message.getInterval(), event -> { // connectionId = webSocketStreamClient.klineStream(message.getSymbol(), message.getInterval(), event -> {
log.info(">>>>>>>>>>binance event:{}<<<<<<<<<<", event); // log.info(">>>>>>>>>>binance event:{}<<<<<<<<<<", event);
// 将从 Binance 接收到的数据转发给前端 // // 将从 Binance 接收到的数据转发给前端
TextMessage textMessage = new TextMessage(event); // TextMessage textMessage = new TextMessage(event);
//
// 推送消息给所有连接的客户端 // // 推送消息给所有连接的客户端
webSocketMap.entrySet() // webSocketMap.entrySet()
.stream() // .stream()
.filter(entry -> entry.getValue().isOpen()) // .filter(entry -> entry.getValue().isOpen())
.forEach(entry -> { // .forEach(entry -> {
try { // try {
entry.getValue().sendMessage(textMessage); // entry.getValue().sendMessage(textMessage);
} catch (IOException e) { // } catch (IOException e) {
log.error(">>>>>>>>>>消息发送错误:{}<<<<<<<<<<", e.getMessage(), e); // log.error(">>>>>>>>>>消息发送错误:{}<<<<<<<<<<", e.getMessage(), e);
} // }
}); // });
}); // });
log.info(">>>>>>>>>启动了 Binance WebSocket 连接: {} , 监控交易对: {} 时间间隔: {}<<<<<<<<", connectionId, message.getSymbol(), message.getInterval()); // log.info(">>>>>>>>>启动了 Binance WebSocket 连接: {} , 监控交易对: {} 时间间隔: {}<<<<<<<<", connectionId, message.getSymbol(), message.getInterval());
} // }
//
@Override // @Override
public void handleTransportError(WebSocketSession webSocketSession, Throwable throwable) throws Exception { // public void handleTransportError(WebSocketSession webSocketSession, Throwable throwable) throws Exception {
//发生错误时调用该方法 // //发生错误时调用该方法
log.error(">>>>>>>>>>WebSocket error: {}<<<<<<<<<<", throwable.getMessage(), throwable); // log.error(">>>>>>>>>>WebSocket error: {}<<<<<<<<<<", throwable.getMessage(), throwable);
webSocketSession.close(CloseStatus.SERVER_ERROR); // webSocketSession.close(CloseStatus.SERVER_ERROR);
webSocketMap.remove(webSocketSession.getId()); // webSocketMap.remove(webSocketSession.getId());
} // }
//
@Override // @Override
public void afterConnectionClosed(WebSocketSession webSocketSession, CloseStatus closeStatus) throws Exception { // public void afterConnectionClosed(WebSocketSession webSocketSession, CloseStatus closeStatus) throws Exception {
//连接关闭时调用该方法 // //连接关闭时调用该方法
log.info(">>>>>>>>>>WebSocket closed:{}<<<<<<<<<<", webSocketSession.getId()); // log.info(">>>>>>>>>>WebSocket closed:{}<<<<<<<<<<", webSocketSession.getId());
webSocketMap.remove(webSocketSession.getId()); // webSocketMap.remove(webSocketSession.getId());
if (CollectionUtils.isEmpty(webSocketMap)) { // if (CollectionUtils.isEmpty(webSocketMap)) {
log.info(">>>>>>>>>>client session all closed!<<<<<<<<<<"); // log.info(">>>>>>>>>>client session all closed!<<<<<<<<<<");
webSocketStreamClient.closeAllConnections(); // webSocketStreamClient.closeAllConnections();
} // }
} // }
//
@Override // @Override
public boolean supportsPartialMessages() { // public boolean supportsPartialMessages() {
return false; // return false;
} // }
//
@Data // @Data
public static class KlineMessage implements Serializable { // public static class KlineMessage implements Serializable {
//
private static final long serialVersionUID = -3288071423561766084L; // private static final long serialVersionUID = -3288071423561766084L;
//
private String symbol; // private String symbol;
//
private String interval; // private String interval;
} // }
} //}

View File

@ -1,122 +1,122 @@
package top.baogutang.admin.schedule; //package top.baogutang.admin.schedule;
//
import cn.hutool.core.bean.BeanUtil; //import cn.hutool.core.bean.BeanUtil;
import com.binance.connector.client.SpotClient; //import com.binance.connector.client.SpotClient;
import com.fasterxml.jackson.core.type.TypeReference; //import com.fasterxml.jackson.core.type.TypeReference;
import com.xxl.job.core.biz.model.ReturnT; //import com.xxl.job.core.biz.model.ReturnT;
import com.xxl.job.core.handler.IJobHandler; //import com.xxl.job.core.handler.IJobHandler;
import com.xxl.job.core.handler.annotation.XxlJob; //import com.xxl.job.core.handler.annotation.XxlJob;
import lombok.Data; //import lombok.Data;
import lombok.extern.slf4j.Slf4j; //import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils; //import org.apache.commons.lang3.StringUtils;
import org.springframework.cloud.context.config.annotation.RefreshScope; //import org.springframework.cloud.context.config.annotation.RefreshScope;
import org.springframework.stereotype.Component; //import org.springframework.stereotype.Component;
import top.baogutang.admin.utils.DingTalkMsgPushUtils; //import top.baogutang.admin.utils.DingTalkMsgPushUtils;
import top.baogutang.admin.utils.OkCoinKLineUtil; //import top.baogutang.admin.utils.OkCoinKLineUtil;
import top.baogutang.common.domain.BinanceResults; //import top.baogutang.common.domain.BinanceResults;
import top.baogutang.common.utils.JacksonUtil; //import top.baogutang.common.utils.JacksonUtil;
//
import javax.annotation.Resource; //import javax.annotation.Resource;
import java.text.SimpleDateFormat; //import java.text.SimpleDateFormat;
import java.util.*; //import java.util.*;
import java.util.stream.Collectors; //import java.util.stream.Collectors;
//
/** ///**
* @description: OKCOIN K线数据 // * @description: OKCOIN K线数据
* @author: nikooh // * @author: nikooh
* @date: 2024/08/22 : 09:52 // * @date: 2024/08/22 : 09:52
*/ // */
@Slf4j //@Slf4j
@Component //@Component
@RefreshScope //@RefreshScope
public class OkCoinMarketCandlesHandler extends IJobHandler { //public class OkCoinMarketCandlesHandler extends IJobHandler {
//
@Resource // @Resource
private DingTalkMsgPushUtils dingTalkMsgPushUtils; // private DingTalkMsgPushUtils dingTalkMsgPushUtils;
//
@Resource // @Resource
private SpotClient spotClient; // private SpotClient spotClient;
//
public static final SimpleDateFormat DATE_FORMAT = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss:SSS"); // public static final SimpleDateFormat DATE_FORMAT = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss:SSS");
//
@Override // @Override
@XxlJob("marketCandlesHandler") // @XxlJob("marketCandlesHandler")
public ReturnT<String> execute(String params) throws Exception { // public ReturnT<String> execute(String params) throws Exception {
//
//
if (StringUtils.isBlank(params)) { // if (StringUtils.isBlank(params)) {
log.error(">>>>>>>>>>job params is null!<<<<<<<<<<"); // log.error(">>>>>>>>>>job params is null!<<<<<<<<<<");
return ReturnT.FAIL; // return ReturnT.FAIL;
} // }
JobParams jobParams = JacksonUtil.fromJson(params, JobParams.class); // JobParams jobParams = JacksonUtil.fromJson(params, JobParams.class);
if (Objects.isNull(jobParams)) { // if (Objects.isNull(jobParams)) {
log.error(">>>>>>>>>>job params is null!<<<<<<<<<<"); // log.error(">>>>>>>>>>job params is null!<<<<<<<<<<");
return ReturnT.FAIL; // return ReturnT.FAIL;
} // }
String interval = jobParams.getInterval(); // String interval = jobParams.getInterval();
Integer limit = jobParams.getLimit(); // Integer limit = jobParams.getLimit();
Arrays.stream(jobParams.getSymbolList().split(",")) // Arrays.stream(jobParams.getSymbolList().split(","))
.forEach(symbol -> { // .forEach(symbol -> {
KLinesRequestParameters kLinesRequestParameters = new KLinesRequestParameters(symbol, interval, limit); // KLinesRequestParameters kLinesRequestParameters = new KLinesRequestParameters(symbol, interval, limit);
Map<String, Object> parameters = BeanUtil.beanToMap(kLinesRequestParameters); // Map<String, Object> parameters = BeanUtil.beanToMap(kLinesRequestParameters);
String resultStr = spotClient.createMarket().uiKlines(parameters); // String resultStr = spotClient.createMarket().uiKlines(parameters);
if (StringUtils.isBlank(resultStr)) { // if (StringUtils.isBlank(resultStr)) {
log.error(">>>>>>>>>>request result is null!<<<<<<<<<<"); // log.error(">>>>>>>>>>request result is null!<<<<<<<<<<");
return; // return;
} // }
List<String[]> kLineDataList = JacksonUtil.fromJson(resultStr, new TypeReference<List<String[]>>() { // List<String[]> kLineDataList = JacksonUtil.fromJson(resultStr, new TypeReference<List<String[]>>() {
}); // });
String[] kLineData = kLineDataList.get(0); // String[] kLineData = kLineDataList.get(0);
log.info(">>>>>>>>>>当前:【{}】 开盘价:【{}】 最高价:【{}】最低价:【{}】收盘价:【{}】<<<<<<<<<<", DATE_FORMAT.format(new Date(Long.parseLong(kLineData[0]))), kLineData[1], kLineData[2], kLineData[3], kLineData[4]); // log.info(">>>>>>>>>>当前:【{}】 开盘价:【{}】 最高价:【{}】最低价:【{}】收盘价:【{}】<<<<<<<<<<", DATE_FORMAT.format(new Date(Long.parseLong(kLineData[0]))), kLineData[1], kLineData[2], kLineData[3], kLineData[4]);
kLineDataList = kLineDataList.stream() // kLineDataList = kLineDataList.stream()
.sorted(Comparator.comparing(data -> data[0], Comparator.reverseOrder())) // .sorted(Comparator.comparing(data -> data[0], Comparator.reverseOrder()))
.limit(5) // .limit(5)
.collect(Collectors.toList()); // .collect(Collectors.toList());
String markdownContent = OkCoinKLineUtil.getCoinMarkdownContent(symbol, kLineDataList); // String markdownContent = OkCoinKLineUtil.getCoinMarkdownContent(symbol, kLineDataList);
dingTalkMsgPushUtils.robotMarkdownMsg("交易产品K线数据", markdownContent); // dingTalkMsgPushUtils.robotMarkdownMsg("交易产品K线数据", markdownContent);
//
}); // });
//
//
return ReturnT.SUCCESS; // return ReturnT.SUCCESS;
} // }
//
@Data // @Data
public static class JobParams { // public static class JobParams {
//
// BTCUSDT,ETHUSDT // // BTCUSDT,ETHUSDT
private String symbolList; // private String symbolList;
//
// 时间粒度 // // 时间粒度
// 1s, 1m, 3m, 5m, 15m, 30m, 1h, 2h, 4h, 6h, 8h, 12h, 1d, 3d, 1w, 1M // // 1s, 1m, 3m, 5m, 15m, 30m, 1h, 2h, 4h, 6h, 8h, 12h, 1d, 3d, 1w, 1M
private String interval; // private String interval;
//
// 默认 500; 最大值 1000 // // 默认 500; 最大值 1000
private Integer limit; // private Integer limit;
} // }
//
@Data // @Data
public static class KLinesRequestParameters { // public static class KLinesRequestParameters {
//
// BTCUSDT,ETHUSDT // // BTCUSDT,ETHUSDT
private String symbol; // private String symbol;
//
// 1s, 1m, 3m, 5m, 15m, 30m, 1h, 2h, 4h, 6h, 8h, 12h, 1d, 3d, 1w, 1M // // 1s, 1m, 3m, 5m, 15m, 30m, 1h, 2h, 4h, 6h, 8h, 12h, 1d, 3d, 1w, 1M
private String interval; // private String interval;
//
// 默认 500; 最大值 1000 // // 默认 500; 最大值 1000
private Integer limit; // private Integer limit;
//
public KLinesRequestParameters(String symbol, String interval, Integer limit) { // public KLinesRequestParameters(String symbol, String interval, Integer limit) {
this.symbol = symbol; // this.symbol = symbol;
this.interval = interval; // this.interval = interval;
this.limit = limit; // this.limit = limit;
} // }
//
public KLinesRequestParameters(String symbol, String interval) { // public KLinesRequestParameters(String symbol, String interval) {
this.symbol = symbol; // this.symbol = symbol;
this.interval = interval; // this.interval = interval;
} // }
} // }
//
} //}

View File

@ -1,34 +1,34 @@
package top.baogutang.admin.services; //package top.baogutang.admin.services;
//
import cn.dev33.satoken.stp.SaTokenInfo; //import cn.dev33.satoken.stp.SaTokenInfo;
import top.baogutang.admin.domain.req.SysUserLoginReq; //import top.baogutang.admin.domain.req.SysUserLoginReq;
import top.baogutang.admin.domain.req.SysUserRegisterReq; //import top.baogutang.admin.domain.req.SysUserRegisterReq;
import top.baogutang.admin.domain.res.SysUserInfo; //import top.baogutang.admin.domain.res.SysUserInfo;
//
/** ///**
* @description: // * @description:
* @author: nikooh // * @author: nikooh
* @date: 2023/06/19 : 12:13 // * @date: 2023/06/19 : 12:13
*/ // */
public interface ISysUserService { //public interface ISysUserService {
//
/** // /**
* 后台系统用户注册 // * 后台系统用户注册
* // *
* @param sysUserRegisterReq 注册请求参数 // * @param sysUserRegisterReq 注册请求参数
*/ // */
void register(SysUserRegisterReq sysUserRegisterReq); // void register(SysUserRegisterReq sysUserRegisterReq);
//
/** // /**
* 登陆接口 // * 登陆接口
* // *
* @param sysUserLoginReq 登陆请求参数 // * @param sysUserLoginReq 登陆请求参数
* @return 登陆用户信息 // * @return 登陆用户信息
*/ // */
SaTokenInfo login(SysUserLoginReq sysUserLoginReq); // SaTokenInfo login(SysUserLoginReq sysUserLoginReq);
//
/** // /**
* 登出接口 // * 登出接口
*/ // */
void logout(); // void logout();
} //}

View File

@ -1,16 +1,16 @@
package top.baogutang.admin.services; //package top.baogutang.admin.services;
//
import java.util.List; //import java.util.List;
//
/** ///**
* @description: // * @description:
* @author: nikooh // * @author: nikooh
* @date: 2024/08/23 : 17:50 // * @date: 2024/08/23 : 17:50
*/ // */
public interface IVirtualCoinService { //public interface IVirtualCoinService {
//
List<String[]> uiKline(String symbol, String interval); // List<String[]> uiKline(String symbol, String interval);
//
// void startWebSocket(String symbol, String interval); //// void startWebSocket(String symbol, String interval);
//
} //}

View File

@ -1,105 +1,105 @@
package top.baogutang.admin.services.impl; //package top.baogutang.admin.services.impl;
//
import cn.dev33.satoken.stp.SaTokenInfo; //import cn.dev33.satoken.stp.SaTokenInfo;
import cn.dev33.satoken.stp.StpUtil; //import cn.dev33.satoken.stp.StpUtil;
import com.baomidou.mybatisplus.core.conditions.Wrapper; //import com.baomidou.mybatisplus.core.conditions.Wrapper;
import com.baomidou.mybatisplus.core.toolkit.IdWorker; //import com.baomidou.mybatisplus.core.toolkit.IdWorker;
import com.baomidou.mybatisplus.core.toolkit.Wrappers; //import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; //import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import lombok.extern.slf4j.Slf4j; //import lombok.extern.slf4j.Slf4j;
import org.springframework.data.redis.core.RedisTemplate; //import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.security.crypto.password.PasswordEncoder; //import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Service; //import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional; //import org.springframework.transaction.annotation.Transactional;
import top.baogutang.admin.dao.entity.SysUserEntity; //import top.baogutang.admin.dao.entity.SysUserEntity;
import top.baogutang.admin.dao.mapper.SysUserMapper; //import top.baogutang.admin.dao.mapper.SysUserMapper;
import top.baogutang.admin.domain.req.SysUserLoginReq; //import top.baogutang.admin.domain.req.SysUserLoginReq;
import top.baogutang.admin.domain.req.SysUserRegisterReq; //import top.baogutang.admin.domain.req.SysUserRegisterReq;
import top.baogutang.admin.services.ISysUserService; //import top.baogutang.admin.services.ISysUserService;
import top.baogutang.common.annotation.RequestLimit; //import top.baogutang.common.annotation.RequestLimit;
import top.baogutang.common.constants.ErrorCodeEnum; //import top.baogutang.common.constants.ErrorCodeEnum;
import top.baogutang.common.exceptions.BusinessException; //import top.baogutang.common.exceptions.BusinessException;
//
import javax.annotation.Resource; //import javax.annotation.Resource;
//
import java.util.Objects; //import java.util.Objects;
//
import static top.baogutang.common.constants.CacheConstant.ENABLE; //import static top.baogutang.common.constants.CacheConstant.ENABLE;
import static top.baogutang.common.constants.CacheConstant.RANDOM_IMAGE_CACHE_KEY; //import static top.baogutang.common.constants.CacheConstant.RANDOM_IMAGE_CACHE_KEY;
//
/** ///**
* @description: // * @description:
* @author: nikooh // * @author: nikooh
* @date: 2023/06/19 : 12:14 // * @date: 2023/06/19 : 12:14
*/ // */
@Slf4j //@Slf4j
@Service //@Service
public class SysUserServiceImpl extends ServiceImpl<SysUserMapper, SysUserEntity> implements ISysUserService { //public class SysUserServiceImpl extends ServiceImpl<SysUserMapper, SysUserEntity> implements ISysUserService {
//
@Resource // @Resource
private SysUserMapper sysUserMapper; // private SysUserMapper sysUserMapper;
//
@Resource // @Resource
private RedisTemplate<String, Object> redisTemplate; // private RedisTemplate<String, Object> redisTemplate;
//
@Resource // @Resource
private PasswordEncoder passwordEncoder; // private PasswordEncoder passwordEncoder;
//
//
@Override // @Override
@RequestLimit // @RequestLimit
@Transactional(rollbackFor = Exception.class) // @Transactional(rollbackFor = Exception.class)
public void register(SysUserRegisterReq sysUserRegisterReq) { // public void register(SysUserRegisterReq sysUserRegisterReq) {
String cacheKey = String.format(RANDOM_IMAGE_CACHE_KEY, sysUserRegisterReq.getCheckKey()); // String cacheKey = String.format(RANDOM_IMAGE_CACHE_KEY, sysUserRegisterReq.getCheckKey());
Object cacheCaptcha = redisTemplate.opsForValue().get(cacheKey); // Object cacheCaptcha = redisTemplate.opsForValue().get(cacheKey);
if (Objects.isNull(cacheCaptcha)) { // if (Objects.isNull(cacheCaptcha)) {
throw new BusinessException(ErrorCodeEnum.CAPTCHA_NOT_EXISTS); // throw new BusinessException(ErrorCodeEnum.CAPTCHA_NOT_EXISTS);
} // }
if (!sysUserRegisterReq.getCaptcha().equalsIgnoreCase((String) cacheCaptcha)) { // if (!sysUserRegisterReq.getCaptcha().equalsIgnoreCase((String) cacheCaptcha)) {
throw new BusinessException(ErrorCodeEnum.CAPTCHA_INCORRECT); // throw new BusinessException(ErrorCodeEnum.CAPTCHA_INCORRECT);
} // }
// 查询邮箱手机号是否已占用 // // 查询邮箱手机号是否已占用
SysUserEntity sysUser = baseMapper.selectByEmailOrMobile(sysUserRegisterReq.getEmail(), sysUserRegisterReq.getMobile()); // SysUserEntity sysUser = baseMapper.selectByEmailOrMobile(sysUserRegisterReq.getEmail(), sysUserRegisterReq.getMobile());
if (Objects.nonNull(sysUser)) { // if (Objects.nonNull(sysUser)) {
throw new BusinessException(ErrorCodeEnum.CURRENT_USER_EXISTS); // throw new BusinessException(ErrorCodeEnum.CURRENT_USER_EXISTS);
} // }
// 可以进行注册 // // 可以进行注册
SysUserEntity userEntity = new SysUserEntity(); // SysUserEntity userEntity = new SysUserEntity();
userEntity.setId(IdWorker.getId()); // userEntity.setId(IdWorker.getId());
userEntity.setUsername(sysUserRegisterReq.getEmail()); // userEntity.setUsername(sysUserRegisterReq.getEmail());
userEntity.setEmail(sysUserRegisterReq.getEmail()); // userEntity.setEmail(sysUserRegisterReq.getEmail());
userEntity.setMobile(sysUserRegisterReq.getMobile()); // userEntity.setMobile(sysUserRegisterReq.getMobile());
userEntity.setPassword(passwordEncoder.encode(sysUserRegisterReq.getPassword())); // userEntity.setPassword(passwordEncoder.encode(sysUserRegisterReq.getPassword()));
saveOrUpdate(userEntity); // saveOrUpdate(userEntity);
} // }
//
@Override // @Override
public SaTokenInfo login(SysUserLoginReq sysUserLoginReq) { // public SaTokenInfo login(SysUserLoginReq sysUserLoginReq) {
String password = sysUserLoginReq.getPassword(); // String password = sysUserLoginReq.getPassword();
SysUserEntity userEntity = this.findByEmail(sysUserLoginReq.getEmail()); // SysUserEntity userEntity = this.findByEmail(sysUserLoginReq.getEmail());
if (userEntity == null) { // if (userEntity == null) {
throw new BusinessException(ErrorCodeEnum.E_BIZ_DIGITAL_ART_USER_NOT_EXISTS); // throw new BusinessException(ErrorCodeEnum.E_BIZ_DIGITAL_ART_USER_NOT_EXISTS);
} // }
boolean userVerify = passwordEncoder.matches(password, userEntity.getPassword()); // boolean userVerify = passwordEncoder.matches(password, userEntity.getPassword());
if (!userVerify) { // if (!userVerify) {
throw new BusinessException(ErrorCodeEnum.PASSWORD_ERROR); // throw new BusinessException(ErrorCodeEnum.PASSWORD_ERROR);
} // }
// Sa-Token // // Sa-Token
StpUtil.login(userEntity.getId()); // StpUtil.login(userEntity.getId());
return StpUtil.getTokenInfo(); // return StpUtil.getTokenInfo();
} // }
//
@Override // @Override
public void logout() { // public void logout() {
StpUtil.logout(); // StpUtil.logout();
} // }
//
//
private SysUserEntity findByEmail(String email) { // private SysUserEntity findByEmail(String email) {
Wrapper<SysUserEntity> wrapper = Wrappers.<SysUserEntity>query() // Wrapper<SysUserEntity> wrapper = Wrappers.<SysUserEntity>query()
.lambda() // .lambda()
.eq(SysUserEntity::getEmail, email) // .eq(SysUserEntity::getEmail, email)
.eq(SysUserEntity::getEnableFlag, ENABLE); // .eq(SysUserEntity::getEnableFlag, ENABLE);
return this.getOne(wrapper); // return this.getOne(wrapper);
} // }
} //}

View File

@ -1,48 +1,48 @@
package top.baogutang.admin.services.impl; //package top.baogutang.admin.services.impl;
//
import cn.hutool.core.bean.BeanUtil; //import cn.hutool.core.bean.BeanUtil;
import com.binance.connector.client.SpotClient; //import com.binance.connector.client.SpotClient;
import com.binance.connector.client.WebSocketStreamClient; //import com.binance.connector.client.WebSocketStreamClient;
import com.fasterxml.jackson.core.type.TypeReference; //import com.fasterxml.jackson.core.type.TypeReference;
import lombok.extern.slf4j.Slf4j; //import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils; //import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service; //import org.springframework.stereotype.Service;
import top.baogutang.admin.schedule.OkCoinMarketCandlesHandler; //import top.baogutang.admin.schedule.OkCoinMarketCandlesHandler;
import top.baogutang.admin.services.IVirtualCoinService; //import top.baogutang.admin.services.IVirtualCoinService;
import top.baogutang.common.utils.JacksonUtil; //import top.baogutang.common.utils.JacksonUtil;
//
import javax.annotation.Resource; //import javax.annotation.Resource;
import java.util.Collections; //import java.util.Collections;
import java.util.List; //import java.util.List;
import java.util.Map; //import java.util.Map;
//
/** ///**
* @description: // * @description:
* @author: nikooh // * @author: nikooh
* @date: 2024/08/23 : 17:50 // * @date: 2024/08/23 : 17:50
*/ // */
@Slf4j //@Slf4j
@Service //@Service
public class VirtualCoinServiceImpl implements IVirtualCoinService { //public class VirtualCoinServiceImpl implements IVirtualCoinService {
//
@Resource // @Resource
private SpotClient spotClient; // private SpotClient spotClient;
//
@Resource // @Resource
private WebSocketStreamClient webSocketStreamClient; // private WebSocketStreamClient webSocketStreamClient;
//
//
@Override // @Override
public List<String[]> uiKline(String symbol, String interval) { // public List<String[]> uiKline(String symbol, String interval) {
OkCoinMarketCandlesHandler.KLinesRequestParameters kLinesRequestParameters = new OkCoinMarketCandlesHandler.KLinesRequestParameters(symbol, interval); // OkCoinMarketCandlesHandler.KLinesRequestParameters kLinesRequestParameters = new OkCoinMarketCandlesHandler.KLinesRequestParameters(symbol, interval);
Map<String, Object> parameters = BeanUtil.beanToMap(kLinesRequestParameters, Boolean.FALSE, Boolean.TRUE); // Map<String, Object> parameters = BeanUtil.beanToMap(kLinesRequestParameters, Boolean.FALSE, Boolean.TRUE);
String resultStr = spotClient.createMarket().uiKlines(parameters); // String resultStr = spotClient.createMarket().uiKlines(parameters);
if (StringUtils.isBlank(resultStr)) { // if (StringUtils.isBlank(resultStr)) {
log.error(">>>>>>>>>>request result is null!<<<<<<<<<<"); // log.error(">>>>>>>>>>request result is null!<<<<<<<<<<");
return Collections.emptyList(); // return Collections.emptyList();
} // }
return JacksonUtil.fromJson(resultStr, new TypeReference<List<String[]>>() { // return JacksonUtil.fromJson(resultStr, new TypeReference<List<String[]>>() {
}); // });
} // }
//
} //}

View File

@ -4,5 +4,5 @@ spring:
main: main:
allow-bean-definition-overriding: true allow-bean-definition-overriding: true
resources: # resources:
static-locations: classpath:/templates/ # static-locations: classpath:/templates/

View File

Before

Width:  |  Height:  |  Size: 8.1 KiB

After

Width:  |  Height:  |  Size: 8.1 KiB

View File

@ -1,13 +1,19 @@
<!DOCTYPE html> <!DOCTYPE html>
<html lang="en"> <html lang="zh-CN">
<head> <head>
<meta charset="UTF-8"/> <link rel="icon" type="image/png" href="/NIKO.png" th:href="@{/NIKO.png}">
<meta name="viewport" content="width=device-width, initial-scale=1.0"/>
<link rel="icon" type="image/png" href="NIKO.png"/>
<title>BAOGUTANG-FILE</title> <title>BAOGUTANG-FILE</title>
<link href="css/bootstrap.min.css" rel="stylesheet"> <meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
<link href="css/font-awesome.min.css" rel="stylesheet"> <meta name="HandheldFriendly" content="True"/>
<link href="css/base.css" rel="stylesheet"> <meta name="MobileOptimized" content="320"/>
<meta http-equiv="Cache-Control" content="max-age=7200"/>
<meta http-equiv="X-UA-Compatible" content="IE=edge"/>
<meta name="viewport" content="width=device-width, initial-scale=1">
<meta name="robots" content="all"/>
<meta name="author" content="BAOGUTANG-FILE"/>
<link href="/css/bootstrap.min.css" rel="stylesheet" th:href="@{/css/bootstrap.min.css}">
<link href="/css/font-awesome.min.css" rel="stylesheet" th:href="@{/css/font-awesome.min.css}">
<link href="/css/base.css" rel="stylesheet" th:href="@{/css/base.css}">
<style> <style>
body { body {
font-family: "Microsoft YaHei", Arial, sans-serif; font-family: "Microsoft YaHei", Arial, sans-serif;

View File

@ -1,7 +1,7 @@
<!DOCTYPE html> <!DOCTYPE html>
<html lang="zh-CN"> <html lang="zh-CN">
<head> <head>
<link rel="icon" type="image/png" href="NIKO.png"> <link rel="icon" type="image/png" href="../static/NIKO.png" th:href="@{/NIKO.png}">
<title>JSON在线解析及格式化验证</title> <title>JSON在线解析及格式化验证</title>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/> <meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
<meta name="HandheldFriendly" content="True"/> <meta name="HandheldFriendly" content="True"/>
@ -11,9 +11,9 @@
<meta name="viewport" content="width=device-width, initial-scale=1"> <meta name="viewport" content="width=device-width, initial-scale=1">
<meta name="robots" content="all"/> <meta name="robots" content="all"/>
<meta name="author" content="BAOGUTANG-JSON"/> <meta name="author" content="BAOGUTANG-JSON"/>
<link href="css/bootstrap.min.css" rel="stylesheet" th:href="@{css/bootstrap.min.css}"> <link href="../static/css/bootstrap.min.css" rel="stylesheet" th:href="@{css/bootstrap.min.css}">
<link href="css/font-awesome.min.css" rel="stylesheet" th:href="@{css/font-awesome.min.css}"> <link href="../static/css/font-awesome.min.css" rel="stylesheet" th:href="@{css/font-awesome.min.css}">
<link href="css/base.css" rel="stylesheet" th:href="@{css/base.css}"> <link href="../static/css/base.css" rel="stylesheet" th:href="@{css/base.css}">
<style> <style>
body, html { body, html {
min-height: 100%; min-height: 100%;