Browse Source

Some backend code

xcbosa mbp16 2 năm trước cách đây
mục cha
commit
edeec054f4
35 tập tin đã thay đổi với 2094 bổ sung0 xóa
  1. BIN
      .DS_Store
  2. BIN
      src/.DS_Store
  3. BIN
      src/main/.DS_Store
  4. BIN
      src/main/java/.DS_Store
  5. BIN
      src/main/java/com/.DS_Store
  6. BIN
      src/main/java/com/yinjie/.DS_Store
  7. BIN
      src/main/java/com/yinjie/bbs_java/.DS_Store
  8. 16 0
      src/main/java/com/yinjie/bbs_java/annotation/Systemlog.java
  9. 79 0
      src/main/java/com/yinjie/bbs_java/aspect/SystemAspect.java
  10. 30 0
      src/main/java/com/yinjie/bbs_java/common/MyMetaObjectHandler.java
  11. 41 0
      src/main/java/com/yinjie/bbs_java/common/Result.java
  12. 38 0
      src/main/java/com/yinjie/bbs_java/common/ResultCodeMessage.java
  13. 144 0
      src/main/java/com/yinjie/bbs_java/common/WebSocketServer.java
  14. 26 0
      src/main/java/com/yinjie/bbs_java/config/MybatisPlusAutoConfiguration.java
  15. 25 0
      src/main/java/com/yinjie/bbs_java/config/MybatisPlusConfig.java
  16. 96 0
      src/main/java/com/yinjie/bbs_java/config/ShiroConfig.java
  17. 37 0
      src/main/java/com/yinjie/bbs_java/config/SwaggerConfig.java
  18. 16 0
      src/main/java/com/yinjie/bbs_java/config/WebSocketConfiguration.java
  19. 323 0
      src/main/java/com/yinjie/bbs_java/controller/ArticleController.java
  20. 113 0
      src/main/java/com/yinjie/bbs_java/controller/FocusAuthorController.java
  21. 48 0
      src/main/java/com/yinjie/bbs_java/controller/MailController.java
  22. 101 0
      src/main/java/com/yinjie/bbs_java/controller/MessageController.java
  23. 68 0
      src/main/java/com/yinjie/bbs_java/controller/PersonController.java
  24. 189 0
      src/main/java/com/yinjie/bbs_java/controller/UserController.java
  25. 153 0
      src/main/java/com/yinjie/bbs_java/controller/admin/AdminController.java
  26. 169 0
      src/main/java/com/yinjie/bbs_java/controller/admin/ArticleAuditController.java
  27. 141 0
      src/main/java/com/yinjie/bbs_java/controller/admin/NoticeController.java
  28. 19 0
      src/main/java/com/yinjie/bbs_java/dto/Achievement.java
  29. 60 0
      src/main/java/com/yinjie/bbs_java/dto/ChildComment.java
  30. 50 0
      src/main/java/com/yinjie/bbs_java/dto/ParComment.java
  31. 43 0
      src/main/java/com/yinjie/bbs_java/dto/UserDto.java
  32. 17 0
      src/main/java/com/yinjie/bbs_java/dto/vo/ArticleFilter.java
  33. 17 0
      src/main/java/com/yinjie/bbs_java/dto/vo/ArticleTypeFilter.java
  34. 17 0
      src/main/java/com/yinjie/bbs_java/dto/vo/MessageFilter.java
  35. 18 0
      src/main/java/com/yinjie/bbs_java/dto/vo/NoticeFilter.java

BIN
.DS_Store


BIN
src/.DS_Store


BIN
src/main/.DS_Store


BIN
src/main/java/.DS_Store


BIN
src/main/java/com/.DS_Store


BIN
src/main/java/com/yinjie/.DS_Store


BIN
src/main/java/com/yinjie/bbs_java/.DS_Store


+ 16 - 0
src/main/java/com/yinjie/bbs_java/annotation/Systemlog.java

@@ -0,0 +1,16 @@
+package com.yinjie.bbs_java.annotation;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+@Target({ElementType.TYPE, ElementType.METHOD})
+@Retention(RetentionPolicy.RUNTIME)
+public @interface Systemlog {
+    /**
+     * 描述
+     */
+    String desc();
+
+}

+ 79 - 0
src/main/java/com/yinjie/bbs_java/aspect/SystemAspect.java

@@ -0,0 +1,79 @@
+package com.yinjie.bbs_java.aspect;
+
+import com.yinjie.bbs_java.annotation.Systemlog;
+import com.yinjie.bbs_java.entity.SystemLog;
+import com.yinjie.bbs_java.service.SystemLogService;
+import com.yinjie.bbs_java.util.JwtUtils;
+import org.aspectj.lang.JoinPoint;
+import org.aspectj.lang.annotation.AfterReturning;
+import org.aspectj.lang.annotation.Aspect;
+import org.aspectj.lang.annotation.Pointcut;
+import org.aspectj.lang.reflect.MethodSignature;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.core.annotation.Order;
+import org.springframework.data.redis.core.RedisTemplate;
+import org.springframework.data.redis.serializer.RedisSerializer;
+import org.springframework.stereotype.Component;
+import org.springframework.web.context.request.RequestContextHolder;
+import org.springframework.web.context.request.ServletRequestAttributes;
+
+import javax.servlet.http.HttpServletRequest;
+import java.lang.reflect.Method;
+import java.net.Inet4Address;
+import java.net.UnknownHostException;
+
+@Aspect
+@Component
+@Order(-1)
+public class SystemAspect {
+
+    @Autowired
+    private SystemLogService SystemLogService;
+
+    @Autowired
+    private RedisTemplate redisTemplate;
+    //定义一个切入点
+    @Pointcut("@annotation(com.yinjie.bbs_java.annotation.Systemlog)")
+    public void operLog() {
+    }
+
+    @AfterReturning(pointcut = "operLog()", returning = "result")
+    public void doAfterReturning(JoinPoint joinPoint, Object result) throws UnknownHostException {
+        saveLog(joinPoint, result, null);
+    }
+    public void saveLog(JoinPoint joinPoint,Object result,Exception e) throws UnknownHostException {
+        // 获取reques对象
+        ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
+        HttpServletRequest request = (attributes == null ? null : attributes.getRequest());
+        String url = request.getServletPath();
+        //构造系统日志
+        SystemLog SystemLog = new SystemLog();
+        JwtUtils jwtUtils = new JwtUtils();
+        System.out.println(redisTemplate);
+        String userId = (String) redisTemplate.opsForValue().get("userId");
+        System.out.println(userId);
+        if(userId != null){
+            SystemLog.setUid(userId);
+        }else {
+            SystemLog.setUid("游客");
+        }
+
+        SystemLog.setIp(Inet4Address.getLocalHost().getHostAddress());
+        SystemLog.setUrl(url);
+        // 记录请求路径、请求描述
+        MethodSignature signature = (MethodSignature) joinPoint.getSignature();
+        SystemLog.setMethodName(String.valueOf(signature));
+        Method method = signature.getMethod();
+        if (method != null){
+            Systemlog SystemLog1 = (Systemlog) method.getAnnotation(Systemlog.class);
+            if (SystemLog1 != null){
+                SystemLog.setDescribe(SystemLog1.desc());
+            }
+        }
+
+        System.out.println(SystemLog);
+        SystemLogService.save(SystemLog);
+
+    }
+
+}

+ 30 - 0
src/main/java/com/yinjie/bbs_java/common/MyMetaObjectHandler.java

@@ -0,0 +1,30 @@
+package com.yinjie.bbs_java.common;
+
+import com.baomidou.mybatisplus.core.handlers.MetaObjectHandler;
+import lombok.extern.slf4j.Slf4j;
+import org.apache.ibatis.reflection.MetaObject;
+import org.springframework.stereotype.Component;
+
+import java.text.SimpleDateFormat;
+import java.time.LocalDateTime;
+import java.util.Date;
+
+@Slf4j
+@Component
+public class MyMetaObjectHandler implements MetaObjectHandler {
+
+    @Override
+    public void insertFill(MetaObject metaObject) {
+        log.info("start insert fill ....");
+        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd:HH:mm:ss");
+        this.setFieldValByName("createTime",simpleDateFormat.format(new Date()),metaObject);
+        this.setFieldValByName("updateTime",simpleDateFormat.format(new Date()),metaObject);
+    }
+
+    @Override
+    public void updateFill(MetaObject metaObject) {
+        log.info("start update fill ....");
+        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd:HH:mm:ss");
+        this.setFieldValByName("updateTime",simpleDateFormat.format(new Date()),metaObject);
+    }
+}

+ 41 - 0
src/main/java/com/yinjie/bbs_java/common/Result.java

@@ -0,0 +1,41 @@
+package com.yinjie.bbs_java.common;
+
+
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+import lombok.extern.slf4j.Slf4j;
+
+@Data
+@Slf4j
+@AllArgsConstructor
+@NoArgsConstructor
+public class Result<T> {
+    private int code;
+    private String message;
+    private T data;
+
+    public Result(int code, String message) {
+        this.code = code;
+        this.message = message;
+    }
+
+    public Result (ResultCodeMessage result){
+        this(result.getCode(), result.getMessage());
+    }
+
+    public Result(ResultCodeMessage result,T data){
+        this.code = result.getCode();
+        this.message = result.getMessage();
+        this.data = data;
+    }
+
+    public Result(T data){
+        this(ResultCodeMessage.SUCCESS,data);
+    }
+
+    public Result(Exception e){
+        this(ResultCodeMessage.FAIL.getCode(),e.getMessage());
+        log.error("请求失败了----》"+e.getMessage());
+    }
+}

+ 38 - 0
src/main/java/com/yinjie/bbs_java/common/ResultCodeMessage.java

