1、技術前提
1.1、后端采用的技術是SpringBoot+MybatisPlus+人人代碼生成器實現的
1.2、前端采用的技術是VUE +ElementUI+人人開源實現的
2、后端實現
2.1、pom依賴
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.1.8.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
<version>3.2.0</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.8</version>
</dependency>
2.2 application.yml配置文件
spring:
application:
name: mall-product
datasource:
url: jdbc:mysql://localhost:3306/mall_pms?useUnicode=true&characterEncoding=UTF-8&serverTimezone=UTC&
driver-class-name: com.mysql.cj.jdbc.Driver
username: root
password: root
mybatis-plus:
mapper-locations: classpath:/mapper/**/*.xml
2.3、實體類
@Data
public class CategoryDTO implements Serializable {
/**
* 分類id
*/
@TableId
private Long catId;
/**
* 分類名稱
*/
private String name;
/**
* 父分類id
*/
private Long parentCid;
/**
* 層級
*/
private Integer catLevel;
/**
* 是否顯示[0-不顯示,1顯示]
*/
private Integer showStatus;
/**
* 排序
*/
private Integer sort;
/**
* 圖標地址
*/
private String icon;
/**
* 計量單位
*/
private String productUnit;
/**
* 商品數量
*/
private Integer productCount;
private List<CategoryDTO> children;
}
2.4 dao層
@Mapper
public interface CategoryDao extends BaseMapper<CategoryEntity> {
}
2.5、service
public interface CategoryService extends IService<CategoryEntity> {
/**
* 查詢三級分類
* @return
*/
List<CategoryDTO> listWithTree();
}
2.6、service實現類具體功能實現
@Override
public List<CategoryDTO> listWithTree() {
//查出所有分類
List<CategoryEntity> categoryList = baseMapper.selectList(null);
List<CategoryDTO> categoryDTOList = new ArrayList<>();
//查詢所有父類目錄
for(CategoryEntity categoryEntity : categoryList) {
if(categoryEntity.getParentCid() == 0) {
CategoryDTO categoryDTO = categoryEntity2CategoryDTO(categoryEntity);
categoryDTOList.add(categoryDTO);
}
categoryDTOList.sort(Comparator.comparing(CategoryDTO::getSort));
}
//查詢子目錄
findSubCategory(categoryDTOList, categoryList);
return categoryDTOList;
}
/**
* 查詢子目錄
* @param categoryDTOList
* @param categoryEntityList
*/
private void findSubCategory(List<CategoryDTO> categoryDTOList, List<CategoryEntity> categoryEntityList) {
//遍歷所有父類分類
for(CategoryDTO categoryDTO : categoryDTOList) {
List<CategoryDTO> subCategoryVoList = new ArrayList<>();
//遍歷父類下的cat_id與子類parent_cid相匹配的分類
for(CategoryEntity category : categoryEntityList) {
if(categoryDTO.getCatId().equals(category.getParentCid())) {
CategoryDTO subCategoryVo = categoryEntity2CategoryDTO(category);
subCategoryVoList.add(subCategoryVo);
}
//升序排序
subCategoryVoList.sort(Comparator.comparing(CategoryDTO::getSort));
//設置subCategories
categoryDTO.setChildren(subCategoryVoList);
}
//遞歸調用
findSubCategory(subCategoryVoList, categoryEntityList);
}
}
/**
* 分類對象轉換
* @param categoryEntity
* @return
*/
private CategoryDTO categoryEntity2CategoryDTO(CategoryEntity categoryEntity) {
CategoryDTO categoryDTO = new CategoryDTO();
BeanUtils.copyProperties(categoryEntity, categoryDTO);
return categoryDTO;
}
2.7controller層
/**
* 查詢出所有分類以及子分類,以樹型結構組裝起來
* @return
*/
@RequestMapping("/list/tree")
public R list() {
List<CategoryDTO> entityList = categoryService.listWithTree();
return R.ok().put("data", entityList);
}
3、前端實現
詳細的我就不一一給出來了,要是看不懂可以參照人人開源或者ElementUi文檔實現其他功能!!!
category.vue
<template>
<el-tree
show-checkbox
node-key="catId"
:data="menus"
:props="defaultProps"
@node-click="handleNodeClick"
:expand-on-click-node="false"
:default-expanded-keys="expandedKey">
>
<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)">
Append
</el-button>
<el-button
v-if="node.childNodes.length == 0"
type="text"
size="mini"
@click="() => remove(node, data)">
Delete
</el-button>
</span>
</span>
</el-tree>
</template>
<script>
export default {
name: "category",
data() {
return {
menus: [],
expandedKey: [],
defaultProps: {
children: 'children',
label: 'name'
}
};
},
methods: {
handleNodeClick(data) {
console.log(data);
},
getMenus() {
this.$http({
url: this.$http.adornUrl('/product/category/list/tree'),
method: 'get'
}).then(({data}) => {
this.menus = data.data;
})
},
append(data) {
console.log("append", data)
},
remove(node, data) {
let ids = [data.catId]
this.$confirm(`是否刪除【${data.name}】菜單?`, '提示', {
confirmButtonText: '確定',
cancelButtonText: '取消',
type: 'warning'
}).then(() => {
console.log("remove", node, data)
this.$http({
url: this.$http.adornUrl('/product/category/delete'),
method: 'post',
data: this.$http.adornData(ids, false)
}).then(({data}) => {
this.$message({
message: '菜單刪除成功',
type: 'success'
});
//刪除成功,重新加載菜單
this.getMenus()
//展開刪除節點的父節點
this.expandedKey = [node.parent.data.catId]
})
}).catch(() => {
});
}
},
created() {
this.getMenus()
}
}
</script>
<style scoped>
</style>
4、啟動項目
@SpringBootApplication
//包掃描
@MapperScan("com.cluck.mall.product.dao")
public class ProductApplication {
public static void main(String[] args) {
SpringApplication.run(ProductApplication.class, args);
}
}
效果圖:
一級分類
一級分類.png
二級分類
二級分類.png
三級分類
三級分類.png
人人開源git地址:https://gitee.com/renrenio
ElementUi地址:https://element.eleme.cn/#/zh-CN
主要功能實現代碼都是在categoryServiceImpl實現類里面,要是前端不太會的話,其實只要把后端功能跑起來就行了,你們肯定是有更好的思路和更簡潔的代碼也是歡迎推薦推薦的~~~~