diff --git a/dev.sql b/dev.sql index d61801a..6289532 100644 --- a/dev.sql +++ b/dev.sql @@ -57,7 +57,7 @@ VALUES (3, '关于这个博客我有话要说', (10, 'Linux下Vim的“假死”', '随手一个Ctrl+S 是个好习惯\n然而....\n然而这个习惯却在我使用Vim的时候坑了我\n由于不是经常发生,也就没在意。每次很麻烦的关掉terminal的窗口,重新再打开terminal。今天发生了好几次,很是郁闷。就想看看究竟是怎么回事,结果发现每次按下Ctrl+S就会出现这个问题。\n后来百度,Google才发现 这货是一个快捷键 对应的是 锁定屏幕\n要解除锁定 只需 Ctrl + Q\n我估计这可能是Vim中我记得最牢的一个快捷键之一吧\n', '随手一个Ctrl+S 是个好习惯\n\n然而....\n\n然而这个习惯却在我使用Vim的时候坑了我\n\n由于不是经常发生,也就没在意。每次很麻烦的关掉terminal的窗口,重新再打开terminal。今天发生了好几次,很是郁闷。就想看看究竟是怎么回事,结果发现每次按下Ctrl+S就会出现这个问题。\n\n后来百度,Google才发现 这货是一个快捷键 对应的是 锁定屏幕\n\n要解除锁定 只需 Ctrl + Q\n\n我估计这可能是Vim中我记得最牢的一个快捷键之一吧', - '', 1, 1, 221, 0, 0, 3, '2019-04-16 15:24:13', NULL, 1, 0), + '', 1, 1, 221, 0, 0, 3, '2019-04-16 15:24:13', NULL, 1, 1), (12, '自己动手撸一个Spring MVC控制器', '自己动手撸一个 MVC 控制器\n\n 用来加深对java反射的理解的练手项目 也是加深对spring MVC 理解的项目\n \n\n\n\nMappping 对象\n\n\n\nimport java.lang.reflect.Method;\n\n/**\n * 用于存储每个url映射\n *\n * @author : xiaohai\n * @date : 2019/03/17 20:58\n */\npublic class Mapping {\n private String[] ......', '## 自己动手撸一个 MVC 控制器\n\n 用来加深对java反射的理解的练手项目 也是加深对spring MVC 理解的项目\n \n\n\n> Mappping 对象\n\n``` \nimport java.lang.reflect.Method;\n\n/**\n * 用于存储每个url映射\n *\n * @author : xiaohai\n * @date : 2019/03/17 20:58\n */\npublic class Mapping {\n private String[] path;\n\n private String requestMethod;// 请求方式\n\n private Class aclass;\n\n private Method method;//注解对应的methods\n\n //setter and getter\n}\n```\n\n
\n\n> RequestMapping注解\n\n```\n@Retention(RetentionPolicy.RUNTIME)\n@Target({ElementType.METHOD,ElementType.TYPE})\npublic @interface RequestMapping {\n String[] value() default "";\n\n RequestMethod method() default RequestMethod.GET;\n}\n```\n\n
\n> Controller注解\n\n```\n@Retention(RetentionPolicy.RUNTIME)\n@Target(ElementType.TYPE)\npublic @interface Controller {\n String value() default "";\n}\n```\n\n\n\n
\n> 核心servlet\n\n``` \n\nimport cn.celess.boot.Application;\nimport cn.celess.boot.annotation.Controller;\nimport cn.celess.boot.annotation.RequestMapping;\nimport cn.celess.boot.entity.Mapping;\nimport cn.celess.boot.util.*;\nimport cn.celess.logtool.Log;\n\nimport javax.servlet.*;\nimport javax.servlet.http.HttpServlet;\nimport javax.servlet.http.HttpServletRequest;\nimport javax.servlet.http.HttpServletResponse;\nimport java.io.IOException;\nimport java.lang.reflect.InvocationTargetException;\nimport java.lang.reflect.Method;\nimport java.util.ArrayList;\nimport java.util.Arrays;\nimport java.util.List;\n\n/**\n * @author : xiaohai\n * @date : 2019/03/17 10:16\n * 核心控制类\n */\npublic class DispatcherServlet extends HttpServlet {\n private static final Log log = new Log(DispatcherServlet.class);\n private static final List mappingList = new ArrayList();\n\n public DispatcherServlet() {\n initRequestMapingMap(Application.classpath);\n }\n\n /**\n * 解析 获取请求的参数 即RequestMapping的value值和method\n * 对path进行整理 保存为/xx/xx/的格式\n *\n * @param request\n * @return\n */\n private String[] pareUrl(HttpServletRequest request) {\n String[] pAndM = new String[2];\n String path = request.getContextPath() + "/";\n String requestUri = request.getRequestURI().replaceFirst(path, "");\n if (requestUri.length() > 0) {\n if (requestUri.substring(requestUri.length() - 1) != "/") {\n requestUri += "/";\n }\n } else {\n requestUri += "/";\n }\n pAndM[0] = "/" + requestUri;\n pAndM[1] = request.getMethod();\n\n return pAndM;\n }\n\n @Override\n protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {\n log.info("执行了service方法");\n this.execute(req, resp);\n }\n\n /**\n * 匹配path和RequestMethod 并执行path匹配的方法\n *\n * @param request\n * @param response\n * @throws ServletException\n * @throws IOException\n */\n public void execute(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {\n\n String[] s = pareUrl(request);\n String urlPath = s[0];\n String requestMethod = s[1];\n\n Class clazz = null;\n Method method = null;\n for (Mapping ml : mappingList) {\n String[] path = ml.getPath();\n for (String str : path) {\n if (urlPath.equals(str)) {\n if (requestMethod.toUpperCase().equals(ml.getRequestMethod())) {\n method = ml.getMethod();\n clazz = ml.getAclass();\n break;\n }\n }\n }\n if (method != null) break;\n }\n\n if (method == null) {\n response.sendError(404);//没找到映射\n return;\n }\n\n Object obj = null;//方法返回值\n\n if (method != null) {\n Object retObject = null;\n try {\n //创建类的实例\n obj = clazz.newInstance();\n //利用反射执行这个方法\n retObject = method.invoke(obj, request, response);\n } catch (IllegalAccessException e) {\n e.printStackTrace();\n } catch (InvocationTargetException e) {\n e.printStackTrace();\n } catch (InstantiationException e) {\n e.printStackTrace();\n }\n }\n }\n\n\n /***\n * 将controller 解析然后存储起来\n * @param packageName\n */\n private void initRequestMapingMap(String packageName) {\n List classList = ReflectUtil.getClasssFromPackage(packageName);\n for (Class c : classList) {\n if (c.isAnnotationPresent(Controller.class)) {\n Method[] methods = c.getDeclaredMethods();\n for (Method m : methods) {\n if (m.isAnnotationPresent(RequestMapping.class)) {\n String[] path = m.getAnnotation(RequestMapping.class).value();\n // 对path 进行 规范化\n for (int i = 0; i < path.length; i++) {\n if (!"/".equals(path[i].substring(0, 1))) {\n path[i] = "/" + path[i];\n }\n if (!"/".equals(path[i].substring(path[i].length() - 1))) {\n path[i] += "/";\n }\n\n }\n String requestMethod = m.getAnnotation(RequestMapping.class).method().getMethod();\n log.info("path : " + Arrays.toString(path) + " requestMethod:" + requestMethod);\n Mapping mapping = new Mapping();\n mapping.setPath(path);\n mapping.setRequestMethod(requestMethod);\n mapping.setAclass(c);\n mapping.setMethod(m);\n\n mappingList.add(mapping);\n }\n }\n }\n }\n log.info("方法映射成功");\n }\n}\n```\n\n\n', @@ -73,7 +73,7 @@ VALUES (3, '关于这个博客我有话要说', (1018, '《小王子》', '爱是一场驯养,狐狸说:“也就是说,对于我,你和其他成千上万的小男孩一样,没有不同。我不需要你;而你,也不需要我。于你而言,我和其他成千上万的狐狸也并无二致。但如果你驯养了我,我们便彼此需要。在这个世上,你就是我的唯一,我亦是你的唯一。” 我会住在其中的一颗星星上面.在某一颗星星上微笑着.每当夜晚你仰望星空的时候.就会像是看到所有的星星都在微笑一般。2019.5.8\n', '爱是一场驯养,狐狸说:“也就是说,对于我,你和其他成千上万的小男孩一样,没有不同。我不需要你;而你,也不需要我。于你而言,我和其他成千上万的狐狸也并无二致。但如果你驯养了我,我们便彼此需要。在这个世上,你就是我的唯一,我亦是你的唯一。” 我会住在其中的一颗星星上面.在某一颗星星上微笑着.每当夜晚你仰望星空的时候.就会像是看到所有的星星都在微笑一般。\n2019.5.8\n', - '', 2, 1, 343, 0, 0, 4, '2019-05-08 11:26:39', NULL, 1, 0), + '', 2, 1, 343, 0, 0, 4, '2019-05-08 11:26:39', NULL, 1, 1), (1286, 'angular中innerHTML的样式的问题', 'angular中innerHTML的样式问题\n\nangular会对css文件的样式进行处理\n例如下图就是被处理过的样式\n使用innerHTML插入dom时标签都是原生标签,是无法匹配到css样式的,而且dom上的style样式也会被清除,所以innerHTML内容是没有样式的。但撒并不是意味着我们就无法给他设置样式,具体操作如下\n\n在要插入的组件的ts的注解上面添加 encapsulation: ViewEncapsulation.None,如下:\n\n\n\n@Component......', '# angular中innerHTML的样式问题\n\n### angular会对css文件的样式进行处理\n例如下图就是被处理过的样式\n![css样式](http://cdn.celess.cn/img_1558454083327.jpg "css样式")\n
\n\n使用innerHTML插入dom时标签都是原生标签,是无法匹配到css样式的,而且dom上的style样式也会被清除,所以innerHTML内容是没有样式的。\n但撒并不是意味着我们就无法给他设置样式,具体操作如下\n\n1. 在要插入的组件的ts的注解上面添加` encapsulation: ViewEncapsulation.None,`如下:\n\n```\n@Component({\n selector: ''app-article'',\n templateUrl: ''./article.component.html'',\n encapsulation: ViewEncapsulation.None,\n styleUrls: [''./article.component.css'']\n})\n```\n2. 插入html 设置样式即可\n查看样式\n![css样式](http://cdn.celess.cn/img_1558454764739.jpg "css样式")\n\n### 新的问题\n虽然插入dom的样式解决了,但是新的问题也随之而来了,由于修改后的css内容不由angular进行特殊处理了,改css样式瞬间变成了全局样式,其他页面的样式也会因为你访问这个页面后而改变样式。所以这是一个不太合理的解决方案。特此记录。', @@ -81,7 +81,7 @@ VALUES (3, '关于这个博客我有话要说', (1287, 'HTML attribute和DOM property', 'Attribute和Property在英文中均为属性的意思,他们有密切的联系,也有不同的差别。\n\nAttribute 是由 HTML 定义的。property 是由 DOM (Document Object Model) 定义的。\n\n\n\n少量 HTML attribute 和 property 之间有着 1:1 的映射,如 id。\n有些 HTML attribute 没有对应的 property,如 colspan。\n有些 DOM property 没有对应的 attribu......', 'Attribute和Property在英文中均为属性的意思,他们有密切的联系,也有不同的差别。\n\n> Attribute 是由 HTML 定义的。property 是由 DOM (Document Object Model) 定义的。\n- 少量 HTML attribute 和 property 之间有着 1:1 的映射,如 id。\n- 有些 HTML attribute 没有对应的 property,如 colspan。\n- 有些 DOM property 没有对应的 attribute,如 textContent。\n- 大量 HTML attribute 看起来映射到了 property…… 但却不像你想的那样!\n\n> 最后一类尤其让人困惑…… 除非你能理解这个普遍原则:\nattribute 初始化 DOM property,然后它们的任务就完成了。property 的值可以改变;attribute 的值不能改变。\n例如,当浏览器渲染 `` 时,它将创建相应 DOM 节点, 它的 value 这个 property 被初始化为 “Bob”。\n当用户在输入框中输入 “Sally” 时,DOM 元素的 value 这个 property 变成了 “Sally”。 但是该 HTML 的 value 这个 attribute 保持不变。如果你读取 input 元素的 attribute,就会发现确实没变: `input.getAttribute(''value'') // 返回 "Bob"`。\nHTML 的 value 这个 attribute 指定了初始值;DOM 的 value 这个 property 是当前值。\ndisabled 这个 attribute 是另一种特例。按钮的 disabled 这个 property 是 false,因为默认情况下按钮是可用的。 当你添加 disabled 这个 attribute 时,只要它出现了按钮的 disabled 这个 property 就初始化为 true,于是按钮就被禁用了。\n添加或删除 disabled 这个 attribute 会禁用或启用这个按钮。但 attribute 的值无关紧要,这就是你为什么没法通过 `` 这种写法来启用按钮。\n设置按钮的 disabled 这个 property(如,通过 Angular 绑定)可以禁用或启用这个按钮。 这就是 property 的价值。\n就算名字相同,HTML attribute 和 DOM property 也不是同一样东西。\n\n摘取自angular中文官网 [原文链接](https://www.angular.cn/guide/template-syntax#html-attribute-vs-dom-property )\n\n看完有点懵 有木有。\n** so,上重点**\n\n**Attribute特性由Html定义,所有出现在HTML标签内的描述节点都是attribute特性。**\n\n**Property属性属于Dom对象,DOM实质就是javascript中的对象。我们可以跟在js中操作普通对象一样获取、设置DOM对象的属性,并且property属性可以是任意类型。**\n\n\n', - NULL, 1, 1, 416, 0, 0, 5, '2019-07-14 07:11:23', NULL, 1, 0), + NULL, 1, 1, 416, 0, 0, 5, '2019-07-14 07:11:23', NULL, 1, 1), (1288, '💔', '我们生活在最好的年纪,也生活在最糟的年纪。\n', '*我们生活在最好的年纪,也生活在最糟的年纪。*', NULL, 1, 1, 359, 0, 0, 1, '2019-09-17 10:27:12', NULL, 1, 0), (1289, '电影推荐 《幸福终点站》', diff --git a/src/main/java/cn/celess/blog/controller/ArticleController.java b/src/main/java/cn/celess/blog/controller/ArticleController.java index c4b011f..7889fba 100644 --- a/src/main/java/cn/celess/blog/controller/ArticleController.java +++ b/src/main/java/cn/celess/blog/controller/ArticleController.java @@ -3,6 +3,7 @@ package cn.celess.blog.controller; import cn.celess.blog.enmu.ResponseEnum; import cn.celess.blog.entity.Response; 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.service.ArticleService; import cn.celess.blog.util.RedisUserUtil; @@ -11,6 +12,8 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.*; import javax.servlet.http.HttpServletRequest; +import java.util.List; +import java.util.stream.Collectors; /** * @author : xiaohai @@ -110,8 +113,9 @@ public class ArticleController { */ @GetMapping("/admin/articles") public Response adminArticles(@RequestParam(name = "page", defaultValue = "1") int page, - @RequestParam(name = "count", defaultValue = "10") int count) { - return Response.success(articleService.adminArticles(count, page)); + @RequestParam(name = "count", defaultValue = "10") int count, + @RequestParam(name = "deleted", defaultValue = "false") boolean deleted) { + return Response.success(articleService.adminArticles(count, page, deleted)); } /** diff --git a/src/main/java/cn/celess/blog/service/ArticleService.java b/src/main/java/cn/celess/blog/service/ArticleService.java index fb15add..53e1494 100644 --- a/src/main/java/cn/celess/blog/service/ArticleService.java +++ b/src/main/java/cn/celess/blog/service/ArticleService.java @@ -52,7 +52,7 @@ public interface ArticleService { * @param page 数据页 * @return 分页数据 */ - PageData adminArticles(int count, int page); + PageData adminArticles(int count, int page, boolean deleted); /** * 获取文章状态为开放的文章 diff --git a/src/main/java/cn/celess/blog/service/serviceimpl/ArticleServiceImpl.java b/src/main/java/cn/celess/blog/service/serviceimpl/ArticleServiceImpl.java index 9b335b2..b5e9c9a 100644 --- a/src/main/java/cn/celess/blog/service/serviceimpl/ArticleServiceImpl.java +++ b/src/main/java/cn/celess/blog/service/serviceimpl/ArticleServiceImpl.java @@ -22,10 +22,12 @@ import org.springframework.beans.BeanUtils; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; +import sun.security.krb5.internal.PAData; import javax.servlet.http.HttpServletRequest; import java.util.ArrayList; import java.util.List; +import java.util.stream.Collectors; /** @@ -273,21 +275,24 @@ public class ArticleServiceImpl implements ArticleService { /** * @param count 数目 - * @param page 页面 默认减1 + * @param page 页面 * @return PageInfo */ @Override - public PageData adminArticles(int count, int page) { - PageHelper.startPage(page, count, "articleId desc"); + public PageData adminArticles(int count, int page, boolean deleted) { List
articleList = articleMapper.findAll(); - PageData pageData = new PageData(new PageInfo
(articleList)); - List articleModelList = new ArrayList<>(); - articleList.forEach(article -> { - ArticleModel articleModel = ModalTrans.article(article); - articleModel.setMdContent(null); - articleModelList.add(articleModel); - }); - pageData.setList(articleModelList); + + PageData pageData = new PageData<>(null, 0, count, page); + List
collect = articleList.stream().filter(article -> article.isDeleted() == deleted).collect(Collectors.toList()); + pageData.setTotal(collect.size()); + List articleModels = collect.stream() + .peek(article -> article.setMdContent(null)) + .map(ModalTrans::article) + .skip((page - 1) * count) + .limit(count) + .collect(Collectors.toList()); + pageData.setList(articleModels); + return pageData; } diff --git a/src/main/resources/mapper/articleMapper.xml b/src/main/resources/mapper/articleMapper.xml index 14b07e9..6e9928d 100644 --- a/src/main/resources/mapper/articleMapper.xml +++ b/src/main/resources/mapper/articleMapper.xml @@ -154,7 +154,7 @@ diff --git a/src/test/java/cn/celess/blog/controller/ArticleControllerTest.java b/src/test/java/cn/celess/blog/controller/ArticleControllerTest.java index 09edaf9..9c747b5 100644 --- a/src/test/java/cn/celess/blog/controller/ArticleControllerTest.java +++ b/src/test/java/cn/celess/blog/controller/ArticleControllerTest.java @@ -272,29 +272,34 @@ public class ArticleControllerTest extends BaseTest { getMockData("/admin/articles?page=1&count=10", userLogin()).andDo(result -> assertEquals(PERMISSION_ERROR.getCode(), mapper.readValue(result.getResponse().getContentAsString(), Response.class).getCode()) ); - // admin权限登陆 - getMockData("/admin/articles?page=1&count=10", adminLogin()).andDo(result -> { - Response> response = mapper.readValue(result.getResponse().getContentAsString(), new TypeReference>>(){}); - assertEquals(SUCCESS.getCode(), response.getCode()); - assertNotNull(response.getResult()); - // 判断pageInfo是否包装完全 - PageData 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()); - assertNull(a.getMdContent()); - } - }); + for (int i = 0; i < 2; i++) { + // admin权限登陆 + int finalI = i; + getMockData("/admin/articles?page=1&count=10&deleted=" + (i == 1), adminLogin()).andDo(result -> { + Response> response = mapper.readValue(result.getResponse().getContentAsString(), new TypeReference>>() { + }); + assertEquals(SUCCESS.getCode(), response.getCode()); + assertNotNull(response.getResult()); + // 判断pageInfo是否包装完全 + PageData 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) { e.printStackTrace(); }