浏览代码

修复获取文章的部分bug和新增注册需要的信息等

fangzhen 8 月之前
父节点
当前提交
3dc4b5ffcf
共有 27 个文件被更改,包括 975 次插入64 次删除
  1. 12 0
      ruoyi-framework/pom.xml
  2. 1 1
      ruoyi-framework/src/main/java/com/ruoyi/framework/config/SecurityConfig.java
  3. 18 1
      ruoyi-framework/src/main/java/com/ruoyi/framework/web/service/SysRegisterService.java
  4. 25 0
      ruoyi-framework/src/main/java/com/ruoyi/framework/webSocket/MessageType.java
  5. 19 0
      ruoyi-framework/src/main/java/com/ruoyi/framework/webSocket/WebSocketConfig.java
  6. 152 0
      ruoyi-framework/src/main/java/com/ruoyi/framework/webSocket/WebSocketServer.java
  7. 47 2
      ruoyi-generator/src/main/java/com/ruoyi/generator/controller/CommunityArticleController.java
  8. 5 0
      ruoyi-generator/src/main/java/com/ruoyi/generator/domain/Community/CommunityCircle.java
  9. 56 0
      ruoyi-generator/src/main/java/com/ruoyi/generator/domain/Community/CommunityUserInfo.java
  10. 49 0
      ruoyi-generator/src/main/java/com/ruoyi/generator/domain/Community/CommunityUserLike.java
  11. 4 1
      ruoyi-generator/src/main/java/com/ruoyi/generator/mapper/community/CommunityArticleMapper.java
  12. 9 0
      ruoyi-generator/src/main/java/com/ruoyi/generator/mapper/community/CommunityUserInfoMapper.java
  13. 9 0
      ruoyi-generator/src/main/java/com/ruoyi/generator/mapper/community/CommunityUserLikeMapper.java
  14. 162 58
      ruoyi-generator/src/main/java/com/ruoyi/generator/service/CommunityArticleServiceImpl.java
  15. 36 1
      ruoyi-generator/src/main/java/com/ruoyi/generator/service/ICommunityArticleService.java
  16. 5 0
      ruoyi-generator/src/main/java/com/ruoyi/generator/vo/CommunityCircleVo.java
  17. 63 0
      ruoyi-generator/src/main/java/com/ruoyi/generator/vo/CommunityUserInfoVo.java
  18. 60 0
      ruoyi-generator/src/main/java/com/ruoyi/generator/vo/CommunityUserLikeVo.java
  19. 1 0
      ruoyi-generator/src/main/resources/mapper/community/ArticleMapper.xml
  20. 60 0
      ruoyi-system/src/main/java/com/ruoyi/system/domain/CommunityChatMsg.java
  21. 9 0
      ruoyi-system/src/main/java/com/ruoyi/system/mapper/CommunityChatMsgMapper.java
  22. 7 0
      ruoyi-system/src/main/java/com/ruoyi/system/service/ICommunityChatMsgService.java
  23. 11 0
      ruoyi-system/src/main/java/com/ruoyi/system/service/impl/CommunityChatMsgServiceImpl.java
  24. 3 0
      ruoyi-ui/.env.development
  25. 29 0
      ruoyi-ui/src/main.js
  26. 5 0
      ruoyi-ui/src/store/modules/user.js
  27. 118 0
      ruoyi-ui/src/utils/websocket.js

+ 12 - 0
ruoyi-framework/pom.xml

@@ -65,6 +65,18 @@
             <scope>compile</scope>
         </dependency>
 
+        <!--webSocket-->
+        <dependency>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-starter-websocket</artifactId>
+            <version>2.0.4.RELEASE</version>
+        </dependency>
+
+        <dependency>
+            <groupId>com.alibaba</groupId>
+            <artifactId>fastjson</artifactId>
+            <version>2.0.31</version>
+        </dependency>
     </dependencies>
 
 </project>

+ 1 - 1
ruoyi-framework/src/main/java/com/ruoyi/framework/config/SecurityConfig.java

@@ -114,7 +114,7 @@ public class SecurityConfig
                 requests.antMatchers("/login", "/register", "/captchaImage").permitAll()
                     // 静态资源,可匿名访问
                     .antMatchers(HttpMethod.GET, "/", "/*.html", "/**/*.html", "/**/*.css", "/**/*.js", "/profile/**").permitAll()
-                    .antMatchers("/swagger-ui.html", "/swagger-resources/**", "/webjars/**", "/*/api-docs", "/druid/**").permitAll()
+                    .antMatchers("/swagger-ui.html", "/swagger-resources/**", "/webjars/**", "/*/api-docs", "/druid/**","/websocket/**").permitAll()
                     // 除上面外的所有请求全部需要鉴权认证
                     .anyRequest().authenticated();
             })

+ 18 - 1
ruoyi-framework/src/main/java/com/ruoyi/framework/web/service/SysRegisterService.java

@@ -1,5 +1,9 @@
 package com.ruoyi.framework.web.service;
 
+import com.ruoyi.common.utils.DateUtils;
+import com.ruoyi.generator.domain.Community.CommunityUserInfo;
+import com.ruoyi.generator.mapper.community.CommunityUserInfoMapper;
+import org.apache.commons.lang3.RandomUtils;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Component;
 import com.ruoyi.common.constant.CacheConstants;
@@ -34,6 +38,9 @@ public class SysRegisterService
 
     @Autowired
     private RedisCache redisCache;
