<repo_name>qq592302116/blog<file_sep>/src/main/java/com/li/blog/module/article/entity/ArticleStatus.java
package com.li.blog.module.article.entity;

import com.baomidou.mybatisplus.annotations.TableName;
import lombok.Data;

@Data
@TableName("blog_article_status")
public class ArticleStatus {
    private Long id;
    private Long approvalAmount;
    private Long browseAmount;
}
<file_sep>/src/main/java/com/li/blog/module/user/controller/dto/RegisterReqDto.java
package com.li.blog.module.user.controller.dto;

import lombok.Data;
import org.hibernate.validator.constraints.NotBlank;

import javax.validation.constraints.Pattern;

/**
 * 注册dto
 */
@Data
public class RegisterReqDto {

    @NotBlank(message = "请输入用户名")
    @Pattern(regexp = "^[A-Za-z0-9_]{4,16}$", message = "用户名格式有误，应该由4到16位(字母，数字，下划线)组成")
    private String account;

    @NotBlank(message = "请输入密码")
    @Pattern(regexp = "^[A-Za-z0-9_]{4,16}$", message = "密码格式有误，应该由4到16位(字母，数字，下划线)组成")
    private String password;

    @NotBlank(message = "再次输入密码不能为空")
    private String rePassword;
}
<file_sep>/src/main/java/com/li/blog/module/user/controller/dto/SkillRespDTO.java
package com.li.blog.module.user.controller.dto;

import lombok.Data;

import java.util.List;

@Data
public class SkillRespDTO {

    private Long id;

    private String name;

    private List<SkillRespDTO> children;

}
<file_sep>/src/main/java/com/li/blog/common/exception/AuthenticationException.java
package com.li.blog.common.exception;

/**
 * 授权异常
 */
public class AuthenticationException extends RuntimeException {
}
<file_sep>/src/main/java/com/li/blog/module/log/entity/LoginLog.java
package com.li.blog.module.log.entity;

import com.baomidou.mybatisplus.annotations.TableName;
import lombok.Data;

import java.util.Date;

/**
 * 登录日志实体类
 */
@Data
@TableName("blog_login_log")
public class LoginLog {
        private Long id;
        private String nickName;
        private String account;
        private Date loginDate;
        private String ip;
}
<file_sep>/src/main/java/com/li/blog/module/article/controller/dto/AuthorRespDto.java
package com.li.blog.module.article.controller.dto;

import lombok.Data;

/**
 * 作者信息响应
 */
@Data
public class AuthorRespDto {
    private Long id;
    private String nickName;
    private String imageAddr;
}
<file_sep>/README.md
### 项目地址
https://github.com/qq592302116/blog
### 技术栈
- springboot
### 亮点
该项目支持个性化，每个同学都可以在该系统中拥有自己的个人博客。
该从简的从简，该华丽的华丽。
### 项目结构
``` bash
blog
├─────java # java源代码
├───────common # 公共类
├───────────annotation # 基础注解类
├───────────base # 基础类
├───────────enums # 全局枚举类
├───────────exception # 全局异常类
├───────────model # 全局实体类
├───────────utils # 工具类
├───────config # 全局配置类
├───────handler # 全局处理器
├───────interceptor # 全局拦截器器
├───────module # 模块
├───────────article # 文章类模块
├───────────log # 日志类模块
├───────────user # 用户类模块
├─────resources # 资源文件(含配置)

```
<file_sep>/src/main/java/com/li/blog/module/article/service/impl/ArticleSortServiceImpl.java
package com.li.blog.module.article.service.impl;

import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.li.blog.common.enums.GlobalEnum;
import com.li.blog.common.exception.BlogException;
import com.li.blog.common.model.GlobalConstant;
import com.li.blog.common.model.JsonResult;
import com.li.blog.common.utils.ThreadLocalMap;
import com.li.blog.module.article.entity.ArticleSort;
import com.li.blog.module.article.mapper.ArticleSortMapper;
import com.li.blog.module.article.service.ArticleSortService;
import com.li.blog.module.user.entity.User;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.Date;
import java.util.List;

