Compare commits

...

18 Commits
v2 ... v2.1.0

Author SHA1 Message Date
禾几海
f375def613 active-profiles 2020-07-25 17:32:02 +08:00
禾几海
af43657b5b null值异常 2020-07-24 21:09:17 +08:00
禾几海
526b73b4f8 优化提示 2020-07-24 16:47:26 +08:00
禾几海
d9db98849a 调整测试基类 2020-07-23 23:32:42 +08:00
禾几海
6c3645ba15 增加获取已删除数据的选项 2020-07-23 23:08:03 +08:00
禾几海
43a5e2ab2f 抽离Mock请求的方法,过渡到jackson 2020-07-23 23:02:53 +08:00
禾几海
739256424f . 2020-07-18 16:48:04 +08:00
禾几海
3c839ad8ca 数据库建表语句和测试数据 2020-07-18 13:33:33 +08:00
禾几海
efbd5b3d72 删除逻辑 2020-07-18 13:32:50 +08:00
禾几海
5ba7e684fa 生成sitemap过滤文章 2020-07-18 12:32:42 +08:00
禾几海
f7c1726d51 添加deleted字段 2020-07-18 12:30:53 +08:00
禾几海
5504abe3e0 Other.java -> CommonController.java 2020-07-18 12:29:07 +08:00
禾几海
5aeec0cfe4 . 2020-07-11 14:14:36 +08:00
禾几海
e2fe41c2e0 换用knife4j,swaggerUI 2020-07-11 14:12:57 +08:00
禾几海
48f485b378 . 2020-07-11 10:52:24 +08:00
禾几海
6ee8fb65c3 ci 2020-07-11 10:52:13 +08:00
禾几海
2106bf4d94 pr 的ci测试 2020-05-27 18:11:27 +08:00
禾几海
72cef158a1 异常 2020-05-27 18:07:55 +08:00
26 changed files with 679 additions and 343 deletions

View File

@@ -1,7 +1,7 @@
# This workflow will build a package using Maven and then publish it to GitHub packages when a release is created # This workflow will build a package using Maven and then publish it to GitHub packages when a release is created
# For more information see: https://github.com/actions/setup-java#apache-maven-with-a-settings-path # For more information see: https://github.com/actions/setup-java#apache-maven-with-a-settings-path
name: Blog backEnd CI name: Deplay
on: on:
push: push:
@@ -24,7 +24,7 @@ jobs:
java-version: 1.8 java-version: 1.8
- name: Build jar file - name: Build jar file
run: echo $APPLICATION_PROPERTIES_TEST|base64 -d > src/main/resources/application-test.properties && echo $APPLICATION_PROPERTIES_PROD|base64 -d> src/main/resources/application-prod.properties && mvn -B package --file pom.xml run: echo $APPLICATION_PROPERTIES_PROD|base64 -d> src/main/resources/application-prod.properties && mvn -B package --file pom.xml
- name: SCP - name: SCP
uses: appleboy/scp-action@master uses: appleboy/scp-action@master

29
.github/workflows/test.yml vendored Normal file
View File

@@ -0,0 +1,29 @@
# This workflow will build a package using Maven and then publish it to GitHub packages when a release is created
# For more information see: https://github.com/actions/setup-java#apache-maven-with-a-settings-path
name: pr Test
on:
push:
pull_request:
branches: [ master ]
jobs:
build:
runs-on: ubuntu-latest
env:
APPLICATION_PROPERTIES_TEST: ${{ secrets.APPLICATION_PROPERTIES_TEST }}
APPLICATION_PROPERTIES_PROD: ${{ secrets.APPLICATION_PROPERTIES_PROD }}
steps:
- uses: actions/checkout@v2
- name: Set up JDK 1.8
uses: actions/setup-java@v1
with:
java-version: 1.8
- name: Test
run: echo $APPLICATION_PROPERTIES_TEST|base64 -d > src/main/resources/application-test.properties && mvn -B test --file pom.xml

View File