+    
+    @Autowired
+    private CommunityUserInfoMapper communityUserInfoMapper;
 
     /**
      * 注册
@@ -75,7 +82,7 @@ public class SysRegisterService
         }
         else
         {
-            sysUser.setNickName(username);
+            sysUser.setNickName(username+ RandomUtils.nextInt(100000,999999));
             sysUser.setPassword(SecurityUtils.encryptPassword(password));
             boolean regFlag = userService.registerUser(sysUser);
             if (!regFlag)
@@ -87,6 +94,16 @@ public class SysRegisterService
                 AsyncManager.me().execute(AsyncFactory.recordLogininfor(username, Constants.REGISTER, MessageUtils.message("user.register.success")));
             }
         }
+
+        //新增加入用户拓展信息表
+        if (StringUtils.isEmpty(msg)) {
+            CommunityUserInfo communityUserInfo = new CommunityUserInfo();
+            communityUserInfo.setUserId(sysUser.getUserId());
+            communityUserInfo.setCreateTime(DateUtils.parseDate(DateUtils.getTime()));
+            communityUserInfo.setCreateBy(sysUser.getUserId());
+            communityUserInfoMapper.insert(communityUserInfo);
+        }
+
         return msg;
     }
 

+ 25 - 0
ruoyi-framework/src/main/java/com/ruoyi/framework/webSocket/MessageType.java

@@ -0,0 +1,25 @@
+package com.ruoyi.framework.webSocket;
+
+/**
+ * 消息类型
+ */
+public enum MessageType {
+
+    SYS("sys", "系统消息"), CHAT("chat", "聊天消息");
+
+    private String type;
+    private String value;
+
+    private MessageType(String type, String value) {
+        this.type = type;
+        this.value = value;
+    }
+
+    public String getType() {
+        return type;
+    }
+
+    public String getValue() {
+        return value;
+    }
+}

+ 19 - 0
ruoyi-framework/src/main/java/com/ruoyi/framework/webSocket/WebSocketConfig.java

@@ -0,0 +1,19 @@
+package com.ruoyi.framework.webSocket;
+
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.web.socket.server.standard.ServerEndpointExporter;
+
+/**
+ * websocket 配置
+ *
+ */
+@Configuration
+public class WebSocketConfig
+{
+    @Bean
+    public ServerEndpointExporter serverEndpointExporter()
+    {
+        return new ServerEndpointExporter();
+    }
+}

+ 152 - 0
ruoyi-framework/src/main/java/com/ruoyi/framework/webSocket/WebSocketServer.java

@@ -0,0 +1,152 @@
+package com.ruoyi.framework.webSocket;
+
+import com.alibaba.fastjson.JSONObject;
+import com.ruoyi.common.utils.DateUtils;
+import com.ruoyi.system.domain.CommunityChatMsg;
+import com.ruoyi.system.service.ICommunityChatMsgService;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Component;
+
+import javax.websocket.*;
+import javax.websocket.server.PathParam;
+import javax.websocket.server.ServerEndpoint;
+import java.io.IOException;
+import java.util.List;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.CopyOnWriteArrayList;
+import java.util.concurrent.atomic.AtomicInteger;
+
+@Component
+@ServerEndpoint("/websocket/{userId}")
+public class WebSocketServer {
+    private static final Logger log = LoggerFactory.getLogger(WebSocketServer.class);
+
+    //静态变量,用来记录当前在线连接数。应该把它设计成线程安全的。
+    private static AtomicInteger onlineNum = new AtomicInteger();
+
+    //concurrent包的线程安全Set,用来存放每个客户端对应的WebSocketServer对象。
+    private static ConcurrentHashMap<String, Session> sessionPools = new ConcurrentHashMap<>();
+
+    /**
+     * 线程安全list,用来存放 在线客户端账号
+     */
+    public static List<String> userList = new CopyOnWriteArrayList<>();
+
+    public static ICommunityChatMsgService chatMsgService;
+
+    @Autowired
+    public void setChatMsgService(ICommunityChatMsgService chatMsgService){
+        WebSocketServer.chatMsgService = chatMsgService;
+    }
+
+    /**
+     * 连接成功
+     *
+     * @param session
+     * @param userId
+     */
+    @OnOpen
+    public void onOpen(Session session, @PathParam(value = "userId") String userId) {
+        sessionPools.put(userId, session);
+        if (!userList.contains(userId)) {
+            addOnlineCount();
+            userList.add(userId);
+        }
+        log.debug("ID为【" + userId + "】的用户加入websocket!当前在线人数为:" + onlineNum);
+        log.debug("当前在线:" + userList);
+    }
+
+    /**
+     * 关闭连接
+     *
+     * @param userId
+     */
+    @OnClose
+    public void onClose(@PathParam(value = "userId") String userId) {
+        sessionPools.remove(userId);
+        if (userList.contains(userId)) {
+            userList.remove(userId);
+            subOnlineCount();
+        }
+        log.debug(userId + "断开webSocket连接!当前人数为" + onlineNum);
+
+    }
+
+    /**
+     * 消息监听
+     *
+     * @param message
+     * @throws IOException
+     */
+    @OnMessage
+    public void onMessage(String message) throws IOException {
+        JSONObject jsonObject = JSONObject.parseObject(message);
+        Long sendUserId = jsonObject.getLong("sendUserId");
+        Long userId = jsonObject.getLong("userId");
+        String type = jsonObject.getString("type");
+        String detail = jsonObject.getString("detail");
+        if (type.equals(MessageType.CHAT.getType())) {
+            log.debug("聊天消息推送");
+            sendToUser(String.valueOf(userId), JSONObject.toJSONString(jsonObject));
+            //存储历史消息
+            CommunityChatMsg chatMsg = new CommunityChatMsg();
+            chatMsg.setSenderId(sendUserId);
+            chatMsg.setReceiverId(userId);
+            chatMsg.setContent(detail);
+            chatMsg.setCreateBy(sendUserId);
+            chatMsg.setCreateTime(DateUtils.parseDate(DateUtils.getTime()));
+            chatMsgService.save(chatMsg);
+        }
+    }
+
+    /**
+     * 连接错误
+     *
+     * @param session
+     * @param throwable
+     * @throws IOException
+     */
+    @OnError
+    public void onError(Session session, Throwable throwable) throws IOException {
+        log.error("websocket连接错误!");
+        throwable.printStackTrace();
+    }
+
+    /**
+     * 发送消息
+     */
+    public void sendMessage(Session session, String message) throws IOException, EncodeException {
+        if (session != null) {
+            synchronized (session) {
+                session.getBasicRemote().sendText(message);
+            }
+        }
+    }
+
+    /**
+     * 给指定用户发送信息
+     */
+    public void sendToUser(String userId, String message) {
+        Session session = sessionPools.get(userId);
+        try {
+            if (session != null) {
+                sendMessage(session, message);
+            } else {
+                log.debug("推送用户不在线");
+            }
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+    }
+
+    public static void addOnlineCount() {
+        onlineNum.incrementAndGet();
+    }
+
+    public static void subOnlineCount() {
+        onlineNum.decrementAndGet();
+
+    }
+}

+ 47 - 2
ruoyi-generator/src/main/java/com/ruoyi/generator/controller/CommunityArticleController.java

@@ -4,8 +4,10 @@ import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
 import com.ruoyi.common.core.controller.BaseController;
 import com.ruoyi.common.core.domain.AjaxResult;
 import com.ruoyi.common.core.page.TableDataInfo;
+import com.ruoyi.common.core.text.Convert;
 import com.ruoyi.common.utils.DateUtils;
 import com.ruoyi.common.utils.SecurityUtils;
+import com.ruoyi.common.utils.ServletUtils;
 import com.ruoyi.generator.domain.Community.*;
 import com.ruoyi.generator.mapper.community.*;
 import com.ruoyi.generator.service.ICommunityArticleService;
@@ -56,8 +58,9 @@ public class CommunityArticleController extends BaseController {
     @GetMapping("/list")
     //@Anonymous
     public TableDataInfo communityList(CommunityArticle communityArticle) {
-        startPage();
-        List<CommunityArticleVo> list = communityArticleService.selectCommunityArticleList(communityArticle);
+        int pageNum = Convert.toInt(ServletUtils.getParameter("pageNum"), 1);
+        int pageSize = Convert.toInt(ServletUtils.getParameter("pageSize"), 10);
+        List<CommunityArticleVo> list = communityArticleService.selectCommunityArticleList(communityArticle, pageNum, pageSize);
         return getDataTable(list);
     }
 
@@ -272,4 +275,46 @@ public class CommunityArticleController extends BaseController {
         }
         return AjaxResult.success(msg);
     }
+
+    /**
+     * 关注用户
+     *
+     * @param likeUserId 被关注人id
+     * @return 当前关注信息
+     */
+
+    @ApiOperation("关注/取关用户")
+    @PostMapping("/likeUser")
+    public AjaxResult userLike(@RequestParam("likeUserId") Long likeUserId) {
+        if (Objects.isNull(likeUserId)) {
+            return AjaxResult.error("参数失效!");
+        }
+        String msg = "";
+        CommunityUserLike communityUserLike = communityArticleService.addOrDeleteUserLike(likeUserId);
+        if (Objects.isNull(communityUserLike) || Objects.isNull(communityUserLike.getId())) {
+            msg = "取消关注";
+        } else {
+            msg = "已关注";
+        }
+        return AjaxResult.success(msg);
+    }
+
+    @ApiOperation("获取当前登录用户信息")
+    @GetMapping("/userInfo")
+    public AjaxResult userInfo() {
+        Long userId = SecurityUtils.getLoginUser().getUserId();
+        return AjaxResult.success(communityArticleService.selectCommunityUserInfoById(userId));
+    }
+
+    @ApiOperation("获取关注列表")
+    @GetMapping("/likeUserList")
+    public AjaxResult likeUserList() {
+        return AjaxResult.success(communityArticleService.selectCommunityUserLikeList(SecurityUtils.getLoginUser().getUserId()));
+    }
+
+    @ApiOperation("获取粉丝列表")
+    @GetMapping("/userFans")
+    public AjaxResult userFans() {
+        return AjaxResult.success(communityArticleService.selectUserFansList(SecurityUtils.getLoginUser().getUserId()));
+    }
 }