@@ -0,0 +1,38 @@
+package com.yinjie.bbs_java.common;
+
+public enum ResultCodeMessage {
+    SUCCESS(0,"请求成功"),
+    FAIL(1,"请求失败"),
+    TOKEN_FAILURE(2,"token已经失效,请重新登录"),
+
+    USERNAME_OR_PASSWORD_EMPTY(100,"账号密码不能为空"),
+    NOT_EXIST_USER(101, "账号不存在"),
+    PASSWORD_ERROR(102, "账号或密码错误"),
+    EXIST_USER(103,"账号已经存在,请去登录"),
+    NOT_PERMISSIONS(104,"没有权限,请先登录"),
+    EXIST_SENSITIVE_WORDS(105,"文章存在敏感词"),
+    NOT_FOCUS_OWN(106,"不能关注自己");
+    private int code;
+    private String message;
+
+    ResultCodeMessage(int code, String message) {
+        this.code = code;
+        this.message = message;
+    }
+
+    public int getCode() {
+        return code;
+    }
+
+    public void setCode(int code) {
+        this.code = code;
+    }
+
+    public String getMessage() {
+        return message;
+    }
+
+    public void setMessage(String message) {
+        this.message = message;
+    }
+}

+ 144 - 0
src/main/java/com/yinjie/bbs_java/common/WebSocketServer.java

@@ -0,0 +1,144 @@
+package com.yinjie.bbs_java.common;
+
+import java.io.IOException;
+import java.util.concurrent.ConcurrentHashMap;
+import javax.websocket.OnClose;
+import javax.websocket.OnError;
+import javax.websocket.OnMessage;
+import javax.websocket.OnOpen;
+import javax.websocket.Session;
+import javax.websocket.server.PathParam;
+import javax.websocket.server.ServerEndpoint;
+
+import com.alibaba.fastjson.JSON;
+import com.alibaba.fastjson.JSONObject;
+import org.apache.commons.lang3.StringUtils;
+import org.springframework.stereotype.Component;
+import cn.hutool.log.Log;
+import cn.hutool.log.LogFactory;
+
+
+/**
+ * @author zhengkai.blog.csdn.net
+ */
+@ServerEndpoint("/websocketServer/{userId}")
+@Component
+public class WebSocketServer {
+
+    static Log log=LogFactory.get(WebSocketServer.class);
+    /**静态变量,用来记录当前在线连接数。应该把它设计成线程安全的。*/
+    private static int onlineCount = 0;
+    /**concurrent包的线程安全Set,用来存放每个客户端对应的MyWebSocket对象。*/
+    private static ConcurrentHashMap<String,WebSocketServer> webSocketMap = new ConcurrentHashMap<>();
+    /**与某个客户端的连接会话,需要通过它来给客户端发送数据*/
+    private Session session;
+    /**接收userId*/
+    private String userId="";
+
+    /**
+     * 连接建立成功调用的方法*/
+    @OnOpen
+    public void onOpen(Session session,@PathParam("userId") String userId) {
+        this.session = session;
+        this.userId=userId;
+        if(webSocketMap.containsKey(userId)){
+            webSocketMap.remove(userId);
+            webSocketMap.put(userId,this);
+            //加入set中
+        }else{
+            webSocketMap.put(userId,this);
+            //加入set中
+            addOnlineCount();
+            //在线数加1
+        }
+
+        log.info("用户连接:"+userId+",当前在线人数为:" + getOnlineCount());
+
+        //            sendMessage("连接成功");
+        log.info("连接成功");
+    }
+
+    /**
+     * 连接关闭调用的方法
+     */
+    @OnClose
+    public void onClose() {
+        if(webSocketMap.containsKey(userId)){
+            webSocketMap.remove(userId);
+            //从set中删除
+            subOnlineCount();
+        }
+        log.info("用户退出:"+userId+",当前在线人数为:" + getOnlineCount());
+    }
+
+    /**
+     * 收到客户端消息后调用的方法
+     *
+     * @param message 客户端发送过来的消息*/
+    @OnMessage
+    public void onMessage(String message, Session session) {
+        log.info("用户消息:"+userId+",报文:"+message);
+        //可以群发消息
+        //消息保存到数据库、redis
+        if(StringUtils.isNotBlank(message)){
+            try {
+                //解析发送的报文
+                JSONObject jsonObject = JSON.parseObject(message);
+                //追加发送人(防止串改)
+                jsonObject.put("fromUserId",this.userId);
+                String toUserId=jsonObject.getString("toUserId");
+                //传送给对应toUserId用户的websocket
+                if(StringUtils.isNotBlank(toUserId)&&webSocketMap.containsKey(toUserId)){
+                    webSocketMap.get(toUserId).sendMessage(jsonObject.toJSONString());
+                }else{
+                    log.error("请求的userId:"+toUserId+"不在该服务器上");
+                    //否则不在这个服务器上,发送到mysql或者redis
+                }
+            }catch (Exception e){
+                e.printStackTrace();
+            }
+        }
+    }
+
+    /**
+     *
+     * @param session
+     * @param error
+     */
+    @OnError
+    public void onError(Session session, Throwable error) {
+        log.error("用户错误:"+this.userId+",原因:"+error.getMessage());
+        error.printStackTrace();
+    }
+    /**
+     * 实现服务器主动推送
+     */
+    public void sendMessage(String message) throws IOException {
+        this.session.getBasicRemote().sendText(message);
+    }
+
+
+    /**
+     * 发送自定义消息
+     * */
+    public static void sendInfo(String message,@PathParam("userId") String userId) throws IOException {
+        log.info("发送消息到:"+userId+",报文:"+message);
+        if(StringUtils.isNotBlank(userId)&&webSocketMap.containsKey(userId)){
+            webSocketMap.get(userId).sendMessage(message);
+        }else{
+            log.error("用户"+userId+",不在线!");
+        }
+    }
+
+    public static synchronized int getOnlineCount() {
+        return onlineCount;
+    }
+
+    public static synchronized void addOnlineCount() {
+        WebSocketServer.onlineCount++;
+    }
+
+    public static synchronized void subOnlineCount() {
+        WebSocketServer.onlineCount--;
+    }
+}

+ 26 - 0
src/main/java/com/yinjie/bbs_java/config/MybatisPlusAutoConfiguration.java

@@ -0,0 +1,26 @@
+package com.yinjie.bbs_java.config;
+
+import com.baomidou.mybatisplus.autoconfigure.MybatisPlusPropertiesCustomizer;
+import com.baomidou.mybatisplus.core.MybatisConfiguration;
+import com.baomidou.mybatisplus.core.config.GlobalConfig;
+import com.baomidou.mybatisplus.core.handlers.MybatisEnumTypeHandler;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+
+@Configuration
+public class MybatisPlusAutoConfiguration {
+
+    @Bean
+    public MybatisPlusPropertiesCustomizer mybatisPlusPropertiesCustomizer() {
+        return properties -> {
+            GlobalConfig globalConfig = properties.getGlobalConfig();
+            globalConfig.setBanner(false);
+            MybatisConfiguration configuration = new MybatisConfiguration();
+            configuration.setDefaultEnumTypeHandler(MybatisEnumTypeHandler.class);
+            properties.setConfiguration(configuration);
+        };
+    }
+
+
+}
+

+ 25 - 0
src/main/java/com/yinjie/bbs_java/config/MybatisPlusConfig.java

@@ -0,0 +1,25 @@
+package com.yinjie.bbs_java.config;
+
+import com.baomidou.mybatisplus.annotation.DbType;
+import com.baomidou.mybatisplus.autoconfigure.ConfigurationCustomizer;
+import com.baomidou.mybatisplus.extension.plugins.MybatisPlusInterceptor;
+import com.baomidou.mybatisplus.extension.plugins.inner.PaginationInnerInterceptor;
+import org.mybatis.spring.annotation.MapperScan;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+
+@Configuration
+@MapperScan("com.yinjie.bbs_java.mapper")
+public class MybatisPlusConfig {
+
+    /**
+     * 新的分页插件,一缓和二缓遵循mybatis的规则,需要设置 MybatisConfiguration#useDeprecatedExecutor = false 避免缓存出现问题(该属性会在旧插件移除后一同移除)
+     */
+    @Bean
+    public MybatisPlusInterceptor mybatisPlusInterceptor() {
+        MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
+        interceptor.addInnerInterceptor(new PaginationInnerInterceptor(DbType.MYSQL));
+        return interceptor;
+    }
+
+}

+ 96 - 0
src/main/java/com/yinjie/bbs_java/config/ShiroConfig.java

