数据表结构:
前端代码
axios.js
import axios from 'axios'; import Qs from 'qs'; import {Message} from 'element-ui'; axios.defaults.baseURL = "/"; // 设置请求超时时间 axios.defaults.timeout = 30000; // 设置post请求头 axios.defaults.headers.post['Content-Type'] = 'application/json;charset=UTF-8'; // 请求拦截 axios.interceptors.request.use(config => { // 在发送请求之前做些什么 验证token之类的 return config; }, error => { // 对请求错误做些什么 Message.error({message: '请求超时!'}) return Promise.error(error); }) // 响应拦截 axios.interceptors.response.use(response => { // 对响应数据做点什么 return response; }, error => { // 对响应错误做点什么 return Promise.reject(error); }); // 封装get方法和post方法 /** * get方法,对应get请求 * @param {String} url [请求的url地址] * @param {Object} params [请求时携带的参数] */ export function get(url, params) { return new Promise((resolve, reject) => { axios.get(url, { params: params }).then(res => { resolve(res.data); // Loading.service(true).close(); // Message({message: '请求成功', type: 'success'}); }).catch(err => { reject(err.data) // Loading.service(true).close(); Message({message: '加载失败', type: 'error'}); }) }); } /** * post方法,对应post请求 * @param {String} url [请求的url地址] * @param {Object} params [请求时携带的参数] */ export function post(url, params) { return new Promise((resolve, reject) => { axios.post(url, params) .then(res => { resolve(res.data); // Loading.service(true).close(); // Message({message: '请求成功', type: 'success'}); }) .catch(err => { reject(err.data) // Loading.service(true).close(); Message({message: '加载失败', type: 'error'}); }) }); } /** * post方法,参数序列化 * @param {String} url [请求的url地址] * @param {Object} params [请求时携带的参数] */ export function qspost(url, params) { return new Promise((resolve, reject) => { axios.post(url, Qs.stringify(params)) .then(res => { resolve(res.data); // Loading.service(true).close(); // Message({message: '请求成功', type: 'success'}); }) .catch(err => { reject(err.data) // Loading.service(true).close(); Message({message: '加载失败', type: 'error'}); }) }); } /** * put方法,对应put请求 * @param {String} url [请求的url地址] * @param {Object} params [请求时携带的参数] */ export function put(url, params) { return new Promise((resolve, reject) => { axios.put(url, params) .then(res => { resolve(res.data); // Loading.service(true).close(); // Message({message: '请求成功', type: 'success'}); }) .catch(err => { reject(err.data) // Loading.service(true).close(); Message({message: '加载失败', type: 'error'}); }) }); } /** * delete * @param {String} url [请求的url地址] * @param {Object} params [请求时携带的参数] */ export function deletefn(url, params) { return new Promise((resolve, reject) => { axios.delete(url, params) .then(res => { resolve(res.data); // Loading.service(true).close(); // Message({message: '请求成功', type: 'success'}); }) .catch(err => { reject(err.data) // Loading.service(true).close(); Message({message: '加载失败', type: 'error'}); }) }); }
category.js
import {post, get, deletefn, put} from '../../utils/axios/axios' //获取分类 export const getCategoryList = data => get('/item/category/list'); //新增一级菜单 export const addCategory = data=> post("/item/category/add",data); //根据id删除节点 export const deleteCategoryById=data=>deletefn(`/item/category/${data.id}`,data); //新增子节点 export const addCategoryByParentId=data=>post(`/item/category/addByParentId`,data); //根据id编辑节点 export const editCategoryById=data=>put(`/item/category/${data.id}`,data);
category.vue
<template> <el-card class="box-card"> <!--面包屑--> <el-breadcrumb separator-class="el-icon-arrow-right"> <el-breadcrumb-item>商品管理</el-breadcrumb-item> <el-breadcrumb-item>分类管理</el-breadcrumb-item> </el-breadcrumb> <el-button @click="addCategoryDialog()" style="margin-top: 20px">增加</el-button> <!--新增一级对话框--> <el-dialog title="新增一级" :visible.sync="addDialogVisible" width="30%" > <el-form ref="form" :model="addForm" label-width="80px"> <el-form-item label="名称"> <el-input v-model="addForm.name"></el-input> </el-form-item> </el-form> <el-button @click="addDialogVisible = false">取 消</el-button> <el-button type="primary" @click="submitCategory">确 定</el-button> </el-dialog> <!--tree--> <el-tree :props="defaultProps" :data="treeData" show-checkbox node-key="id" :default-expand-all="false" :expand-on-click-node="false"> <span class="custom-tree-node" slot-scope="{ node, data }"> <span>{{ node.label }}</span> <span> <el-button type="text" size="mini" @click="() => append(data.id,data.isParent)"> 增加 </el-button> <el-button type="text" size="mini" @click="() => remove(data.id)"> 删除 </el-button> <el-button type="text" size="mini" @click="() => edit(data.id,data.isParent,data.parentId,data.name)"> 编辑 </el-button> </span> </span> </el-tree> <!--新增子菜单对话框--> <el-dialog title="新增子菜单" :visible.sync="addCategoryByParentIdDialogVisible" width="30%" > <el-form ref="form" :model="addForm" label-width="80px"> <el-form-item label="名称"> <el-input v-model="addForm.name"></el-input> </el-form-item> </el-form> <el-button @click="addCategoryByParentIdDialogVisible = false">取 消</el-button> <el-button type="primary" @click="submitCategoryByParentId">确 定</el-button> </el-dialog> <!--编辑节点对话框--> <el-dialog title="编辑" :visible.sync="editCategoryByParentIdDialogVisible" width="30%" > <el-form ref="form" :model="addForm" label-width="80px"> <el-form-item label="名称"> <el-input v-model="addForm.name"></el-input> </el-form-item> </el-form> <el-button @click="editCategoryByParentIdDialogVisible = false">取 消</el-button> <el-button type="primary" @click="submitEditCategoryById">确 定</el-button> </el-dialog> </el-card> </template> <script> import {getCategoryList,addCategory,deleteCategoryById,addCategoryByParentId,editCategoryById} from "../../api/item/category"; export default { name: "Category", data() { return { treeData: [], defaultProps: { label: 'name' }, addDialogVisible: false, addForm: { name: '' }, addCategoryByParentIdDialogVisible:false, parentId:'', isParent:'', id:'', editCategoryByParentIdDialogVisible:false } }, created() { this.getlist(); }, methods: { /** * 获取数据 */ getlist() { getCategoryList().then(res => { console.log("res") console.log(res) console.log("~~~~~~~~~") this.treeData = this.arraytotree(res.data); console.log(this.treeData) }).catch(res => { }) }, handleNodeClick(data) { console.log(data); }, //数组转化为树 arraytotree(arr) { var top = [], sub = [], tempObj = {}; arr.forEach(function (item) { if (item.parentId === 0) { // 顶级分类 top.push(item) } else { sub.push(item) // 其他分类 } item.children = []; // 默然添加children属性 tempObj[item.id] = item // 用当前分类的id做key,存储在tempObj中 }) sub.forEach(function (item) { // 取父级 var parent = tempObj[item.parentId] || {'children': []} // 把当前分类加入到父级的children中 parent.children.push(item) }) return top }, addCategoryDialog() { this.addDialogVisible = true; }, /** * 新增一级目录 */ submitCategory(){ addCategory(this.addForm).then(res=>{ console.log(res) if (res.code===200){ this.$message({ type: 'success', message: '新增一级目录成功' }); this.addForm={} this.addDialogVisible=false this.getlist(); } if (res.code===601){ this.$message({ type: 'error', message: '已存在相同的一级目录' }); this.addForm={} this.addDialogVisible=false this.getlist(); } }).catch(res=>{ }) }, append(id,isParent) { this.id=id this.isParent=isParent console.log(id) console.log(isParent) this.addCategoryByParentIdDialogVisible=true; }, /** * 新增子节点 */ submitCategoryByParentId(){ //把新增子节点的parentId设置为获取到的节点id addCategoryByParentId({name:this.addForm.name,isParent:this.isParent,parentId:this.id}).then(res=>{ if (res.code===200){ this.$message({ type:'success', message:'新增成功' }) this.addCategoryByParentIdDialogVisible=false; this.addForm={} this.getlist(); } }).catch(res=>{ }) }, /** * 通过id删除节点 * @param id */ remove(id) { console.log(id) deleteCategoryById({id:id}).then(res=>{ if (res.data===200){ this.$message({ type: 'success', message: '删除成功' }); } this.getlist(); }).catch(res=>{ }) }, edit(id,isParent,parentId,name) { this.id=id; this.isParent=isParent; this.parentId=parentId this.addForm.name=name; this.editCategoryByParentIdDialogVisible=true; }, /** * 根据id编辑节点 */ submitEditCategoryById(){ editCategoryById({id:this.id,name:this.addForm.name,isParent:this.isParent,parentId:this.parentId}).then(res=>{ if (res.code===200){ this.$message({ type: 'success', message: '更新成功' }); this.addForm={} this.editCategoryByParentIdDialogVisible=false this.getlist(); } if (res.code===801){ this.$message({ type: 'error', message: '更新失败' }); this.addForm={} this.editCategoryByParentIdDialogVisible=false this.getlist(); } }).catch(res=>{ }) } } } </script> <style scoped> .el-tree { margin-top: 20px; } .custom-tree-node { flex: 1; display: flex; align-items: center; justify-content: space-between; font-size: 14px; padding-right: 8px; } </style>
后端代码:
实体类:
@Entity @Table(name = "tb_category") public class Category { @Id @Column(name = "id") @GeneratedValue(strategy = GenerationType.IDENTITY) private Integer id; @Column(name = "name") private String name; @Column(name = "parent_id") private Integer parentId; @Column(name = "is_parent") private Integer isParent; @Column(name = "sort") private Integer sort; public Integer getId() { return id; } public void setId(Integer id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } public Integer getParentId() { return parentId; } public void setParentId(Integer parentId) { this.parentId = parentId; } public Integer getIsParent() { return isParent; } public void setIsParent(Integer isParent) { this.isParent = isParent; } public Integer getSort() { return sort; } public void setSort(Integer sort) { this.sort = sort; } }
controller:
@RestController @RequestMapping(value = "category") public class CategoryController { @Autowired private CategoryService categoryService; /** * 查询所有节点 * @return */ @RequestMapping(value = "/list", method = RequestMethod.GET) public Result findCategory() { List<Category> list = categoryService.findCategory(); if (CollectionUtils.isEmpty(list)) { return ResultUtil.error(404, "资源未找到到"); } return ResultUtil.success(list); } /** * 新增一级目录 * @param category * @return */ @RequestMapping(value = "/add", method = RequestMethod.POST) public Result addCategory(@RequestBody Category category) { Category category1 = categoryService.findCategory(category); if (!StringUtils.isEmpty(category1)) { return ResultUtil.error(601, "新增失败"); } categoryService.addCategory(category); return ResultUtil.success(); } /** * 根据id删除节点 * @param id * @return */ @RequestMapping(value = "{id}",method = RequestMethod.DELETE) public Result deleteCategory(@PathVariable("id") Integer id ){ Optional<Category> optional= categoryService.findCategoryById(id); if (!StringUtils.isEmpty(optional)){ categoryService.deleteCategory(id); return ResultUtil.success(); } return ResultUtil.error(701,"删除失败"); } /** * 根据父节点新增子节点 * @param category * @return */ @RequestMapping(value = "/addByParentId",method = RequestMethod.POST) public Result saveCategoryById(@RequestBody Category category){ categoryService.save(category); return ResultUtil.success(); } /** * 通过id更新节点 * @param id * @param category * @return */ @RequestMapping(value = "{id}",method = RequestMethod.PUT) public Result updateCategory(@PathVariable("id") Integer id,@RequestBody Category category ){ Optional<Category> optional = categoryService.findCategoryById(id); if (!StringUtils.isEmpty(optional)){ categoryService.updateCategory(category); return ResultUtil.success(); } return ResultUtil.error(801,"更新失败"); } }
service:
public interface CategoryService { List<Category> findCategory(); void addCategory(Category category); Category findCategory(Category category); void deleteCategory(Integer id); Optional<Category> findCategoryById(Integer id); void save( Category category); void updateCategory(Category category); }
serviceImpl:
@Service public class CategoryServiceImpl implements CategoryService { @Autowired private CategoryDao categoryDao; @Override public List<Category> findCategory() { return categoryDao.findAll(); } @Override public void addCategory(Category category) { category.setParentId(0); category.setIsParent(1); category.setName(category.getName()); category.setSort(1); categoryDao.save(category); } @Override public Category findCategory(Category category) { categoryDao.findByName(category.getName()); return categoryDao.findByName(category.getName()); } @Override public void deleteCategory(Integer id) { categoryDao.deleteById(id); } @Override public Optional<Category> findCategoryById(Integer id) { return categoryDao.findById(id); } @Override public void save( Category category) { category.setSort(1); categoryDao.save(category); } @Override public void updateCategory(Category category) { category.setSort(2); categoryDao.save(category); } }
dao:
import com.leyou.entity.Category; import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.data.jpa.repository.JpaSpecificationExecutor; import java.util.Optional; public interface CategoryDao extends JpaRepository<Category,Integer> , JpaSpecificationExecutor<Category> { Category findByName(String name); Optional<Category> findById(Integer id); }