@@ -1,6 +1,30 @@
CREATE DATABASE `t_blog`; CREATE DATABASE if not exists `blog`;
USE t_blog; USE blog;
CREATE TABLE `user`
(
`u_id` int not null primary key auto_increment,
`u_email` varchar(50) not null,
`u_pwd` varchar(40) not null comment '密码',
`u_email_status` boolean default false comment '邮箱验证状态',
`u_avatar` varchar(255) default null comment '用户头像',
`u_desc` tinytext COLLATE utf8mb4_unicode_ci default null comment '用户的描述',
`u_recently_landed_time` datetime default null comment '最近的登录时间',
`u_display_name` varchar(30) COLLATE utf8mb4_unicode_ci default null comment '展示的昵称',
`u_role` varchar(40) not null default 'user' comment '权限组',
`status` tinyint(1) not null default 0 comment '账户状态',
unique key `uni_user_id` (`u_id`),
unique key `uni_user_email` (`u_email`)
) comment '用户表';
CREATE TABLE `tag_category`
(
`t_id` bigint(20) primary key auto_increment,
`t_name` varchar(255) not null,
`is_category` boolean not null default true,
`is_delete` boolean not null default false comment '该数据是否被删除'
) comment '标签和分类表';
CREATE TABLE `article` CREATE TABLE `article`
( (
@@ -14,30 +38,25 @@ CREATE TABLE `article`
`a_reading_number` int default 0 comment '文章阅读数', `a_reading_number` int default 0 comment '文章阅读数',
`a_like` int default 0 comment '文章点赞数', `a_like` int default 0 comment '文章点赞数',
`a_dislike` int default 0 comment '文章不喜欢数', `a_dislike` int default 0 comment '文章不喜欢数',
`a_category_id` int not null comment '文章分类id', `a_category_id` bigint not null comment '文章分类id',
`a_publish_date` datetime default CURRENT_TIMESTAMP comment '文章发布时间', `a_publish_date` datetime default CURRENT_TIMESTAMP comment '文章发布时间',
`a_update_date` datetime default null comment '文章的更新时间', `a_update_date` datetime default null comment '文章的更新时间',
`a_is_open` boolean default true comment '文章是否可见', `a_is_open` boolean default true comment '文章是否可见',
`is_delete` boolean not null default false comment '该数据是否被删除' `is_delete` boolean not null default false comment '该数据是否被删除',
foreign key (a_category_id) references tag_category (t_id),
foreign key (a_author_id) references user (u_id)
) DEFAULT CHARSET = utf8mb4 ) DEFAULT CHARSET = utf8mb4
COLLATE utf8mb4_general_ci,comment '文章表'; COLLATE utf8mb4_general_ci,comment '文章表';
CREATE TABLE `article_tag` CREATE TABLE `article_tag`
( (
`at_id` bigint(20) primary key auto_increment, `at_id` bigint(20) primary key auto_increment,
`a_id` bigint(20) not null comment '文章id', `a_id` bigint(20) not null comment '文章id',
`t_id` bigint not null comment 'tag/category 的id', `t_id` bigint not null comment 'tag/category 的id',
`is_delete` boolean not null default false comment '该数据是否被删除' foreign key (a_id) references article (a_id),
foreign key (t_id) references tag_category (t_id)
) comment '文章标签表'; ) comment '文章标签表';
CREATE TABLE `tag_category`
(
`t_id` bigint(20) primary key auto_increment,
`t_name` varchar(255) not null,
`is_category` boolean not null default true,
`is_delete` boolean not null default false comment '该数据是否被删除'
) comment '标签和分类表';
CREATE TABLE `comment` CREATE TABLE `comment`
( (
`co_id` bigint(20) primary key auto_increment, `co_id` bigint(20) primary key auto_increment,
@@ -79,23 +98,6 @@ CREATE TABLE `web_update`
`is_delete` boolean not null default false comment '该数据是否被删除' `is_delete` boolean not null default false comment '该数据是否被删除'
) comment '更新内容表'; ) comment '更新内容表';
CREATE TABLE `user`
(
`u_id` int not null primary key auto_increment,
`u_email` varchar(50) not null,
`u_pwd` varchar(40) not null comment '密码',
`u_email_status` boolean default false comment '邮箱验证状态',
`u_avatar` varchar(255) default null comment '用户头像',
`u_desc` tinytext COLLATE utf8mb4_unicode_ci default null comment '用户的描述',
`u_recently_landed_time` datetime default null comment '最近的登录时间',
`u_display_name` varchar(30) COLLATE utf8mb4_unicode_ci default null comment '展示的昵称',
`u_role` varchar(40) not null default 'user' comment '权限组',
`status` tinyint(1) not null default 0 comment '账户状态',
unique key `uni_user_id` (`u_id`),
unique key `uni_user_email` (`u_email`)
) comment '用户表';
CREATE VIEW articleView CREATE VIEW articleView
(articleId, title, summary, mdContent, url, isOriginal, readingCount, likeCount, dislikeCount, (articleId, title, summary, mdContent, url, isOriginal, readingCount, likeCount, dislikeCount,
publishDate, updateDate, isOpen, publishDate, updateDate, isOpen,
@@ -139,7 +141,7 @@ where article.a_id = article_tag.a_id
CREATE VIEW commentView CREATE VIEW commentView
(commentId, pagePath, content, date, status, pid, toAuthorId, toAuthorEmail, toAuthorDisplayName, (commentId, pagePath, content, date, status, pid, toAuthorId, toAuthorEmail, toAuthorDisplayName,
toAuthorAvatar, fromAuthorId, fromAuthorEmail, fromAuthorDisplayName, toAuthorAvatar, fromAuthorId, fromAuthorEmail, fromAuthorDisplayName,
fromAuthorAvatar, isDelete) fromAuthorAvatar)
as as
select cuT.co_id as commentId, select cuT.co_id as commentId,
cuT.co_page_path as pagePath, cuT.co_page_path as pagePath,
@@ -154,8 +156,7 @@ select cuT.co_id as commentId,
userFrom.u_id as fromAuthorId, userFrom.u_id as fromAuthorId,
userFrom.u_email as fromAuthorEmail, userFrom.u_email as fromAuthorEmail,
userFrom.u_display_name as fromAuthorDisplayName, userFrom.u_display_name as fromAuthorDisplayName,
userFrom.u_avatar as fromAuthorAvatar, userFrom.u_avatar as fromAuthorAvatar
cuT.is_delete as isDelete
from (select comment.co_id, from (select comment.co_id,
comment.co_page_path, comment.co_page_path,
comment.co_content, comment.co_content,
@@ -166,8 +167,7 @@ from (select comment.co_id,
comment.co_to_author_id, comment.co_to_author_id,
userTo.u_email as toEmail, userTo.u_email as toEmail,
userTo.u_display_name as toDisplayName, userTo.u_display_name as toDisplayName,
userTo.u_avatar as toAvatar, userTo.u_avatar as toAvatar
comment.is_delete
from comment from comment
left join user userTo on (comment.co_to_author_id = userTo.u_id) left join user userTo on (comment.co_to_author_id = userTo.u_id)
) as cuT, ) as cuT,

204
dev.sql Normal file

File diff suppressed because one or more lines are too long

View File

@@ -55,12 +55,12 @@
<dependency> <dependency>
<groupId>io.springfox</groupId> <groupId>io.springfox</groupId>
<artifactId>springfox-swagger2</artifactId> <artifactId>springfox-swagger2</artifactId>
<version>2.6.1</version> <version>2.9.2</version>
</dependency> </dependency>
<dependency> <dependency>
<groupId>io.springfox</groupId> <groupId>com.github.xiaoymin</groupId>
<artifactId>springfox-swagger-ui</artifactId> <artifactId>swagger-bootstrap-ui</artifactId>
<version>2.6.1</version> <version>1.9.6</version>
</dependency> </dependency>
<!--MarkDown 2 html --> <!--MarkDown 2 html -->

View File

@@ -26,7 +26,7 @@ public class CorsConfig {
config.addAllowedOrigin("https://celess.cn"); config.addAllowedOrigin("https://celess.cn");
config.addAllowedOrigin("https://www.celess.cn"); config.addAllowedOrigin("https://www.celess.cn");
// 本地调试时的跨域 // 本地调试时的跨域
if ("dev".equals(activeModel)) { if (!"prod".equals(activeModel)) {
config.addAllowedOrigin("http://localhost:4200"); config.addAllowedOrigin("http://localhost:4200");
config.addAllowedOrigin("http://127.0.0.1:4200"); config.addAllowedOrigin("http://127.0.0.1:4200");
} }

View File

@@ -7,6 +7,7 @@ import springfox.documentation.builders.ApiInfoBuilder;
import springfox.documentation.builders.PathSelectors; import springfox.documentation.builders.PathSelectors;
import springfox.documentation.builders.RequestHandlerSelectors; import springfox.documentation.builders.RequestHandlerSelectors;
import springfox.documentation.service.ApiInfo; import springfox.documentation.service.ApiInfo;
import springfox.documentation.service.Contact;
import springfox.documentation.spi.DocumentationType; import springfox.documentation.spi.DocumentationType;
import springfox.documentation.spring.web.plugins.Docket; import springfox.documentation.spring.web.plugins.Docket;
import springfox.documentation.swagger2.annotations.EnableSwagger2; import springfox.documentation.swagger2.annotations.EnableSwagger2;
@@ -25,7 +26,7 @@ public class SwaggerConfig {
@Bean @Bean
public Docket createRestApi() { public Docket createRestApi() {
return new Docket(DocumentationType.SWAGGER_2) return new Docket(DocumentationType.SWAGGER_2)
.enable("dev".equals(environment)) .enable(!"prod".equals(environment))
.apiInfo(apiInfo()) .apiInfo(apiInfo())
.select() .select()
.apis(RequestHandlerSelectors.basePackage("cn.celess.blog")) .apis(RequestHandlerSelectors.basePackage("cn.celess.blog"))
@@ -37,7 +38,7 @@ public class SwaggerConfig {
return new ApiInfoBuilder() return new ApiInfoBuilder()
.title("小海博客的APi") .title("小海博客的APi")
.description("小海博客的APi") .description("小海博客的APi")
.contact("小海") .contact(new Contact("小海", "https://www.celess.cn", "a@celess.cn"))
.version("1.0") .version("1.0")
.build(); .build();
} }

View File

@@ -56,10 +56,13 @@ public class AuthenticationFilter implements HandlerInterceptor {
return writeResponse(ResponseEnum.LOGIN_EXPIRED, response, request); return writeResponse(ResponseEnum.LOGIN_EXPIRED, response, request);
} }
String email = jwtUtil.getUsernameFromToken(jwtStr); String email = jwtUtil.getUsernameFromToken(jwtStr);
if (!redisUtil.hasKey(email + "-login") || jwtUtil.isTokenExpired(jwtStr)) { if (jwtUtil.isTokenExpired(jwtStr)) {
// 登陆过期 // 登陆过期
return writeResponse(ResponseEnum.LOGIN_EXPIRED, response, request); return writeResponse(ResponseEnum.LOGIN_EXPIRED, response, request);
} }
if (!redisUtil.hasKey(email + "-login")) {
return writeResponse(ResponseEnum.LOGOUT, response, request);
}
String role = userService.getUserRoleByEmail(email); String role = userService.getUserRoleByEmail(email);
if (role.equals(ROLE_USER) || role.equals(ROLE_ADMIN)) { if (role.equals(ROLE_USER) || role.equals(ROLE_ADMIN)) {
// 更新token // 更新token

View File

@@ -3,6 +3,7 @@ package cn.celess.blog.controller;
import cn.celess.blog.enmu.ResponseEnum; import cn.celess.blog.enmu.ResponseEnum;
import cn.celess.blog.entity.Response; import cn.celess.blog.entity.Response;
import cn.celess.blog.entity.model.ArticleModel; import cn.celess.blog.entity.model.ArticleModel;
import cn.celess.blog.entity.model.PageData;
import cn.celess.blog.entity.request.ArticleReq; import cn.celess.blog.entity.request.ArticleReq;
import cn.celess.blog.service.ArticleService; import cn.celess.blog.service.ArticleService;
import cn.celess.blog.util.RedisUserUtil; import cn.celess.blog.util.RedisUserUtil;
@@ -11,6 +12,8 @@ import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*; import org.springframework.web.bind.annotation.*;
import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletRequest;
import java.util.List;
import java.util.stream.Collectors;
/** /**
* @author : xiaohai * @author : xiaohai
@@ -110,8 +113,9 @@ public class ArticleController {
*/ */
@GetMapping("/admin/articles") @GetMapping("/admin/articles")
public Response adminArticles(@RequestParam(name = "page", defaultValue = "1") int page, public Response adminArticles(@RequestParam(name = "page", defaultValue = "1") int page,
@RequestParam(name = "count", defaultValue = "10") int count) { @RequestParam(name = "count", defaultValue = "10") int count,
return Response.success(articleService.adminArticles(count, page)); @RequestParam(name = "deleted", defaultValue = "false") boolean deleted) {
return Response.success(articleService.adminArticles(count, page, deleted));
} }
/** /**

View File

@@ -1,190 +1,190 @@
package cn.celess.blog.controller; package cn.celess.blog.controller;
import cn.celess.blog.enmu.ResponseEnum; import cn.celess.blog.enmu.ResponseEnum;
import cn.celess.blog.entity.Response; import cn.celess.blog.entity.Response;
import cn.celess.blog.entity.model.QiniuResponse; import cn.celess.blog.entity.model.QiniuResponse;
import cn.celess.blog.exception.MyException; import cn.celess.blog.exception.MyException;
import cn.celess.blog.service.CountService; import cn.celess.blog.service.CountService;
import cn.celess.blog.service.QiniuService; import cn.celess.blog.service.QiniuService;
import cn.celess.blog.util.HttpUtil; import cn.celess.blog.util.HttpUtil;
import cn.celess.blog.util.RedisUtil; import cn.celess.blog.util.RedisUtil;
import cn.celess.blog.util.VeriCodeUtil; import cn.celess.blog.util.VeriCodeUtil;
import net.sf.json.JSONArray; import net.sf.json.JSONArray;
import net.sf.json.JSONObject; import net.sf.json.JSONObject;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.MediaType; import org.springframework.http.MediaType;
import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController; import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile; import org.springframework.web.multipart.MultipartFile;
import javax.imageio.ImageIO; import javax.imageio.ImageIO;
import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpServletResponse;
import java.awt.image.BufferedImage; import java.awt.image.BufferedImage;
import java.io.IOException; import java.io.IOException;
import java.io.OutputStream; import java.io.OutputStream;
import java.util.Enumeration; import java.util.Enumeration;
import java.util.HashMap; import java.util.HashMap;
import java.util.Map; import java.util.Map;
import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeUnit;
/** /**
* @author : xiaohai * @author : xiaohai
* @date : 2019/04/02 22:03 * @date : 2019/04/02 22:03
*/ */
@RestController @RestController
public class Other { public class CommonController {
public static final Logger logger = LoggerFactory.getLogger(Object.class); public static final Logger logger = LoggerFactory.getLogger(Object.class);
@Autowired @Autowired
CountService countService; CountService countService;
@Autowired @Autowired
QiniuService qiniuService; QiniuService qiniuService;
@Autowired @Autowired
RedisUtil redisUtil; RedisUtil redisUtil;
@Autowired @Autowired
HttpServletRequest request; HttpServletRequest request;
@GetMapping("/counts") @GetMapping("/counts")
public Response allCount() { public Response allCount() {
Map<String, Long> countMap = new HashMap<>(); Map<String, Long> countMap = new HashMap<>();
countMap.put("articleCount", countService.getArticleCount()); countMap.put("articleCount", countService.getArticleCount());
countMap.put("commentCount", countService.getCommentCount()); countMap.put("commentCount", countService.getCommentCount());
countMap.put("categoryCount", countService.getCategoriesCount()); countMap.put("categoryCount", countService.getCategoriesCount());
countMap.put("tagCount", countService.getTagsCount()); countMap.put("tagCount", countService.getTagsCount());
countMap.put("visitorCount", countService.getVisitorCount()); countMap.put("visitorCount", countService.getVisitorCount());
return Response.success(countMap); return Response.success(countMap);
} }
/** /**
* 获取header的全部参数 * 获取header的全部参数
* *
* @param request HttpServletRequest * @param request HttpServletRequest
* @return Response * @return Response
*/ */
@GetMapping("/headerInfo") @GetMapping("/headerInfo")
public Response headerInfo(HttpServletRequest request) { public Response headerInfo(HttpServletRequest request) {
Map<String, Object> map = new HashMap<>(); Map<String, Object> map = new HashMap<>();
Enumeration<String> headerNames = request.getHeaderNames(); Enumeration<String> headerNames = request.getHeaderNames();
String str = null; String str = null;
while (headerNames.hasMoreElements()) { while (headerNames.hasMoreElements()) {
str = headerNames.nextElement(); str = headerNames.nextElement();
map.put(str, request.getHeader(str)); map.put(str, request.getHeader(str));
} }
map.put("sessionID", request.getSession().getId()); map.put("sessionID", request.getSession().getId());
map.put("request.getRemoteAddr()", request.getRemoteAddr()); map.put("request.getRemoteAddr()", request.getRemoteAddr());
return Response.success(map); return Response.success(map);
} }
/** /**
* 返回验证码 * 返回验证码
* *
* @param response HttpServletResponse * @param response HttpServletResponse
* @throws IOException IOException * @throws IOException IOException
*/ */
@GetMapping(value = "/imgCode", produces = MediaType.IMAGE_PNG_VALUE) @GetMapping(value = "/imgCode", produces = MediaType.IMAGE_PNG_VALUE)
public void getImg(HttpServletResponse response) throws IOException { public void getImg(HttpServletResponse response) throws IOException {
Object[] obj = VeriCodeUtil.createImage(); Object[] obj = VeriCodeUtil.createImage();
request.getSession().setAttribute("code", obj[0]); request.getSession().setAttribute("code", obj[0]);
//将图片输出给浏览器 //将图片输出给浏览器
BufferedImage image = (BufferedImage) obj[1]; BufferedImage image = (BufferedImage) obj[1];
response.setContentType("image/png"); response.setContentType("image/png");
OutputStream os = response.getOutputStream(); OutputStream os = response.getOutputStream();
ImageIO.write(image, "png", os); ImageIO.write(image, "png", os);
os.close(); os.close();
} }
/** /**
* 验证 验证码的正确性 * 验证 验证码的正确性
* *
* @param code 传进来的验证码 * @param code 传进来的验证码
* @param request HttpServletRequest * @param request HttpServletRequest
* @return Session中写入验证状态 * @return Session中写入验证状态
*/ */
@PostMapping("/verCode") @PostMapping("/verCode")
public Response verCode(@RequestParam("code") String code, HttpServletRequest request) { public Response verCode(@RequestParam("code") String code, HttpServletRequest request) {
request.getSession().setAttribute("verImgCodeStatus", false); request.getSession().setAttribute("verImgCodeStatus", false);
String codeStr = (String) request.getSession().getAttribute("code"); String codeStr = (String) request.getSession().getAttribute("code");
if (code == null) { if (code == null) {
throw new MyException(ResponseEnum.PARAMETERS_ERROR); throw new MyException(ResponseEnum.PARAMETERS_ERROR);
} }
if (codeStr == null) { if (codeStr == null) {
throw new MyException(ResponseEnum.IMG_CODE_TIMEOUT); throw new MyException(ResponseEnum.IMG_CODE_TIMEOUT);
} }
code = code.toLowerCase(); code = code.toLowerCase();
codeStr = codeStr.toLowerCase(); codeStr = codeStr.toLowerCase();
if (code.equals(codeStr)) { if (code.equals(codeStr)) {
request.getSession().removeAttribute("code"); request.getSession().removeAttribute("code");
request.getSession().setAttribute("verImgCodeStatus", true); request.getSession().setAttribute("verImgCodeStatus", true);
return Response.success("验证成功"); return Response.success("验证成功");
} else { } else {
request.getSession().removeAttribute("code"); request.getSession().removeAttribute("code");
return Response.failure("验证失败,请重新获取验证码"); return Response.failure("验证失败,请重新获取验证码");
} }
} }
/** /**
* FIXME :: 单张图片多次上传的问题 * FIXME :: 单张图片多次上传的问题
* editor.md图片上传的接口 * editor.md图片上传的接口
* FUCK !!! * FUCK !!!
* *
* @param file 文件 * @param file 文件
* @return * @return
* @throws IOException * @throws IOException
*/ */
@PostMapping("/imgUpload") @PostMapping("/imgUpload")
public void upload(HttpServletRequest request, HttpServletResponse response, @RequestParam("editormd-image-file") MultipartFile file) throws IOException { public void upload(HttpServletRequest request, HttpServletResponse response, @RequestParam("editormd-image-file") MultipartFile file) throws IOException {
JSONObject jsonObject = new JSONObject(); JSONObject jsonObject = new JSONObject();
String uploadTimesStr = redisUtil.get(request.getRemoteAddr() + "-ImgUploadTimes"); String uploadTimesStr = redisUtil.get(request.getRemoteAddr() + "-ImgUploadTimes");
int uploadTimes = 0; int uploadTimes = 0;
if (uploadTimesStr != null) { if (uploadTimesStr != null) {
uploadTimes = Integer.parseInt(uploadTimesStr); uploadTimes = Integer.parseInt(uploadTimesStr);
} }
if (uploadTimes == 10) { if (uploadTimes == 10) {
throw new MyException(ResponseEnum.FAILURE.getCode(), "上传次数已达10次请2小时后在上传"); throw new MyException(ResponseEnum.FAILURE.getCode(), "上传次数已达10次请2小时后在上传");
} }
request.setCharacterEncoding("utf-8"); request.setCharacterEncoding("utf-8");
response.setContentType("text/html"); response.setContentType("text/html");
if (file.isEmpty()) { if (file.isEmpty()) {
jsonObject.put("success", 0); jsonObject.put("success", 0);
jsonObject.put("message", "上传失败,请选择文件"); jsonObject.put("message", "上传失败,请选择文件");
response.getWriter().println(jsonObject.toString()); response.getWriter().println(jsonObject.toString());
return; return;
} }
String fileName = file.getOriginalFilename(); String fileName = file.getOriginalFilename();
String mime = fileName.substring(fileName.lastIndexOf(".")); String mime = fileName.substring(fileName.lastIndexOf("."));
if (".png".equals(mime.toLowerCase()) || ".jpg".equals(mime.toLowerCase()) || if (".png".equals(mime.toLowerCase()) || ".jpg".equals(mime.toLowerCase()) ||
".jpeg".equals(mime.toLowerCase()) || ".bmp".equals(mime.toLowerCase())) { ".jpeg".equals(mime.toLowerCase()) || ".bmp".equals(mime.toLowerCase())) {
QiniuResponse qiniuResponse = qiniuService.uploadFile(file.getInputStream(), "img_" + System.currentTimeMillis() + mime); QiniuResponse qiniuResponse = qiniuService.uploadFile(file.getInputStream(), "img_" + System.currentTimeMillis() + mime);
jsonObject.put("success", 1); jsonObject.put("success", 1);
jsonObject.put("message", "上传成功"); jsonObject.put("message", "上传成功");
jsonObject.put("url", "http://cdn.celess.cn/" + qiniuResponse.key); jsonObject.put("url", "http://cdn.celess.cn/" + qiniuResponse.key);
response.getWriter().println(jsonObject.toString()); response.getWriter().println(jsonObject.toString());
redisUtil.setEx(request.getRemoteAddr() + "-ImgUploadTimes", uploadTimes + 1 + "", 2, TimeUnit.HOURS); redisUtil.setEx(request.getRemoteAddr() + "-ImgUploadTimes", uploadTimes + 1 + "", 2, TimeUnit.HOURS);
return; return;
} }
jsonObject.put("success", 0); jsonObject.put("success", 0);
jsonObject.put("message", "上传失败,请上传图片文件"); jsonObject.put("message", "上传失败,请上传图片文件");
response.getWriter().println(jsonObject.toString()); response.getWriter().println(jsonObject.toString());
} }
@GetMapping("/bingPic") @GetMapping("/bingPic")
public Response bingPic() { public Response bingPic() {
JSONObject imageObj; JSONObject imageObj;
try { try {
imageObj = JSONObject.fromObject(HttpUtil.get("https://cn.bing.com/HPImageArchive.aspx?format=js&idx=0&n=1&mkt=zh-CN")); imageObj = JSONObject.fromObject(HttpUtil.get("https://cn.bing.com/HPImageArchive.aspx?format=js&idx=0&n=1&mkt=zh-CN"));
} catch (IOException e) { } catch (IOException e) {
return Response.failure(null); return Response.failure(null);
} }
JSONArray jsonArray = imageObj.getJSONArray("images"); JSONArray jsonArray = imageObj.getJSONArray("images");
String imageName = jsonArray.getJSONObject(0).getString("url"); String imageName = jsonArray.getJSONObject(0).getString("url");
return Response.success("https://cn.bing.com" + imageName); return Response.success("https://cn.bing.com" + imageName);
} }
} }

View File

@@ -33,6 +33,7 @@ public enum ResponseEnum {
PWD_SAME(3601, "新密码与原密码相同"), PWD_SAME(3601, "新密码与原密码相同"),
PWD_NOT_SAME(3602, "新密码与原密码不相同"), PWD_NOT_SAME(3602, "新密码与原密码不相同"),
LOGIN_EXPIRED(3700, "登陆过期"), LOGIN_EXPIRED(3700, "登陆过期"),
LOGOUT(3710, "账户已注销"),
PWD_WRONG(3800, "密码不正确"), PWD_WRONG(3800, "密码不正确"),
JWT_EXPIRED(3810, "Token过期"), JWT_EXPIRED(3810, "Token过期"),

View File

@@ -11,15 +11,15 @@ import java.io.Serializable;
* @date : 2019/03/28 15:24 * @date : 2019/03/28 15:24
*/ */
@Data @Data
public class Response implements Serializable { public class Response<T> implements Serializable {
private int code; private int code;
private String msg; private String msg;
private Object result; private T result;
public Response() { public Response() {
} }
public Response(int code, String msg, Object result) { public Response(int code, String msg, T result) {
this.code = code; this.code = code;
this.msg = msg; this.msg = msg;
this.result = result; this.result = result;

View File

@@ -82,4 +82,6 @@ public class ArticleModel {
* 文章的状态 true公开 false:不公开 * 文章的状态 true公开 false:不公开
*/ */
private Boolean open; private Boolean open;
private boolean deleted;
} }

View File

@@ -20,4 +20,5 @@ public class CategoryModel {
private String name; private String name;
private List<ArticleModel> articles; private List<ArticleModel> articles;
private boolean deleted;
} }

View File

@@ -21,4 +21,5 @@ public class TagModel {
private List<ArticleModel> articles; private List<ArticleModel> articles;
private boolean deleted;
} }

View File

@@ -37,4 +37,6 @@ public class UserModel {
private String role = "user"; private String role = "user";
private String token; private String token;
private int status;
} }

View File

@@ -21,4 +21,6 @@ public class WebUpdateModel {
this.info = info; this.info = info;
this.time = time; this.time = time;
} }
private boolean deleted;
} }

View File

@@ -52,7 +52,7 @@ public interface ArticleService {
* @param page 数据页 * @param page 数据页
* @return 分页数据 * @return 分页数据
*/ */
PageData<ArticleModel> adminArticles(int count, int page); PageData<ArticleModel> adminArticles(int count, int page, boolean deleted);
/** /**
* 获取文章状态为开放的文章 * 获取文章状态为开放的文章

View File

@@ -22,10 +22,12 @@ import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional; import org.springframework.transaction.annotation.Transactional;
import sun.security.krb5.internal.PAData;
import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletRequest;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
import java.util.stream.Collectors;
/** /**
@@ -145,7 +147,7 @@ public class ArticleServiceImpl implements ArticleService {
//删除指定文章 //删除指定文章
articleMapper.delete(articleId); articleMapper.delete(articleId);
articleTagMapper.deleteByArticleId(articleId); //articleTagMapper.deleteByArticleId(articleId);
return true; return true;
} }
@@ -273,21 +275,24 @@ public class ArticleServiceImpl implements ArticleService {
/** /**
* @param count 数目 * @param count 数目
* @param page 页面 默认减1 * @param page 页面
* @return PageInfo * @return PageInfo
*/ */
@Override @Override
public PageData<ArticleModel> adminArticles(int count, int page) { public PageData<ArticleModel> adminArticles(int count, int page, boolean deleted) {
PageHelper.startPage(page, count, "articleId desc");
List<Article> articleList = articleMapper.findAll(); List<Article> articleList = articleMapper.findAll();
PageData<ArticleModel> pageData = new PageData<ArticleModel>(new PageInfo<Article>(articleList));
List<ArticleModel> articleModelList = new ArrayList<>(); PageData<ArticleModel> pageData = new PageData<>(null, 0, count, page);
articleList.forEach(article -> { List<Article> collect = articleList.stream().filter(article -> article.isDeleted() == deleted).collect(Collectors.toList());
ArticleModel articleModel = ModalTrans.article(article); pageData.setTotal(collect.size());
articleModel.setMdContent(null); List<ArticleModel> articleModels = collect.stream()
articleModelList.add(articleModel); .peek(article -> article.setMdContent(null))
}); .map(ModalTrans::article)
pageData.setList(articleModelList); .skip((page - 1) * count)
.limit(count)
.collect(Collectors.toList());
pageData.setList(articleModels);
return pageData; return pageData;
} }

View File

@@ -52,6 +52,12 @@ public class PartnerSiteServiceImpl implements PartnerSiteService {
reqBody.setUrl("http://" + reqBody.getUrl()); reqBody.setUrl("http://" + reqBody.getUrl());
} }
BeanUtils.copyProperties(reqBody, partnerSite); BeanUtils.copyProperties(reqBody, partnerSite);
if (reqBody.getIconPath() == null) {
partnerSite.setIconPath("");
}
if (reqBody.getDesc() == null) {
partnerSite.setDesc("");
}
partnerMapper.insert(partnerSite); partnerMapper.insert(partnerSite);
return partnerSite; return partnerSite;
} }

View File

@@ -24,6 +24,7 @@ import java.util.Date;
import java.util.HashMap; import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.stream.Collectors;
/** /**
* @Author: 小海 * @Author: 小海
@@ -99,7 +100,7 @@ public class SitemapGenerateUtil {
urlList.put("https://www.celess.cn", DateFormatUtil.getForXmlDate(new Date())); urlList.put("https://www.celess.cn", DateFormatUtil.getForXmlDate(new Date()));
urlList.put("https://www.celess.cn/links", DateFormatUtil.getForXmlDate(new Date())); urlList.put("https://www.celess.cn/links", DateFormatUtil.getForXmlDate(new Date()));
urlList.put("https://www.celess.cn/leaveMsg", DateFormatUtil.getForXmlDate(new Date())); urlList.put("https://www.celess.cn/leaveMsg", DateFormatUtil.getForXmlDate(new Date()));
List<Article> articles = articleMapper.findAll(); List<Article> articles = articleMapper.findAll().stream().filter(article -> article.getOpen()&&!article.isDeleted()).collect(Collectors.toList());
articles.forEach(article -> { articles.forEach(article -> {
urlList.put("https://www.celess.cn/article/" + article.getId(), DateFormatUtil.getForXmlDate( urlList.put("https://www.celess.cn/article/" + article.getId(), DateFormatUtil.getForXmlDate(
article.getUpdateDate() == null ? article.getPublishDate() : article.getUpdateDate())); article.getUpdateDate() == null ? article.getPublishDate() : article.getUpdateDate()));

View File

@@ -37,8 +37,8 @@
<insert id="insert" useGeneratedKeys="true" keyProperty="id"> <insert id="insert" useGeneratedKeys="true" keyProperty="id">
insert into comment (co_page_path, co_content, co_date, co_pid, co_from_author_id, co_to_author_id, is_delete) insert into comment (co_page_path, co_content, co_date, co_pid, co_from_author_id, co_to_author_id, co_status)
VALUES (#{pagePath}, #{content}, now(), #{pid}, #{fromUser.id}, #{toUser.id}, false) VALUES (#{pagePath}, #{content}, now(), #{pid}, #{fromUser.id}, #{toUser.id}, 0)
</insert> </insert>
<update id="updateContent"> <update id="updateContent">
@@ -84,7 +84,6 @@
<select id="findAllByPagePath" resultMap="commentViewResultMap" parameterType="string"> <select id="findAllByPagePath" resultMap="commentViewResultMap" parameterType="string">
select * select *
from commentView from commentView
# 无奈之举
<if test="toString() != null "> <if test="toString() != null ">
where pagePath = #{pagePath} where pagePath = #{pagePath}
</if> </if>

View File

@@ -154,7 +154,7 @@
<select id="findAll" resultMap="articleViewResultMap"> <select id="findAll" resultMap="articleViewResultMap">
select * select *
from articleView from articleView
where isDelete = false order by articleId desc
</select> </select>

View File

@@ -1,30 +1,37 @@
package cn.celess.blog; package cn.celess.blog;
import cn.celess.blog.entity.Response;
import cn.celess.blog.entity.model.UserModel;
import cn.celess.blog.entity.request.LoginReq; import cn.celess.blog.entity.request.LoginReq;
import net.sf.json.JSONObject; import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.junit.After; import org.junit.After;
import org.junit.Before; import org.junit.Before;
import org.junit.Test; import org.junit.Test;
import org.junit.runner.RunWith; import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest; import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.http.MediaType;
import org.springframework.mock.web.MockHttpSession; import org.springframework.mock.web.MockHttpSession;
import org.springframework.test.context.ActiveProfiles; import org.springframework.test.context.ActiveProfiles;
import org.springframework.test.context.junit4.SpringRunner; import org.springframework.test.context.junit4.SpringRunner;
import org.springframework.test.context.web.WebAppConfiguration; import org.springframework.test.context.web.WebAppConfiguration;
import org.springframework.test.web.servlet.MockMvc; import org.springframework.test.web.servlet.MockMvc;
import org.springframework.test.web.servlet.MvcResult; import org.springframework.test.web.servlet.ResultActions;
import org.springframework.test.web.servlet.ResultHandler; import org.springframework.test.web.servlet.request.MockHttpServletRequestBuilder;
import org.springframework.test.web.servlet.request.MockMvcRequestBuilders; import org.springframework.test.web.servlet.request.MockMvcRequestBuilders;
import org.springframework.test.web.servlet.result.MockMvcResultHandlers;
import org.springframework.test.web.servlet.setup.MockMvcBuilders; import org.springframework.test.web.servlet.setup.MockMvcBuilders;
import org.springframework.web.context.WebApplicationContext; import org.springframework.web.context.WebApplicationContext;
import javax.servlet.http.Cookie;
import java.util.UUID; import java.util.UUID;
import static cn.celess.blog.enmu.ResponseEnum.SUCCESS;
import static org.junit.Assert.*; import static org.junit.Assert.*;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
/** /**
* @Author: 小海 * @Author: 小海
@@ -40,6 +47,12 @@ public class BaseTest {
protected MockMvc mockMvc; protected MockMvc mockMvc;
protected final static String Code = "code"; protected final static String Code = "code";
protected final static String Result = "result"; protected final static String Result = "result";
private static String userToken = null;
private static String adminToken = null;
/**
* jackson 序列化/反序列化Json
*/
protected final ObjectMapper mapper = new ObjectMapper();
@Autowired @Autowired
private WebApplicationContext wac; private WebApplicationContext wac;
@@ -57,51 +70,125 @@ public class BaseTest {
System.out.println("==========> 测试结束 <========="); System.out.println("==========> 测试结束 <=========");
} }
/**
*  admin 权限用户登录
*
* @return token
*/
protected String adminLogin() { protected String adminLogin() {
try { if (adminToken != null) return adminToken;
LoginReq req = new LoginReq(); LoginReq req = new LoginReq();
req.setEmail("a@celess.cn"); req.setEmail("a@celess.cn");
req.setPassword("123456789"); req.setPassword("123456789");
req.setIsRememberMe(false); req.setIsRememberMe(false);
JSONObject loginReq = JSONObject.fromObject(req); adminToken = login(req);
String str = mockMvc.perform(MockMvcRequestBuilders.post("/login").content(loginReq.toString()).contentType("application/json")) assertNotNull(adminToken);
// .andDo(MockMvcResultHandlers.print()) return adminToken;
.andReturn().getResponse().getContentAsString();
String token = JSONObject.fromObject(str).getJSONObject(Result).getString("token");
assertNotNull(token);
return token;
} catch (Exception e) {
e.printStackTrace();
return null;
}
} }
/**
* user 权限用户登录
*
* @return token
*/
protected String userLogin() { protected String userLogin() {
if (userToken != null) return userToken;
LoginReq req = new LoginReq();
req.setEmail("zh56462271@qq.com");
req.setPassword("123456789");
req.setIsRememberMe(false);
userToken = login(req);
assertNotNull(userToken);
return userToken;
}
/**
* 登录逻辑
*
* @param req 用户信息
* @return token | null
*/
private String login(LoginReq req) {
String str = null;
try { try {
LoginReq req = new LoginReq(); str = getMockData(post("/login"), null, req)
req.setEmail("zh56462271@qq.com");
req.setPassword("123456789");
req.setIsRememberMe(false);
JSONObject loginReq = JSONObject.fromObject(req);
String str = mockMvc.perform(MockMvcRequestBuilders.post("/login").content(loginReq.toString()).contentType("application/json"))
// .andDo(MockMvcResultHandlers.print())
.andReturn().getResponse().getContentAsString(); .andReturn().getResponse().getContentAsString();
String token = JSONObject.fromObject(str).getJSONObject(Result).getString("token"); Response<UserModel> response = mapper.readValue(str, new TypeReference<Response<UserModel>>() {
});
assertEquals(SUCCESS.getCode(), response.getCode());
String token = response.getResult().getToken();
assertNotNull(token); assertNotNull(token);
return token; return token;
} catch (Exception e) { } catch (Exception e) {
e.printStackTrace(); e.printStackTrace();
return null;
} }
return null;
} }
@Test @Test
public void test() { public void test() {
// 测试登录
assertNotNull(userLogin());
assertNotNull(adminLogin());
try {
// 测试getMockData方法
assertNotNull(getMockData(get("/headerInfo")));
} catch (Exception e) {
e.printStackTrace();
}
} }
/**
* 产生指定长度的随机字符
*
* @param len
* @return
*/
protected String randomStr(int len) { protected String randomStr(int len) {
return UUID.randomUUID().toString().replaceAll("-", "").substring(0, len); return UUID.randomUUID().toString().replaceAll("-", "").substring(0, len);
} }
/**
* 抽离的mock请求方法
*
* @param builder MockHttpServletRequestBuilder get(...) post(...) ....
* @return 返回 ResultActions
* @throws Exception exc
*/
protected ResultActions getMockData(MockHttpServletRequestBuilder builder) throws Exception {
return getMockData(builder, null, null);
}
/**
* 抽离的mock请求方法 重载
*
* @param builder ..
* @param token 用户登录的token
* @return ..
* @throws Exception ..
*/
protected ResultActions getMockData(MockHttpServletRequestBuilder builder, String token) throws Exception {
return getMockData(builder, token, null);
}
/**
* 抽离的mock请求方法 重载
*
* @param builder ..
* @param token ..
* @param content http中发送的APPLICATION_JSON的json数据
* @return ..
* @throws Exception ..
*/
protected ResultActions getMockData(MockHttpServletRequestBuilder builder, String token, Object content) throws Exception {
// MockHttpServletRequestBuilder mockHttpServletRequestBuilder = get(url);
if (token != null) {
builder.header("Authorization", token);
}
if (content != null) {
builder.content(mapper.writeValueAsString(content)).contentType(MediaType.APPLICATION_JSON);
}
return mockMvc.perform(builder).andExpect(status().isOk());
}
} }