@@ -0,0 +1,96 @@
+package com.yinjie.bbs_java.config;
+
+import com.yinjie.bbs_java.shiro.AccountRealm;
+import com.yinjie.bbs_java.shiro.JwtFilter;
+import org.apache.shiro.mgt.DefaultSessionStorageEvaluator;
+import org.apache.shiro.mgt.DefaultSubjectDAO;
+import org.apache.shiro.session.mgt.SessionManager;
+import org.apache.shiro.spring.LifecycleBeanPostProcessor;
+import org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor;
+import org.apache.shiro.spring.web.ShiroFilterFactoryBean;
+import org.apache.shiro.spring.web.config.DefaultShiroFilterChainDefinition;
+import org.apache.shiro.spring.web.config.ShiroFilterChainDefinition;
+import org.apache.shiro.web.mgt.DefaultWebSecurityManager;
+import org.apache.shiro.web.session.mgt.DefaultWebSessionManager;
+import org.crazycake.shiro.RedisCacheManager;
+import org.crazycake.shiro.RedisSessionDAO;
+import org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.apache.shiro.mgt.SecurityManager;
+import org.springframework.context.annotation.DependsOn;
+
+import javax.servlet.Filter;
+import java.util.HashMap;
+import java.util.LinkedHashMap;
+import java.util.Map;
+
+/**
+ * shiro启用注解拦截控制器
+ */
+@Configuration
+public class ShiroConfig {
+    @Autowired
+    JwtFilter jwtFilter;
+    @Bean
+    public SessionManager sessionManager(RedisSessionDAO redisSessionDAO) {
+        DefaultWebSessionManager sessionManager = new DefaultWebSessionManager();
+        sessionManager.setSessionDAO(redisSessionDAO);
+        return sessionManager;
+    }
+    @Bean
+    public DefaultWebSecurityManager securityManager(AccountRealm accountRealm,
+                                                     SessionManager sessionManager,
+                                                     RedisCacheManager redisCacheManager) {
+        DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager(accountRealm);
+        securityManager.setSessionManager(sessionManager);
+        securityManager.setCacheManager(redisCacheManager);
+        /*
+         * 关闭shiro自带的session,详情见文档
+         */
+        DefaultSubjectDAO subjectDAO = new DefaultSubjectDAO();
+        DefaultSessionStorageEvaluator defaultSessionStorageEvaluator = new DefaultSessionStorageEvaluator();
+        defaultSessionStorageEvaluator.setSessionStorageEnabled(false);
+        subjectDAO.setSessionStorageEvaluator(defaultSessionStorageEvaluator);
+        securityManager.setSubjectDAO(subjectDAO);
+        return securityManager;
+    }
+    @Bean
+    public ShiroFilterChainDefinition shiroFilterChainDefinition() {
+        DefaultShiroFilterChainDefinition chainDefinition = new DefaultShiroFilterChainDefinition();
+        Map<String, String> filterMap = new LinkedHashMap<>();
+        filterMap.put("/**", "jwt"); // 主要通过注解方式校验权限
+        chainDefinition.addPathDefinitions(filterMap);
+        return chainDefinition;
+    }
+    @Bean("shiroFilterFactoryBean")
+    public ShiroFilterFactoryBean shiroFilterFactoryBean(SecurityManager securityManager,
+                                                         ShiroFilterChainDefinition shiroFilterChainDefinition) {
+        ShiroFilterFactoryBean shiroFilter = new ShiroFilterFactoryBean();
+        shiroFilter.setSecurityManager(securityManager);
+        Map<String, Filter> filters = new HashMap<>();
+        filters.put("jwt", jwtFilter);
+        shiroFilter.setFilters(filters);
+        Map<String, String> filterMap = shiroFilterChainDefinition.getFilterChainMap();
+        shiroFilter.setFilterChainDefinitionMap(filterMap);
+        return shiroFilter;
+    }
+
+    // 开启注解代理(默认好像已经开启,可以不要)
+
+    @Bean
+    public AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor(SecurityManager securityManager){
+        AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor = new AuthorizationAttributeSourceAdvisor();
+        authorizationAttributeSourceAdvisor.setSecurityManager(securityManager);
+        return authorizationAttributeSourceAdvisor;
+    }
+    @Bean
+    public DefaultAdvisorAutoProxyCreator getDefaultAdvisorAutoProxyCreator() {
+        DefaultAdvisorAutoProxyCreator creator = new DefaultAdvisorAutoProxyCreator();
+        creator.setProxyTargetClass(true);
+        creator.setUsePrefix(true);
+        return creator;
+    }
+
+}

+ 37 - 0
src/main/java/com/yinjie/bbs_java/config/SwaggerConfig.java

@@ -0,0 +1,37 @@
+package com.yinjie.bbs_java.config;
+
+import io.swagger.annotations.ApiOperation;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import springfox.documentation.builders.ApiInfoBuilder;
+import springfox.documentation.builders.PathSelectors;
+import springfox.documentation.builders.RequestHandlerSelectors;
+import springfox.documentation.oas.annotations.EnableOpenApi;
+import springfox.documentation.service.ApiInfo;
+import springfox.documentation.service.Contact;
+import springfox.documentation.spi.DocumentationType;
+import springfox.documentation.spring.web.plugins.Docket;
+
+@EnableOpenApi   // 开启Swagger自定义接口文档
+@Configuration   // 相当于Spring配置中的<beans>
+public class SwaggerConfig {
+    @Bean   // 相当于Spring 配置中的<bean>
+    public Docket createRestApi() {
+        return new Docket(DocumentationType.OAS_30)
+                .apiInfo(apiInfo())
+                .select()
+                .apis(RequestHandlerSelectors.withMethodAnnotation(ApiOperation.class))
+                .paths(PathSelectors.any())
+                .build();
+    }
+    // API基础信息定义(就是更新Swagger默认页面上的信息)
+    private ApiInfo apiInfo() {
+        return new ApiInfoBuilder()
+                .title("No404网站接口文档")
+                .description("文档描述:更多问题,请联系开发者")
+                .contact(new Contact("Jack", "http://localhost:8888", "2240581781@qq.com"))
+                .version("1.0")
+                .build();
+    }
+
+}

+ 16 - 0
src/main/java/com/yinjie/bbs_java/config/WebSocketConfiguration.java

@@ -0,0 +1,16 @@
+package com.yinjie.bbs_java.config;
+
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.web.socket.config.annotation.EnableWebSocket;
+import org.springframework.web.socket.server.standard.ServerEndpointExporter;
+
+@Configuration
+@EnableWebSocket
+public class WebSocketConfiguration {
+
+    @Bean
+    public ServerEndpointExporter serverEndpointExporter() {
+        return new ServerEndpointExporter();
+    }
+}

+ 323 - 0
src/main/java/com/yinjie/bbs_java/controller/ArticleController.java

