开发基于SpringBoot和BootStrap的全栈论坛网站(六):完成个人中心、问题详情和问题编辑

如果你对这个项目感兴趣,可以从头看起:

开发基于SpringBoot和BootStrap的全栈论坛网站(一):准备阶段

开发基于SpringBoot和BootStrap的全栈论坛网站(二):后端人员如何快速使用BootStrap

开发基于SpringBoot和BootStrap的全栈论坛网站(三):登陆注册以及cookies的功能完成

开发基于SpringBoot和BootStrap的全栈论坛网站(四):完成问题发布功能

开发基于SpringBoot和BootStrap的全栈论坛网站(五):完成首页展示以及分页功能

做完登陆注册功能后先不急着做首页,因为我想的是首页能展示已经发布的问题信息,所以先做一个问题发布功能,前端还是使用BootStrap写,通过官网的组件和布局编写页面。源码会放在文末,源码的开发进度会快于这篇博客。

当做完了之前的所有步骤之后,后续的内容开发就变得相对来说很简单了,总的逻辑都是差不多的,每个用户肯定会有一个个人中心界面,里面存放自己写的问题和收到的回复等等,今天要做的就是编写这个个人中心功能。展示效果如下:

点击右上角小三角,选择我的提问,可以看到自己发布的所有问题,点击每一个问题进入详情界面

目前仅展示问题名称,作者发布时间,内容,如果检测到用户就是作者,可进行编辑操作

点击编辑,进入编辑界面

(一)页面的搭建

首先在导航栏中为我的消息加上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);
}

这样问题编辑功能就完成了。源代码如下:github代码

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Java鱼仔

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值