如果你对这个项目感兴趣,可以从头看起:
开发基于SpringBoot和BootStrap的全栈论坛网站(一):准备阶段
开发基于SpringBoot和BootStrap的全栈论坛网站(二):后端人员如何快速使用BootStrap
开发基于SpringBoot和BootStrap的全栈论坛网站(三):登陆注册以及cookies的功能完成
开发基于SpringBoot和BootStrap的全栈论坛网站(四):完成问题发布功能
开发基于SpringBoot和BootStrap的全栈论坛网站(五):完成首页展示以及分页功能
做完登陆注册功能后先不急着做首页,因为我想的是首页能展示已经发布的问题信息,所以先做一个问题发布功能,前端还是使用BootStrap写,通过官网的组件和布局编写页面。源码会放在文末,源码的开发进度会快于这篇博客。
当做完了之前的所有步骤之后,后续的内容开发就变得相对来说很简单了,总的逻辑都是差不多的,每个用户肯定会有一个个人中心界面,里面存放自己写的问题和收到的回复等等,今天要做的就是编写这个个人中心功能。展示效果如下:
点击右上角小三角,选择我的提问,可以看到自己发布的所有问题,点击每一个问题进入详情界面
目前仅展示问题名称,作者发布时间,内容,如果检测到用户就是作者,可进行编辑操作
(一)页面的搭建
<ul class="dropdown-menu"><li><a href="/personal/questions">我的提问</a></li><li><a href="#">个人资料</a></li><li><a href="/logout">退出登陆</a></li>
</ul>
对于我的消息的布局,依旧使用bootstrap的栅格系统,页面左右比例3:1,问题的展示逻辑和首页类似,只是这里需要增加用户检测,如果问题的发起者就是当前登陆用户,则分页展示,右侧的列表组依旧来自bootstrap官网的组件:
只需要复制代码然后修改成自己的就行,我在这里加了判断逻辑,目的是让当前选中的高亮
<div class="col-lg-3 col-md-12 col-sm-12 col-ss-12"><div class="list-group personal"><a href="/personal/questions" th:class="${section=='questions'}?'list-group-item active' : 'list-group-item' ">我的问题</a><a href="/personal/information" th:class="${section=='information'}?'list-group-item active' : 'list-group-item' ">我的消息</a></div>
</div>
其余的前端代码见文末源码。
(二)个人中心后端处理逻辑
在controller层建立PersonalController,首先获取当前登陆的用户信息,接着和首页一样在questionService进行处理,返回当前页面需要展示的数据的页码栏情况
//个人中心
@Controller
public class PersonalController {@Resourceprivate UserMapper userMapper;@Resourceprivate QuestionService questionService;@GetMapping("/personal/{action}")public String personal(@PathVariable(name = "action")String action,Model model,HttpServletRequest request,@RequestParam(name = "page",defaultValue = "1")int page,@RequestParam(name = "size",defaultValue = "5")int size){//获取当前用户Cookie[] cookies = request.getCookies();if (cookies == null) {return "login";}User user = null;for (Cookie cookie : cookies) {if (cookie.getName().equals("token")) {String token = cookie.getValue();user = userMapper.findBytoken(token);if (user != null) {request.getSession().setAttribute("user", user);}break;}}//判断action是什么if (action.equals("questions")){model.addAttribute("section","questions");model.addAttribute("sectionname","我的问题");}else if (action.equals("information")){model.addAttribute("section","information");model.addAttribute("sectionname","我的消息");}PageDto pagination=questionService.list(user.getId(),page,size);model.addAttribute("pagination", pagination);return "personal";}
}
questionService.list(user.getId(),page,size);的实现方法:找出来每页需要展示的内容,添加到pageDto中,pageDto中同时还储存页面信息
public PageDto list(int userid, int page, int size) {PageDto pageDto = new PageDto();int totalcount = questionMapper.countbyid(userid);pageDto.setPagination(totalcount,page,size);//size*{page-1}int offset = size * (page - 1);//每页只展示5条//select * from question where createid=#{userid} limit #{offset},#{size}List<Question> questions = questionMapper.listbyid(userid,offset, size);List<Questiondto> questiondtoList = new ArrayList<>();for (Question question : questions) {User user = userMapper.findById(question.getCreateid());Questiondto questiondto = new Questiondto();//把第一个对象的所有属性拷贝到第二个对象中BeanUtils.copyProperties(question, questiondto);questiondto.setUser(user);questiondtoList.add(questiondto);}pageDto.setQuestions(questiondtoList);return pageDto;
}
最后返回给前端的model包含了所有需要展示的内容,前端只需要根据model布局页面即可。
(三)为每个问题做问题详情页
我们现在做的不管是首页还是我的问题中,都无法点击相关问题,为每个问题增加href标签,地址为:http://localhost:8080/question/问题的id,这样就可以通过id知道是哪篇文章
<h4 class="media-heading"><a th:href="@{'/question/'+${question.id}}" th:text="title"></a>
</h4>
<span><a th:text="${question.description}" th:href="@{'/question/'+${question.id}}"></a>
</span>
问题详情页的后端处理逻辑很简单,只需要通过id查询这篇文章和作者即可,我们之前已经创建了问题和用户联立的DTO
@Controller
public class QuestionController {@Resourceprivate QuestionService questionService;@GetMapping("/question/{id}")public String question(@PathVariable(name = "id")int id,Model model){Questiondto questiondto=questionService.getbyid(id);model.addAttribute("questionDto",questiondto);return "question";}
}
对前端的布局不再做过多解释,大家可以看源码。
(四)完成问题编辑功能
问题编辑按钮只有在当前用户等于问题作者时才会出现,因此在前端界面做一个逻辑判断处理:
<a th:href="@{'/publish/'+${questionDto.id}}" th:if="${session.user!=null && session.user.id==questionDto.createid}"><span class="glyphicon glyphicon-pencil question-menu" aria-hidden="true">编辑</span>
</a>
点击编辑过后会跳转到问题发布界面,那如何判断这个时候是要新发布还是编辑更新呢?因此需要设置一个新的属性id来处理这个问题,在publish.html中增加
<input type="hidden" name="id" th:value="${id}">
这条input组件不会出现在页面中,但是传递了id属性,这里的id为问题id,页面编辑控制器代码如下:
@GetMapping("/publish/{id}")
public String edit(@PathVariable(name = "id")int id,Model model){Question question=questionMapper.getbyId(id);model.addAttribute("title", question.getTitle());model.addAttribute("description", question.getDescription());model.addAttribute("tag", question.getTag());//用来标识问题是修改而不是重新创建model.addAttribute("id",question.getId());return "publish";
}
修改此前创建的publishController,在参数中获取id的值,如果为空则附上默认值-1,意思就是如果是第一次创建,id=-1,如果是编辑,id就是问题id
@RequestParam(value = "id",defaultValue = "-1")int id,
根据id的值,执行不同的功能
if(id==-1){questionMapper.createquestion(question);
}else {question.setId(id);questionMapper.updatequestion(question);
}
这样问题编辑功能就完成了。源代码如下:github代码