1
zj
2024-08-03 388cab2e8ce85f138f4d1bc3bfbf6acd0778467f
1
11 files modified
2 files added
209 ■■■■■ changed files
websocketSerivce/src/main/java/org/example/controller/UserController.java 104 ●●●● patch | view | raw | blame | history
websocketSerivce/src/main/java/org/example/dao/MenuMapper.java 9 ●●●●● patch | view | raw | blame | history
websocketSerivce/src/main/java/org/example/pojo/ConfigCurrency.java 4 ●●●● patch | view | raw | blame | history
websocketSerivce/src/main/java/org/example/pojo/Log.java 4 ●●●● patch | view | raw | blame | history
websocketSerivce/src/main/java/org/example/pojo/LoginOut.java 1 ●●●● patch | view | raw | blame | history
websocketSerivce/src/main/java/org/example/pojo/MarketDataOut.java 5 ●●●●● patch | view | raw | blame | history
websocketSerivce/src/main/java/org/example/pojo/Menu.java 18 ●●●●● patch | view | raw | blame | history
websocketSerivce/src/main/java/org/example/pojo/bo/WsBo.java 5 ●●●● patch | view | raw | blame | history
websocketSerivce/src/main/java/org/example/pojo/vo/SaveConfigVo.java 2 ●●●●● patch | view | raw | blame | history
websocketSerivce/src/main/java/org/example/server/impl/CurrencySerivceImpl.java 4 ●●●● patch | view | raw | blame | history
websocketSerivce/src/main/java/org/example/task/MarketDataTask.java 5 ●●●● patch | view | raw | blame | history
websocketSerivce/src/main/java/org/example/util/LoginInterceptor.java 9 ●●●● patch | view | raw | blame | history
websocketSerivce/src/main/java/org/example/websocket/server/WsServer.java 39 ●●●●● patch | view | raw | blame | history
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();