分布式电商项目二十一:编写商品服务中产品标签的三级分类功能
编写商品服务中产品标签的三级分类功能
编写增加和删除的业务功能
标签的增删按钮已经设置完毕,但是还不能真正修改数据库中的内容,需要添加增删的逻辑。首先看一下renren-fast生成的逆向代码的删除逻辑是什么样子的:
来到mall-product/src/main/java/com/lastingwar/mall/product/controller/CategoryController.java
/*** 删除*/@RequestMapping("/delete")//@RequiresPermissions("product:category:delete")public R delete(@RequestBody Long[] catIds){categoryService.removeByIds(Arrays.asList(catIds));return R.ok();}
是一个@RequestBody 格式的,这种格式只接受post请求,内容为长整型数组ID的形式。为了测试删除功能,先在数据库中添加一条测试数据:
之后为了测试方便,下载Postman软件。输入内容:

返回信息{ "msg": "success", "code": 0 }
之后在数据库中刷新会发现添加的测试数据被删除了。
添加删除的业务逻辑
在正常使用中,不能直接删除掉数据库中的标签数据,要先查询是否有别的数据对其进行引用,直接删除会造成内容缺失。首先,注释掉之前的删除方法,添加自己的删除方法:
/*** 删除*/@RequestMapping("/delete")//@RequiresPermissions("product:category:delete")public R delete(@RequestBody Long[] catIds){//categoryService.removeByIds(Arrays.asList(catIds));categoryService.removeMenusByIds(Arrays.asList(catIds));return R.ok();}
并且快捷键ALT+entl添加这个方法:

