SpringBoot开发一个小而美的个人博客(五)分类、标签管理

分类管理和标签管理的功能和页面都很相似,都是两个页面,一个新增页面,一个列表显示页面。

新增、编辑页面

列表显示页面

新增、编辑

新增和编辑都是在一个页面实现,可以通过是否有id,判断是进行新增操作还是修改操作。

前端核心代码

html代码

<div class="m-container-big m-padded-tn-big">
        <div class="ui container">
            <form action="#" method="POST"  th:object="${type}" th:action="*{id}==null ? @{/admin/types} : @{/admin/types/{id}(id=*{id})}" class="ui form">
                <input type="hidden" name="id"  th:value="*{id}">
                <div class="required field">
                    <div class="ui left labeled input">
                        <label  class="ui teal basic label">名称</label>
                        <input type="text" name="name" placeholder="分类名称" th:value="*{name}">
                    </div>
                </div>

                <!-- 错误信息会显示在这里 -->
                <div class="ui error message"></div>
                <div class="ui negative message" th:if="${#fields.hasErrors('name')}"  >
                    <i class="close icon"></i>
                    <div class="header">验证失败</div>
                    <p th:errors="*{name}">提交信息不符合规则</p>
                </div>

                <div class="ui right aligned container">
                    <button type="button" class="ui button" onclick="widows.history.go(-1)">返回</button>
                    <button class="ui teal submit button">提交</button>
                </div>
            </form>
        </div>
    </div>
th:action="*{id}==null ? @{/admin/types} : @{/admin/types/{id}(id=*{id})}"

这里用了三元运算符 如果id不为空则进行修改操作,id为空则进行编辑操作。

 <input type="hidden" name="id"  th:value="*{id}">

这里放了一个隐含域 ,从列表显示页面点击编辑会跳转到新增页面,同时将id传过来。根据id进行修改。

后面是错误信息提示,包括分类/标签不能为空,分类/标签已存在。非空判断在前端进行

js代码

 $('.ui.form').form({
            fields:{
                title:{
                    identifier: 'name', //和表单里的name值一致
                    rules: [{ 
                        type: 'empty', //非空验证
                        prompt: '请输入分类名称',
                    }]
                }
            }
        })

后端核心代码

service层实现类

    @Transactional
    @Override
    public Type saveType(Type type) {

        return typeRepository.save(type);
    }

    @Override
    public Type getTypeByName(String name) {
        return typeRepository.findByName(name);
    }

    @Transactional
    @Override
    public Type updateType(Long id, Type type) {
        Type t= typeRepository.getById(id);
        if(t==null){
          throw new NotFoundException("不存在该类型");
        }
        BeanUtils.copyProperties(type,t);//将type复制到t
        return  typeRepository.save(t);
    }

此处需要注意的是,涉及到增删改操作最好放在事务里面,添加@Transactional注解

controller层

    @PostMapping("/types")
    public String addtype(@Valid Type type, BindingResult bindingResult, 
          RedirectAttributes attributes){
        if(bindingResult.hasErrors()){
            return "admin/type-input";
        }
        Type type1=typeService.getTypeByName(type.getName());
        if(type1!=null){
            bindingResult.rejectValue("name","nameError","该分类已存在,不可重复添加");
        }
        Type t=typeService.saveType(type);
        if(t==null){
            attributes.addFlashAttribute("message","新增失败");
        }else{
            attributes.addFlashAttribute("message","新增成功");
        }
        return "redirect:/admin/types";
    }
    @PostMapping("/types/{id}")
    public String edittype(@Valid Type type, BindingResult bindingResult,@PathVariable             
         Long id ,RedirectAttributes attributes){
        Type type1=typeService.getTypeByName(type.getName());
        if(type1!=null){
            bindingResult.rejectValue("name","nameError","该分类已存在,不可重复添加");
        }
        if(bindingResult.hasErrors()){
            return "admin/type-input";
        }
        Type t=typeService.updateType(id,type);
        if(t==null){
            attributes.addFlashAttribute("message","修改失败");
        }else{
            attributes.addFlashAttribute("message","修改成功");
        }
        return "redirect:/admin/types";
    }

