中软实习培训记录十(0730)

  • 删除功能
    • 删除功能实现
    • 删除功能演示
  • 用户的新闻浏览系统
    • 界面设计
    • 主页新闻列表实现
      • 主页新闻列表显示
    • 主页类别列表实现
      • 主页类别列表显示
    • 主页标签列表实现
      • 主页标签列表显示
    • 主页最新推荐实现
      • 主页最新推荐显示
    • 主页搜索实现
      • 主页搜索演示
    • 新闻详情页实现
      • 新闻详情页展示
      • 存在问题
      • 代码更新

今天主要来完成剩余的新闻管理的删除功能

删除功能

删除功能实现

1、Service接口中定义删除方法,通过id删除数据项

//删除void deleteNew(Long id);

在NewServiceImpl中实现方法:

@Overridepublic void deleteNew(Long id) {newRepository.deleteById(id);}

2、到NewController中,进行删除操作,同时进行操作成功提示。

@GetMapping("/news/{id}/delete")public String delete(@PathVariable Long id,RedirectAttributes attributes){newService.deleteNew(id);attributes.addFlashAttribute("message","删除成功");return REDIRECT_LIST;}

删除功能演示

点击新闻对应的“删除”按钮

删除成功,同时进行提示:

用户的新闻浏览系统

前面我们已经实现了一个新闻的后台管理系统,现在开始设计用户的新闻浏览系统

界面设计


根据上面的界面,可以看出,我们希望实现主页上首先能展示分类列表、标签列表、新闻列表、最新推荐等内容,同时点击之后能进行相应的跳转。

主页新闻列表实现

1、我们首先来实现主页上的新闻列表罗列,同时新闻的展示有分页的效果,因此首先需要在NewService中进行定义:

//主页显示新闻列表Page<News> ListNew(Pageable pageable);

在ServiceImpl中进行实现,只要调用findAll即可

@Overridepublic Page<News> ListNew(Pageable pageable) {return newRepository.findAll(pageable);}

2、Controller部分,我们创建IndexController,注意该类放在web文件夹下,与之前的admin并级

@Controller
public class IndexController {@Autowiredprivate TypeService typeService;@Autowiredprivate TagService tagService;@Autowiredprivate NewService newService;@GetMapping("/")public String index(@PageableDefault(size = 3,sort = {"updateTime"},direction = Sort.Direction.DESC)Pageable pageable, Model model){model.addAttribute("page",newService.ListNew(pageable));return "index";}}

主页新闻列表显示


成功实现了新闻列表的显示,因为数据库中新闻数据较少,所以暂时无法看到分页效果。
新闻列表中包含了新闻标题、新闻描述、发布作者、时间以及所属类别

主页类别列表实现

类别在显示的时候,需要根据类别下文章数进行排序,因此我们就需要进行统计

1、在TypeService定义方法:

    //主页显示文章数排前几的类别List<Type> listTypeTop(Integer size);

在TypeServiceImpl进行实现

