分类管理和标签管理的功能和页面都很相似,都是两个页面,一个新增页面,一个列表显示页面。
新增、编辑页面
列表显示页面
新增、编辑新增和编辑都是在一个页面实现,可以通过是否有id,判断是进行新增操作还是修改操作。
前端核心代码
html代码
th:action="*{id}==null ? @{/admin/types} : @{/admin/types/{id}(id=*{id})}"
这里用了三元运算符 如果id不为空则进行修改操作,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 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注解可以初始化分页的默认条件,如每页几条数据,按照哪个字段排序,正序还是倒序。
前端核心代码
提示:
| 分类名称 | 操作 | ||||
|---|---|---|---|---|---|
| 1 | 编辑 删除 | ||||
| 1}"> 上一页 下一页 新增 | |||||
消息提示部分是显示操作是否成功,通过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开发个人博客