通过@Valid和@NotBlank注解在后端进行非空判断,这段代码写在Type实体类中。BindingResult用在实体类校验信息返回结果绑定,和@Valid一起使用,并且一定要写在@Valid之后。

@NotBlank(message = "分类名称不能为空")
    private String name;

@PathVariable注解是用于拿到路径中的参数,这里可以获取到id值,然后根据id值进行修改操作。

新增/编辑大概主要就是这些。

列表显示

后端核心代码

service层实现类

    @Transactional
    @Override
    public Page<Type> listType(Pageable pageable) {
        return typeRepository.findAll(pageable);
    }

返回一个page ,其中有分页总条数,总页数,当前页是否为第一页或最后一页等。

controller层

    @GetMapping("/types")
    public String types(@PageableDefault(size=5,sort={"id"} ,direction = 
    Sort.Direction.DESC)
                                    Pageable pageable, Model model){
        model.addAttribute("page",typeService.listType(pageable));
        System.out.println(typeService.listType(pageable));
        return "admin/types";
    }

通过@PageableDefault注解可以初始化分页的默认条件,如每页几条数据,按照哪个字段排序,正序还是倒序。

前端核心代码

<div class="m-container m-padded-tn-big">
        <div class="ui container">
            <!--    消息提示        -->
            <div class="ui success message " th:unless="${#strings.isEmpty(message)}">
                <i class="close icon"></i>
                <div class="header">提示:</div>
                <p th:text="${message}"></p>
            </div>
         <table class="ui celled table">
             <thead>
                 <tr>
                     <th></th>
                     <th>分类名称</th>
                     <th>操作</th>
                 </tr>
             </thead>
             <tbody>
                 <tr th:each="type,iterStat : ${page.content}">
                     <!--   iterStat  拿到分页数据的索引                  -->
                     <td th:text="${iterStat.count}">1</td>
                     <td th:text="${type.name}"></td>
                     <td>
                         <a href="#" th:href="@{/admin/types/{id}/input(id=${type.id})}" class="ui mini positive basic button">编辑</a>
                         <a href="#" th:href="@{/admin/types/{id}/delete(id=${type.id})}" class="ui mini negative basic button">删除</a>
                     </td>
                 </tr>

             </tbody>
             <tfoot>
                 <tr>
                     <th colspan="6" >
                         <div class="ui mini pagination menu" th:if="${page.totalPages>1}">
                             <a th:href="@{/admin/types(page=${page.number}-1)}" class=" item" th:unless="${page.first}">上一页</a>
                             <a th:href="@{/admin/types(page=${page.number}+1)}" class="mini item" th:unless="${page.last}" >下一页</a>
                         </div>
                         <a href="#" th:href="@{/admin/types/input}" class="ui mini right floated teal basic button">新增</a>
                     </th>
                 </tr>
             </tfoot>
         </table>
        </div>
    </div>

消息提示部分是显示操作是否成功,通过js代码控制。

        //消息提示关闭初始化
        $('.message .close').on('click',function(){
            $(this).closest('.message')
            .transition('fade');
        });

通过 th:each 循环分页内容拿到每一条数据和索引(iterStat.count),然后显示在表格中。底部的分页条,如果总页数只有一页就不显示,当当前页是第一页是不显示上一页的按钮,当当前页是最后一页时不显示下一页的按钮。分别通过  th:if="${page.totalPages>1}",th:unless="${page.first}",th:unless="${page.last}"来判断。

最后就是删除了,直接根据id进行删除操作就行了。分类/标签管理就差不多了。

冲啊!!!

SpringBoot开发一个小而美的个人博客(一) 前端页面(一)_舒克、舒克的博客-CSDN博客_springboot开发一个页面

SpringBoot开发一个小而美的个人博客(二) 前端页面(二)_舒克、舒克的博客-CSDN博客

SpringBoot开发一个小而美的个人博客(三) 框架搭建_舒克、舒克的博客-CSDN博客_springboot开发个人博客

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值