/**
 * 文章分类实现类
 */
@Slf4j
@Service
public class ArticleSortServiceImpl implements ArticleSortService {
    @Autowired
    private ArticleSortMapper articleSortMapper;

    @Override
    public JsonResult addSort(String name) throws BlogException {
        User user = (User) ThreadLocalMap.get(GlobalConstant.Sys.TOKEN_AUTH_DTO);
        // 查询分类是否存在
        ArticleSort articleSort = new ArticleSort();
        articleSort.setSortName(name);
        articleSort = articleSortMapper.selectOne(articleSort);
        if (articleSort != null) {
            throw new BlogException(-1, "当前分类已存在");
        }

        ArticleSort addSort = new ArticleSort();
        addSort.setSortName(name);
        Date date = new Date();
        addSort.setCreatedDate(date);
        addSort.setCreatedUser(user.getAccount());
        addSort.setUpdatedDate(date);
        addSort.setUpdatedUser(user.getAccount());
        addSort.setDelStatus(GlobalEnum.DelStatus.NotDelete.getCode());
        log.info("用户 {} 新增一条分类 sort={},{}", user.getAccount(), addSort);
        return JsonResult.success();
    }

    @Override
    public JsonResult findAllSort() throws BlogException {

        List<ArticleSort> articleSort = articleSortMapper.selectList(
                new EntityWrapper<ArticleSort>().eq("delStatus", GlobalEnum.DelStatus.NotDelete.getCode())
        );
        return JsonResult.success(articleSort);
    }
}
<file_sep>/src/main/java/com/li/blog/module/user/entity/Skill.java
package com.li.blog.module.user.entity;

import com.baomidou.mybatisplus.annotations.TableName;
import lombok.Data;

@TableName("blog_skill")
@Data
public class Skill {
    private Long id;
    private Long userId;
    private Long parents;
    private String name;
    private Integer showStatus;
}
<file_sep>/src/main/java/com/li/blog/module/article/service/impl/ArticleBasisServiceImpl.java
package com.li.blog.module.article.service.impl;

import com.li.blog.common.enums.GlobalEnum;
import com.li.blog.common.exception.BlogException;
import com.li.blog.common.model.GlobalConstant;
import com.li.blog.common.model.JsonResult;
import com.li.blog.common.utils.ArticleUtils;
import com.li.blog.common.utils.ThreadLocalMap;
import com.li.blog.module.article.controller.dto.ArticleAddReqDto;
import com.li.blog.module.article.entity.ArticleBasis;
import com.li.blog.module.article.entity.ArticleContent;
import com.li.blog.module.article.entity.ArticleSort;
import com.li.blog.module.article.entity.ArticleStatus;
import com.li.blog.module.article.mapper.ArticleBasisMapper;
import com.li.blog.module.article.mapper.ArticleContentMapper;
import com.li.blog.module.article.mapper.ArticleSortMapper;
import com.li.blog.module.article.mapper.ArticleStatusMapper;
import com.li.blog.module.article.service.ArticleBasisService;
import com.li.blog.module.user.entity.User;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.Date;

@Service
@Slf4j
public class ArticleBasisServiceImpl implements ArticleBasisService {

    @Autowired
    private ArticleBasisMapper articleBasisMapper;
    @Autowired
    private ArticleSortMapper articleSortMapper;
    @Autowired
    private ArticleContentMapper articleContentMapper;
    @Autowired
    private ArticleStatusMapper articleStatusMapper;

