谷粒商城实战笔记-50-51-商品分类的删除


这两节的内容是开发商品分类的删除功能。

一,50-商品服务-API-三级分类-删除-逻辑删除

前端已经开发了删除按钮,后端要有对应的接口实现。

1,逻辑删除的配置

在工作中,所有的删除都应该是逻辑删除,不能用物理硬删除。

mybatis-plus支持逻辑删除的配置,配置步骤如下:

  • ①配置全局的逻辑删除规则(可省略)
  • ②配置逻辑删除Bean(可省略)
  • ③Bean相应字段上加上注解@TableLogic

1.1 配置全局的逻辑删除规则(可省略)

mybatis-plus:
  global-config:
    db-config:
      logic-delete-value: 1
      logic-not-delete-value: 0

在这里插入图片描述

logic-delete-value: 1

这个配置项定义了当一个记录被逻辑删除时,其逻辑删除字段(通常是一个布尔型或整型字段)的值应该是多少。在这个例子中,如果一个记录的逻辑删除字段值为1,那么框架认为这个记录是被逻辑删除的。

logic-not-delete-value: 0

这个配置项定义了当一个记录未被逻辑删除时,其逻辑删除字段的值应该是多少。在这个例子中,如果一个记录的逻辑删除字段值为0,那么框架认为这个记录是有效的,没有被逻辑删除。

1.2 配置逻辑删除Bean(可省略)

在mybatis-plus3.1.1版本后,无需此步骤,我用的3.2,所以这步可以省略。

1.3 Bean相应字段上加上注解@TableLogic

商品分类表中用showStatus字段表示记录是否逻辑删除。

所以在对应的实体类CategoryEntity.java中showStatus字段上加上注解。
在这里插入图片描述
这里需要说明的是,如果表示逻辑删除的值和全局配置不一致,可以在注解上单独配置。

比如全局配置中1表示已删除,而三级分类表1表示未删除,产生了冲突,解决冲突的办法就是在注解上通过val和delVal字段进行设置。

2,后台接口开发

2.1,Controller类中修改接口

	@RequestMapping("/delete")
    public R delete(@RequestBody Long[] catIds){
//		categoryService.removeByIds(Arrays.asList(catIds));
		categoryService.removeMenuByIds(Arrays.asList(catIds));

        return R.ok();
    }

removeMenuByIds是新实现的方法,逆向工程生成的方法removeByIds缺少必要的校验,我们不用这个方法。

2.2,CategoryServiceImpl类中增加接口

    @Override
    public void removeMenuByIds(List<Long> ids) {
        baseMapper.deleteBatchIds(ids);
    }

在这里插入图片描述

2.3,postman验证

重启product服务,在postman中通过网关调用删除接口。

二,51-商品服务-API-三级分类-删除-删除效果细化

1,前端调用delete接口

category.vue模块中,remove方法如下。

remove(node, data) {
      var ids = [node.catId];

      this.$confirm(
        `确定对[id=${ids.join(",")}]进行[${id ? "删除" : "批量删除"}]操作?`,
        "提示",
        {
          confirmButtonText: "确定",
          cancelButtonText: "取消",
          type: "warning",
        }
      )
        .then(() => {
          this.$http({
            url: this.$http.adornUrl("/product/category/delete"),
            method: "post",
            data: this.$http.adornData(ids, false),
          }).then(({ data }) => {
            if (data && data.code === 0) {
              this.$message({
                message: "操作成功",
                type: "success",
                duration: 1500,
                onClose: () => {
                  console.log("删除成功,关闭消息提示");
                  this.getMenus();
                },
              });
            } else {
              this.$message.error(data.msg);
            }
          });
        })
        .catch(() => {});
    },

在删除前弹窗提示是否确认删除,确认后,调用接口,把要删除的分类Id传递给后端,后端软删除对应分类记录。

2,模板代码配置

后续会频繁使用httpget和httppost请求,为了提高效率,可以配置到模板中。

"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 请求"
	}

这样只要输入httpposthttpgetvscode就可以给出提示,确认后就可以自动插入模板代码,代替手敲,极大的提高编码效率。

3,验证

在页面上点击电子书分类后的delete按钮,弹出如下提示。

在这里插入图片描述

点击确定,提示删除成功。

在这里插入图片描述

在后台数据产看cat_id165的数据,show_status=0说明已经被逻辑删除。
在这里插入图片描述

4,细节优化

  • ①在删除前弹窗提示是否确认删除,确认后,调用接口,把要删除的分类Id传递给后端,后端软删除对应分类记录。
  • ②点击删除后,后端已经删除,但是前端未刷新,可以调用方法this.getMenus();重新查询分类数据刷新界面。
  • ③删除成功后重新请求会导致已经展开的菜单,又收缩了,用户体验不好,最好的效果是只有被删除的分类消失,页面其他部分保持不变。实现这个需求需要用到el-tree组件的default-expanded-keys,用来指定需要展开的节点的id。
    第一步,在el-tree中给属性绑定一个数组,default-expanded-keys="expandedKeys"
    第二步,在js脚本的data中声明这个数组,expandedKeys: []
    第三步,删除成功,重启请求分类数据后,将要被删除的分类节点的父节点的catId赋值给数组,this.expandedKeys = node.parent.data.catId; // 重置展开节点

Category.vue完整代码。

<template>
  <el-tree
    node-key="catId"
    :data="menus"
    :props="defaultProps"
    :expand-on-click-node="false"
    show-checkbox
    default-expanded-keys="expandedKeys"
  >
    <span class="custom-tree-node" slot-scope="{ node, data }">
      <span>{{ node.label }}</span>
      <span>
        <el-button
          v-if="node.level <= 2"
          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 {
  components: {},
  props: {},
  data() {
    return {
      menus: [],
      expandedKeys: [],
      defaultProps: {
        children: "children",
        label: "name",
      },
    };
  },
  methods: {
    append(data) {
      console.log(data);
    },
    remove(node, data) {
      console.log(node, data);
      var ids = [node.data.catId];

      this.$confirm(
        `确定对[id=${ids.join(",")}]进行[${ids.length == 1 ? "删除" : "批量删除"}]操作?`,
        "提示",
        {
          confirmButtonText: "确定",
          cancelButtonText: "取消",
          type: "warning",
        }
      )
        .then(() => {
          this.$http({
            url: this.$http.adornUrl("/product/category/delete"),
            method: "post",
            data: this.$http.adornData(ids, false),
          }).then(({ data }) => {
            if (data && data.code === 0) {
              this.$message({
                message: "操作成功",
                type: "success",
                duration: 1500,
                onClose: () => {
                  console.log("删除成功,关闭消息提示");
                  this.getMenus(); // 重新获取数据
                  this.expandedKeys = node.parent.data.catId; // 重置展开节点
                },
              });
            } else {
              this.$message.error(data.msg);
            }
          });
        })
        .catch(() => {});
    },
    // 获取分类数据
    getMenus() {
      this.dataListLoading = true;
      this.$http({
        url: this.$http.adornUrl("/product/category/list/tree"),
        method: "get",
      }).then(({ data }) => {
        console.log(data);
        this.dataListLoading = false;
        this.menus = data.data;
      });
    },
  },
  created() {
    this.getMenus(); // 获取分类数据
  },
};
</script>
<style scoped>
</style>
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

小手追梦

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值