商品属性组管理

发布于:2024-05-21 ⋅ 阅读:(198) ⋅ 点赞:(0)

文章目录

1.数据库表设计

1.在sunliving_commodity数据库中创建商品属性表
use sunliving_commodity; 

CREATE TABLE `commodity_attrgroup`
(
    id          BIGINT NOT NULL AUTO_INCREMENT COMMENT 'id',
    `name`      CHAR(20) COMMENT '组名',
    sort        INT COMMENT '排序',
    description VARCHAR(255) COMMENT '说明',
    icon        VARCHAR(255) COMMENT '组图标',
    category_id BIGINT COMMENT '所属分类 id',
    PRIMARY KEY (id)
) CHARSET = utf8mb4 COMMENT ='家居商品属性分组';
2.插入测试数据
INSERT INTO
    `commodity_attrgroup` (id,`name`, sort,description,icon,category_id)
VALUES(1, '主体',0,'主体说明','',301);
INSERT INTO
    `commodity_attrgroup` (id,`name`, sort,description,icon,category_id)
VALUES(2, '规格',0,'规格说明','',301);
INSERT INTO
    `commodity_attrgroup` (id,`name`, sort,description,icon,category_id)
VALUES(3, '功能',0,'功能说明','',301);

SELECT * FROM `commodity_attrgroup`;

image-20240417153534386

2.renren-generator生成CRUD

1.配置renren-generator生成代码
1.application.yml 配置数据库连接
2.generator.properties 配置生成器

image-20240417154423651

3.根据端口访问生成器服务 http://localhost:81/

image-20240417154816414

image-20240417154844525

4.生成代码

image-20240417154929806

image-20240417155101591

5.将main目录覆盖掉本项目的main目录,注意如果冲突立即停止,手动调整

image-20240417155741594

image-20240417155816274

2.检查代码
1.数据表字段

image-20240417160506416

2.application.yml的mybatis-plus配置(默认开启自动驼峰命名)

image-20240417161232148

3.AttrgroupEntity.java
  • 检查驼峰命名对应没问题

4.AttrgroupDao.java(@Mapper 注入容器)

image-20240417161611767

5.AttrgroupDao.xml(application.yml 配置扫描)

image-20240417161653800

6.AttrgroupService.java

image-20240417161937226

7.AttrgroupServiceImpl.java(@Service 注入容器)

image-20240417162318227

8.AttrgroupController.java(@RestController 注入容器)
@RequiresPermissions注解全部注销掉

image-20240417163153751

3.测试后端代码
1.测试查询

http://localhost:9091/sunliving-commodity/commodity/attrgroup/list

image-20240417163520623

2.测试修改

http://localhost:9091/sunliving-commodity/commodity/attrgroup/update

image-20240417163834469

image-20240417163856338

4.前端创建页面并完成crud测试
1.创建目录和菜单

image-20240417165611243

image-20240417170055780

image-20240417170125807

2.将代码生成器生成的两个前端页面拷贝到前端对应目录下
1.后端生成页面所在位置

image-20240417170406023

2.粘贴到前端指定位置

image-20240417170555783

3.修改attrgroup.vue的一个url,查看是否能正常访问

image-20240417171528726

4.重启前端项目测试,跨域问题,说明成功访问到了后端资源(直接使用网关解决跨域即可)

image-20240417171605814

3.区分多环境并配置GateWay
1.由于还是访问的 sunliving-commodity 模块,所以之前已经区分过多环境了

dev.env.js

image-20240417171947941

prod.env.js

image-20240417172014247

2.配置GateWay也配置过了

image-20240417172258472

3.修改attrgroup.vue的一个url为使用GateWay的请求

image-20240417193010395

4.再次访问,请求成功!
5.将其使用环境变量替换,并修改attrgroup.vue和attrgroup-add-or-update.vue的所有请求(共四个)

image-20240417194512771

image-20240417194527923

image-20240417194539635

image-20240417194553301

6.如果有时候会出现不好使的情况,就进Nacos把服务影响的服务下线(因为之前已经上线了项目,但是后端没更新)

image-20240417194750981

image-20240417194815250

3.前端显示树形菜单和属性分组信息

1.view层进行布局,将页面分成两列
  • 第一列是树形菜单
  • 第二列就是表单
<!-- 
1. el-row 是 elementui 的布局控件 参考 elementui 官网 - Layout 布局 -分栏间隔
2. 我们将其分成两栏, 一栏放置分类树形菜单 一栏放置家居分类属性组的表单-->
<el-row :gutter="20">
<el-col :span="5">
<!--1. 分类树形占 5 个单元宽度, 保留 ref, :data, :props, node-key 基本显示的属性
2. node-click 实际是 el-tree 中规定好的实际,会传递三个参数: 参考 elmentui 官网
elementui-Tree 树形控件-Events -->
<el-tree ref="categoryTree" :data="data" :props="defaultProps" node-key="id">
<span class="custom-tree-node" slot-scope="{ node, data }">
<span>{{ node.label }}</span>
</span>
</el-tree>
</el-col>
<el-col :span="19">
<!-- 说明 原家居分类属性组的表单放在这里 带 div. -->
</el-col>
</el-row>
2.数据池绑定两个树形菜单的属性
      data: [], // 树形控件的数据
      defaultProps: { // 树形控件的默认属性配置
        children: 'childrenCategories',
        label: 'name'
      },