    @Override
    @Transactional(rollbackFor = Exception.class)
    public JsonResult addArticle(ArticleAddReqDto reqDto) throws BlogException {
        User user = (User) ThreadLocalMap.get(GlobalConstant.Sys.TOKEN_AUTH_DTO);
        // 查询当前添加的分类是否存在
        Integer sortId = reqDto.getArticleSort();
        ArticleSort sort = articleSortMapper.selectById(sortId);
        if (sort == null) {
            throw new BlogException(-1, "分类不存在");
        }

        // 文章基础添加
        ArticleBasis articleBasis = new ArticleBasis();
        articleBasis.setTitle(reqDto.getTitle());
        articleBasis.setArticleSort(sortId);
        articleBasis.setCoverImage(reqDto.getConverImage());
        articleBasis.setAuthor(user.getAccount());
        articleBasis.setSummary(ArticleUtils.summaryRegularByContent(reqDto.getHtml()));
        Date date = new Date();
        articleBasis.setCreatedDate(date);
        articleBasis.setUpdatedDate(date);
        articleBasis.setShowStatus(GlobalEnum.ShowStatus.Show.getCode());
        articleBasis.setDelStatus(GlobalEnum.DelStatus.NotDelete.getCode());
        articleBasisMapper.insertAllColumn(articleBasis);
        Long articleId = articleBasis.getId();
        log.info("用户 {} 写入一个文章 article = {}", user.getAccount(), articleBasis);
        // 文章内容添加
        ArticleContent articleContent = new ArticleContent();
        articleContent.setId(articleId);
        articleContent.setContent(reqDto.getHtml());
        articleContent.setMarkDown(reqDto.getMarkDown());
        articleContentMapper.insertArticleContent(articleContent);

        // 文章状态添加数据
        ArticleStatus articleStatus = new ArticleStatus();
        articleStatus.setId(articleId);
        articleStatus.setBrowseAmount(0L);
        articleStatus.setApprovalAmount(0L);
        articleStatusMapper.insertArticleStatus(articleStatus);

        return JsonResult.success();
    }

    @Override
    public JsonResult listArticle(String account) throws BlogException {
        // 查询用户的所有文章
        return null;
    }
}
<file_sep>/src/main/java/com/li/blog/module/article/controller/ArticleBasisController.java
package com.li.blog.module.article.controller;

import com.li.blog.common.annotation.Login;
import com.li.blog.common.base.BaseController;
import com.li.blog.common.model.JsonResult;
import com.li.blog.module.article.controller.dto.ArticleAddReqDto;
import com.li.blog.module.article.service.ArticleBasisService;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

/**
 * 文章基础控制层
 */
@RestController
@RequestMapping("/api/article")
public class ArticleBasisController extends BaseController {

    @Autowired
    private ArticleBasisService articleBasisService;

    @PostMapping("/add")
    @Login
    public JsonResult add(@Validated ArticleAddReqDto reqDto) {
        return articleBasisService.addArticle(reqDto);
    }

    @GetMapping("/listArticle")
    public JsonResult listArticle(String account) {
        if (StringUtils.isBlank(account)) {
            JsonResult.error(-1, "非法参数");
        }
        return  null;
    }
}
<file_sep>/src/main/java/com/li/blog/handler/WebMvcConfigurer.java
package com.li.blog.handler;

import com.li.blog.interceptor.AuthenticationInterceptor;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.CorsRegistry;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;

/**
 * @ClassName: CorsAdapter
 * @Description: 跨域适配器
 * @author: qq592302116
 * @date: 2018/8/6 22:08
 */
@Configuration
public class WebMvcConfigurer  extends WebMvcConfigurerAdapter {

    /**
     * 跨域请求
     * @param registry
     */
//    nginx实现跨域
    @Override
    public void addCorsMappings(CorsRegistry registry) {
        registry.addMapping("/**")
                .allowedOrigins("*")
                .allowedMethods("GET", "POST", "PUT", "OPTIONS", "DELETE", "PATCH")
                .allowCredentials(true).maxAge(3600);

    }

    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(authenticationInterceptor()).addPathPatterns("/**");
        super.addInterceptors(registry);
    }

    @Bean
    public AuthenticationInterceptor authenticationInterceptor(){
        return new AuthenticationInterceptor();
    }

}
<file_sep>/src/main/java/com/li/blog/common/base/BaseController.java
package com.li.blog.common.base;

import com.baomidou.mybatisplus.plugins.Page;
import com.li.blog.common.model.GlobalConstant;
import com.li.blog.common.utils.ThreadLocalMap;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.web.bind.annotation.ModelAttribute;