@@ -0,0 +1,323 @@
+package com.yinjie.bbs_java.controller;
+
+
+import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
+import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.yinjie.bbs_java.annotation.Systemlog;
+import com.yinjie.bbs_java.common.Result;
+import com.yinjie.bbs_java.common.ResultCodeMessage;
+import com.yinjie.bbs_java.common.WebSocketServer;
+import com.yinjie.bbs_java.dto.Achievement;
+import com.yinjie.bbs_java.dto.ChildComment;
+import com.yinjie.bbs_java.dto.ParComment;
+import com.yinjie.bbs_java.dto.vo.ArticleFilter;
+import com.yinjie.bbs_java.dto.vo.ArticleTypeFilter;
+import com.yinjie.bbs_java.entity.*;
+import com.yinjie.bbs_java.service.*;
+import com.yinjie.bbs_java.util.filter.WordFilter;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import org.apache.shiro.authz.annotation.RequiresAuthentication;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.*;
+import javax.validation.Valid;
+import java.io.IOException;
+import java.util.HashMap;
+import java.util.List;
+
+/**
+ * <p>
+ *  前端控制器
+ * </p>
+ *
+ * @author Jack
+ * @since 2022-03-09 15:57:10
+ */
+@RestController
+@RequestMapping("/article")
+@Api(tags = "主页文章接口")
+public class ArticleController {
+
+    @Autowired
+    private ArticleService articleService;
+
+    @Autowired
+    private ArticleTypeService articleTypeService;
+
+    @Autowired
+    private ParCommentService parCommentService;
+
+    @Autowired
+    private ChildCommentService childCommentService;
+
+    @Autowired
+    private UserService userService;
+
+    @Autowired
+    private UserCollectionService userCollectionService;
+
+    @Autowired
+    private MessageService messageService;
+
+
+    @ApiOperation(value = "主页接口",notes = "展示主页列表")
+    @GetMapping()
+    public Result<IPage> index(@RequestParam(defaultValue = "article") String category,
+                                  Integer type_id,
+                               @RequestParam(defaultValue = "1",name = "page") Integer page,
+                               String title){
+        Page<Article> page1 = new Page<>(page,10);
+        IPage<Article> page2 = articleService.selectArticlePage(page1, category, type_id,title);
+        return new Result<IPage>(page2);
+    }
+
+    @ApiOperation(value = "后台文章类型接口",notes = "提供类型列表")
+    @GetMapping("/typeList")
+    public Result<List<ArticleType>> selectTypes(ArticleTypeFilter articleTypeFilter){
+        try {
+            QueryWrapper<ArticleType> articleTypeQueryWrapper = new QueryWrapper<>();
+            if (articleTypeFilter != null){
+                if (articleTypeFilter.getType() != null && articleTypeFilter.getType() != ""){
+                    articleTypeQueryWrapper.eq("type",articleTypeFilter.getType());
+                }
+                if (articleTypeFilter.getCreatorId() != null){
+                    articleTypeQueryWrapper.eq("creator_id",articleTypeFilter.getCreatorId());
+                }
+                if (articleTypeFilter.getStartTime() != null){
+                    articleTypeQueryWrapper.gt("type",articleTypeFilter.getType());
+                }
+                if (articleTypeFilter.getEndTime() != null){
+                    articleTypeQueryWrapper.eq("type",articleTypeFilter.getType());
+                }
+            }
+            List<ArticleType> typeLists = articleTypeService.list(articleTypeQueryWrapper);
+            return new Result<List<ArticleType>>(typeLists);
+        } catch (Exception e) {
+            return new Result<>(e);
+        }
+    }
+
+    @ApiOperation(value = "前台文章类型接口",notes = "提供类型列表")
+    @GetMapping("/typeList1")
+    public Result<List<ArticleType>> selectTypes(){
+        try {
+            List<ArticleType> typeLists = articleTypeService.list(new QueryWrapper<ArticleType>().eq("status",0));
+            return new Result<List<ArticleType>>(typeLists);
+        } catch (Exception e) {
+            return new Result<>(e);
+        }
+    }
+
+    @Systemlog(desc = "用户发布了文章")
+    @ApiOperation(value = "发布文章接口",notes = "发布文章")
+    @RequiresAuthentication
+    @PostMapping("/post")
+    public Result postArticle(@Valid @RequestBody Article article){
+        try {
+            String context = article.getContent() + article.getTitle();
+            //敏感词过滤
+            String sensitiveWord = WordFilter.replaceWords(context);
+            List<String> sensitiveWord1 = WordFilter.getSensitiveWord(context, 1);
+            System.out.println(sensitiveWord1);
+            if (!sensitiveWord1.isEmpty()){
+                return new Result(ResultCodeMessage.EXIST_SENSITIVE_WORDS,sensitiveWord1);
+            }
+            //默认都是未审核
+            article.setStatus(1);
+            articleService.saveOrUpdate(article);
+            return new Result(ResultCodeMessage.SUCCESS);
+        } catch (Exception e) {
+            return new Result(e);
+        }
+    }
+
+    @Systemlog(desc = "浏览文章详细")
+    @ApiOperation(value = "文章详情",notes = "通过id查询文章详情")
+    @GetMapping("/articleDetail")
+    public Result selectArticleById(Integer articleId){
+        Article article = articleService.selectArticleById(articleId);
+        return new Result(article);
+    }
+
+    @Systemlog(desc = "查询我的成就")
+    @ApiOperation(value = "我的成就接口",notes = "查询我的成就")
+    @RequiresAuthentication
+    @GetMapping("/achievement")
+    public Result selectAchievement(String authorId){
+        HashMap<String, String> map = new HashMap<>();
+        map.put("author_id",authorId);
+        map.put("category","article");
+        long articleCount = articleService.count(new QueryWrapper<Article>().allEq(map));
+        map.clear();
+        map.put("author_id",authorId);
+        map.put("category","answer");
+        long answerCount = articleService.count(new QueryWrapper<Article>().allEq(map));
+        Article article = articleService.getOne(new QueryWrapper<Article>().select("sum(approves) as approvesCount").eq("author_id",authorId));
+        Achievement achievement = new Achievement();
+        achievement.setArticleCount(articleCount);
+        achievement.setAnswerCount(answerCount);
+        if (article != null){
+            achievement.setApproves(article.getApprovesCount());
+        }else {
+            achievement.setApproves(0l);
+        }
+        return new Result(achievement);
+    }
+
+
+    @Systemlog(desc = "用户删除了自己的文章")
+    @RequiresAuthentication
+    @ApiOperation(value = "删除文章接口",notes = "删除自己的文章")
+    @GetMapping("/deleteArticle")
+    public Result deleteArticle(Integer articleId){
+        try {
+            articleService.removeById(articleId);
+            return new Result(ResultCodeMessage.SUCCESS);
+        } catch (Exception e) {
+            return new Result(e);
+        }
+    }
+
+    @Systemlog(desc = "用户点赞了文章")
+    @RequiresAuthentication
+    @ApiOperation(value = "点赞接口",notes = "点赞和取消点赞")
+    @GetMapping("/approve")
+    public Result approve(Integer id,boolean good){
+        Article article = articleService.getById(id);
+        UpdateWrapper<Article> articleUpdateWrapper = new UpdateWrapper<>();
+        articleUpdateWrapper.eq("id",id);
+        if (good){
+            articleUpdateWrapper.set("approves",article.getApproves() + 1);
+            articleService.update(articleUpdateWrapper);
+        }else {
+            articleUpdateWrapper.set("approves",article.getApproves() - 1);
+            articleService.update(articleUpdateWrapper);
+        }
+        return new Result(ResultCodeMessage.SUCCESS);
+    }
+
+    @ApiOperation(value = "评论接口",notes = "根据文章id查出该文章所有的评论")
+    @GetMapping("/selectComment")
+    public Result selectComment(Integer id){
+        List<ParComment> parComments = articleService.selectComment(id);
+        parComments.forEach(s -> System.out.println(s));
+        return new Result(parComments);
+    }
+
+    @Systemlog(desc = "用户进行了评论")
+    @RequiresAuthentication
+    @ApiOperation(value = "父评论接口",notes = "一级评论的添加")
+    @PostMapping("/addParComment")
+    public Result addParComment(@Valid @RequestBody ParComment parComment){
+        Article article = articleService.getById(parComment.getArticleId());
+        User user = userService.getById(parComment.getUserId());
+        try {
+                WebSocketServer.sendInfo(user.getEmail()+"用户评论了你的文章",article.getAuthorId());
+            Message message = new Message();
+            message.setOriId(parComment.getUserId());
+            message.setDesId(user.getId());
+            message.setContent("评论了你");
+            message.setMesType(0);
+            message.setStatus(0);
+            messageService.save(message);
+        } catch (IOException e) {
+            e.printStackTrace();
+        }
+        parCommentService.save(parComment);
+
+        //评论数加一
+        articleService.update(new UpdateWrapper<Article>().set("comments",article.getComments() + 1).eq("id",article.getId()));
+        return new Result(ResultCodeMessage.SUCCESS);
+    }
+
+    @Systemlog(desc = "用户进行了评论")
+    @RequiresAuthentication
+    @ApiOperation(value = "子评论接口",notes = "二级评论的添加")
+    @PostMapping("/addChildComment")
+    public Result addChildComment(@Valid @RequestBody ChildComment childComment){
+        //给被评论者发一个提示信息,提示他的评论被别人回复了
+        try {
+            System.out.println("是否有回复者,id为========》"+childComment.getReplyReplyId().equals(""));
+            if (childComment.getReplyReplyId() != null && !childComment.getReplyReplyId().equals("")){
+                WebSocketServer.sendInfo(childComment.getReplyEmail()+"用户回复了你的评论",childComment.getReplyReplyId());
+                Message message = new Message();
+                message.setOriId(childComment.getReplyId());
+                message.setDesId(childComment.getReplyReplyId());
+                message.setContent("回复了你");
+                message.setMesType(0);
+                message.setStatus(0);
+                messageService.save(message);
+            }else {
+                ParComment parComment = parCommentService.getById(childComment.getParentId());
+                WebSocketServer.sendInfo(childComment.getReplyEmail()+"用户回复了你的评论",parComment.getUserId());
+                Message message = new Message();
+                message.setOriId(childComment.getReplyId());
+                message.setDesId(parComment.getUserId());
+                message.setContent("回复了你");
+                message.setMesType(0);
+                message.setStatus(0);
+                messageService.save(message);
+            }
+        } catch (IOException e) {
+            e.printStackTrace();
+        }
+        childCommentService.save(childComment);
+        Article article = articleService.getById(childComment.getArticleId());
+        //评论数加一
+        articleService.update(new UpdateWrapper<Article>().set("comments",article.getComments() + 1).eq("id",article.getId()));
+        return new Result(ResultCodeMessage.SUCCESS);
+    }
+
+    @ApiOperation(value = "浏览记录接口",notes = "记录浏览数量")
+    @GetMapping("/addviews")
+    public Result addview(Integer articleId){
+        Article article = articleService.getById(articleId);
+        System.out.println("点赞的文章是========》"+article);
+        articleService.update(new UpdateWrapper<Article>().set("views",article.getViews() + 1).eq("id",articleId));
+        return new Result(ResultCodeMessage.SUCCESS);
+    }
+
+    @Systemlog(desc = "用户收藏了文章")
+    @ApiOperation(value = "收藏文章接口",notes = "用于收藏文章")
+    @PostMapping("/addCollection")
+    @RequiresAuthentication
+    public Result addCollection(@RequestBody UserCollection userCollection){
+        System.out.println(userCollection);
+        try {
+            if (userCollection.getIsCollection() == 1){
+                userCollectionService.save(userCollection);
+                //该文章收藏+1
+                Article article = articleService.getById(userCollection.getArticleId());
+                articleService.update(new UpdateWrapper<Article>().set("collections",article.getCollections()+1).eq("id",article.getId()));
+
+            }else {
+                HashMap<String, Object> map = new HashMap<>();
+                map.put("article_id",userCollection.getArticleId());
+                map.put("user_id",userCollection.getUserId());
+                userCollectionService.remove(new QueryWrapper<UserCollection>().allEq(map));
+            }
+
+        } catch (Exception e) {
+            e.printStackTrace();
+            return new Result(e);
+        }
+        return new Result(ResultCodeMessage.SUCCESS);
+    }
+
+    @ApiOperation(value = "查询所有文章",notes = "用于管理员查询所有文章")
+    @GetMapping("/selectALLArticle")
+    public Result selectALLArticle(ArticleFilter articleFilter){
+        System.out.println(articleFilter);
+        List<Article> articleList = articleService.selectALLArticle(articleFilter);
+        return new Result(articleList);
+    }
+
+    @ApiOperation(value = "查询同类型的文章五条",notes = "")
+    @GetMapping("/selectArticleByType")
+    public Result selectArticleByType(Integer typeId){
+        List<Article> articleList = articleService.selectArticleByType(typeId);
+        return new Result(articleList);
+    }
+}

+ 113 - 0
src/main/java/com/yinjie/bbs_java/controller/FocusAuthorController.java

@@ -0,0 +1,113 @@
+package com.yinjie.bbs_java.controller;
+
+
+import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
+import com.yinjie.bbs_java.annotation.Systemlog;
+import com.yinjie.bbs_java.common.Result;
+import com.yinjie.bbs_java.common.ResultCodeMessage;
+import com.yinjie.bbs_java.common.WebSocketServer;
+import com.yinjie.bbs_java.entity.FocusAuthor;
+import com.yinjie.bbs_java.entity.Message;
+import com.yinjie.bbs_java.entity.UserCollection;
+import com.yinjie.bbs_java.service.FocusAuthorService;
+import com.yinjie.bbs_java.service.MessageService;
+import com.yinjie.bbs_java.service.UserCollectionService;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.*;
+
+import java.io.IOException;
+import java.util.HashMap;
+
+/**
+ * <p>
+ *  前端控制器
+ * </p>
+ *
+ * @author Jack
+ * @since 2022-03-13 17:01:47
+ */
+@RestController
+@RequestMapping("/focus_author")
+@Api(tags = "关注接口")
+public class FocusAuthorController {
+
+    @Autowired
+    private FocusAuthorService focusAuthorService;
+
+    @Autowired
+    private UserCollectionService userCollectionService;
+
+    @Autowired
+    private MessageService messageService;
+
+    @Systemlog(desc = "用户关注了别人")
+    @ApiOperation(value = "点击关注",notes = "在文章详情的页面,选择关注作者")
+    @GetMapping()
+    public Result focus_author(String focusId,String focusedId, boolean isfocus){
+        if (focusedId.equals(focusId)){
+            return new Result(ResultCodeMessage.NOT_FOCUS_OWN);
+        }
+        FocusAuthor focusAuthor = new FocusAuthor();
+        focusAuthor.setFocusId(focusId);
+        focusAuthor.setFocusedId(focusedId);
+        System.out.println(focusAuthor);
+        if (isfocus){
+            System.out.println(focusAuthor);
+            focusAuthorService.save(focusAuthor);
+            try {
+                WebSocketServer.sendInfo("有人关注了你!",focusedId);
+                Message message = new Message();
+                message.setOriId(focusId);
+                message.setDesId(focusedId);
+                message.setContent("关注了你");
+                message.setMesType(0);
+                message.setStatus(0);
+                messageService.save(message);
+            } catch (IOException e) {
+                e.printStackTrace();
+            }
+        }else {
+            HashMap<String, String> map = new HashMap<>();
+            map.put("focus_id",focusAuthor.getFocusId());
+            map.put("focused_id",focusAuthor.getFocusedId());
+            focusAuthorService.remove(new QueryWrapper<FocusAuthor>().allEq(map));
+        }
+        return new Result(ResultCodeMessage.SUCCESS);
+    }
+
+    @ApiOperation(value = "查询是否关注作者和收藏文章的接口",notes = "用来判断关注和收藏的样式是否是已关注..")
+    @GetMapping("/isFocusOrCollection")
+    public Result isFocusOrCollection(Integer articleId,String authorId,String focusId){
+        boolean isFocus = false;
+        boolean isCollection = false;
+        //查询用户是否关注该文章
+        HashMap<String, Object> map = new HashMap<>();
+        System.out.println(focusId);
+        if (focusId == null || focusId == ""){
+            map.put("isFocus",isFocus);
+            map.put("isCollection",isCollection);
+            return new Result(map);
+        }
+        map.put("focus_id",focusId);
+        map.put("focused_id",authorId);
+        FocusAuthor focusAuthor = focusAuthorService.getOne(new QueryWrapper<FocusAuthor>().allEq(map));
+        System.out.println("=================有没有======"+focusAuthor);
+        if (focusAuthor != null){
+            isFocus = true;
+        }
+        //查询用户是否收藏该文章
+        map.clear();
+        map.put("article_id",articleId);
+        map.put("user_id",focusId);
+        UserCollection userCollection = userCollectionService.getOne(new QueryWrapper<UserCollection>().allEq(map));
+        if (userCollection != null){
+            isCollection = true;
+        }
+        map.clear();
+        map.put("isFocus",isFocus);
+        map.put("isCollection",isCollection);
+        return new Result(map);
+    }
+}