+ 5 - 0
ruoyi-generator/src/main/java/com/ruoyi/generator/domain/Community/CommunityCircle.java

@@ -44,6 +44,11 @@ public class CommunityCircle implements Serializable {
     */
     @ApiModelProperty("创建人")
     private Long createBy;
+    /**
+     * 封面url
+     */
+    @ApiModelProperty("封面url")
+    private String imageUrl;
     /**
     * 创建时间
     */

+ 56 - 0
ruoyi-generator/src/main/java/com/ruoyi/generator/domain/Community/CommunityUserInfo.java

@@ -0,0 +1,56 @@
+package com.ruoyi.generator.domain.Community;
+
+import com.baomidou.mybatisplus.annotation.IdType;
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.annotation.TableName;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+import javax.validation.constraints.NotNull;
+import java.util.Date;
+
+/**
+ * @TableName community_user_info
+ */
+@Data
+@TableName("community_user_info")
+public class CommunityUserInfo {
+
+    /**
+     * 唯一id
+     */
+    @NotNull(message = "[唯一id]不能为空")
+    @ApiModelProperty("唯一id")
+    @TableId(type = IdType.AUTO, value = "id")
+    private Long id;
+    /**
+     * 用户id
+     */
+    @ApiModelProperty("用户id")
+    private Long userId;
+    /**
+     * 简介
+     */
+    @ApiModelProperty("简介")
+    private String profile;
+    /**
+     * 创建人
+     */
+    @ApiModelProperty("创建人")
+    private Long createBy;
+    /**
+     * 创建时间
+     */
+    @ApiModelProperty("创建时间")
+    private Date createTime;
+    /**
+     * 更新人
+     */
+    @ApiModelProperty("更新人")
+    private Long updateBy;
+    /**
+     * 更新时间
+     */
+    @ApiModelProperty("更新时间")
+    private Date updateTime;
+}

+ 49 - 0
ruoyi-generator/src/main/java/com/ruoyi/generator/domain/Community/CommunityUserLike.java

@@ -0,0 +1,49 @@
+package com.ruoyi.generator.domain.Community;
+
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.annotation.TableName;
+import com.fasterxml.jackson.annotation.JsonFormat;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+import javax.validation.constraints.NotNull;
+import java.io.Serializable;
+import java.util.Date;
+
+/**
+* 用户关注表
+* @TableName community_user_like
+*/
+@Data
+@TableName("community_user_like")
+public class CommunityUserLike implements Serializable {
+
+    /**
+    * 唯一id
+    */
+    @NotNull(message="[唯一id]不能为空")
+    @ApiModelProperty("唯一id")
+    @TableId("id")
+    private Long id;
+    /**
+    * 关注人id
+    */
+    @ApiModelProperty("关注人id")
+    private Long userId;
+    /**
+    * 被关注人id
+    */
+    @ApiModelProperty("被关注人id")
+    private Long likeUserId;
+    /**
+    * 创建人
+    */
+    @ApiModelProperty("创建人")
+    private Long createBy;
+    /**
+    * 创建时间
+    */
+    @ApiModelProperty("创建时间")
+    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
+    private Date createTime;
+}

+ 4 - 1
ruoyi-generator/src/main/java/com/ruoyi/generator/mapper/community/CommunityArticleMapper.java

@@ -24,7 +24,10 @@ public interface CommunityArticleMapper extends BaseMapper<CommunityArticle> {
      * @param communityArticle 文章条件
      * @return 文章首页信息
      */
-    List<CommunityArticleVo> selectCommunityArticleList(@Param("communityArticle")CommunityArticle communityArticle, @Param("circleIds") List<Long> circleIds);
+    List<CommunityArticleVo> selectCommunityArticleList(@Param("communityArticle") CommunityArticle communityArticle,
+                                                        @Param("circleIds") List<Long> circleIds,
+                                                        @Param("offset") int offset,
+                                                        @Param("limit") int limit);
 
     /**
      * 获取该用户是否收藏该文章

+ 9 - 0
ruoyi-generator/src/main/java/com/ruoyi/generator/mapper/community/CommunityUserInfoMapper.java

@@ -0,0 +1,9 @@
+package com.ruoyi.generator.mapper.community;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.ruoyi.generator.domain.Community.CommunityUserInfo;
+import org.apache.ibatis.annotations.Mapper;
+
+@Mapper
+public interface CommunityUserInfoMapper extends BaseMapper<CommunityUserInfo> {
+}

+ 9 - 0
ruoyi-generator/src/main/java/com/ruoyi/generator/mapper/community/CommunityUserLikeMapper.java

@@ -0,0 +1,9 @@
+package com.ruoyi.generator.mapper.community;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.ruoyi.generator.domain.Community.CommunityUserLike;
+import org.apache.ibatis.annotations.Mapper;
+
+@Mapper
+public interface CommunityUserLikeMapper extends BaseMapper<CommunityUserLike> {
+}

+ 162 - 58
ruoyi-generator/src/main/java/com/ruoyi/generator/service/CommunityArticleServiceImpl.java

@@ -8,9 +8,7 @@ import com.ruoyi.common.utils.SecurityUtils;
 import com.ruoyi.common.utils.bean.BeanUtils;
 import com.ruoyi.generator.domain.Community.*;
 import com.ruoyi.generator.mapper.community.*;
-import com.ruoyi.generator.vo.CommunityArticleCommentVo;
-import com.ruoyi.generator.vo.CommunityArticleVo;
-import com.ruoyi.generator.vo.CommunityCircleVo;
+import com.ruoyi.generator.vo.*;
 import com.ruoyi.system.mapper.SysUserMapper;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -70,6 +68,12 @@ public class CommunityArticleServiceImpl extends ServiceImpl<CommunityArticleMap
     @Autowired
     private CommunityUserCircleMapper communityUserCircleMapper;
 
+    @Autowired
+    private CommunityUserLikeMapper communityUserLikeMapper;
+
+    @Autowired
+    private CommunityUserInfoMapper communityUserInfoMapper;
+
     /**
      * 查询文章列表
      *
@@ -77,7 +81,7 @@ public class CommunityArticleServiceImpl extends ServiceImpl<CommunityArticleMap
      * @return 文章信息集合
      */
     @Override
-    public List<CommunityArticleVo> selectCommunityArticleList(CommunityArticle communityArticle) {
+    public List<CommunityArticleVo> selectCommunityArticleList(CommunityArticle communityArticle, int pageNum, int pageSize) {
         //找出板块下的分类
         Long classId = communityArticle.getClassId();
         List<CommunityClassCircle> classCircles = communityClassCircleMapper.selectList(new QueryWrapper<CommunityClassCircle>().eq("class_id", classId));
@@ -85,64 +89,68 @@ public class CommunityArticleServiceImpl extends ServiceImpl<CommunityArticleMap
         for (CommunityClassCircle classCircle : classCircles) {
             circleIds.add(classCircle.getCircleId());
         }
-
-        List<CommunityArticleVo> communityArticleVos = communityArticleMapper.selectCommunityArticleList(communityArticle, circleIds);
-        Long userId = SecurityUtils.getUserId();
-        for (CommunityArticleVo articleVo : communityArticleVos) {
-            //设置文章的点赞数量
-            articleVo.setLikeCount(communityLikeMapper
-                    .selectList(new QueryWrapper<CommunityLike>()
-                            .eq("article_id", articleVo.getId()))
-                    .size());
-
-            //文章下的评论
-            List<CommunityArticleCommentVo> comments = articleVo.getComments();
-            for (CommunityArticleCommentVo communityArticleCommentVo : comments) {
-                //获取评论的用户信息
-                SysUser sysUser = sysUserMapper.selectUserById(communityArticleCommentVo.getUserId());
-                communityArticleCommentVo.setUsername(sysUser.getUserName());
-                communityArticleCommentVo.setAvatar(sysUser.getAvatar());
-                //当前登录用户是否已点赞
-                List<CommunityCommentLike> commentLikes = communityCommentLikeMapper
-                        .selectList(new QueryWrapper<CommunityCommentLike>()
-                                .eq("comment_id", communityArticleCommentVo.getId()).eq("user_id", userId));
-                communityArticleCommentVo.setCommentLike(!commentLikes.isEmpty());
-
-                //该评论的点赞数量
-                communityArticleCommentVo.setCommentLikeCount(communityCommentLikeMapper
-                        .selectList(new QueryWrapper<CommunityCommentLike>()
-                                .eq("comment_id", communityArticleCommentVo.getId()))
+        List<CommunityArticleVo> communityArticleVos = new ArrayList<>();
+        if (!classCircles.isEmpty()) {
+
+            int offset = (pageNum - 1) * pageSize;
+            communityArticleVos = communityArticleMapper.selectCommunityArticleList(communityArticle, circleIds, offset, pageSize);
+            Long userId = SecurityUtils.getUserId();
+            for (CommunityArticleVo articleVo : communityArticleVos) {
+                //设置文章的点赞数量
+                articleVo.setLikeCount(communityLikeMapper
+                        .selectList(new QueryWrapper<CommunityLike>()
+                                .eq("article_id", articleVo.getId()))
                         .size());
-            }
 
-            //判断是否已收藏
-            CommunityArticleCollect collect = communityCollectMapper
-                    .selectOne(new QueryWrapper<CommunityArticleCollect>()
-                            .eq("user_id", userId)
-                            .eq("article_id", articleVo.getId()));
-            articleVo.setCollect(!Objects.isNull(collect));
-
-            //判断是否已点赞
-            CommunityLike like = communityLikeMapper
-                    .selectOne(new QueryWrapper<CommunityLike>()
-                            .eq("user_id", userId)
-                            .eq("article_id", articleVo.getId()));
-            articleVo.setLike(!Objects.isNull(like));
-
-            //获取文章标签
-            List<CommunityArticleTag> articleTags = communityArticleTagMapper
-                    .selectList(new QueryWrapper<CommunityArticleTag>()
-                            .eq("article_id", articleVo.getId()));
-            List<Long> tagIds = new ArrayList<>();
-            for (CommunityArticleTag articleTag : articleTags) {
-                tagIds.add(articleTag.getTagId());
-            }
+                //文章下的评论
+                List<CommunityArticleCommentVo> comments = articleVo.getComments();
+                for (CommunityArticleCommentVo communityArticleCommentVo : comments) {
+                    //获取评论的用户信息
+                    SysUser sysUser = sysUserMapper.selectUserById(communityArticleCommentVo.getUserId());
+                    communityArticleCommentVo.setUsername(sysUser.getUserName());
+                    communityArticleCommentVo.setAvatar(sysUser.getAvatar());
+                    //当前登录用户是否已点赞
+                    List<CommunityCommentLike> commentLikes = communityCommentLikeMapper
+                            .selectList(new QueryWrapper<CommunityCommentLike>()
+                                    .eq("comment_id", communityArticleCommentVo.getId()).eq("user_id", userId));
+                    communityArticleCommentVo.setCommentLike(!commentLikes.isEmpty());
+
+                    //该评论的点赞数量
+                    communityArticleCommentVo.setCommentLikeCount(communityCommentLikeMapper
+                            .selectList(new QueryWrapper<CommunityCommentLike>()
+                                    .eq("comment_id", communityArticleCommentVo.getId()))
+                            .size());
+                }
+
+                //判断是否已收藏
+                CommunityArticleCollect collect = communityCollectMapper
+                        .selectOne(new QueryWrapper<CommunityArticleCollect>()
+                                .eq("user_id", userId)
+                                .eq("article_id", articleVo.getId()));
+                articleVo.setCollect(!Objects.isNull(collect));
+
+                //判断是否已点赞
+                CommunityLike like = communityLikeMapper
+                        .selectOne(new QueryWrapper<CommunityLike>()
+                                .eq("user_id", userId)
+                                .eq("article_id", articleVo.getId()));
+                articleVo.setLike(!Objects.isNull(like));
+
+                //获取文章标签
+                List<CommunityArticleTag> articleTags = communityArticleTagMapper
+                        .selectList(new QueryWrapper<CommunityArticleTag>()
+                                .eq("article_id", articleVo.getId()));
+                List<Long> tagIds = new ArrayList<>();
+                for (CommunityArticleTag articleTag : articleTags) {
+                    tagIds.add(articleTag.getTagId());
+                }
+
+                if (!tagIds.isEmpty()) {
+                    List<CommunityTag> communityTags = communityTagMapper.selectBatchIds(tagIds);
+                    articleVo.setTags(communityTags);
+                }
 
-            if (!tagIds.isEmpty()) {
-                List<CommunityTag> communityTags = communityTagMapper.selectBatchIds(tagIds);
-                articleVo.setTags(communityTags);
             }
-
         }
         return communityArticleVos;
     }
@@ -323,4 +331,100 @@ public class CommunityArticleServiceImpl extends ServiceImpl<CommunityArticleMap
         }
         return communityCircleVos;
     }
+
+    /**
+     * 关注或取消关注用户粉丝/关注
+     *
+     * @param likeUserId 被关注人id
+     * @return 登录用户关注信息
+     */
+    @Override
+    public CommunityUserLike addOrDeleteUserLike(Long likeUserId) {
+        Long userId = SecurityUtils.getLoginUser().getUserId();  // 当前登录用户id
+        //1.检查是否已被当前用户关注
+        CommunityUserLike communityUserLike = communityUserLikeMapper.selectOne(new QueryWrapper<CommunityUserLike>()
+                .eq("user_id", userId)
+                .eq("like_user_id", likeUserId));
+        //2.1 没有则进行关注,返回关注列表信息
+        if (Objects.isNull(communityUserLike) || Objects.isNull(communityUserLike.getId())) {
+            communityUserLike = new CommunityUserLike();
+            communityUserLike.setUserId(userId);
+            communityUserLike.setLikeUserId(likeUserId);
+            communityUserLike.setCreateBy(userId);
+            communityUserLike.setCreateTime(DateUtils.parseDate(DateUtils.getTime()));
+            communityUserLikeMapper.insert(communityUserLike);
+
+            communityUserLike = communityUserLikeMapper.selectOne(new QueryWrapper<CommunityUserLike>()
+                    .eq("user_id", userId)
+                    .eq("like_user_id", likeUserId));
+            return communityUserLike;
+        }
+
+        //2.2 已关注则取消关注
+        communityUserLikeMapper.deleteById(communityUserLike);
+        return null;
+    }
+
+    /**
+     * 获取当前登录用户信息
+     *
+     * @param userId 用户id
+     * @return 用户信息
+     */
+    @Override
+    public CommunityUserInfoVo selectCommunityUserInfoById(Long userId) {
+        SysUser sysUser = sysUserMapper.selectUserById(userId);
+        CommunityUserInfo communityUserInfo = communityUserInfoMapper
+                .selectOne(new QueryWrapper<CommunityUserInfo>().eq("user_id", userId));
+        CommunityUserInfoVo communityUserInfoVo = new CommunityUserInfoVo();
+        BeanUtils.copyProperties(communityUserInfo, communityUserInfoVo);
+        communityUserInfoVo.setAvatar(sysUser.getAvatar());
+        communityUserInfoVo.setNickName(sysUser.getNickName());
+        communityUserInfoVo.setUserId(userId);
+        return communityUserInfoVo;
+    }
+
+    /**
+     * 获取关注列表
+     *
+     * @param userId 登录用户id
+     * @return 当前用户关注列表
+     */
+    @Override
+    public List<CommunityUserLikeVo> selectCommunityUserLikeList(Long userId) {
+        List<CommunityUserLike> communityUserLikes = communityUserLikeMapper.selectList(new QueryWrapper<CommunityUserLike>().eq("user_id", userId));
+        List<CommunityUserLikeVo> communityUserLikeVos = new ArrayList<>();
+        CommunityUserLikeVo communityUserLikeVo = null;
+        for (CommunityUserLike communityUserLike : communityUserLikes) {
+            communityUserLikeVo = new CommunityUserLikeVo();
+            SysUser sysUser = sysUserMapper.selectUserById(communityUserLike.getLikeUserId());
+            BeanUtils.copyProperties(communityUserLike, communityUserLikeVo);
+            communityUserLikeVo.setLikeUsername(sysUser.getUserName());
+            communityUserLikeVos.add(communityUserLikeVo);
+        }
+        return communityUserLikeVos;
+    }
+
+
+    /**
+     * 获取粉丝列表
+     *
+     * @param userId 登录用户id
+     * @return 当前用户粉丝列表
+     */
+    @Override
+    public List<CommunityUserLikeVo> selectUserFansList(Long userId) {
+        List<CommunityUserLike> communityUserLikes = communityUserLikeMapper.selectList(new QueryWrapper<CommunityUserLike>().eq("like_user_id", userId));
+        List<CommunityUserLikeVo> communityUserLikeVos = new ArrayList<>();
+        CommunityUserLikeVo communityUserLikeVo = null;
+        for (CommunityUserLike communityUserLike : communityUserLikes) {
+            communityUserLikeVo = new CommunityUserLikeVo();
+            BeanUtils.copyProperties(communityUserLike, communityUserLikeVo);
+            SysUser sysUser = sysUserMapper.selectUserById(communityUserLike.getUserId());
+            communityUserLikeVo.setUsername(sysUser.getUserName());
+            communityUserLikeVos.add(communityUserLikeVo);
+        }
+        return communityUserLikeVos;
+    }
+
 }

+ 36 - 1
ruoyi-generator/src/main/java/com/ruoyi/generator/service/ICommunityArticleService.java

@@ -4,6 +4,8 @@ import com.baomidou.mybatisplus.extension.service.IService;
 import com.ruoyi.generator.domain.Community.*;
 import com.ruoyi.generator.vo.CommunityArticleVo;
 import com.ruoyi.generator.vo.CommunityCircleVo;
+import com.ruoyi.generator.vo.CommunityUserInfoVo;
+import com.ruoyi.generator.vo.CommunityUserLikeVo;
 
 import java.text.ParseException;
 import java.util.List;
@@ -20,7 +22,7 @@ public interface ICommunityArticleService extends IService<CommunityArticle> {
      * @param communityArticle 文章信息
      * @return 文章信息集合
      */
-    List<CommunityArticleVo> selectCommunityArticleList(CommunityArticle communityArticle);
+    List<CommunityArticleVo> selectCommunityArticleList(CommunityArticle communityArticle, int pageNum, int pageSize);
 
     /**
      * 发布文章
@@ -86,8 +88,41 @@ public interface ICommunityArticleService extends IService<CommunityArticle> {
 
     /**
      * 根据板块获取圈子列表
+     *
      * @param classId 板块id
      * @return 圈子列表信息
      */
     List<CommunityCircleVo> selectCommunityCircleList(String classId);
+
+    /**
+     * 关注或取消关注用户粉丝/关注
+     *
+     * @param likeUserId 被关注人id
+     * @return 登录用户关注信息
+     */
+    CommunityUserLike addOrDeleteUserLike(Long likeUserId);
+
+    /**
+     * 获取当前登录用户信息
+     *
+     * @param userId 用户id
+     * @return 用户信息
+     */
+    CommunityUserInfoVo selectCommunityUserInfoById(Long userId);
+
+    /**
+     * 获取关注列表
+     *
+     * @param userId 登录用户id
+     * @return 当前用户关注列表
+     */
+    List<CommunityUserLikeVo> selectCommunityUserLikeList(Long userId);
+
+    /**
+     * 获取粉丝列表
+     *
+     * @param userId 登录用户id
+     * @return 当前用户粉丝列表
+     */
+    List<CommunityUserLikeVo> selectUserFansList(Long userId);
 }

+ 5 - 0
ruoyi-generator/src/main/java/com/ruoyi/generator/vo/CommunityCircleVo.java

@@ -44,6 +44,11 @@ public class CommunityCircleVo implements Serializable {
      */
     @ApiModelProperty("关注")
     private boolean isLike;
+    /**
+     * 封面url
+     */
+    @ApiModelProperty("封面url")
+    private String imageUrl;
     /**
     * 创建人
     */

+ 63 - 0
ruoyi-generator/src/main/java/com/ruoyi/generator/vo/CommunityUserInfoVo.java

@@ -0,0 +1,63 @@
+package com.ruoyi.generator.vo;
+
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+import javax.validation.constraints.NotNull;
+import java.io.Serializable;
+import java.util.Date;
+
+/**
+* 
+* @TableName community_user_info
+*/
+@Data
+public class CommunityUserInfoVo implements Serializable {
+
+    /**
+    * 唯一id
+    */
+    @NotNull(message="[唯一id]不能为空")
+    @ApiModelProperty("唯一id")
+    private Long id;
+    /**
+    * 用户id
+    */
+    @ApiModelProperty("用户id")
+    private Long userId;
+    /**
+     * 昵称
+     */
+    @ApiModelProperty("昵称")
+    private String nickName;
+    /**
+     * 头像地址
+     */
+    @ApiModelProperty("头像地址")
+    private String avatar;
+    /**
+     * 简介
+     */
+    @ApiModelProperty("简介")
+    private String profile;
+    /**
+    * 创建人
+    */
+    @ApiModelProperty("创建人")
+    private Long createBy;
+    /**
+    * 创建时间
+    */
+    @ApiModelProperty("创建时间")
+    private Date createTime;
+    /**
+    * 更新人
+    */
+    @ApiModelProperty("更新人")
+    private Long updateBy;
+    /**
+    * 更新时间
+    */
+    @ApiModelProperty("更新时间")
+    private Date updateTime;
+}

+ 60 - 0
ruoyi-generator/src/main/java/com/ruoyi/generator/vo/CommunityUserLikeVo.java

@@ -0,0 +1,60 @@
+package com.ruoyi.generator.vo;
+
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.annotation.TableName;
+import com.fasterxml.jackson.annotation.JsonFormat;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+import javax.validation.constraints.NotNull;
+import java.io.Serializable;
+import java.util.Date;
+
+/**
+* 用户关注表
+* @TableName community_user_like
+*/
+@Data
+@TableName("community_user_like")
+public class CommunityUserLikeVo implements Serializable {
+
+    /**
+    * 唯一id
+    */
+    @NotNull(message="[唯一id]不能为空")
+    @ApiModelProperty("唯一id")
+    @TableId("id")
+    private Long id;
+    /**
+    * 关注人id
+    */
+    @ApiModelProperty("关注人id")
+    private Long userId;
+    /**
+     * 关注人名称
+     */
+    @ApiModelProperty("关注人名称")
+    private String username;
+    /**
+    * 被关注人id
+    */
+    @ApiModelProperty("被关注人id")
+    private Long likeUserId;
+
+    /**
+     * 被关注人名称
+     */
+    @ApiModelProperty("被关注人名称")
+    private String likeUsername;
+    /**
+    * 创建人
+    */
+    @ApiModelProperty("创建人")
+    private Long createBy;
+    /**
+    * 创建时间
+    */
+    @ApiModelProperty("创建时间")
+    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
+    private Date createTime;
+}

+ 1 - 0
ruoyi-generator/src/main/resources/mapper/community/ArticleMapper.xml

@@ -143,6 +143,7 @@
                 </foreach>
             </if>
         </where>
+        limit #{offset},#{limit}
     </select>
 
     <select id="selectCommunityArticleCollectById" resultMap="CommunityCollectResult">

+ 60 - 0
ruoyi-system/src/main/java/com/ruoyi/system/domain/CommunityChatMsg.java

@@ -0,0 +1,60 @@
+package com.ruoyi.system.domain;
+
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.annotation.TableName;
+import com.fasterxml.jackson.annotation.JsonFormat;
+import lombok.Data;
+import org.hibernate.validator.constraints.Length;
+
+import javax.validation.constraints.NotNull;
+import javax.validation.constraints.Size;
+import java.io.Serializable;
+import java.util.Date;
+
+/**
+* 社区聊天信息
+* @TableName community_chat_msg
+*/
+@Data
+@TableName("community_chat_msg")
+public class CommunityChatMsg implements Serializable {
+
+    /**
+    * 唯一Id
+    */
+    @NotNull(message="[唯一Id]不能为空")
+    @TableId("id")
+    private Long id;
+    /**
+    * 内容
+    */
+    @Size(max= -1,message="编码长度不能超过-1")
+    @Length(max= -1,message="编码长度不能超过-1")
+    private String content;
+    /**
+    * 消息发送人id
+    */
+    private Long senderId;
+    /**
+    * 消息接收人id
+    */
+    private Long receiverId;
+    /**
+    * 创建时间
+    */
+    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
+    private Date createTime;
+    /**
+    * 更新时间
+    */
+    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
+    private Date updateTime;
+    /**
+    * 创建人
+    */
+    private Long createBy;
+    /**
+    * 更新人
+    */
+    private Long updateBy;
+}

+ 9 - 0
ruoyi-system/src/main/java/com/ruoyi/system/mapper/CommunityChatMsgMapper.java

@@ -0,0 +1,9 @@
+package com.ruoyi.system.mapper;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.ruoyi.system.domain.CommunityChatMsg;
+import org.apache.ibatis.annotations.Mapper;
+
+@Mapper
+public interface CommunityChatMsgMapper extends BaseMapper<CommunityChatMsg> {
+}

+ 7 - 0
ruoyi-system/src/main/java/com/ruoyi/system/service/ICommunityChatMsgService.java

@@ -0,0 +1,7 @@
+package com.ruoyi.system.service;
+
+import com.baomidou.mybatisplus.extension.service.IService;
+import com.ruoyi.system.domain.CommunityChatMsg;
+
+public interface ICommunityChatMsgService extends IService<CommunityChatMsg> {
+}

+ 11 - 0
ruoyi-system/src/main/java/com/ruoyi/system/service/impl/CommunityChatMsgServiceImpl.java

@@ -0,0 +1,11 @@
+package com.ruoyi.system.service.impl;
+
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import com.ruoyi.system.domain.CommunityChatMsg;
+import com.ruoyi.system.mapper.CommunityChatMsgMapper;
+import com.ruoyi.system.service.ICommunityChatMsgService;
+import org.springframework.stereotype.Service;
+
+@Service
+public class CommunityChatMsgServiceImpl extends ServiceImpl<CommunityChatMsgMapper, CommunityChatMsg> implements ICommunityChatMsgService {
+}

+ 3 - 0
ruoyi-ui/.env.development

@@ -7,5 +7,8 @@ ENV = 'development'
 # 若依管理系统/开发环境
 VUE_APP_BASE_API = '/dev-api'
 
+# websocket服务地址
+VUE_APP_SOCKET_SERVER = 'ws://localhost:8080/websocket/'
+
 # 路由懒加载
 VUE_CLI_BABEL_TRANSPILE_MODULES = true

+ 29 - 0
ruoyi-ui/src/main.js

@@ -37,6 +37,8 @@ import DictTag from '@/components/DictTag'
 import VueMeta from 'vue-meta'
 // 字典数据组件
 import DictData from '@/components/DictData'
+// webSocket工具
+import webSocket from "./utils/webSocket"
 
 // 全局方法挂载
 Vue.prototype.getDicts = getDicts
@@ -48,6 +50,7 @@ Vue.prototype.selectDictLabel = selectDictLabel
 Vue.prototype.selectDictLabels = selectDictLabels
 Vue.prototype.download = download
 Vue.prototype.handleTree = handleTree
+Vue.prototype.$websocket = webSocket
 
 // 全局组件挂载
 Vue.component('DictTag', DictTag)
@@ -78,6 +81,32 @@ Vue.use(Element, {
 
 Vue.config.productionTip = false
 
+let newVue = new Vue({
+  el: '#app',
+  created() {
+    //监听用户窗口是否关闭
+    window.addEventListener('beforeunload', this.closeSocket);
+  },
+  destroyed() {
+    window.removeEventListener('beforeunload', this.closeSocket);
+  },
+  methods: {
+    onBeforeUnload(event) {
+      // 在这里编写你想要执行的代码
+      // 例如:发送数据到服务器或者显示警告信息
+      // 设置event.returnValue以显示浏览器默认的警告信息
+      event.returnValue = '您可能有未保存的更改!';
+    },
+    closeSocket() {
+      //关闭websocket连接
+      this.$websocket.close();
+    }
+  },
+  router,
+  store,
+  render: h => h(App)
+})
+
 new Vue({
   el: '#app',
   router,

+ 5 - 0
ruoyi-ui/src/store/modules/user.js

@@ -1,5 +1,6 @@
 import { login, logout, getInfo } from '@/api/login'
 import { getToken, setToken, removeToken } from '@/utils/auth'
+import newVue from "@/main";
 
 const user = {
   state: {
@@ -65,6 +66,8 @@ const user = {
           commit('SET_ID', user.userId)
           commit('SET_NAME', user.userName)
           commit('SET_AVATAR', avatar)
+          //TODO 获取用户信息时检查socket连接状态并进行连接
+          newVue.$websocket.initWebSocket();
           resolve(res)
         }).catch(error => {
           reject(error)
@@ -79,6 +82,8 @@ const user = {
           commit('SET_TOKEN', '')
           commit('SET_ROLES', [])
           commit('SET_PERMISSIONS', [])
+          //TODO 用户退出登录后关闭连接
+          newVue.$websocket.close();
           removeToken()
           resolve()
         }).catch(error => {

+ 118 - 0
ruoyi-ui/src/utils/websocket.js

@@ -0,0 +1,118 @@
+import { Notification } from "element-ui";
+import { getToken } from "./auth";
+import store from '../store'
+
+var socket = null;//实例对象
+var lockReconnect = false; //是否真正建立连接
+var timeout = 20 * 1000; //20秒一次心跳
+var timeoutObj = null; //心跳倒计时
+var serverTimeoutObj = null; //服务心跳倒计时
+var timeoutnum = null; //断开 重连倒计时
+
+const initWebSocket = async () => {
+  if ("WebSocket" in window) {
+    if (!store.state.user.id) {
+      console.log("未登录!websocket工具获取不到userId")
+    }else {
+      const wsUrl = process.env.VUE_APP_SOCKET_SERVER + store.state.user.id;
+      socket = new WebSocket(wsUrl);
+      socket.onerror = webSocketOnError;
+      socket.onmessage = webSocketOnMessage;
+      socket.onclose = closeWebsocket;
+      socket.onopen = openWebsocket;
+    }
+  } else {
+    Notification.error({
+      title: "错误",
+      message: "您的浏览器不支持websocket,请更换Chrome或者Firefox",
+    });
+  }
+}
+
+//建立连接
+const openWebsocket = (e) => {
+  start();
+}
+
+const start = ()=> {
+  //开启心跳
+  timeoutObj && clearTimeout(timeoutObj);
+  serverTimeoutObj && clearTimeout(serverTimeoutObj);
+  timeoutObj = setTimeout(function() {
+    //这里发送一个心跳,后端收到后,返回一个心跳消息
+    if (socket.readyState == 1) {
+      //如果连接正常
+      // socket.send("heartbeat");
+    } else {
+      //否则重连
+      reconnect();
+    }
+    serverTimeoutObj = setTimeout(function() {
+      //超时关闭
+      socket.close();
+    }, timeout);
+  }, timeout);
+}
+
+//重新连接
+const reconnect =() => {
+  if (lockReconnect) {
+    return;
+  }
+  lockReconnect = true;
+  //没连接上会一直重连,设置延迟避免请求过多
+  timeoutnum && clearTimeout(timeoutnum);
+  timeoutnum = setTimeout(function() {
+    //新连接
+    initWebSocket();
+    lockReconnect = false;
+  }, 1000);
+}
+
+//重置心跳
+const reset =() => {
+  //清除时间
+  clearTimeout(timeoutObj);
+  clearTimeout(serverTimeoutObj);
+  //重启心跳
+  start();
+}
+
+const sendWebsocket = (message) =>{
+  socket.send(message);
+}
+
+const webSocketOnError = (e) => {
+  initWebSocket();
+  reconnect();
+
+}
+
+//服务器返回的数据
+const webSocketOnMessage = (e)=> {
+  //判断是否登录
+  if (getToken()) {
+    //window自定义事件
+    window.dispatchEvent(
+      new CustomEvent("onmessageWS", {
+        detail: {
+          data: JSON.parse(e?.data)
+        },
+      })
+    );
+  }
+  // socket.onmessage(e)
+  reset();
+}
+
+const closeWebsocket=(e) => {
+  reconnect();
+}
+
+//断开连接
+const close =() => {
+//WebSocket对象也有发送和关闭的两个方法,只需要在自定义方法中分别调用send()和close()即可实现。
+  socket.close();
+}
+//具体问题具体分析,把需要用到的方法暴露出去
+export default { initWebSocket, sendWebsocket, webSocketOnMessage, close };