文章目录
- 前端代码使用el-tree
- 后端代码实现(SpringBoot + tkmapper)
-
前端代码使用el-tree
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>分类管理</title>
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/semantic-ui@2.4.2/dist/semantic.min.css">
<script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script>
<link rel="stylesheet" href="https://unpkg.com/element-ui/lib/theme-chalk/index.css">
<script src="https://unpkg.com/element-ui/lib/index.js">
</script>
<script src="static/js/base.js"></script>
<script src="static/js/axios.min.js"></script>
<style>
.custom-tree-node {
flex: 1;
display: flex;
align-items: center;
justify-content: space-between;
font-size: 14px;
padding-right: 8px;
}
</style>
</head>
<body>
<div id="app">
<el-alert title="商品分类管理页面" description="对商品的分类进行管理" type="success" description="对商品的多级分类进行管理" show-icon>
</el-alert>
<h2 class="ui teal header" style="color: teawl;margin-top: 30px;text-align: center;">欢迎来到分类管理页面</h2>
<div class="category">
<h3 class="ui teal header">商品多级分类名称:</h3>
<el-input placeholder="输入关键字进行商品分类的过滤" v-model="filterText"
style="width: 800px;background: transparent;border: none; background-color: rgba(255, 255, 255, 0.247);">
</el-input>
<el-switch
style="display: inline-block;"
v-model="value2"
active-color="#13ce66"
inactive-color="#ff4949"
active-text="开启拖拽"
>
</el-switch>
<el-button type="danger" size="small" @click="batchDelete" style="padding-right: 30px">批量删除</el-button>
<el-tree show-checkbox class="filter-tree" :data="data1"
node-key="categoryId"
:default-expanded-keys="expandedkeys"
:props="defaultProps"
:filter-node-method="filterNode"
ref="menusTree" :expand-on-click-node="false" >
<span class="custom-tree-node" slot-scope="{ node, data }">
<span>{{ node.label }}</span>
<span>
<el-button v-if="node.level <= 2" type="text" size="mini" @click="() => append(data)">
增加
</el-button>
<el-button type="text" size="mini" @click="() => edit(data)">
修改
</el-button>
<el-button v-if="node.childNodes.length == 0" type="text" size="mini" @click="() => remove(node, data)">
删除
</el-button>
</span>
</span>
</el-tree>
<el-dialog title="添加分类" :visible.sync="dialogFormVisible">
<el-form :model="category">
<el-form-item label="分类名称">
<el-input v-model="category.categoryName" autocomplete="off"></el-input>
</el-form-item>
</el-form>
<div slot="footer" class="dialog-footer">
<el-button @click="dialogFormVisible = false">取 消</el-button>
<el-button type="primary" @click="addCategory">确 定</el-button>
</div>
</el-dialog>
</div>
</div>
<script src="static/js/cookie_utils.js"></script>
<script src="static/js/base.js"></script>
<script>
new Vue({
el: '#app',
data: {
expandedkeys:[],
dialogFormVisible:false,
value2:false,
category:{
categoryId:"",
categoryName:"",
categoryLevel:0,
parentId:0,
},
data1: [],
message: "hello",
dataList: [],
categories: [],
inputCategoryLevel1: true,
token: "",
userId: "",
disabled: true,
filterText: "",
data: [{
id: 1,
label: '一级 1',
children: [{
id: 4,
label: '二级 1-1',
children: [{
id: 9,
label: '三级 1-1-1'
}, {
id: 10,
label: '三级 1-1-2'
}]
}]
}, {
id: 2,
label: '一级 2',
children: [{
id: 5,
label: '二级 2-1'
}, {
id: 6,
label: '二级 2-2'
}]
}, {
id: 3,
label: '一级 3',
children: [{
id: 7,
label: '二级 3-1'
}, {
id: 8,
label: '二级 3-2'
}]
}],
defaultProps: {
children: 'categories',
label: 'categoryName',
}
},
watch: {
filterText(val) {
this.$refs.menusTree.filter(val);
}
},
created() {
this.showCategorires();
},
methods: {
filterNode(value, data) {
console.log(value);
if (!value) return true;
return data.categoryName.indexOf(value) !== -1;
},
showCategorires() {
let token = getCookieValue("token");
console.log(token);
this.token = token;
let userId = getCookieValue("userId");
console.log(userId, "UserId");
this.userId = userId;
var url22 = baseUrl + "index/categorylist";
axios({
url: url22,
method: "post",
headers: {
token: this.token
},
data: this.userId
}).then(res => {
console.log(res.data.data);
this.categories = res.data.data;
this.data1 = res.data.data;
this.dataList = this.categories.filter(function (type) {
return type.parentId == "1";
});
console.log(this.categories, "categoryList")
this.categories.forEach(element => {
});
})
},
append(data) {
console.log("分类添加", data);
this.category = {};
this.dialogFormVisible = true;
this.category.parentId = data.categoryId;
this.category.categoryLevel = data.categoryLevel*1 +1;
},
addCategory(){
console.log("提交的分类数据",this.category);
var url5 = baseUrl + "category/addOrUpdate";
axios({
url: url5,
method: "post",
headers: {
token: this.token
},
data: this.category
}).then(res => {
if(res.data.code == 1){
this.showCategorires();
this.dialogFormVisible = false;
ELEMENT.Message.success("商品分类添加成功");
this.expandedkeys = [this.category.parentId]
}
else if(res.data.code == 2){
console.log("商品分类修改数据----",res.data);
this.showCategorires();
this.dialogFormVisible = false;
ELEMENT.Message.success("商品分类修改成功");
this.expandedkeys = [this.category.categoryId]
}
})
},
remove(node, data) {
console.log("分类参数",node,data);
var cids = [data.categoryId];
console.log("分类id-------",cids);
var url3 = baseUrl + "category/delete";
this.$confirm(`此操作将永久,删除【${data.categoryName}】 是否继续?`, '提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning'
}).then(() => {
axios({
url: url3,
method: "post",
headers: {
token: this.token
},
data: cids
}).then(res => {
if(res.data.code == 1){
this.showCategorires();
ELEMENT.Message.success("删除分类成功");
this.dialogFormVisible = false;
}
this.expandedkeys = [node.parent.data.categoryId];
})
}).catch(() => {
});
},
edit(data){
console.log("分类数据",data);
this.category.categoryId = data.categoryId;
this.category.categoryLevel = data.categoryLevel;
this.category.parentId = data.parentId;
this.category.categoryName = data.categoryName;
this.dialogFormVisible = true;
},
batchDelete(){
let cids = [];
let categoryNames = [];
let checkedNodes = this.$refs.menusTree.getCheckedNodes();
console.log("商品分类选中结点数据",checkedNodes);
for (let index = 0; index < checkedNodes.length; index++) {
cids.push(checkedNodes[index].categoryId);
categoryNames.push(checkedNodes[index].categoryName);
}
var url3 = baseUrl + "category/delete";
this.$confirm(`此操作将批量删除【${categoryNames}】 是否继续?`, '提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning'
}).then(() => {
axios({
url: url3,
method: "post",
headers: {
token: this.token
},
data: cids
}).then(res => {
if(res.data.code == 1){
this.showCategorires();
ELEMENT.Message.success("批量删除分类成功");
this.dialogFormVisible = false;
this.expandedkeys = [node.parent.data.categoryId];
}
})
}).catch(() => {
});
},
UpdateHandle(row) {
row.disabled = false;
this.inputCategoryLevel1 = false;
console.log(row);
},
}
})
</script>
</body>
</html>
后端代码实现(SpringBoot + tkmapper)
package com.qfedu.fmmall.controller;
import com.qfedu.fmmall.entity.Category;
import com.qfedu.fmmall.service.CategoryService;
import com.qfedu.fmmall.vo.ResultVO;
import org.springframework.web.bind.annotation.*;
import javax.annotation.Resource;
import javax.xml.transform.Result;
import java.util.Arrays;
@RestController
@CrossOrigin
@RequestMapping("/category")
public class CategoryController {
@Resource
private CategoryService categoryService;
@PostMapping("/delete")
public ResultVO deleteCatetegoryByid(@RequestBody Integer[] cids){
return categoryService.removeMenuByIds(Arrays.asList(cids));
}
@PostMapping("/addOrUpdate")
public ResultVO addOrUpdateCatetegory(@RequestBody Category category){
if(category.getCategoryId() != null){
return categoryService.updateByCatgegoryId(category);
}
return categoryService.addCategory(category);
}
}
Service层实现
package com.qfedu.fmmall.service.impl;
import com.alibaba.druid.util.StringUtils;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.JavaType;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.qfedu.fmmall.dao.CategoryMapper;
import com.qfedu.fmmall.entity.Category;
import com.qfedu.fmmall.entity.CategoryVO;
import com.qfedu.fmmall.entity.ProductImg;
import com.qfedu.fmmall.service.CategoryService;
import com.qfedu.fmmall.vo.ParentCategory;
import com.qfedu.fmmall.vo.ResultStatus;
import com.qfedu.fmmall.vo.ResultVO;
import io.swagger.models.auth.In;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;
import tk.mybatis.mapper.entity.Example;
import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.TimeUnit;
@Service
public class CategoryServiceimpl implements CategoryService {
@Autowired
private CategoryMapper categoryMapper;
@Resource
private StringRedisTemplate stringRedisTemplate;
@Resource
ObjectMapper objectMapper = new ObjectMapper();
public ResultVO listcategories(String userId) {
List<CategoryVO> categoryVOS = null;
String categoriesStr = stringRedisTemplate.boundValueOps("categories").get();
try {
if(categoriesStr != null && !"".equals(categoriesStr)){
JavaType javaType = objectMapper.getTypeFactory().constructParametricType(ArrayList.class, CategoryVO.class);
categoryVOS = objectMapper.readValue(categoriesStr, javaType);
} else {
categoryVOS=categoryMapper.selectAllCategories2(0);
String s = objectMapper.writeValueAsString(categoryVOS);
stringRedisTemplate.boundValueOps("categories").set(s,1, TimeUnit.DAYS);
}
} catch (Exception e) {
e.printStackTrace();
}
ResultVO resultVO = resultVO = new ResultVO(ResultStatus.OK, "success", categoryVOS);
return resultVO;
}
@Override
public ResultVO listParentlist(String userId, String token) {
ResultVO resultVO = new ResultVO();
if("1=".equals(userId) && !StringUtils.isEmpty(token)){
List<ParentCategory> parentCategories = categoryMapper.queryCategoryList();
resultVO.setData(parentCategories);
System.out.println(parentCategories);
}
return resultVO;
}
@Override
public ResultVO querySubCategory(Integer parenId, String token) {
ResultVO resultVO = new ResultVO();
if(!StringUtils.isEmpty(token)){
List<ParentCategory> parentCategories = categoryMapper.querySubCategoryList(parenId);
resultVO.setData(parentCategories);
System.out.println(parentCategories);
}
return resultVO;
}
@Override
public ResultVO removeMenuByIds(List<Integer> asList) {
for (int i = 0; i < asList.size(); i++) {
int j = categoryMapper.deleteByPrimaryKey(asList.get(i));
stringRedisTemplate.delete("categories");
return new ResultVO(ResultStatus.OK,j > 0 ? "删除成功":"删除失败",j );
}
return null;
}
@Override
public ResultVO updateByCatgegoryId(Category category) {
int i = categoryMapper.updateByPrimaryKeySelective(category);
stringRedisTemplate.delete("categories");
return new ResultVO(ResultStatus.UPDATEOK,i > 0 ? "商品分类更新成功" : "更新商品分类失败",i);
}
@Override
public ResultVO addCategory(Category category) {
Category category1 = new Category();
BeanUtils.copyProperties(category,category1);
category1.setParentId(category.getParentId());
category.setCategoryName(category.getCategoryName());
int i = categoryMapper.insertSelective(category1);
stringRedisTemplate.delete("categories");
return new ResultVO(ResultStatus.OK,i > 0 ? "添加分类成功" : "添加分类失败",i);
}
}