import javax.servlet.http.HttpServletRequest;

/**
 * @ClassName: BaseController
 * @Description: 基础Controller，所有Controller类都要基础该类
 * @author: <NAME>
 * @date: 2018/8/1 22:16
 */
@Slf4j
public abstract class BaseController {


    /**
     * 方法访问时进行的初始化
     */
    @ModelAttribute()
    public void initPageInfo(HttpServletRequest request) {
        log.info("-------初始化开始----");
        // 初始化分页对象
        Page page = new Page();
        page.setCurrent(Integer.parseInt(StringUtils.isBlank(request.getParameter("page")) ? "1" : request.getParameter("page")));
        page.setSize(Integer.parseInt(StringUtils.isBlank(request.getParameter("limit")) ? "20" : request.getParameter("limit")));
        ThreadLocalMap.put(GlobalConstant.Sys.CURRENT_PAGE_OBJECT, page);
    }
}
<file_sep>/src/main/java/com/li/blog/module/article/mapper/ArticleBasisMapper.java
package com.li.blog.module.article.mapper;

import com.baomidou.mybatisplus.mapper.BaseMapper;
import com.li.blog.module.article.controller.dto.ArticleListRespDto;
import com.li.blog.module.article.entity.ArticleBasis;
import org.apache.ibatis.annotations.Param;
import org.springframework.stereotype.Repository;

import java.util.List;

@Repository
public interface ArticleBasisMapper extends BaseMapper<ArticleBasis> {

    List<ArticleListRespDto> selectArticleListAtTheIndex(@Param("account") String account);
}
<file_sep>/src/main/java/com/li/blog/module/user/entity/User.java
package com.li.blog.module.user.entity;

import com.baomidou.mybatisplus.annotations.TableName;
import lombok.Data;

import java.util.Date;

/**
 * 用户实体类
 */
@Data
@TableName("blog_user")
public class User {
    private Long id;

    private String nickName;

    private Integer sex;

    private String account;

    private String password;

    private String phone;

    private String email;

    private String imageAddr;

    private Date createdDate;

    private String createdUser;

    private Date updatedDate;

    private String updatedUser;

    private Integer delStatus;

}
<file_sep>/src/blog.sql
/*
 Navicat Premium Data Transfer

 Source Server         : 本地
 Source Server Type    : MySQL
 Source Server Version : 80000
 Source Host           : localhost:3306
 Source Schema         : blog

 Target Server Type    : MySQL
 Target Server Version : 80000
 File Encoding         : 65001

 Date: 19/10/2018 14:43:39
*/

SET NAMES utf8mb4;
SET FOREIGN_KEY_CHECKS = 0;

-- ----------------------------
-- Table structure for blog_article_basis
-- ----------------------------
DROP TABLE IF EXISTS `blog_article_basis`;
CREATE TABLE `blog_article_basis`  (
  `id` int(20) NOT NULL AUTO_INCREMENT,
  `title` varchar(20) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL COMMENT '标题',
  `coverImage` varchar(150) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '封面图片地址',
  `articleSort` int(20) NULL DEFAULT NULL COMMENT '文章分类id',
  `author` varchar(15) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL COMMENT '作者',
  `summary` text CHARACTER SET utf8 COLLATE utf8_general_ci NULL COMMENT '摘要',
  `createdDate` datetime(0) NOT NULL COMMENT '发布时间',
  `updatedDate` datetime(0) NOT NULL COMMENT '修改时间',
  `showStatus` int(1) NOT NULL DEFAULT 0 COMMENT '是否显示(0:否，1:是)',
  `delStatus` int(1) NOT NULL DEFAULT 0 COMMENT '是否删除(0:否，1:是)',
  PRIMARY KEY (`id`) USING BTREE,
  INDEX `title`(`title`) USING BTREE,
  INDEX `author`(`author`) USING BTREE
) ENGINE = InnoDB CHARACTER SET = utf8 COLLATE = utf8_general_ci COMMENT = '文章基础表' ROW_FORMAT = Dynamic;