3.方法池编写获取data的方法
    // 获取分类列表(带层级)
    getCategories() {
      this.$http({
        url: process.env.COMMODITY_BASEPATH + '/commodity/category/list/tree',
        method: 'get'
      }).then(({data}) => { // 解构了data
        this.data = data.data;
      })
    }
4.初始化时调用
  created() { // 生命周期钩子,初始化时调用
    this.getCategories()
  }
5.结果展示

image-20240418100708082

5.点击家居第三级分类,显示对应商品属性组信息

1.后端 sunliving-commodity模块
1.com/sun/sunliving/commodity/service/AttrgroupService.java 新增方法
    /**
     * 条件分页查询属性分组
     * @param params
     * @param categoryId
     * @return
     */
    PageUtils queryPage(Map<String, Object> params, Long categoryId);
2.com/sun/sunliving/commodity/service/impl/AttrgroupServiceImpl.java
    @Override
    public PageUtils queryPage(Map<String, Object> params, Long categoryId) {
        //1.获取查询输入框的key
        String key = (String) params.get("key");

        //2.构造查询条件
        QueryWrapper<AttrgroupEntity> wrapper = new QueryWrapper<>();
        //如果key不为空
        if (StringUtils.isNotBlank(key)) {
            System.out.println("key = " + key);
            // id等于key或者name like %key%
            wrapper.eq("id", key).or().like("name", key);
        }
        // 如果categoryId不为0
        if (categoryId != 0) {
            // categoryId等于categoryId
            wrapper.eq("category_id", categoryId);
        }

        // 3.分页查询
        IPage<AttrgroupEntity> page = this.page(
                new Query<AttrgroupEntity>().getPage(params),
                // 查询条件
                wrapper
        );
        return new PageUtils(page);
    }
3.com/sun/sunliving/commodity/controller/AttrgroupController.java
    /**
     * 条件分页查询属性分组
     */
    @RequestMapping("/list/{categoryId}")
    public R list(@RequestParam Map<String, Object> params, @PathVariable("categoryId") Long categoryId) {
        PageUtils page = attrgroupService.queryPage(params, categoryId);

        return R.ok().put("page", page);
    }
2.前端 attrgroup.vue
1.el-tree添加点击事件,得到节点信息

image-20240418115705730

2.数据池定义catId默认为0

image-20240418115826952

3.方法池实现点击方法,点击后如果为三级节点就进行条件查询
    // 点击树形节点,获取数据,如果是第三级就进行条件分页查询
    nodeclick(data) {
      if (data.catLevel == 3) {
        this.catId = data.id
        this.getDataList() // 进行条件分页查询
      }
    }
4.修改getDataList,添加catId的参数条件

image-20240418115946759

3.整体分析
1.后端接口
  • 如果传递了参数key,则添加name like key或者id等于key的查询条件
  • 如果catId不为0,则添加按照catId进行查询的条件
2.前端逻辑
  • 点击节点,获取该节点的信息
  • 如果等级是3,则给数据池中的catId赋值,然后调用getDataList查询,携带catId
  • 这样,初始化时catId默认为0,key也为空,所以不带条件查询
  • 点击了节点则会按照catId查询
  • 输入了key则会按照key查询
  • 既点击了节点又输入了key,则会进行两个条件的查询
4.后端sunliving-commodity模块引入分页插件完成分页功能
com/sun/sunliving/commodity/config/CorsConfig.java
package com.sun.sunliving.commodity.config;

import com.baomidou.mybatisplus.extension.plugins.PaginationInterceptor;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.transaction.annotation.EnableTransactionManagement;

/**
 * Description: 分页插件使用
 *
 * @Author sun
 * @Create 2024/4/18 13:06
 * @Version 1.0
 */
@Configuration
@EnableTransactionManagement // 开启事务
@MapperScan("com.sun.sunliving.commodity.dao") // 扫描mapper接口
public class MyBatisConfig {
    // 引入分页插件
    @Bean
    public PaginationInterceptor paginationInterceptor() {
        PaginationInterceptor paginationInterceptor = new PaginationInterceptor();
    // 设置请求的页面大于最大页后操作,
    // true 调回到首页,false 继续请求 默认 false
        paginationInterceptor.setOverflow(true);
    // 设置最大单页限制数量,默认 500 条,-1 不受限制
        paginationInterceptor.setLimit(100);
        return paginationInterceptor;
    }
}