+ 48 - 0
src/main/java/com/yinjie/bbs_java/controller/MailController.java

@@ -0,0 +1,48 @@
+package com.yinjie.bbs_java.controller;
+
+import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
+import com.yinjie.bbs_java.annotation.Systemlog;
+import com.yinjie.bbs_java.common.Result;
+import com.yinjie.bbs_java.common.ResultCodeMessage;
+import com.yinjie.bbs_java.email.servive.MailService;
+import com.yinjie.bbs_java.entity.User;
+import com.yinjie.bbs_java.service.UserService;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.util.StringUtils;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestMethod;
+import org.springframework.web.bind.annotation.RestController;
+
+import java.util.Random;
+
+@Slf4j
+@RestController
+@RequestMapping("/mail")
+@Api(tags = "发送邮件接口")
+public class MailController {
+    @Autowired
+    private MailService mailService;
+
+    @Autowired
+    private UserService userService;
+
+    @ApiOperation(value = "验证码接口",notes = "获取验证码")
+    @RequestMapping(value = "/getCheckCode", method = RequestMethod.POST)
+    public Result<String> getCheckCode(@RequestBody User user){
+        User user1 = userService.getOne(new QueryWrapper<User>().eq("email", user.getEmail()));
+        log.info("进入方法getCheckCode:"+user.toString());
+        String checkCode = String.valueOf(new Random().nextInt(899999) + 100000);
+        String message = "您的注册验证码为:"+checkCode;
+        try {
+            mailService.sendSimpleMail(user.getEmail(), "注册验证码", message);
+        }catch (Exception e){
+            return new Result(e);
+        }
+
+        return new Result<>(checkCode);
+    }
+}

+ 101 - 0
src/main/java/com/yinjie/bbs_java/controller/MessageController.java

@@ -0,0 +1,101 @@
+package com.yinjie.bbs_java.controller;
+
+import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
+import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
+import com.yinjie.bbs_java.common.Result;
+import com.yinjie.bbs_java.dto.vo.MessageFilter;
+import com.yinjie.bbs_java.entity.Message;
+import com.yinjie.bbs_java.service.MessageService;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.util.ObjectUtils;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+import java.util.List;
+
+@RestController
+@Api(tags = {"消息接口"})
+@RequestMapping("/message")
+public class MessageController {
+
+    @Autowired
+    private MessageService messageService;
+
+    @ApiOperation(value = "消息列表",notes = "根据用户id查询消息")
+    @GetMapping("/selectAllMessage")
+    public Result selectAllMessage(String uid){
+        List<Message> messageList = messageService.selectAllMessage(uid);
+        return new Result(messageList);
+    }
+
+    @ApiOperation(value = "消息列表",notes = "查询所有消息")
+    @GetMapping("/selectAllMessage1")
+    public Result selectAllMessage1(MessageFilter messageFilter){
+        QueryWrapper<Message> messageQueryWrapper = new QueryWrapper<>();
+        if (messageFilter != null){
+            if (!ObjectUtils.isEmpty(messageFilter.getOriId())){
+                messageQueryWrapper.eq("ori_id",messageFilter.getOriId());
+            }
+            if (!ObjectUtils.isEmpty(messageFilter.getDesId())){
+                messageQueryWrapper.eq("des_id",messageFilter.getDesId());
+            }
+            if (!ObjectUtils.isEmpty(messageFilter.getStartTime())){
+                messageQueryWrapper.ge("create_time",messageFilter.getStartTime());
+            }
+            if (!ObjectUtils.isEmpty(messageFilter.getEndTime())){
+                messageQueryWrapper.le("create_time",messageFilter.getEndTime());
+            }
+        }
+        List<Message> messageList = messageService.list(messageQueryWrapper);
+        return new Result(messageList);
+    }
+
+    @ApiOperation(value = "更新消息状态",notes = "可以将消息设置为已读还是未读")
+    @GetMapping("/updateStatus")
+    public Result updateStatus(Integer id, Integer status){
+        try {
+            messageService.update(new UpdateWrapper<Message>().set("status", status).eq("id", id));
+            Message message = messageService.getOne(new QueryWrapper<Message>().eq("id", id));
+            return new Result(message);
+        } catch (Exception e) {
+            e.printStackTrace();
+            return new Result(e);
+        }
+    }
+
+    @ApiOperation(value = "一键已读接口",notes = "批量将消息改成已读")
+    @GetMapping("/updateStatusBatch")
+    public Result updateStatusBatch(String uid){
+        try {
+            messageService.update(new UpdateWrapper<Message>().set("status",1).eq("des_id",uid));
+            List<Message> messageList = messageService.selectAllMessage(uid);
+            return new Result(messageList);
+        } catch (Exception e) {
+            e.printStackTrace();
+            return new Result(e);
+        }
+    }
+
+    @ApiOperation(value = "一键清楚消息接口",notes = "将某个用户的消息全部删除")
+    @GetMapping("/deleteMessageBatch")
+    public Result deleteMessageBatch(String uid){
+        try {
+            messageService.remove(new QueryWrapper<Message>().eq("des_id",uid));
+            List<Message> messageList = messageService.selectAllMessage(uid);
+            return new Result(messageList);
+        } catch (Exception e) {
+            e.printStackTrace();
+            return new Result(e);
+        }
+    }
+
+    @ApiOperation(value = "未读消息数量",notes = "可以查询是否有未读的消息")
+    @GetMapping("/selectUnread")
+    public Result selectUnread(String uid){
+        List<Message> messageList = messageService.list(new QueryWrapper<Message>().eq("status",0).eq("des_id",uid));
+        return new Result(messageList.size());
+    }
+}

+ 68 - 0
src/main/java/com/yinjie/bbs_java/controller/PersonController.java

@@ -0,0 +1,68 @@
+package com.yinjie.bbs_java.controller;
+
+import com.yinjie.bbs_java.annotation.Systemlog;
+import com.yinjie.bbs_java.common.Result;
+import com.yinjie.bbs_java.dto.UserDto;
+import com.yinjie.bbs_java.entity.Article;
+import com.yinjie.bbs_java.service.ArticleService;
+import com.yinjie.bbs_java.service.UserService;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import org.apache.shiro.authz.annotation.RequiresAuthentication;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestParam;
+import org.springframework.web.bind.annotation.RestController;
+
+import java.util.HashMap;
+import java.util.List;
+
+@RestController
+@RequestMapping("/person")
+@Api(tags = "个人主页接口")
+public class PersonController {
+
+    @Autowired
+    private ArticleService articleService;
+
+    @Autowired
+    private UserService userService;
+
+    @Systemlog(desc = "用户查看了自己发布的文章")
+    @RequiresAuthentication
+    @GetMapping("/personArticle")
+    @ApiOperation(value = "查询个人发布的文章",notes = "个人文章")
+    public Result SelectPersonArticle(String uid, @RequestParam(value = "category",defaultValue = "article") String category){
+        System.out.println(uid);
+        List<Article> articleList = articleService.selectPersonArticle(uid,category);
+        return new Result(articleList);
+    }
+
+
+    @Systemlog(desc = "用户查看了关注我的人和我关注的人")
+    @RequiresAuthentication
+    @GetMapping("/myfocus")
+    @ApiOperation(value = "关注的人和关注我的人接口",notes = "显示我关注的,和关注我的人")
+    public Result SelectMyFocus(String uid){
+        HashMap<String, List<UserDto>> map = new HashMap<>();
+        //我关注的
+        List<UserDto> MyFocus = userService.SelectMyFocus(uid);
+        //关注我的
+        List<UserDto> MyFocused = userService.SelectMyFocused(uid);
+        map.put("MyFocus",MyFocus);
+        map.put("MyFocused",MyFocused);
+        return new Result(map);
+    }
+
+    @Systemlog(desc = "用户查看了自己收藏的文章")
+    @RequiresAuthentication
+    @GetMapping("/myCollection")
+    @ApiOperation(value = "我收藏的文章",notes = "展示我收藏的文章")
+    public Result SelectMyCollection(String uid){
+        List<Article> articleList = articleService.selectMyCollection(uid);
+        return new Result(articleList);
+    }
+
+
+}

+ 189 - 0
src/main/java/com/yinjie/bbs_java/controller/UserController.java

