当做完了之前的所有步骤之后,后续的内容开发就变得相对来说很简单了,总的逻辑都是差不多的,每个用户肯定会有一个个人中心界面,里面存放自己写的问题和收到的回复等等,今天要做的就是编写这个个人中心功能。展示效果如下:
点击右上角小三角,选择我的提问,可以看到自己发布的所有问题,点击每一个问题进入详情界面
目前仅展示问题名称,作者发布时间,内容,如果检测到用户就是作者,可进行编辑操作
点击编辑,进入编辑界面
# (一)页面的搭建 {#一-页面的搭建}
首先在导航栏中为我的消息加上href标签
<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 {
@Resource
private UserMapper userMapper;
@Resource
private 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 {
@Resource
private 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);
}
这样问题编辑功能就完成了。