image-20240418131642516

6.通过管理系统来添加属性组

1.前端引入级联选择器 attrgroup-add-or-update.vue
1.方法池获取分类列表(带层级)
      // 获取分类列表(带层级)
      getCategories() {
        this.$http({
          url: process.env.COMMODITY_BASEPATH + '/commodity/category/list/tree',
          method: 'get'
        }).then(({data}) => { // 解构了data
           this.data = data.data;
        })
      }
2.created方法调用一下
    created() {
      this.getCategories()
    }
3.输出一下data,是可以获取到树形菜单的值的

image-20240418133914588

4.view引入树形菜单
      <el-cascader
        v-model="cascadedCategoryId"
        :options="categories"
        :props="props"
      ></el-cascader>

image-20240418140659590

5.配置数据池
        categories: [], // 树形数据
        cascadedCategoryId: [], // 级联选择器的值,从 categories 中取,如果是三级就是[1,2,3]的形式
        props: {
          value: 'id', // 从 categories 中取 id放到 cascadedCategoryId
          label: 'name', // 从 categories 中取 name作为级联选择器的显示标签
          children: 'childrenCategories', // 从 categories 中取 childrenCategories作为级联选择器的子选项
          expandTrigger: 'hover' // 悬停展开
        }
6.方法池中将树形数据给categories

image-20240418140848573

7.查看效果

image-20240418140905458

2. 后端 sunliving-commodity模块
1.修改com/sun/sunliving/commodity/entity/CategoryEntity.java,添加注解,使得如果为空就不返回子列表

image-20240418141709357

2.成功解决显示空白的问题

image-20240418141809607

3.前端提交表单
1.修改提交表单逻辑,从级联选择器中取最后一个id值

image-20240418142850500

2.尝试提交,校验失败

image-20240418143150803

3.解决方式:将级联选择器的值赋值给表单,还按照原来方式提交

image-20240418144226729

image-20240418144252315

7.通过管理系统,修改属性组

1.问题分析
1.目前点击修改,所属分类id不会自动显示
2.原因是点击修改按钮的回显策略是之前的回显表单数据,所以失效了
2.解决思路分析
1.找到目前这个view所绑定的model

image-20240418172014804

2.点击修改后的策略是向/info/{id}发送请求获取数据

image-20240418172050261

3.所以解决方式就是:修改后端/info/{id}的逻辑,使其可以返回这个级联菜单的model数据
3.具体实现
1.由于是返回一个AttrgroupEntity.java,所以需要添加级联菜单的属性

image-20240418172353422

2.经过分析,这个级联菜单的属性需要查找category表的所有父ip
1.com/sun/sunliving/commodity/service/CategoryService.java
    /**
     * 根据id来获取该id对应的所有父id的数组
     *
     * @return
     */
    List<Long> getCascadedCategoryId(Long categoryId);
2.com/sun/sunliving/commodity/service/impl/CategoryServiceImpl.java
    @Override
    public List<Long> getCascadedCategoryId(Long categoryId) {
        ArrayList<Long> res = new ArrayList<>();
        // 根据categoryId查询出所有的父id,并放到res中
        // 查询一下当前记录
        CategoryEntity categoryEntity = categoryDao.selectById(categoryId);

        // 只要当前记录不为空,就一直循环
        while (categoryEntity != null) {
            res.add(categoryEntity.getId());
            categoryId = categoryEntity.getParentId();
            categoryEntity = categoryDao.selectById(categoryId);
        }

        // 使用 Collections.reverse 直接反转
        Collections.reverse(res);
        return res;
    }
3.修改com/sun/sunliving/commodity/controller/AttrgroupController.java 通过
    /**
     * 信息
     */
    @RequestMapping("/info/{id}")
    // @RequiresPermissions("commodity:attrgroup:info")
    public R info(@PathVariable("id") Long id) {
        AttrgroupEntity attrgroup = attrgroupService.getById(id);
        // 调用categoryService获取所属分类id的所有父id
        List<Long> cascadedCategoryId = categoryService.getCascadedCategoryId(attrgroup.getCategoryId());
        attrgroup.setCascadedCategoryId(cascadedCategoryId);
        return R.ok().put("attrgroup", attrgroup);
    }
4.修改attrgroup-add-or-update.vue 点击修改回显级联菜单

image-20240418192627062

4.解决点击新增时级联菜单仍然保留上一次结果的问题
1.关闭对话框时新增方法

image-20240418194243553

2.实现方法,关闭弹窗啊时清空级联选择器的值

image-20240418194310338

5.增加级联菜单搜索功能
1.在级联菜单空间加两个属性即可

image-20240418194023204

2.结果展示

image-20240418194426526


网站公告

今日签到

点亮在社区的每一天
去签到