@@ -0,0 +1,189 @@
+package com.yinjie.bbs_java.controller;
+
+
+
+import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
+import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
+
+
+import com.yinjie.bbs_java.annotation.Systemlog;
+import com.yinjie.bbs_java.common.Result;
+import com.yinjie.bbs_java.common.ResultCodeMessage;
+import com.yinjie.bbs_java.dto.ChildComment;
+import com.yinjie.bbs_java.dto.ParComment;
+import com.yinjie.bbs_java.dto.UserDto;
+import com.yinjie.bbs_java.entity.User;
+import com.yinjie.bbs_java.service.ChildCommentService;
+import com.yinjie.bbs_java.service.ParCommentService;
+import com.yinjie.bbs_java.service.UserService;
+
+import com.yinjie.bbs_java.util.JwtUtils;
+import com.yinjie.bbs_java.util.SaltUtil;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import org.apache.shiro.SecurityUtils;
+import org.apache.shiro.authz.annotation.RequiresAuthentication;
+import org.apache.shiro.crypto.hash.Md5Hash;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.data.redis.core.RedisTemplate;
+import org.springframework.util.StringUtils;
+import org.springframework.web.bind.annotation.*;
+import org.springframework.web.multipart.MultipartFile;
+
+import javax.servlet.http.HttpServletResponse;
+import javax.validation.Valid;
+import com.yinjie.bbs_java.util.qiniuyun.service.UploadPictureService;
+
+import java.io.IOException;
+
+/**
+ * <p>
+ *  前端控制器
+ * </p>
+ *
+ * @author Jack
+ * @since 2022-03-07 10:31:02
+ */
+@RestController
+@RequestMapping("/user")
+@Api(tags = "用户接口")
+public class UserController {
+
+    @Autowired
+    private UserService userService;
+
+    @Autowired
+    private JwtUtils jwtUtils;
+
+    @Autowired
+    private UploadPictureService uploadPicrureService;
+
+    @Autowired
+    private RedisTemplate redisTemplate;
+
+    @Autowired
+    private ParCommentService parCommentService;
+
+    @Autowired
+    private ChildCommentService childCommentService;
+
+    @Systemlog(desc = "用户进行了登录")
+    @PostMapping("/login")
+    @ApiOperation(value = "登录接口",notes = "对用户登录进行控制")
+    public Result<UserDto> login(@RequestBody @Valid UserDto userDto, HttpServletResponse response){
+        User user = userService.selectUserByEmail(userDto.getEmail());
+        //将用户输入的密码转化成md5加上盐再进行与数据库比较
+        Md5Hash md5Hash = new Md5Hash(userDto.getPassword(),user.getSalt());
+        System.out.println(md5Hash.toHex());
+        if (StringUtils.isEmpty(user)){
+            return new Result<>(ResultCodeMessage.NOT_EXIST_USER);
+        }
+        if (!user.getPassword().equals(md5Hash.toHex())){
+            return new Result<>(ResultCodeMessage.PASSWORD_ERROR);
+        }
+        String jwt = jwtUtils.generateToken(user.getId());
+        response.setHeader("Authorization", jwt);
+        response.setHeader("Access-Control-Expose-Headers", "Authorization");
+        userDto.setAvatar(user.getAvatar());
+        userDto.setId(user.getId());
+        userDto.setRole(user.getRole());
+        userDto.setEmail(user.getEmail());
+        userDto.setCreateTime(user.getCreateTime());
+        userDto.setDescribe(user.getDescribe());
+        userDto.setNickName(user.getNickName());
+        redisTemplate.opsForValue().set("userId",userDto.getId());
+        return new Result<UserDto>(userDto);
+    }
+
+    @Systemlog(desc = "用户进行了注册")
+    @ApiOperation(value = "注册接口",notes = "用户注册")
+    @PostMapping("/register")
+    public Result register(@Valid @RequestBody User user, HttpServletResponse response){
+        //首先检查该邮箱账号是否已注册
+        User user1 = userService.getOne(new QueryWrapper<User>().eq("email", user.getEmail()));
+        if (!StringUtils.isEmpty(user1)){
+            return new Result<>(ResultCodeMessage.EXIST_USER);
+        }
+        //采用md5和随机盐对密码进行加密
+        String salt = SaltUtil.getSalt(6);
+        user.setSalt(salt);
+        Md5Hash md5Hash = new Md5Hash(user.getPassword(),salt);
+        user.setPassword(md5Hash.toHex());
+        //默认的头像
+        user.setAvatar("https://cube.elemecdn.com/0/88/03b0d39583f48206768a7534e55bcpng.png");
+        try {
+            userService.save(user);
+            User user2 = userService.selectUserByEmail(user.getEmail());
+            UserDto userDto = new UserDto();
+            userDto.setAvatar(user.getAvatar());
+            userDto.setId(user.getId());
+            userDto.setRole(user.getRole());
+            userDto.setEmail(user.getEmail());
+
+            String jwt = jwtUtils.generateToken(user.getId());
+            response.setHeader("Authorization", jwt);
+            response.setHeader("Access-Control-Expose-Headers", "Authorization");
+            return new Result(userDto);
+        } catch (Exception e) {
+            return new Result(e);
+        }
+
+    }
+
+    // 退出
+    @Systemlog(desc = "用户退出了系统")
+    @ApiOperation(value = "退出接口",notes = "用户退出")
+    @GetMapping("/logout")
+    @RequiresAuthentication
+    public Result logout() {
+        redisTemplate.delete("userId");
+        SecurityUtils.getSubject().logout();
+        return new Result();
+    }
+
+    //修改个人信息
+    @Systemlog(desc = "用户进修改了个人信息")
+    @ApiOperation(value = "修改个人信息接口",notes = "修改个人信息")
+    @RequiresAuthentication
+    @PostMapping("/changePerson")
+    public Result changePerson(@RequestBody UserDto userDto){
+        UpdateWrapper<User> userUpdateWrapper = new UpdateWrapper<>();
+        userUpdateWrapper.set("avatar",userDto.getAvatar());
+        userUpdateWrapper.set("`nick_name`",userDto.getNickName());
+        userUpdateWrapper.set("`describe`",userDto.getDescribe());
+        userService.update(userUpdateWrapper.eq("id",userDto.getId()));
+
+        //修改父评论和子评论中的头像和昵称
+        UpdateWrapper<ParComment> parCommentUpdateWrapper = new UpdateWrapper<>();
+        parCommentUpdateWrapper.set("user_avatar",userDto.getAvatar());
+        parCommentUpdateWrapper.set("nick_name",userDto.getNickName());
+        parCommentService.update(parCommentUpdateWrapper.eq("user_id",userDto.getId()));
+
+        //修改子评论中的用户头像和昵称
+        UpdateWrapper<ChildComment> childCommentUpdateWrapper = new UpdateWrapper<>();
+
+        childCommentUpdateWrapper
+                .set("reply_avatar",userDto.getAvatar())
+                .set("reply_nick_name",userDto.getNickName())
+                .eq("reply_id",userDto.getId());
+        childCommentService.update(childCommentUpdateWrapper);
+        childCommentUpdateWrapper.clear();
+        childCommentUpdateWrapper
+                .set("reply_reply_nick_name",userDto.getNickName())
+                .eq("reply_reply_id",userDto.getId());
+        childCommentService.update(childCommentUpdateWrapper);
+
+        return new Result(ResultCodeMessage.SUCCESS);
+    }
+
+
+    //图片上传
+    @Systemlog(desc = "用户上传图片文件")
+    @ApiOperation(value = "图片上传接口",notes = "用于上传图片文件")
+    @PostMapping("/uploadAvatar")
+    public Result uploadAvatar(MultipartFile file) throws IOException {
+        String avatarUrl = uploadPicrureService.uploadPicture(file);
+        return new Result(avatarUrl);
+    }
+
+}

+ 153 - 0
src/main/java/com/yinjie/bbs_java/controller/admin/AdminController.java

@@ -0,0 +1,153 @@
+package com.yinjie.bbs_java.controller.admin;
+
+import com.alibaba.fastjson.JSONArray;
+import com.alibaba.fastjson.JSONObject;
+import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
+import com.yinjie.bbs_java.common.Result;
+import com.yinjie.bbs_java.common.ResultCodeMessage;
+import com.yinjie.bbs_java.entity.SystemLog;
+import com.yinjie.bbs_java.entity.User;
+import com.yinjie.bbs_java.service.SystemLogService;
+import com.yinjie.bbs_java.service.UserService;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import org.apache.shiro.authz.annotation.RequiresAuthentication;
+import org.apache.shiro.authz.annotation.RequiresRoles;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.*;
+
+import java.util.List;
+
+@RestController
+@RequestMapping("/admin")
+@Api(tags = "管理员接口")
+public class AdminController {
+
+    @Autowired
+    private UserService userService;
+
+    @Autowired
+    private SystemLogService systemLogService;
+
+    @RequiresRoles("admin")
+    @GetMapping("/login")
+    public Result login(){
+        System.out.println("查询管理员*******");
+        return new Result(ResultCodeMessage.SUCCESS);
+    }
+
+
+    @ApiOperation(value = "查询所有用户接口",notes = "用于管理员查询所有用户信息")
+    @RequiresRoles("admin")
+    @GetMapping("/selectALLUser")
+    public Result selectALLUser(){
+        try {
+            List<User> userList = userService.selectALLUser();
+            return new Result(userList);
+        } catch (Exception e) {
+            e.printStackTrace();
+            return new Result(e);
+        }
+    }
+
+    @ApiOperation(value = "修改用户角色接口",notes = "用于管理员修改用户角色")
+    @RequiresRoles("admin")
+    @GetMapping("/updateRole")
+    public Result updateRole(String id,Integer roleId){
+        try {
+            boolean update = userService.update(new UpdateWrapper<User>().set("role_id", roleId).eq("id", id));
+            List<User> users = userService.selectALLUser();
+            return new Result(users);
+        } catch (Exception e) {
+            e.printStackTrace();
+            return new Result(e);
+        }
+    }
+
+    @ApiOperation(value = "删除用户接口",notes = "用于管理员删除某个用户")
+    @RequiresRoles("admin")
+    @GetMapping("/deleteUser")
+    public Result deleteUser(String id){
+        try {
+            userService.removeById(id);
+            List<User> users = userService.selectALLUser();
+            return new Result(users);
+        } catch (Exception e) {
+            e.printStackTrace();
+            return new Result(e);
+        }
+    }
+
+    @ApiOperation(value = "禁用用户接口",notes = "用于管理员禁用某个用户账号")
+    @RequiresRoles("admin")
+    @GetMapping("/disableUser")
+    public Result disableUser(String id, Integer status){
+        try {
+            userService.update(new UpdateWrapper<User>().set("status",status).eq("id",id));
+            List<User> users = userService.selectALLUser();
+            return new Result(users);
+        } catch (Exception e) {
+            e.printStackTrace();
+            return new Result(e);
+        }
+    }
+
+    @ApiOperation(value = "批量删除用户接口",notes = "管理员批量删除用户的接口")
+    @RequiresAuthentication
+    @PostMapping("/batchDelUser")
+    public Result batchDelUser(@RequestBody JSONObject userList){
+        JSONArray userList1 = userList.getJSONArray("userList");
+        List<User> userList2 = userList1.toJavaList(User.class);
+        try {
+            boolean update = userService.removeBatchByIds(userList2);
+            List<User> userList3 = userService.selectALLUser();
+            return new Result(userList3);
+        }catch (Exception e){
+            return new Result(e);
+        }
+    }
+
+    @ApiOperation(value = "系统日志接口",notes = "用于管理员查询系统运行状况")
+    @RequiresRoles("admin")
+    @GetMapping("/selectAllLog")
+    public Result selectAllLog(){
+        try {
+            List<SystemLog> systemLogList = systemLogService.list();
+            return new Result(systemLogList);
+        } catch (Exception e) {
+            e.printStackTrace();
+            return new Result(e);
+        }
+    }
+
+    @ApiOperation(value = "删除系统日志接口",notes = "用于管理员删除系统日志")
+    @RequiresRoles("admin")
+    @GetMapping("/deleteLog")
+    public Result deleteLog(Integer id){
+        try {
+            systemLogService.removeById(id);
+            List<SystemLog> systemLogList = systemLogService.list();
+            return new Result(systemLogList);
+        } catch (Exception e) {
+            e.printStackTrace();
+            return new Result(e);
+        }
+    }
+
+    @ApiOperation(value = "批量删除日志接口",notes = "管理员批量删除日志的接口")
+    @RequiresAuthentication
+    @PostMapping("/batchDelLog")
+    public Result batchDelLog(@RequestBody JSONObject systemList){
+        JSONArray systemList1= systemList.getJSONArray("systemList");
+        List<SystemLog> systemLogList2 = systemList1.toJavaList(SystemLog.class);
+        try {
+            systemLogService.removeBatchByIds(systemLogList2);
+            List<SystemLog> systemLogList3 = systemLogService.list();
+            return new Result(systemLogList3);
+        }catch (Exception e){
+            return new Result(e);
+        }
+    }
+
+
+}