View File

@@ -8,6 +8,8 @@ import cn.celess.blog.entity.model.ArticleModel;
import cn.celess.blog.entity.model.PageData; import cn.celess.blog.entity.model.PageData;
import cn.celess.blog.entity.request.ArticleReq; import cn.celess.blog.entity.request.ArticleReq;
import cn.celess.blog.mapper.ArticleMapper; import cn.celess.blog.mapper.ArticleMapper;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;
import net.sf.json.JSONObject; import net.sf.json.JSONObject;
import org.junit.Test; import org.junit.Test;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
@@ -260,55 +262,43 @@ public class ArticleControllerTest extends BaseTest {
@Test @Test
public void adminArticles() { public void adminArticles() {
String token;
try { try {
// 未登录 getMockData(get("/admin/articles?page=1&count=10")).andExpect(result ->
mockMvc.perform(get("/admin/articles?page=1&count=10")) assertEquals(HAVE_NOT_LOG_IN.getCode(), mapper.readValue(result.getResponse().getContentAsString(), Response.class).getCode())
.andExpect(status().isOk()) );
.andDo(result -> {
assertEquals(HAVE_NOT_LOG_IN.getCode(),
JSONObject.fromObject(result.getResponse().getContentAsString()).getInt(Code)
);
});
// User权限登陆 // User权限登陆
token = userLogin(); getMockData(get("/admin/articles?page=1&count=10"), userLogin()).andDo(result ->
mockMvc.perform(get("/admin/articles?page=1&count=10") assertEquals(PERMISSION_ERROR.getCode(), mapper.readValue(result.getResponse().getContentAsString(), Response.class).getCode())
.header("Authorization", token)) );
.andExpect(status().isOk()) for (int i = 0; i < 2; i++) {
.andDo(result -> { // admin权限登陆
JSONObject object = JSONObject.fromObject(result.getResponse().getContentAsString()); int finalI = i;
assertEquals(PERMISSION_ERROR.getCode(), object.getInt(Code)); getMockData(get("/admin/articles?page=1&count=10&deleted=" + (i == 1)), adminLogin()).andDo(result -> {
}); Response<PageData<ArticleModel>> response = mapper.readValue(result.getResponse().getContentAsString(), new TypeReference<Response<PageData<ArticleModel>>>() {
token = adminLogin();
// admin权限登陆
mockMvc.perform(get("/admin/articles?page=1&count=10")
.header("Authorization", token))
.andExpect(status().isOk())
.andDo(result -> {
JSONObject adminLogin = JSONObject.fromObject(result.getResponse().getContentAsString());
assertEquals(SUCCESS.getCode(), adminLogin.getInt(Code));
assertNotNull(adminLogin.getString(Result));
// 判断pageInfo是否包装完全
PageData<ArticleModel> pageData = (PageData<ArticleModel>) JSONObject.toBean(adminLogin.getJSONObject(Result), PageData.class);
assertNotEquals(0, pageData.getTotal());
assertEquals(1, pageData.getPageNum());
assertEquals(10, pageData.getPageSize());
// 内容完整
for (Object arc : pageData.getList()) {
ArticleModel a = (ArticleModel) JSONObject.toBean(JSONObject.fromObject(arc), ArticleModel.class);
assertNotNull(a.getTitle());
assertNotNull(a.getId());
assertNotNull(a.getOriginal());
assertNotNull(a.getPublishDateFormat());
assertNotNull(a.getOpen());
assertNotNull(a.getReadingNumber());
assertNotNull(a.getLikeCount());
assertNotNull(a.getDislikeCount());
assertNull(a.getMdContent());
}
}); });
assertEquals(SUCCESS.getCode(), response.getCode());
assertNotNull(response.getResult());
// 判断pageInfo是否包装完全
PageData<ArticleModel> pageData = response.getResult();
assertNotEquals(0, pageData.getTotal());
assertEquals(1, pageData.getPageNum());
assertEquals(10, pageData.getPageSize());
// 内容完整
for (ArticleModel a : pageData.getList()) {
assertNotNull(a.getTitle());
assertNotNull(a.getId());
assertNotNull(a.getOriginal());
assertNotNull(a.getPublishDateFormat());
assertNotNull(a.getOpen());
assertNotNull(a.getReadingNumber());
assertNotNull(a.getLikeCount());
assertNotNull(a.getDislikeCount());
assertEquals((finalI == 1), a.isDeleted());
assertNull(a.getMdContent());
}
});
}
} catch (Exception e) { } catch (Exception e) {
e.printStackTrace(); e.printStackTrace();
} }

View File

@@ -75,10 +75,8 @@ public class ArticleTagMapperTest extends BaseTest {
@Test @Test
public void deleteMultiById() { public void deleteMultiById() {
ArticleTag articleTag = new ArticleTag(); ArticleTag articleTag = new ArticleTag();
Article article = new Article(); Article article = articleMapper.getLastestArticle();
article.setId(-1L); Tag tag = tagMapper.getLastestTag();
Tag tag = new Tag();
tag.setId(1L);
articleTag.setArticle(article); articleTag.setArticle(article);
articleTag.setTag(tag); articleTag.setTag(tag);
@@ -89,7 +87,7 @@ public class ArticleTagMapperTest extends BaseTest {
articleTagMapper.insert(articleTag); articleTagMapper.insert(articleTag);
articleTagMapper.insert(articleTag); articleTagMapper.insert(articleTag);
List<ArticleTag> allByArticleId = articleTagMapper.findAllByArticleId(-1L); List<ArticleTag> allByArticleId = articleTagMapper.findAllByArticleId(article.getId());
assertTrue(allByArticleId.size() >= 6); assertTrue(allByArticleId.size() >= 6);
int lines = articleTagMapper.deleteMultiById(allByArticleId); int lines = articleTagMapper.deleteMultiById(allByArticleId);
assertTrue(lines >= 6); assertTrue(lines >= 6);