websocketSerivce/src/main/java/org/example/controller/UserController.java
@@ -12,10 +12,8 @@ import org.example.common.ServerResponse; import org.example.dao.ConfigCurrencyMapper; import org.example.dao.LogMapper; import org.example.pojo.ConfigCurrency; import org.example.pojo.Log; import org.example.pojo.LoginOut; import org.example.pojo.User; import org.example.dao.MenuMapper; import org.example.pojo.*; import org.example.pojo.vo.DeleteConfigVo; import org.example.pojo.vo.SaveConfigVo; import org.example.pojo.vo.UpdateUserVo; @@ -29,6 +27,7 @@ import java.sql.Date; import java.time.LocalDate; import java.util.*; import java.util.stream.Collectors; /** * @program: demo @@ -50,6 +49,9 @@ @Autowired private LogMapper logMapper; @Autowired private MenuMapper menuMapper; @PostMapping("/login") @ResponseBody public ServerResponse saveUser(@RequestParam("account") String account @@ -63,31 +65,13 @@ if (!MD5Util.verify(password, user.getPassword())) { return ServerResponse.createBySuccessMsg("密码错误"); } List<Menu> menus = menuMapper.selectList(new LambdaQueryWrapper<Menu>()); if(user.getIsRoot() == 1){ String token = JwtUtil.getToken(user); Map<String,Object> map = new HashMap<>(); map.put("token",token); String loginJson = "[\n" + " {\n" + " \"title\":\"行情比对\",\n" + " \"name\":\"index\",\n" + " \"path\":\"/index\",\n" + " \"icon\":\"el-icon-data-analysis\",\n" + " \"component\":\"comparison\"\n" + " },\n" + " {\n" + " \"title\":\"用户管理\",\n" + " \"name\":\"user\",\n" + " \"path\":\"/user\",\n" + " \"icon\":\"el-icon-user\",\n" + " \"component\": \"user\"\n" + " }\n" + "]"; ObjectMapper objectMapper = new ObjectMapper(); List<LoginOut> loginOuts = objectMapper.readValue(loginJson, new TypeReference<List<LoginOut>>() {}); map.put("menu",loginOuts); map.put("user",user); map.put("menu",menus); return ServerResponse.createBySuccess(map); } @@ -104,19 +88,9 @@ String token = JwtUtil.getToken(user); Map<String,Object> map = new HashMap<>(); map.put("token",token); String loginJson = "[\n" + " {\n" + " \"title\":\"行情比对\",\n" + " \"name\":\"index\",\n" + " \"path\":\"/index\",\n" + " \"icon\":\"el-icon-data-analysis\",\n" + " \"component\":\"comparison\"\n" + " }\n" + "]"; ObjectMapper objectMapper = new ObjectMapper(); List<LoginOut> loginOuts = objectMapper.readValue(loginJson, new TypeReference<List<LoginOut>>() {}); map.put("menu",loginOuts); List<Menu> menuList = menus.stream().filter(f -> f.getIsRoot() == 0).collect(Collectors.toList()); map.put("menu",menuList); map.put("user",user); String key = "user_"; RedisUtil.set(key+user.getId(),token); String ip = IpAddressUtil.getIpAddress(request); @@ -140,38 +114,39 @@ } @PostMapping("/saveConfig") public ServerResponse saveConfig(@RequestBody SaveConfigVo saveConfigVo) { // currencyMapper.delete(new LambdaQueryWrapper<ConfigCurrency>().eq(ConfigCurrency::getUserId,saveConfigVo.getUserId())); public ServerResponse saveConfig(@RequestBody SaveConfigVo saveConfigVo,HttpServletRequest request) { String token = request.getHeader("token"); User user = JwtUtil.verify(token); saveConfigVo.getCurrencyList().forEach(f->{ ConfigCurrency currency = new ConfigCurrency(); currency.setUserId(saveConfigVo.getUserId()); currency.setUserId(user.getId()); currency.setCurrency(f.getCurrency()); currency.setBuy(f.getBuy()); currency.setSell(f.getSell()); currencyMapper.insert(currency); }); List<ConfigCurrency> configCurrencies = currencyMapper.selectList(new LambdaQueryWrapper<ConfigCurrency>().eq(ConfigCurrency::getUserId, saveConfigVo.getUserId())); List<ConfigCurrency> configCurrencies = currencyMapper.selectList(new LambdaQueryWrapper<ConfigCurrency>().eq(ConfigCurrency::getUserId, user.getId())); String key = "config_"; Gson gson = new GsonBuilder().setPrettyPrinting().create(); String json = gson.toJson(configCurrencies); RedisUtil.set(key+saveConfigVo.getUserId(),json); RedisUtil.set(key+user.getId(),json); return ServerResponse.createBySuccess(); } @PostMapping("/deleteConfig") public ServerResponse deleteConfig(@RequestBody DeleteConfigVo deleteConfigVo) { currencyMapper.delete(new LambdaQueryWrapper<ConfigCurrency>() .eq(ConfigCurrency::getUserId,deleteConfigVo.getUserId()) .in(ConfigCurrency::getId,deleteConfigVo.getConfigId())); List<ConfigCurrency> configCurrencies = currencyMapper.selectList(new LambdaQueryWrapper<ConfigCurrency>().eq(ConfigCurrency::getUserId, deleteConfigVo.getUserId())); @GetMapping("/deleteConfig") public ServerResponse deleteConfig(@RequestParam("id") int id,HttpServletRequest request) { String token = request.getHeader("token"); User user = JwtUtil.verify(token); currencyMapper.deleteById(id); List<ConfigCurrency> configCurrencies = currencyMapper.selectList(new LambdaQueryWrapper<ConfigCurrency>().eq(ConfigCurrency::getUserId, user.getId())); String key = "config_"; Gson gson = new GsonBuilder().setPrettyPrinting().create(); String json = gson.toJson(configCurrencies); RedisUtil.set(key+deleteConfigVo.getUserId(),json); RedisUtil.set(key+user.getId(),json); return ServerResponse.createBySuccess(); } @PostMapping("/selectConfig") @GetMapping("/selectConfig") public ServerResponse selectConfig(@RequestParam(value = "currency", required = false) String currency, @RequestParam("pageNum") int pageNum, @RequestParam("pageSize") int pageSize, @@ -180,13 +155,14 @@ User user = JwtUtil.verify(token); Page<ConfigCurrency> page = new Page<>(pageNum, pageSize); Page<ConfigCurrency> configCurrencyPage = currencyMapper.selectPage(page, new LambdaQueryWrapper<ConfigCurrency>() .eq(StringUtils.isNotEmpty(currency), ConfigCurrency::getCurrency, currency)); .eq(StringUtils.isNotEmpty(currency), ConfigCurrency::getCurrency, currency).eq(ConfigCurrency::getUserId,user.getId())); return ServerResponse.createBySuccess(configCurrencyPage); } @PostMapping("/saveUser") public ServerResponse saveUser(User user) { public ServerResponse saveUser(@RequestBody User user) { long count = userService.count(new LambdaQueryWrapper<User>().eq(User::getAccount, user.getAccount())); if(count > 0){ return ServerResponse.createByErrorMsg("账号已存在"); @@ -205,6 +181,15 @@ } userService.removeById(id); return ServerResponse.createBySuccess(); } @GetMapping("/selectById") public ServerResponse selectById(@RequestParam("id") Integer id) { User byId = userService.getById(id); if(null == byId || byId.getIsRoot() == 1){ return ServerResponse.createByErrorMsg("用户不存在"); } return ServerResponse.createBySuccess(byId); } @PostMapping("/updateUser") @@ -227,10 +212,21 @@ @RequestParam("pageSize") int pageSize) { Page<User> page = new Page<>(pageNum, pageSize); Page<User> pageList = userService.page(page, new LambdaQueryWrapper<User>() .eq(StringUtils.isNotEmpty(account), User::getAccount, account) .like(StringUtils.isNotEmpty(account), User::getAccount, account) .eq(User::getIsShow,0) .eq(User::getIsRoot,0) .orderByDesc(User::getAddTime)); return ServerResponse.createBySuccess(pageList); } @GetMapping("/selectLog") public ServerResponse selectLog(@RequestParam(value = "account", required = false) String account, @RequestParam("pageNum") int pageNum, @RequestParam("pageSize") int pageSize) { Page<Log> page = new Page<>(pageNum, pageSize); Page<Log> pageList = logMapper.selectPage(page, new LambdaQueryWrapper<Log>() .like(StringUtils.isNotEmpty(account), Log::getAccount, account) .orderByDesc(Log::getLoginTime)); return ServerResponse.createBySuccess(pageList); } } websocketSerivce/src/main/java/org/example/dao/MenuMapper.java
New file @@ -0,0 +1,9 @@ package org.example.dao; import com.baomidou.mybatisplus.core.mapper.BaseMapper; import org.apache.ibatis.annotations.Mapper; import org.example.pojo.Menu; @Mapper public interface MenuMapper extends BaseMapper<Menu> { } websocketSerivce/src/main/java/org/example/pojo/ConfigCurrency.java
@@ -17,11 +17,15 @@ @TableId(type = IdType.AUTO) private String id; //用户id private Integer userId; //币种 private String currency; //买入平台 private String buy; //卖出平台 private String sell; } websocketSerivce/src/main/java/org/example/pojo/Log.java
@@ -19,14 +19,18 @@ @TableId(type = IdType.AUTO) private Integer id; //账号 private String account; //登录时间 @TableField(fill = FieldFill.INSERT) @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8") //指定格式 private Date loginTime; //登录ip private String ip; //登录地址 private String address; websocketSerivce/src/main/java/org/example/pojo/LoginOut.java
@@ -8,6 +8,7 @@ private String title; private String name; private String path; private String isShow; private String icon; private String component; websocketSerivce/src/main/java/org/example/pojo/MarketDataOut.java
@@ -45,4 +45,9 @@ //自选标记 private boolean isMarker = false; //过滤数据 private String buyAndSell; private boolean isFilter = false; } websocketSerivce/src/main/java/org/example/pojo/Menu.java
New file @@ -0,0 +1,18 @@ package org.example.pojo; import lombok.Data; @Data public class Menu { private Integer id; private String title; private String name; private String path; private Boolean isShow; private String icon; private String component; private Integer isRoot; } websocketSerivce/src/main/java/org/example/pojo/bo/WsBo.java
@@ -34,6 +34,9 @@ //过滤平台 逗号分割 private String platformList; //需要标记的币种 //需要标记的币种 买入平台卖出平台拼接多个逗号分隔 private String isMarker; //过滤数据 private String buyAndSell; } websocketSerivce/src/main/java/org/example/pojo/vo/SaveConfigVo.java
@@ -13,7 +13,5 @@ @Data public class SaveConfigVo { private Integer userId; private List<ConfigCurrencyVo> currencyList; } websocketSerivce/src/main/java/org/example/server/impl/CurrencySerivceImpl.java
@@ -1,5 +1,5 @@ package org.example.server.impl; import org.example.websocket.server.WsServer; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.JsonNode; @@ -19,7 +19,6 @@ import org.example.pojo.bo.MarketBo; import org.example.server.CurrencySerivce; import org.example.util.RedisUtil; import org.example.websocket.server.WsServer; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import org.yaml.snakeyaml.error.Mark; @@ -235,6 +234,7 @@ marketDataOut.setBuyTotalPrice(markets1.getBids().getP().multiply(markets1.getBids().getV()).toString()); // 设置买入总价 marketDataOut.setSellTotalPrice(markets2.getAsks().getP().multiply(markets2.getAsks().getV()).toString()); // 设置卖出总价 marketDataOut.setServceTime(formattedDateTime); // 设置服务时间 marketDataOut.setBuyAndSell(marketDataOut.getBaseAsset()+markets1.getExchange()+markets2.getExchange()); marketDataOuts.add(marketDataOut); // 添加到输出列表 } websocketSerivce/src/main/java/org/example/task/MarketDataTask.java
@@ -27,12 +27,9 @@ private final Lock syncCurrencyLock = new ReentrantLock(); // @Scheduled(initialDelay = 0, fixedRate = Long.MAX_VALUE) @Scheduled(initialDelay = 0, fixedRate = Long.MAX_VALUE) public void start() { log.info("行情数据计算-------------启动"); // 启动任务调度器 // currencySerivce.scheduler(); executor.execute(() -> { try { websocketSerivce/src/main/java/org/example/util/LoginInterceptor.java
@@ -27,7 +27,14 @@ throws Exception { // 假设登录状态信息保存在 session 中,这里简单示例,实际项目中可能会有自己的登录状态判断逻辑 String token = request.getHeader("token"); String token = null; // 如果是 OPTIONS 请求,我们就让他通过,不管他 if (request.getMethod().equals("OPTIONS")) { response.setStatus(HttpServletResponse.SC_OK); return true; }else { token = request.getHeader("token"); } if(null == token){ // 未登录,返回未授权错误码或重定向到登录页 response.setStatus(HttpServletResponse.SC_UNAUTHORIZED); // 返回 401 未授权状态码 websocketSerivce/src/main/java/org/example/websocket/server/WsServer.java
@@ -67,11 +67,7 @@ @OnOpen public void onOpen(Session session) { WsBo wsBo = getWsBoForSession(session.getId()); String s = RedisUtil.get("user_" + wsBo.getUserId()); if(null == s || s.isEmpty() && !wsBo.getToken().equals(s)){ closeSession(session, "用户未登录"); } this.session = session; int count = onlineCount.incrementAndGet(); wsServers.add(this); @@ -88,6 +84,10 @@ private boolean hasReceivedSubscription(Session session) { WsBo wsBo = getWsBoForSession(session.getId()); String s = RedisUtil.get("user_" + wsBo.getUserId()); if(null == s || s.isEmpty() && !wsBo.getToken().equals(s)){ closeSession(session, "用户未登录"); } return wsBo != null; } @@ -115,8 +115,10 @@ @OnMessage public void onMessage(String message, Session session) throws IOException { try { WsBo bean = JSONUtil.toBean(message, WsBo.class); threadLocalData.put(session.getId(), bean); if(!message.equals("ping")){ WsBo bean = JSONUtil.toBean(message, WsBo.class); threadLocalData.put(session.getId(), bean); } }catch (Exception e){ log.error("客户段订阅消息格式错误"); } @@ -192,14 +194,13 @@ ObjectMapper objectMapper = new ObjectMapper(); currencies = objectMapper.readValue(value, new TypeReference<List<ConfigCurrency>>() {}); } if(!CollectionUtils.isEmpty(currencies)){ List<String> currency = currencies.stream().map(ConfigCurrency::getCurrency).collect(Collectors.toList()); List<String> buy = currencies.stream().map(ConfigCurrency::getBuy).collect(Collectors.toList()); List<String> sell = currencies.stream().map(ConfigCurrency::getSell).collect(Collectors.toList()); redisValueMap = redisValueMap.stream() .filter(data -> !currency.contains(data.getBaseAsset()) && !buy.contains(data.getBuyingPlatform()) && !sell.contains(data.getSellPlatform())) .collect(Collectors.toList()); if (!CollectionUtils.isEmpty(currencies)) { Set<String> filtrationSet = currencies.stream() .map(f -> f.getCurrency() + f.getBuy() + f.getSell()) .collect(Collectors.toSet()); redisValueMap.removeIf(data -> filtrationSet.contains(data.getBuyAndSell())); } //查询币种 if(null != wsBo.getCurrency()){ @@ -226,11 +227,19 @@ .filter(data -> !list.contains(data.getBuyingPlatform()) && !list.contains(data.getSellPlatform())) .collect(Collectors.toList()); } //过滤数据 if(null != wsBo.getBuyAndSell()){ List<String> list = Arrays.asList(wsBo.getBuyAndSell().split(",")); redisValueMap = redisValueMap.stream() .filter(data -> !list.contains(data.getBuyAndSell())) .collect(Collectors.toList()); } //自选标记 if(null != wsBo.getIsMarker()){ List<String> list = Arrays.asList(wsBo.getIsMarker().split(",")); redisValueMap.stream() .filter(data -> list.contains(data.getBaseAsset())) .filter(data -> list.contains(data.getBuyAndSell())) .forEach(data -> data.setMarker(true)); } Gson gson = new GsonBuilder().setPrettyPrinting().create();