+ 169 - 0
src/main/java/com/yinjie/bbs_java/controller/admin/ArticleAuditController.java

@@ -0,0 +1,169 @@
+package com.yinjie.bbs_java.controller.admin;
+
+
+import com.alibaba.fastjson.JSONArray;
+import com.alibaba.fastjson.JSONObject;
+import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
+import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
+import com.yinjie.bbs_java.common.Result;
+import com.yinjie.bbs_java.common.ResultCodeMessage;
+import com.yinjie.bbs_java.entity.Article;
+import com.yinjie.bbs_java.entity.ArticleType;
+import com.yinjie.bbs_java.entity.Message;
+import com.yinjie.bbs_java.service.ArticleService;
+import com.yinjie.bbs_java.service.ArticleTypeService;
+import com.yinjie.bbs_java.service.MessageService;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import org.apache.shiro.authz.annotation.RequiresAuthentication;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.*;
+
+import java.security.MessageDigest;
+import java.util.List;
+
+@RestController
+@RequestMapping("/audit")
+@Api(tags = "管理员文章管理接口")
+public class ArticleAuditController {
+
+    @Autowired
+    private ArticleService articleService;
+
+    @Autowired
+    private ArticleTypeService articleTypeService;
+
+    @Autowired
+    private MessageService messageService;
+
+    @ApiOperation(value = "单个审核接口",notes = "管理员单个审核文章的接口")
+    @RequiresAuthentication
+    @GetMapping("/ArticleAudit")
+    public Result ArticleAudit(Integer articleId,String userid,Integer status){
+        System.out.println("审核的文章id"+articleId+"  "+"审核状态"+status);
+        try {
+            boolean update = articleService.update(new UpdateWrapper<Article>().set("status", status).eq("id", articleId));
+            //发送消息给用户,
+            Article article = articleService.getOne(new QueryWrapper<Article>().eq("id", articleId));
+            Message message = new Message();
+            message.setOriId(userid);
+            message.setDesId(article.getAuthorId());
+            if (status == 0){
+                message.setContent("审核通过了你的文章");
+            }else {
+                message.setContent("你的文章审核未通过");
+            }
+            message.setMesType(1);
+            message.setStatus(0);
+            System.out.println(message);
+            messageService.save(message);
+            List<Article> articleList = articleService.selectALLArticle();
+            return new Result(articleList);
+        }catch (Exception e){
+            e.printStackTrace();
+            return new Result(e);
+        }
+    }
+
+    @ApiOperation(value = "批量审核接口",notes = "管理员批量审核文章的接口")
+    @RequiresAuthentication
+    @PostMapping("/batchAudit")
+    public Result batchAudit(@RequestBody JSONObject auditList, Integer status){
+        Integer status1 = auditList.getObject("status", Integer.class);
+        JSONArray auditList1 = auditList.getJSONArray("auditList");
+        List<Article> articleList1 = auditList1.toJavaList(Article.class);
+        for (Article article : articleList1){
+            article.setStatus(status1);
+        }
+        try {
+            boolean update = articleService.updateBatchById(articleList1);
+            List<Article> articleList = articleService.selectALLArticle();
+            return new Result(articleList);
+        }catch (Exception e){
+            return new Result(e);
+        }
+    }
+
+    @ApiOperation(value = "批量删除接口",notes = "管理员批量删除文章的接口")
+    @RequiresAuthentication
+    @PostMapping("/batchDel")
+    public Result batchDel(@RequestBody JSONObject delList){
+        JSONArray delList1 = delList.getJSONArray("delList");
+        List<Article> articleList1 = delList1.toJavaList(Article.class);
+        try {
+            boolean update = articleService.removeBatchByIds(articleList1);
+            List<Article> articleList = articleService.selectALLArticle();
+            return new Result(articleList);
+        }catch (Exception e){
+            return new Result(e);
+        }
+    }
+
+    @ApiOperation(value = "添加类型接口",notes = "管理员添加文章类型")
+    @RequiresAuthentication
+    @GetMapping ("/addType")
+    public Result addType(String type,String creatorId){
+        ArticleType articleType = new ArticleType();
+        articleType.setType(type);
+        articleType.setCreatorId(creatorId);
+        articleType.setStatus(0);
+        articleType.setIsDelete(0);
+        try {
+            boolean save = articleTypeService.save(articleType);
+            List<ArticleType> articleTypes = articleTypeService.list();
+            return new Result(articleTypes);
+        } catch (Exception e) {
+            e.printStackTrace();
+            return new Result(e);
+        }
+    }
+
+
+    @ApiOperation(value = "删除类型接口",notes = "管理员单个删除类型接口")
+    @RequiresAuthentication
+    @GetMapping("/deleteArticleType")
+    public Result deleteArticleType(Integer tid){
+        boolean b = articleTypeService.removeById(tid);
+        if (b){
+            List<ArticleType> list = articleTypeService.list();
+            return new Result(list);
+        }else {
+            return new Result(ResultCodeMessage.FAIL);
+        }
+    }
+
+
+    @ApiOperation(value = "批量删除类型接口",notes = "管理员批量删除文章类型的接口")
+    @RequiresAuthentication
+    @PostMapping("/batchDelType")
+    public Result batchDelType(@RequestBody JSONObject delList){
+        JSONArray delList1 = delList.getJSONArray("delList");
+        List<ArticleType> articleList1 = delList1.toJavaList(ArticleType.class);
+        try {
+            boolean update = articleTypeService.removeBatchByIds(articleList1);
+            List<ArticleType> articleList = articleTypeService.list();
+            return new Result(articleList);
+        }catch (Exception e){
+            return new Result(e);
+        }
+    }
+
+    @ApiOperation(value = "禁用文章类型接口",notes = "暂时禁止使用文章类型")
+    @RequiresAuthentication
+    @GetMapping("/disableArticleType")
+    public Result disableArticleType(Integer id, Integer status){
+        try {
+            boolean update = articleTypeService.update(new UpdateWrapper<ArticleType>().set("status", status).eq("id", id));
+            if (update){
+                List<ArticleType> list = articleTypeService.list();
+                return new Result(list);
+            }else {
+                return new Result(ResultCodeMessage.FAIL);
+            }
+        } catch (Exception e) {
+            e.printStackTrace();
+            return new Result(e);
+        }
+    }
+
+}

+ 141 - 0
src/main/java/com/yinjie/bbs_java/controller/admin/NoticeController.java