@Overridepublic List<Type> listTypeTop(Integer size) {Sort sort=Sort.by(Sort.Direction.DESC,"news.size");//根据新闻篇数降序排列Pageable pageable= PageRequest.of(0,size,sort);return typeRepository.findTop(pageable);}

**注意,**因为返回值需要一个findTop的内容,同时使得找到的内容根据pageable设定的显示,因此在TypeRepository中新增一条方法

@Query("select t from Type t")List<Type> findTop(Pageable pageable);

2、回到IndexController,添加操作,在index方法中添加属性

@GetMapping("/")public String index(@PageableDefault(size = 3,sort = {"updateTime"},direction = Sort.Direction.DESC)Pageable pageable, Model model){model.addAttribute("page",newService.ListNew(pageable));model.addAttribute("types",typeService.listTypeTop(3));return "index";}

主页类别列表显示

主页标签列表实现

1、跟类别Type一样处理,TagService处定义方法

List<Tag> listTagTop(Integer size);

在TagServiceImpl中进行实现:

@Overridepublic List<Tag> listTagTop(Integer size) {Sort sort=Sort.by(Sort.Direction.DESC,"newsList.size");Pageable pageable= PageRequest.of(0,size,sort);return tagRepository.findTop(pageable);}

**注意,**同样需要在TagRepository中新增一条方法:

@Query("select t from Tag t")List<Tag> findTop(Pageable pageable);

2、回到IndexController,添加操作,在index方法中添加属性

@GetMapping("/")public String index(@PageableDefault(size = 3,sort = {"updateTime"},direction = Sort.Direction.DESC)Pageable pageable, Model model){model.addAttribute("page",newService.ListNew(pageable));model.addAttribute("types",typeService.listTypeTop(3));model.addAttribute("tags",tagService.listTagTop(3));return "index";}

主页标签列表显示

主页最新推荐实现

1、在NewService中定义方法

//主页最新推荐新闻列表
List<News> listRecommendNewTop(Integer size);

在NewServiceImpl中进行实现,要求推荐的新闻按照更新时间进行降序排列:

@Overridepublic List<News> listRecommendNewTop(Integer size) {Sort sort=Sort.by(Sort.Direction.DESC,"updateTime");Pageable pageable= PageRequest.of(0,size,sort);return newRepository.findTop(pageable);}

**注意,**同样需要在NewRepository中新增一条方法,进行更新:

 @Query("select n from News n where n.recommend=true")List<News> findTop(Pageable pageable);

2、回到IndexController,添加操作,更新,在index方法中添加属性

@GetMapping("/")public String index(@PageableDefault(size = 3,sort = {"updateTime"},direction = Sort.Direction.DESC)Pageable pageable, Model model){model.addAttribute("page",newService.ListNew(pageable));model.addAttribute("types",typeService.listTypeTop(3));model.addAttribute("tags",tagService.listTagTop(3));model.addAttribute("recommendNews",newService.listRecommendNewTop(3));return "index";}

主页最新推荐显示

主页搜索实现

在主页的搜索框中输入字段,希望能够通过模糊查询找出标题或者新闻主体内容【注意主页上显示的是标题和描述、并非主体内容】包含该字段的所有新闻

1、在NewService中新定义接口,参数除了分页外还有查询条件:

//全局搜索Page<News> listNew(String query,Pageable pageable);

在NewServiceImpl中进行实现:

@Overridepublic Page<News> listNew(String query, Pageable pageable) {return newRepository.findByQuery(query,pageable);}

**注意,**同样需要在NewRepository中新增一条方法,实现根据新闻标题和内容中是否符合查询条件,来得到对应的新闻:

@Query("select n from News n where n.title like ?1 or n.content like ?1")Page<News> findByQuery(String query, Pageable pageable);

2、回到IndexController,添加操作,不再是像前面Type、Tag等显示在index方法中添加属性,而是另起一个方法:

@PostMapping("/search")public String search(@PageableDefault(size = 3,sort = {"updateTime"},direction = Sort.Direction.DESC) Pageable pageable,@RequestParam String query,Model model){model.addAttribute("page",newService.listNew("%"+query+"%", pageable));model.addAttribute("query",query);return "search";}

主页搜索演示

在主页右上角搜索框中输入查询条件,得到一个新的查询结果页面,对于搜索出来的两条数据,的确符合搜索要求,第一条数据显而易见标题就已符合“12”条件,第二条数据则是因为文章主体内容为“1234567”,包含了“12”而搜索得到。
搜索功能成功!

新闻详情页实现

我们在主页上点击新闻列表中的某一篇新闻,进入新闻详情页,查看新闻的具体内容

1、在Service中,我们已经定义了getNew方法

News getNew(Long id);

因此我们可以直接进行调用,不需要额外写Service方法了

2、IndexController中新建一个news方法,对详情页部分进行处理:

@RequestMapping("/news/{id}")public String news(@PathVariable Long id,Model model){model.addAttribute("news",newService.getNew(id));return "new";}

新闻详情页展示


存在问题

我们在管理系统进行新闻编辑的时候,是实现了文本的MarkDown编辑功能,如下:

但是我们在用户查看新闻详情页的时候,这个设置的格式却没有出现,而是直接打出了#,与预期不符。

因此针对这个问题,我们对引入一个工具类进而对代码进行修改。

代码更新

1、引入工具包

package com.zr0726.news.util;import org.commonmark.Extension;
import org.commonmark.ext.gfm.tables.TableBlock;
import org.commonmark.ext.gfm.tables.TablesExtension;
import org.commonmark.ext.heading.anchor.HeadingAnchorExtension;
import org.commonmark.node.Link;
import org.commonmark.node.Node;
import org.commonmark.parser.Parser;
import org.commonmark.renderer.html.AttributeProvider;
import org.commonmark.renderer.html.AttributeProviderContext;
import org.commonmark.renderer.html.AttributeProviderFactory;
import org.commonmark.renderer.html.HtmlRenderer;import java.util.*;public class MarkdownUtils {/*** markdown格式转换成HTML格式* @param markdown* @return*/public static String markdownToHtml(String markdown) {Parser parser = Parser.builder().build();Node document = parser.parse(markdown);HtmlRenderer renderer = HtmlRenderer.builder().build();return renderer.render(document);}/*** 增加扩展[标题锚点,表格生成]* Markdown转换成HTML* @param markdown* @return*/public static String markdownToHtmlExtensions(String markdown) {//h标题生成idSet<Extension> headingAnchorExtensions = Collections.singleton(HeadingAnchorExtension.create());//转换table的HTMLList<Extension> tableExtension = Arrays.asList(TablesExtension.create());Parser parser = Parser.builder().extensions(tableExtension).build();Node document = parser.parse(markdown);HtmlRenderer renderer = HtmlRenderer.builder().extensions(headingAnchorExtensions).extensions(tableExtension).attributeProviderFactory(new AttributeProviderFactory() {public AttributeProvider create(AttributeProviderContext context) {return new CustomAttributeProvider();}}).build();return renderer.render(document);}/*** 处理标签的属性*/static class CustomAttributeProvider implements AttributeProvider {@Overridepublic void setAttributes(Node node, String tagName, Map<String, String> attributes) {//改变a标签的target属性为_blankif (node instanceof Link) {attributes.put("target", "_blank");}if (node instanceof TableBlock) {attributes.put("class", "ui celled table");}}}public static void main(String[] args) {String table = "| hello | hi   | 哈哈哈   |\n" +"| ----- | ---- | ----- |\n" +"| 斯维尔多  | 士大夫  | f啊    |\n" +"| 阿什顿发  | 非固定杆 | 撒阿什顿发 |\n" +"\n";String a = "[imCoding 爱编程](http://www.lirenmi.cn)";System.out.println(markdownToHtmlExtensions(a));}}

2、在NewService中重定义一个方法,对新闻内容进行markdown到html的转换

//处理markdownNews getAndConvert(Long id);

NewServiceImpl中进行实现:

@Overridepublic News getAndConvert(Long id) {News news=newRepository.findById(id).orElse(null);if(news==null){System.out.println("该新闻不存在");}News news1=new News();BeanUtils.copyProperties(news,news1);String content=news1.getContent();news1.setContent(MarkdownUtils.markdownToHtmlExtensions(content));return news1;}

3、IndexController的news方法中我们原本调用了getNews方法,现在利用工具进行convert之后,我们修改调用新定义的getAndConvert方法

@RequestMapping("/news/{id}")public String news(@PathVariable Long id,Model model){model.addAttribute("news",newService.getAndConvert(id));return "new";}

4、效果演示:
注意在编辑新闻的时候,设置格式时,#与内容要隔一个空,不然也会被直接当作内容输入。

中软实习培训记录十(0730)相关推荐

  1. 中软实习培训记录十二(0802)

    中软实习培训记录十二(0802) 归档功能实现 归档功能演示 异常事件处理 演示 拦截器 介绍 构建拦截器 在上周我们已经完成了新闻的后台管理部分以及用户浏览界面的分类.标签和主页,今天来实现界面上的 ...

  2. 中软实习培训记录十一(0731)

    中软实习培训记录十一(0731) 新闻详情页内的评论功能 实体类设计 评论展示部分 定义评论功能接口 定义Repository Controller处理 评论保存发布部分 定义评论功能接口 Contr ...

  3. 中软实习培训记录八(0728)

    中软实习培训记录八(0728) 分类新增 设计思路 新增功能实现 新增功能演示 分类删除 删除功能实现 删除功能演示 分类修改 设计思路 修改功能实现 修改功能演示 新模块--标签 标签实体类设计 具 ...

  4. 中软实习培训记录十三(0803)

    中软实习培训记录十三(0803) 现存问题-数据覆盖为空 问题解决 日志信息--切面 面向切面编程简介 日志打印 现存问题-数据覆盖为空 在前段时间,我们完成了所有功能,又进行了完善.但是我们后续检查 ...

  5. 中软实习培训记录二(0721)

    中软实习培训记录二(0721) 一.Tomcat的下载安装 二.Java Enterprise --登陆跳转 demo 一.Tomcat的下载安装 1.进入Apache Tomcat官网,选择你需要的 ...

  6. 中软实习培训记录三(0722)

    中软实习培训记录三(0722) SSM项目概述 SSM项目Demo实现过程--登陆 SSM项目Demo扩展--用户查看 SSM项目Demo扩展--用户添加 SSM项目Demo扩展--用户删除 SSM项 ...

  7. 中软实习首日培训记录

    中软实习首日培训记录 一.软件安装 二.SSM项目初步学习 MyBits简介 Spring:IoC控制反转 MVC简介 三. 创建maven项目 四.以小的程序入手熟悉数据库的操作 方法二 一.软件安 ...

  8. 中软计算机培训考试,在线考试教育,中软,的解决方案.docx

    在线考试教育,中软,的解决方案 在线考试教育,中软,解决方案 篇一:中软测试题 中软的一次试题: 1. 请说明下面代码的执行结果: byte a=1; byte b=1; byte c=a+b; (c ...

  9. 萌新小白萌新中软实习day7

    实体设计+用户登录+类别分页展示 今日代码的github链接 遇到的问题 导入依赖出现错误 Cannot resolve org.springframework.boot:spring-boot-st ...

最新文章

  1. 超全干货 | 软件测试岗技术笔试
  2. arm-none-eabi-gcc install
  3. python为什么closed_为什么python类的函数被调用两次[关闭](Why a function of python class is called twice [closed])...
  4. Linux进阶之软件管理
  5. Django连接mysql数据库(python3.6)
  6. TypeScript,初次见面,请多指教 ?
  7. 源码编译php mysql_linux下apache+mysql+php开发环境纯源代码编译搭建(转)
  8. weblogic 文件服务器,weblogic配置文件服务器
  9. java自定义表单系统_java自定义表单
  10. Charles使用详解
  11. 微信小程序-TabBar用法
  12. [OPS][GPU]GPU峰值计算能力计算
  13. 远距离485无线传输方案
  14. 房屋托管平台“朴邻”签约法大大,电子合同提升客户签约体验
  15. B+树在MySQL索引的应用和InnoDB的索引优化
  16. Coursera 算法二 week 4 Boggle
  17. java读取jpg点数_我的世界:基岩版beta1.16.0.61修复59个“特性”,同步Java版?
  18. 关于ca以及证书颁发的一些事
  19. Python利用Twitter API根据tweet id抓取tweet(via tweepy/twython)
  20. ​CrossOver2022Mac或Linux​系统无缝切换

热门文章

  1. 互联网药库试水:北京今年展开互联网虚拟药库
  2. Matlab与oneNET通过Mqtt通信
  3. 入门机器学习(二十一)--大规模机器学习(Large Scale Machine Learning)
  4. Unity3D动画游戏设计算法--序列化与反序列化
  5. thzbt.co forum.php,无线城市掌上公交
  6. 微软发布警告:黑客利用Office漏洞发动垃圾邮件攻击
  7. MDaemon与外部系统整合
  8. 802.11协议下的数据帧
  9. 为什么有的人宁愿在一线城市吃苦,也不愿回小城市享乐?
  10. win10系统和压缩内存磁盘占用过高的解决方案