-- ----------------------------
-- Table structure for blog_article_content
-- ----------------------------
DROP TABLE IF EXISTS `blog_article_content`;
CREATE TABLE `blog_article_content`  (
  `id` int(20) NOT NULL COMMENT '文章基础id',
  `content` text CHARACTER SET utf8 COLLATE utf8_general_ci NULL COMMENT 'html源码',
  `markDown` text CHARACTER SET utf8 COLLATE utf8_general_ci NULL COMMENT 'markDown',
  PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB CHARACTER SET = utf8 COLLATE = utf8_general_ci COMMENT = '文章内容表' ROW_FORMAT = Dynamic;

-- ----------------------------
-- Table structure for blog_article_log
-- ----------------------------
DROP TABLE IF EXISTS `blog_article_log`;
CREATE TABLE `blog_article_log`  (
  `id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '日志id',
  `userId` int(20) NOT NULL COMMENT '用户id',
  `articleId` int(20) NOT NULL COMMENT '文章基础id',
  `status` int(4) NOT NULL COMMENT '操作状态(2000:浏览，2001:点赞)',
  `ipAddr` varchar(20) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT 'ip地址',
  `createdDate` datetime(0) NOT NULL COMMENT '创建时间',
  PRIMARY KEY (`id`) USING BTREE,
  INDEX `articleId`(`articleId`) USING BTREE,
  INDEX `ipAddr`(`ipAddr`) USING BTREE
) ENGINE = InnoDB CHARACTER SET = utf8 COLLATE = utf8_general_ci COMMENT = '文章日志表' ROW_FORMAT = Dynamic;

-- ----------------------------
-- Table structure for blog_article_sort
-- ----------------------------
DROP TABLE IF EXISTS `blog_article_sort`;
CREATE TABLE `blog_article_sort`  (
  `id` int(10) NOT NULL AUTO_INCREMENT COMMENT '分类id',
  `sortName` varchar(10) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL COMMENT '分类名称',
  `createdDate` datetime(0) NOT NULL COMMENT '创建时间',
  `createdUser` varchar(50) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL COMMENT '创建的人',
  `updatedDate` datetime(0) NOT NULL COMMENT '修改时间',
  `updatedUser` varchar(50) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL COMMENT '修改的人',
  `delStatus` int(1) NOT NULL DEFAULT 0 COMMENT '是否删除(0:否，1:是)',
  PRIMARY KEY (`id`) USING BTREE,
  UNIQUE INDEX `sortName`(`sortName`) USING BTREE
) ENGINE = InnoDB CHARACTER SET = utf8 COLLATE = utf8_general_ci COMMENT = '分类表' ROW_FORMAT = Dynamic;

-- ----------------------------
-- Records of blog_article_sort
-- ----------------------------
INSERT INTO `blog_article_sort` VALUES (1, '后端', '2018-09-20 15:04:17', 'a123456', '2018-09-20 15:04:17', 'a123456', 0);
INSERT INTO `blog_article_sort` VALUES (2, '前端', '2018-09-20 15:04:31', 'a123456', '2018-09-20 15:04:31', 'a123456', 0);

-- ----------------------------
-- Table structure for blog_article_status
-- ----------------------------
DROP TABLE IF EXISTS `blog_article_status`;
CREATE TABLE `blog_article_status`  (
  `id` int(20) NOT NULL COMMENT '文章基础id',
  `approvalAmount` bigint(20) NULL DEFAULT 0 COMMENT '点赞量',
  `browseAmount` bigint(20) NULL DEFAULT 0 COMMENT '浏览量',
  PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB CHARACTER SET = utf8 COLLATE = utf8_general_ci COMMENT = '文章状况表' ROW_FORMAT = Dynamic;

-- ----------------------------
-- Table structure for blog_login_log
-- ----------------------------
DROP TABLE IF EXISTS `blog_login_log`;
CREATE TABLE `blog_login_log`  (
  `id` bigint(20) NOT NULL AUTO_INCREMENT,
  `nickName` varchar(50) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '昵称',
  `account` varchar(50) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL COMMENT '账号',
  `loginDate` datetime(0) NOT NULL COMMENT '登录时间',
  `ip` varchar(50) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL COMMENT '客户端ip',
  PRIMARY KEY (`id`) USING BTREE,
  INDEX `account`(`account`) USING BTREE
) ENGINE = InnoDB CHARACTER SET = utf8 COLLATE = utf8_general_ci COMMENT = '登录日志表' ROW_FORMAT = Dynamic;

-- ----------------------------
-- Records of blog_login_log
-- ----------------------------
INSERT INTO `blog_login_log` VALUES (1, '程序单身狗', 'a123456', '2018-09-20 16:09:56', '127.0.0.1');

-- ----------------------------
-- Table structure for blog_skill
-- ----------------------------
DROP TABLE IF EXISTS `blog_skill`;
CREATE TABLE `blog_skill`  (
  `id` bigint(20) NOT NULL AUTO_INCREMENT,
  `userId` bigint(20) NULL DEFAULT 0 COMMENT '用户id',
  `parents` bigint(20) NULL DEFAULT 0 COMMENT '父类节点(默认0，为最顶节点)',
  `name` varchar(50) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL COMMENT '技能名称',
  `showStatus` int(1) NOT NULL DEFAULT 0 COMMENT '是否显示(0:显示，1:不显示)',
  PRIMARY KEY (`id`) USING BTREE,
  INDEX `userId`(`userId`) USING BTREE
) ENGINE = InnoDB CHARACTER SET = utf8 COLLATE = utf8_general_ci COMMENT = '技能表' ROW_FORMAT = Dynamic;

-- ----------------------------
-- Records of blog_skill
-- ----------------------------
INSERT INTO `blog_skill` VALUES (1, 1, 0, 'Java', 0);
INSERT INTO `blog_skill` VALUES (2, 1, 1, 'SpringBoot', 0);
INSERT INTO `blog_skill` VALUES (3, 1, 1, 'SpringCloud', 0);
INSERT INTO `blog_skill` VALUES (4, 1, 3, 'Eureka', 0);
INSERT INTO `blog_skill` VALUES (5, 1, 2, '拦截器', 0);

-- ----------------------------
-- Table structure for blog_user
-- ----------------------------
DROP TABLE IF EXISTS `blog_user`;
CREATE TABLE `blog_user`  (
  `id` bigint(20) NOT NULL AUTO_INCREMENT,
  `nickName` varchar(50) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '昵称',
  `sex` int(1) NULL DEFAULT 0 COMMENT '性别(0:男，1:女)',
  `account` varchar(50) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL COMMENT '账号',
  `password` varchar(100) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL COMMENT '密码，加密存储',
  `phone` varchar(20) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '手机号',
  `email` varchar(50) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '邮箱',
  `imageAddr` varchar(150) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '头像地址',
  `createdDate` datetime(0) NOT NULL COMMENT '创建该账号时间',
  `createdUser` varchar(50) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL COMMENT '创建该账号的人',
  `updatedDate` datetime(0) NOT NULL COMMENT '修改该账号的时间',
  `updatedUser` varchar(50) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL COMMENT '修改该账号的人',
  `delStatus` int(1) NOT NULL DEFAULT 0 COMMENT '是否删除(0:否，1:是)',
  PRIMARY KEY (`id`) USING BTREE,
  UNIQUE INDEX `account`(`account`) USING BTREE,
  INDEX `phone`(`phone`) USING BTREE
) ENGINE = InnoDB CHARACTER SET = utf8 COLLATE = utf8_general_ci COMMENT = '用户表' ROW_FORMAT = Dynamic;

-- ----------------------------
-- Records of blog_user
-- ----------------------------
INSERT INTO `blog_user` VALUES (1, '程序单身狗', 1, 'a123456', '$2a$10$BqmTaIp15.iujHAaPcGQmuK7PJbqwHYN0r5MfsJpC6GtXAztb5LC6', '13410828409', '<EMAIL>', '/baidu/a', '2018-08-13 11:48:09', 'a123456', '2018-08-13 11:48:22', 'a123456', 0);
INSERT INTO `blog_user` VALUES (2, 'dog-1', 0, 'abcd', '$2a$10$8z0zfL9W/SzOBcSflzRbEutXaSAA5CpV5eOJWqMBHnuWyYoxbon/y', NULL, NULL, NULL, '2018-08-23 10:27:39', 'abcd', '2018-08-23 10:27:39', 'abcd', 0);
INSERT INTO `blog_user` VALUES (3, 'dog-2', 0, 'abcde', '$2a$10$XweNRRbZUg8PPuP4KGmVNuolW2/vZ.CVJ6Mqoq6o1a2EVIH6RkzFq', NULL, NULL, NULL, '2018-08-23 10:30:23', 'abcde', '2018-08-23 10:30:23', 'abcde', 0);
INSERT INTO `blog_user` VALUES (4, 'dog-3', 0, 'abcdef', '$2a$10$t1pTK6eflgjoOmnwfOM5ueMPfIsBd/jEGEkF8xKzgPuhEwwfoHif6', NULL, NULL, NULL, '2018-08-23 10:32:12', 'abcdef', '2018-08-23 10:32:12', 'abcdef', 0);
INSERT INTO `blog_user` VALUES (5, 'dog-4', 0, 'abcdefg', '$2a$10$WPvjzn66NGm/3sbtI4gVNe.jP7SidF.wOuYROIparFoLUvrqfeHj6', NULL, NULL, NULL, '2018-08-23 10:36:44', 'abcdefg', '2018-08-23 10:36:44', 'abcdefg', 0);
INSERT INTO `blog_user` VALUES (6, 'dog-5', 0, '<PASSWORD>', '$2a$10$lT/noE/JcgZdgT3mtGiAGuLnTe9mcfEYOLwXdDOcokQw/xuZLvCWO', NULL, NULL, NULL, '2018-08-23 10:37:35', 'abcdefge', '2018-08-23 10:37:35', 'abcdefge', 0);

SET FOREIGN_KEY_CHECKS = 1;
<file_sep>/src/main/java/com/li/blog/module/article/controller/dto/ArticleAddReqDto.java
package com.li.blog.module.article.controller.dto;

import lombok.Data;
import org.hibernate.validator.constraints.NotBlank;

/**
 * 文章添加请求DTO
 */
@Data
public class ArticleAddReqDto {
    /**
     * 文章标题
     */
    @NotBlank(message = "请写下您的文章标题")
    private String title;

    /**
     * 文章封面图
     */
    @NotBlank(message = "请上传您的封面图")
    private String converImage;

    /**
     * 文章分类id
     */
    private Integer articleSort;

    /**
     * HTML源码
     */
    private String html;

    /**
     * markDowm源码
     */
    private String markDown;
}
<file_sep>/src/main/java/com/li/blog/module/article/mapper/ArticleSortMapper.java
package com.li.blog.module.article.mapper;

import com.baomidou.mybatisplus.mapper.BaseMapper;
import com.li.blog.module.article.entity.ArticleSort;
import org.springframework.stereotype.Repository;

/**
 * 文章分类持久类
 */
@Repository
public interface ArticleSortMapper extends BaseMapper<ArticleSort> {
}
<file_sep>/src/main/java/com/li/blog/module/user/controller/dto/LoginReqDto.java
package com.li.blog.module.user.controller.dto;

import lombok.Data;
import org.hibernate.validator.constraints.NotBlank;

/**
 * 登录dto
 */
@Data
public class LoginReqDto {

    @NotBlank(message = "用户名不能为空")
    private String account;

    @NotBlank(message = "密码不能为空")
    private String password;
}
<file_sep>/src/main/java/com/li/blog/handler/GlobalDefultExceptionHandler.java
package com.li.blog.handler;

import com.li.blog.common.exception.AuthenticationException;
import com.li.blog.common.exception.BlogException;
import com.li.blog.common.model.JsonResult;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.HttpStatus;
import org.springframework.validation.BindException;
import org.springframework.validation.BindingResult;
import org.springframework.validation.FieldError;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseStatus;
import org.springframework.web.bind.annotation.RestControllerAdvice;

import javax.servlet.http.HttpServletResponse;

/**
 * 全局异常处理
 */
@Slf4j
@RestControllerAdvice
public class GlobalDefultExceptionHandler {

    @ExceptionHandler(BlogException.class)
    public JsonResult blogExceptionHandler(BlogException e) {
        log.error("{}",e);
        return JsonResult.error(e.getCode(), e.getMsg());
    }

    @ExceptionHandler(Exception.class)
    public JsonResult defultExceptionHandler(Exception e) {
        log.error("{}", e);
        return JsonResult.error();
    }

    /**
     * 校验错误拦截处理
     *
     * @param e
     * @return
     */
    @ExceptionHandler(BindException.class)
    public JsonResult bindExceptionHandler(BindException e) {
        BindingResult bindingResult = e.getBindingResult();
        FieldError fieldError = bindingResult.getFieldError();
        log.error("校验参数：错误对象={},错误字段={}，错误详情={}", e.getObjectName(), fieldError.getField(), fieldError.getDefaultMessage());
        return JsonResult.error(-2, fieldError.getDefaultMessage());
    }

    @ExceptionHandler(AuthenticationException.class)
    @ResponseStatus(HttpStatus.UNAUTHORIZED)
    public JsonResult authenticationException(AuthenticationException e, HttpServletResponse response) {
        response.setHeader("Access-Control-Allow-Origin","*");
        return JsonResult.error(401, null);
    }
}
<file_sep>/src/main/java/com/li/blog/module/user/service/SkillService.java
package com.li.blog.module.user.service;

import com.li.blog.common.model.JsonResult;
import com.li.blog.module.user.controller.dto.SkillAddReqDTO;
import com.li.blog.module.user.controller.dto.SkillRespDTO;

import java.util.List;

/**
 * 技能树服务
 *
 * @author bertonlee
 */
public interface SkillService {

    /**
     * 首页查询技能树
     * @param userId
     * @return
     */
    List<SkillRespDTO> querySkillTreeByHome(Long userId);

    /**
     * 添加技能节点
     *
     * @param skillAddReqDTO
     * @return
     */
    JsonResult addSkillNode(SkillAddReqDTO skillAddReqDTO);

    /**
     * 删除技能节点，若为父类，递归删除
     * @param id
     * @return
     */
    JsonResult deleteSkillNode(Long id);
}
<file_sep>/src/main/java/com/li/blog/module/user/controller/UserController.java
package com.li.blog.module.user.controller;

import com.li.blog.common.base.BaseController;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

/**
 * 用户Controller
 */
@RestController
@RequestMapping("/api/user")
public class UserController extends BaseController{




}
<file_sep>/src/main/java/com/li/blog/module/article/controller/dto/ArticleListRespDto.java
package com.li.blog.module.article.controller.dto;

import lombok.Data;

import java.util.Date;

@Data
public class ArticleListRespDto {
    private Long id;
    private String title;
    private String summary;
    private String coverImage;
    private Date createdDate;
    private Long pageviews;
    private Long star;
}
<file_sep>/src/main/java/com/li/blog/common/exception/BlogException.java
package com.li.blog.common.exception;

import lombok.Data;

/**
 * 公用异常类
 */
@Data
public class BlogException extends RuntimeException {
    private int code;
    private String msg;

    public BlogException(int code, String msg) {
        this.code = code;
        this.msg = msg;
    }

    public BlogException() {
        code = -1;
        msg = "非法异常！";
    }
}
<file_sep>/src/main/java/com/li/blog/module/user/mapper/UserMapper.java
package com.li.blog.module.user.mapper;

import com.baomidou.mybatisplus.mapper.BaseMapper;
import com.li.blog.module.user.entity.User;
import org.springframework.stereotype.Repository;

/**
 * 用户操作持久类
 */
@Repository
public interface UserMapper extends BaseMapper<User> {
}