@@ -0,0 +1,141 @@
+package com.yinjie.bbs_java.controller.admin;
+
+
+import com.alibaba.fastjson.JSONArray;
+import com.alibaba.fastjson.JSONObject;
+import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
+import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
+import com.yinjie.bbs_java.common.Result;
+import com.yinjie.bbs_java.common.ResultCodeMessage;
+import com.yinjie.bbs_java.dto.vo.NoticeFilter;
+import com.yinjie.bbs_java.entity.Notice;
+import com.yinjie.bbs_java.service.NoticeService;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import org.apache.shiro.authz.annotation.RequiresAuthentication;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.util.ObjectUtils;
+import org.springframework.web.bind.annotation.*;
+
+import javax.validation.Valid;
+import java.util.List;
+
+/**
+ * <p>
+ *  前端控制器
+ * </p>
+ *
+ * @author Jack
+ * @since 2022-04-12 22:57:16
+ */
+@RestController
+@RequestMapping("/notice")
+@Api(tags = "公告管理接口")
+public class NoticeController {
+
+    @Autowired
+    private NoticeService noticeService;
+
+    @ApiOperation(value = "查询最新的3条公告",notes = "展示公告")
+    @GetMapping("/selectNotices")
+    public Result selectNotices(){
+        List<Notice> noticeList = noticeService.list(new QueryWrapper<Notice>().orderByDesc("update_time").last("limit 3"));
+        return new Result(noticeList);
+    }
+
+    @ApiOperation(value = "公告详情接口",notes = "查询公告详情")
+    @GetMapping("/selectNoticeDetail")
+    public Result selectNoticeDetail(Integer id){
+        Notice notice = noticeService.selectNoticeDetail(id);
+        return new Result(notice);
+    }
+
+    @RequiresAuthentication
+    @ApiOperation(value = "公告接口",notes = "公告列表查询接口")
+    @GetMapping("/selectALLNotice")
+    public Result selectALLNotice(NoticeFilter noticeFilter){
+        QueryWrapper<Notice> noticeQueryWrapper = new QueryWrapper<>();
+        if (noticeFilter != null){
+            if (!ObjectUtils.isEmpty(noticeFilter.getTitle())){
+                noticeQueryWrapper.like("title",noticeFilter.getTitle());
+            }
+            if (!ObjectUtils.isEmpty(noticeFilter.getCreatorId())){
+                noticeQueryWrapper.eq("creator_id",noticeFilter.getCreatorId());
+            }
+            if (!ObjectUtils.isEmpty(noticeFilter.getStartTime())){
+                noticeQueryWrapper.gt("create_time",noticeFilter.getStartTime());
+            }
+            if (!ObjectUtils.isEmpty(noticeFilter.getEndTime())){
+                noticeQueryWrapper.le("create_time",noticeFilter.getEndTime());
+            }
+        }
+        List<Notice> noticeList = noticeService.list(noticeQueryWrapper);
+        return new Result(noticeList);
+    }
+
+    @RequiresAuthentication
+    @ApiOperation(value = "公告发布、修改接口",notes = "管理员发布、修改公告接口")
+    @PostMapping("/post")
+    public Result post(@Valid @RequestBody Notice notice){
+        System.out.println(notice);
+        try {
+            boolean save = noticeService.saveOrUpdate(notice);
+            if (save){
+                List<Notice> noticeList = noticeService.list();
+                return new Result(noticeList);
+            }else {
+                return new Result(ResultCodeMessage.FAIL);
+            }
+        } catch (Exception e) {
+            e.printStackTrace();
+            return new Result(e);
+        }
+    }
+
+
+    @ApiOperation(value = "禁用公告接口",notes = "暂时禁止展示某个公告")
+    @RequiresAuthentication
+    @GetMapping("/disableNotice")
+    public Result disableArticleType(Integer id, Integer status){
+        try {
+            boolean update = noticeService.update(new UpdateWrapper<Notice>().set("status", status).eq("id", id));
+            if (update){
+                List<Notice> list = noticeService.list();
+                return new Result(list);
+            }else {
+                return new Result(ResultCodeMessage.FAIL);
+            }
+        } catch (Exception e) {
+            e.printStackTrace();
+            return new Result(e);
+        }
+    }
+
+    @ApiOperation(value = "删除公告接口",notes = "管理员单个公告接口")
+    @RequiresAuthentication
+    @GetMapping("/deleteNotice")
+    public Result deleteNotice(Integer id){
+        boolean b = noticeService.removeById(id);
+        if (b){
+            List<Notice> list = noticeService.list();
+            return new Result(list);
+        }else {
+            return new Result(ResultCodeMessage.FAIL);
+        }
+    }
+
+    @ApiOperation(value = "批量删除公告接口",notes = "管理员批量删除公告的接口")
+    @RequiresAuthentication
+    @PostMapping("/batchDelNotice")
+    public Result batchDelNotice(@RequestBody JSONObject noticeList){
+        JSONArray noticeList1 = noticeList.getJSONArray("noticeList");
+        List<Notice> noticeList2 = noticeList1.toJavaList(Notice.class);
+        try {
+            boolean update = noticeService.removeBatchByIds(noticeList2);
+            List<Notice> noticeList3 = noticeService.list();
+            return new Result(noticeList3);
+        }catch (Exception e){
+            return new Result(e);
+        }
+    }
+}

+ 19 - 0
src/main/java/com/yinjie/bbs_java/dto/Achievement.java

@@ -0,0 +1,19 @@
+package com.yinjie.bbs_java.dto;
+
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+import lombok.ToString;
+
+@Data
+@ToString
+@NoArgsConstructor
+@AllArgsConstructor
+public class Achievement {
+
+    private Long articleCount;
+
+    private Long answerCount;
+
+    private Long approves;
+}

+ 60 - 0
src/main/java/com/yinjie/bbs_java/dto/ChildComment.java

@@ -0,0 +1,60 @@
+package com.yinjie.bbs_java.dto;
+
+import com.baomidou.mybatisplus.annotation.FieldFill;
+import com.baomidou.mybatisplus.annotation.TableField;
+import com.baomidou.mybatisplus.annotation.TableName;
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+import lombok.ToString;
+
+@Data
+@ToString
+@AllArgsConstructor
+@NoArgsConstructor
+@TableName("bbs_child_comment")
+public class ChildComment {
+
+    @TableField("id")
+    private Integer id;
+
+    @TableField("article_id")
+    private Integer articleId;
+
+    @TableField("parent_id")
+    private String parentId;
+
+    @TableField("reply_id")
+    private String replyId;
+
+    @TableField("reply_email")
+    private String replyEmail;
+
+    @TableField("reply_nick_name")
+    private String replyNickName;
+
+    @TableField("reply_avatar")
+    private String replyAvatar;
+
+    @TableField("reply_reply_id")
+    private String replyReplyId;
+
+    @TableField("reply_reply_email")
+    private String replyReplyEmail;
+
+    @TableField("reply_reply_nick_name")
+    private String replyReplyNickName;
+
+    @TableField("reply_reply_avatar")
+    private String replyReplyAvatar;
+
+    @TableField("content")
+    private String content;
+
+    @TableField(value = "create_time",fill = FieldFill.INSERT)
+    private String createTime;
+
+    @TableField(value = "update_time",fill = FieldFill.INSERT_UPDATE)
+    private String updateTime;
+
+}

+ 50 - 0
src/main/java/com/yinjie/bbs_java/dto/ParComment.java

@@ -0,0 +1,50 @@
+package com.yinjie.bbs_java.dto;
+
+import com.baomidou.mybatisplus.annotation.FieldFill;
+import com.baomidou.mybatisplus.annotation.TableField;
+import com.baomidou.mybatisplus.annotation.TableName;
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+import lombok.ToString;
+
+import java.util.List;
+
+@Data
+@ToString
+@AllArgsConstructor
+@NoArgsConstructor
+@TableName("bbs_par_comment")
+public class ParComment {
+
+    @TableField("id")
+    private Integer id;
+
+    @TableField("article_id")
+    private Integer articleId;
+
+    @TableField("user_id")
+    private String userId;
+
+    @TableField("user_email")
+    private String userEmail;
+
+    @TableField("user_avatar")
+    private String userAvatar;
+
+    @TableField("content")
+    private String content;
+
+    @TableField(value = "create_time",fill = FieldFill.INSERT)
+    private String createTime;
+
+    @TableField(value = "update_time",fill = FieldFill.INSERT_UPDATE)
+    private String updateTime;
+
+    @TableField("nick_name")
+    private String nickName;
+
+    @TableField(exist = false)
+    private List<ChildComment> childCommentList;
+
+}

+ 43 - 0
src/main/java/com/yinjie/bbs_java/dto/UserDto.java

@@ -0,0 +1,43 @@
+package com.yinjie.bbs_java.dto;
+
+import com.baomidou.mybatisplus.annotation.TableField;
+import com.baomidou.mybatisplus.annotation.TableId;
+import lombok.Data;
+
+import javax.validation.constraints.Email;
+import javax.validation.constraints.NotBlank;
+import javax.validation.constraints.NotNull;
+import java.io.Serializable;
+
+@Data
+public class UserDto implements Serializable {
+
+    @TableId("id")
+    private String id;
+
+    @TableField("email")
+    @NotBlank(message = "邮箱不能为空")
+    @Email(message = "邮箱格式不正确")
+    private String email;
+
+    @NotBlank(message = "密码不能为空")
+    @TableField("password")
+    private String password;
+
+    @TableField("avatar")
+    private String avatar;
+
+    @TableField("role")
+    private String role;
+
+    @TableField("create_time")
+    private String createTime;
+
+    @TableField("describe")
+    private String describe;
+
+    @TableField("nick_name")
+    private String NickName;
+}
+
+

+ 17 - 0
src/main/java/com/yinjie/bbs_java/dto/vo/ArticleFilter.java

@@ -0,0 +1,17 @@
+package com.yinjie.bbs_java.dto.vo;
+
+import lombok.Data;
+import lombok.ToString;
+
+@Data
+@ToString
+public class ArticleFilter {
+
+    private String author;
+
+    private String content;
+
+    private String startTime;
+
+    private String endTime;
+}

+ 17 - 0
src/main/java/com/yinjie/bbs_java/dto/vo/ArticleTypeFilter.java

@@ -0,0 +1,17 @@
+package com.yinjie.bbs_java.dto.vo;
+
+import lombok.Data;
+import lombok.ToString;
+
+@Data
+@ToString
+public class ArticleTypeFilter {
+
+    private String type;
+
+    private String creatorId;
+
+    private String startTime;
+
+    private String endTime;
+}

+ 17 - 0
src/main/java/com/yinjie/bbs_java/dto/vo/MessageFilter.java

@@ -0,0 +1,17 @@
+package com.yinjie.bbs_java.dto.vo;
+
+import lombok.Data;
+import lombok.ToString;
+
+@Data
+@ToString
+public class MessageFilter {
+
+    private String oriId;
+
+    private String desId;
+
+    private String startTime;
+
+    private String endTime;
+}

+ 18 - 0
src/main/java/com/yinjie/bbs_java/dto/vo/NoticeFilter.java

@@ -0,0 +1,18 @@
+package com.yinjie.bbs_java.dto.vo;
+
+
+import lombok.Data;
+import lombok.ToString;
+
+@Data
+@ToString
+public class NoticeFilter {
+
+    private String title;
+
+    private String creatorId;
+
+    private String startTime;
+
+    private String endTime;
+}