之后到实现类CategoryServiceImpl编写这个方法:
由于现在还不能确认具体的删除方法,所以先添加为TODO待办中:
@Service("categoryService")
public class CategoryServiceImpl extends ServiceImpl<CategoryDao, CategoryEntity> implements CategoryService {@Overridepublic void removeMenusByIds(List<Long> asList) {//TODO 1.检查当前的商品目录,是否能被删除baseMapper.deleteBatchIds(asList);}
还有一点需要注意,这里自带的删除功能,删除数据之后,数据库中就没有了,所以项目一般使用逻辑删除,使用show_status作为标志位:

删除数据只需要把标志位修改为0 。Mybatis-plus提供有逻辑删除功能,具体内容参考官方文档因为使用的是Spring Boot mp-starter只需要配置和注解就行。来到标签的实体类:mall-product/src/main/java/com/lastingwar/mall/product/entity/CategoryEntity.java
添加注解,写上相应的逻辑删除规则:
/*** 是否显示[0-不显示,1显示]*/@TableLogic(value = "1",delval = "0")private Integer showStatus;
逻辑删除测试
重启商品服务,并且在数据库中再创建一条测试数据,
来到postman,再次删除测试,返回
{"msg": "success","code": 0
}
来到数据库,数据没有删除,show_status字段值变为0 。

之后再vue中添加删除的方法:
remove(node, data) {//业务逻辑待编写var ids = [data.catId]this.$http({url: this.$http.adornUrl('/product/category/delete'),method: 'post',data: this.$http.adornData(ids, false)}).then(({data})=>{console.log("删除成功");this.getMenus();//重新获取页面})}
ps:可以把页面请求的固定代码加入到用户片段中,方便使用
{"生成vue模板": {"prefix": "vue","body": ["","","$5","","","",""],"description": "生成vue模板"},"http-get 请求" : {"prefix": "httpget","body":["this.\\$http({","url: this.\\$http.adornUrl(''),","method: 'get',","params:this.\\$http.adornParams({})","}).then(({data}) => {","})"],"description": "httpGET请求"},"http-post 请求" : {"prefix": "httppost","body":["this.\\$http({","url: this.\\$http.adornUrl(''),","method: 'post',","data: this.\\$http.adornData(data, false)","}).then(({data}) => { });"],"description": "httpPOST请求"}
}
之后优化删除的功能删除的时候弹框和打开的标签不会因删除而折叠,根据elementUI官方推荐的方法
<!-- -->
<template><el-tree:data="menus":props="defaultProps":expand-on-click-node="false"show-checkboxnode-key="catId":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-buttonv-if="node.childNodes.length==0"type="text"size="mini"@click="() => remove(node, data)">Delete</el-button></span></span></el-tree>
</template><script>
//这里可以导入其他文件(比如:组件,工具js,第三方插件js,json文件,图片文件等等)
//例如:import 《组件名称》 from '《组件路径》';export default {//import引入的组件需要注入到对象中才能使用components: {},data() {//这里存放数据return {menus: [],// 保存默认展开的IDexpandedKey:[],defaultProps: {children: "children",label: "name"}};},//监听属性 类似于data概念computed: {},//监控data中的数据变化watch: {},//方法集合methods: {getMenus() {this.$http({url: this.$http.adornUrl("/product/category/list/tree"),method: "get"}).then(({ data }) => {console.log("成功获取到菜单数据...", data.data);this.menus = data.data;});},append(data) {//业务逻辑待编写},remove(node, data) {//业务逻辑待编写var ids = [data.catId];this.$confirm(`是否删除【${data.name}】菜单`, "提示", {confirmButtonText: "确定",cancelButtonText: "取消",type: "warning"}).then(() => {this.$http({url: this.$http.adornUrl("/product/category/delete"),method: "post",data: this.$http.adornData(ids, false)}).then(({ data }) => {this.$message({type: 'success',message: '菜单删除成功!'});// 获取菜单this.getMenus();//设置需要展开的IDthis.expandedKey=[node.parent.data.catId]});}).catch(() => {//点击取消});}},//生命周期 - 创建完成(可以访问当前this实例)created() {this.getMenus();},//生命周期 - 挂载完成(可以访问DOM元素)mounted() {},beforeCreate() {}, //生命周期 - 创建之前beforeMount() {}, //生命周期 - 挂载之前beforeUpdate() {}, //生命周期 - 更新之前updated() {}, //生命周期 - 更新之后beforeDestroy() {}, //生命周期 - 销毁之前destroyed() {}, //生命周期 - 销毁完成activated() {} //如果页面有keep-alive缓存功能,这个函数会触发
};
</script>
<style scoped>
</style>
**ps:测试时逻辑删除的数据可以在SQLyog中使用SQL语句
UPDATE `pms_category` SET show_status=1;
修改回来**

编写添加的业务逻辑
添加菜单的功能需要我们在点击之后生产一个对话框,输入子标签来进行添加。对应的官方文档。
<!-- -->
<template><div><el-tree:data="menus":props="defaultProps":expand-on-click-node="false"show-checkboxnode-key="catId":default-expanded-keys="expandedKey"><span class="custom-tree-node" slot-scope="{ node, data }"><span>{{ node.label }}</span><span><el-buttonv-if="node.level <=2"type="text"size="mini"@click="() => append(data)">Append</el-button><el-buttonv-if="node.childNodes.length==0"type="text"size="mini"@click="() => remove(node, data)">Delete</el-button></span></span></el-tree><el-dialog title="提示" :visible.sync="dialogVisible" width="30%" ><span>这是一段信息</span><span slot="footer" class="dialog-footer"><el-button @click="dialogVisible = false">取 消</el-button><el-button type="primary" @click="dialogVisible = false">确 定</el-button></span></el-dialog></div>
</template><script>
//这里可以导入其他文件(比如:组件,工具js,第三方插件js,json文件,图片文件等等)
//例如:import 《组件名称》 from '《组件路径》';export default {//import引入的组件需要注入到对象中才能使用components: {},data() {//这里存放数据return {menus: [],// 保存默认展开的IDexpandedKey: [],// 对话框的形态dialogVisible:false,defaultProps: {children: "children",label: "name"}};},//监听属性 类似于data概念computed: {},//监控data中的数据变化watch: {},//方法集合methods: {getMenus() {this.$http({url: this.$http.adornUrl("/product/category/list/tree"),method: "get"}).then(({ data }) => {console.log("成功获取到菜单数据...", data.data);this.menus = data.data;});},append(data) {//业务逻辑待编写//打开对话框this.dialogVisible=true;},remove(node, data) {//业务逻辑待编写var ids = [data.catId];this.$confirm(`是否删除【${data.name}】菜单`, "提示", {confirmButtonText: "确定",cancelButtonText: "取消",type: "warning"}).then(() => {this.$http({url: this.$http.adornUrl("/product/category/delete"),method: "post",data: this.$http.adornData(ids, false)}).then(({ data }) => {this.$message({type: "success",message: "菜单删除成功!"});// 获取菜单this.getMenus();//设置需要展开的IDthis.expandedKey = [node.parent.data.catId];});}).catch(() => {//点击取消});}},//生命周期 - 创建完成(可以访问当前this实例)created() {this.getMenus();},//生命周期 - 挂载完成(可以访问DOM元素)mounted() {},beforeCreate() {}, //生命周期 - 创建之前beforeMount() {}, //生命周期 - 挂载之前beforeUpdate() {}, //生命周期 - 更新之前updated() {}, //生命周期 - 更新之后beforeDestroy() {}, //生命周期 - 销毁之前destroyed() {}, //生命周期 - 销毁完成activated() {} //如果页面有keep-alive缓存功能,这个函数会触发
};
</script>
<style scoped>
</style>
对话框需要绑定:visible.sync="dialogVisible"这个值,当这个值为true时就会打开对话框,所以我们在data中添加dialogVisible属性,默认为false,点击append时调用相应的方法,并把dialogVisible值改为true。
之后修改对话框,把显示信息的基本对话框,修改为能提交表单的对话框:
<el-dialog title="提示" :visible.sync="dialogVisible" width="30%"><el-form :model="form"><el-form-item label="活动名称" :label-width="formLabelWidth"><el-input v-model="form.name" autocomplete="off"></el-input></el-form-item><el-form-item label="活动区域" :label-width="formLabelWidth"><el-select v-model="form.region" placeholder="请选择活动区域"><el-option label="区域一" value="shanghai"></el-option><el-option label="区域二" value="beijing"></el-option></el-select></el-form-item></el-form><span slot="footer" class="dialog-footer"><el-button @click="dialogVisible = false">取 消</el-button><el-button type="primary" @click="dialogVisible = false">确 定</el-button></span></el-dialog>
最后完善表单提交对象的内容,对标数据库的内容,进行修改:
<!-- -->
<template><div><el-tree:data="menus":props="defaultProps":expand-on-click-node="false"show-checkboxnode-key="catId":default-expanded-keys="expandedKey"><span class="custom-tree-node" slot-scope="{ node, data }"><span>{{ node.label }}</span><span><el-buttonv-if="node.level <=2"type="text"size="mini"@click="() => append(data)">Append</el-button><el-buttonv-if="node.childNodes.length==0"type="text"size="mini"@click="() => remove(node, data)">Delete</el-button></span></span></el-tree><el-dialog title="提示" :visible.sync="dialogVisible" width="30%"><el-form :model="category"><el-form-item label="分类名称"><el-input v-model="category.name" autocomplete="off"></el-input></el-form-item></el-form><span slot="footer" class="dialog-footer"><el-button @click="dialogVisible = false">取 消</el-button><el-button type="primary" @click="addCategory">确 定</el-button></span></el-dialog></div>
</template><script>
//这里可以导入其他文件(比如:组件,工具js,第三方插件js,json文件,图片文件等等)
//例如:import 《组件名称》 from '《组件路径》';export default {//import引入的组件需要注入到对象中才能使用components: {},data() {//这里存放数据return {menus: [],// 保存默认展开的IDexpandedKey: [],// 对话框的形态dialogVisible: false,//对应表单category: {name: "",parentCid: 0,catLevel: 0,showStatus: 1,sort: 0,productUnit: "",icon: "",catId: null},defaultProps: {children: "children",label: "name"}};},//监听属性 类似于data概念computed: {},//监控data中的数据变化watch: {},//方法集合methods: {getMenus() {this.$http({url: this.$http.adornUrl("/product/category/list/tree"),method: "get"}).then(({ data }) => {console.log("成功获取到菜单数据...", data.data);this.menus = data.data;});},append(data) {//业务逻辑待编写//打开对话框this.dialogVisible = true;this.dialogType = "add";this.title = "添加分类";this.dialogVisible = true;this.category.parentCid = data.catId;this.category.catLevel = data.catLevel * 1 + 1;//下面的内容至空,防止信息错误this.category.catId = null;this.category.name = "";this.category.icon = "";this.category.productUnit = "";this.category.sort = 0;this.category.showStatus = 1;},//添加三级分类方法addCategory() {console.log("提交的三级分类数据", this.category);},remove(node, data) {//业务逻辑待编写var ids = [data.catId];this.$confirm(`是否删除【${data.name}】菜单`, "提示", {confirmButtonText: "确定",cancelButtonText: "取消",type: "warning"}).then(() => {this.$http({url: this.$http.adornUrl("/product/category/delete"),method: "post",data: this.$http.adornData(ids, false)}).then(({ data }) => {this.$message({type: "success",message: "菜单删除成功!"});// 获取菜单this.getMenus();//设置需要展开的IDthis.expandedKey = [node.parent.data.catId];});}).catch(() => {//点击取消});}},//生命周期 - 创建完成(可以访问当前this实例)created() {this.getMenus();},//生命周期 - 挂载完成(可以访问DOM元素)mounted() {},beforeCreate() {}, //生命周期 - 创建之前beforeMount() {}, //生命周期 - 挂载之前beforeUpdate() {}, //生命周期 - 更新之前updated() {}, //生命周期 - 更新之后beforeDestroy() {}, //生命周期 - 销毁之前destroyed() {}, //生命周期 - 销毁完成activated() {} //如果页面有keep-alive缓存功能,这个函数会触发
};
</script>
<style scoped>
</style>
完善添加数据进数据库的内容
先看一下保存的后端实现:
/*** 保存*/@RequestMapping("/save")//@RequiresPermissions("product:category:save")public R save(@RequestBody CategoryEntity category){categoryService.save(category);return R.ok();}
实现方法很简单,接收一个JSON文件转化为实体对象。直接在vue模型中调用这个方法即可。
<!-- -->
<template><div><el-tree:data="menus":props="defaultProps":expand-on-click-node="false"show-checkboxnode-key="catId":default-expanded-keys="expandedKey"><span class="custom-tree-node" slot-scope="{ node, data }"><span>{{ node.label }}</span><span><el-buttonv-if="node.level <=2"type="text"size="mini"@click="() => append(data)">Append</el-button><el-buttonv-if="node.childNodes.length==0"type="text"size="mini"@click="() => remove(node, data)">Delete</el-button></span></span></el-tree><el-dialog title="提示" :visible.sync="dialogVisible" width="30%"><el-form :model="category"><el-form-item label="分类名称"><el-input v-model="category.name" autocomplete="off"></el-input></el-form-item></el-form><span slot="footer" class="dialog-footer"><el-button @click="dialogVisible = false">取 消</el-button><el-button type="primary" @click="addCategory">确 定</el-button></span></el-dialog></div>
</template><script>
//这里可以导入其他文件(比如:组件,工具js,第三方插件js,json文件,图片文件等等)
//例如:import 《组件名称》 from '《组件路径》';export default {//import引入的组件需要注入到对象中才能使用components: {},data() {//这里存放数据return {menus: [],// 保存默认展开的IDexpandedKey: [],// 对话框的形态dialogVisible: false,//对应表单category: {name: "",parentCid: 0,catLevel: 0,showStatus: 1,sort: 0,productUnit: "",icon: "",catId: null},defaultProps: {children: "children",label: "name"}};},//监听属性 类似于data概念computed: {},//监控data中的数据变化watch: {},//方法集合methods: {getMenus() {this.$http({url: this.$http.adornUrl("/product/category/list/tree"),method: "get"}).then(({ data }) => {console.log("成功获取到菜单数据...", data.data);this.menus = data.data;});},append(data) {//业务逻辑待编写//打开对话框this.dialogVisible = true;this.category.parentCid = data.catId;this.category.catLevel = data.catLevel * 1 + 1;this.category.catId = null;this.category.name = "";this.category.icon = "";this.category.productUnit = "";this.category.sort = 0;this.category.showStatus = 1;},//添加三级分类方法addCategory() {console.log("提交的三级分类数据", this.category);this.$http({url: this.$http.adornUrl("/product/category/save"),method: "post",data: this.$http.adornData(this.category, false)}).then(({ data }) => {this.$message({type: "success",message: "菜单添加成功!"});//关闭对话框this.dialogVisible = false;//刷新出新的菜单this.getMenus();//设置需要默认展开的菜单this.expandedKey = [this.category.parentCid];});},remove(node, data) {//业务逻辑待编写var ids = [data.catId];this.$confirm(`是否删除【${data.name}】菜单`, "提示", {confirmButtonText: "确定",cancelButtonText: "取消",type: "warning"}).then(() => {this.$http({url: this.$http.adornUrl("/product/category/delete"),method: "post",data: this.$http.adornData(ids, false)}).then(({ data }) => {this.$message({type: "success",message: "菜单删除成功!"});// 获取菜单this.getMenus();//设置需要展开的IDthis.expandedKey = [node.parent.data.catId];});}).catch(() => {//点击取消});}},//生命周期 - 创建完成(可以访问当前this实例)created() {this.getMenus();},//生命周期 - 挂载完成(可以访问DOM元素)mounted() {},beforeCreate() {}, //生命周期 - 创建之前beforeMount() {}, //生命周期 - 挂载之前beforeUpdate() {}, //生命周期 - 更新之前updated() {}, //生命周期 - 更新之后beforeDestroy() {}, //生命周期 - 销毁之前destroyed() {}, //生命周期 - 销毁完成activated() {} //如果页面有keep-alive缓存功能,这个函数会触发
};
</script>
<style scoped>
</style>
进入到人人开源界面添加标签进行测试:

至此删除和添加标签功能完整。
本文来自互联网用户投稿,文章观点仅代表作者本人,不代表本站立场,不承担相关法律责任。如若转载,请注明出处。 如若内容造成侵权/违法违规/事实不符,请点击【内容举报】进行投诉反馈!
