✅P77_平台属性-规格参数列表

gong_yz大约 6 分钟谷粒商城

规格参数页面

实现效果

页面编写

参考:layout布局->分栏间隔, 一行有24列,三级分类6列,表格18列,gutter:设置列间距

具体实现思路

src\views\modules\product下创建baseattr.vue

第一步将分栏间隔的页面布局引入页面中,

<el-row :gutter="20">
  <el-col :span="6">三级分类</div></el-col>
  <el-col :span="18">表格</div></el-col>
</el-row>

然后三级分类通过引入的公共三级分类组件来实现,表格部分是将逆向工程生成的attr.vue代码剩余内容复制到baseattr.vue

最后编写获取分类规格参数接口;

baseattr.vue代码

baseattr.vue内容详解:

  • <category @node-click="treeNodeClick"></category>
    1. 导入三级分类公共组件:import Category from '../common/category.vue';
    2. <el-col :span="6"> </el-col>中使用Category 组件
    3. @node-click="treeNodeClick":三级分类子组件传递给父组件baseattr.vue数据,实现点击三级分类右侧表格展示关联数据
  • 导入AttrAddOrUpdate 组件,供后续新增、修改弹窗使用:
    1. import addOrUpdate from './attr-add-or-update.vue';
    2. components: { Category, AttrAddOrUpdate }:组件注入到对象中才能使用
  • url: this.$http.adornUrl(/product/attr/base/list/${this.catId}):调用后台获取分类规格参数接口
<template>
    <div>
        <el-row :gutter="20">
            <el-col :span="6">
                <!-- 组件名大小写都可以 -->
                <category @node-click="treeNodeClick"></category>
            </el-col>
            <el-col :span="18">
                <div class="mod-config">
                    <el-form :inline="true" :model="dataForm" @keyup.enter.native="getDataList()">
                        <el-form-item>
                            <el-input v-model="dataForm.key" placeholder="参数名" clearable></el-input>
                        </el-form-item>
                        <el-form-item>
                            <el-button @click="getDataList()">查询</el-button>
                            <el-button v-if="isAuth('product:attr:save')" type="primary"
                                @click="addOrUpdateHandle()">新增</el-button>
                            <el-button v-if="isAuth('product:attr:delete')" type="danger" @click="deleteHandle()"
                                :disabled="dataListSelections.length <= 0">批量删除</el-button>
                        </el-form-item>
                    </el-form>
                    <el-table :data="dataList" border v-loading="dataListLoading" @selection-change="selectionChangeHandle"
                        style="width: 100%;">
                        <el-table-column type="selection" header-align="center" align="center" width="50">
                        </el-table-column>
                        <el-table-column prop="attrId" header-align="center" align="center" label="id">
                        </el-table-column>
                        <el-table-column prop="attrName" header-align="center" align="center" label="属性名">
                        </el-table-column>
                        <el-table-column prop="searchType" header-align="center" align="center" label="可检索">
                        </el-table-column>
                        <el-table-column prop="valueType" header-align="center" align="center" label="值类型">
                        </el-table-column>
                        <el-table-column prop="icon" header-align="center" align="center" label="图标">
                        </el-table-column>
                        <el-table-column prop="valueSelect" header-align="center" align="center" label="可选值">
                        </el-table-column>
                        <!-- <el-table-column prop="attrType" header-align="center" align="center"
                            label="属性类型[0-销售属性,1-基本属性,2-既是销售属性又是基本属性]">
                        </el-table-column> -->
                        <el-table-column prop="enable" header-align="center" align="center" label="启用">
                        </el-table-column>
                        <el-table-column prop="catelogId" header-align="center" align="center" label="所属分类">
                        </el-table-column>
                        <el-table-column prop="showDesc" header-align="center" align="center" label="快速展示">
                        </el-table-column>
                        <el-table-column fixed="right" header-align="center" align="center" width="150" label="操作">
                            <template slot-scope="scope">
                                <el-button type="text" size="small"
                                    @click="addOrUpdateHandle(scope.row.attrId)">修改</el-button>
                                <el-button type="text" size="small" @click="deleteHandle(scope.row.attrId)">删除</el-button>
                            </template>
                        </el-table-column>
                    </el-table>
                    <el-pagination @size-change="sizeChangeHandle" @current-change="currentChangeHandle"
                        :current-page="pageIndex" :page-sizes="[10, 20, 50, 100]" :page-size="pageSize" :total="totalPage"
                        layout="total, sizes, prev, pager, next, jumper">
                    </el-pagination>
                    <!-- 弹窗, 新增 / 修改 -->
                    <add-or-update v-if="addOrUpdateVisible" ref="addOrUpdate"
                        @refreshDataList="getDataList"></add-or-update>
                </div>
            </el-col>
        </el-row>
    </div>
</template>

<script>
//这里可以导入其他文件(比如:组件,工具js,第三方插件js,json文件,图片文件等等)
//例如:import 《组件名称》 from '《组件路径》';
import Category from '../common/category.vue';
import addOrUpdate from './attr-add-or-update.vue';

export default {
    //import引入的组件需要注入到对象中才能使用
    components: { Category, AttrAddOrUpdate },
    props: {},
    data() {
        //这里存放数据
        return {
            catId:0,
            dataForm: {
                key: ''
            },
            dataList: [],
            pageIndex: 1,
            pageSize: 10,
            totalPage: 0,
            dataListLoading: false,
            dataListSelections: [],
            addOrUpdateVisible: false
        };
    },
    //监听属性 类似于data概念
    computed: {},
    //监控data中的数据变化
    watch: {},
    //方法集合
    methods: {


        //子组件传给父组件的参数
        treeNodeClick(data, node, component) {
            console.log("父组件接收到子组件传递过来的数据为:", data, node, component);
            if (node.level == 3) {
                this.catId = data.catId;
                this.getDataList();
            }
        },

        // 获取数据列表
        getDataList() {
            this.dataListLoading = true
            this.$http({
                url: this.$http.adornUrl(`/product/attr/base/list/${this.catId}`),
                method: 'get',
                params: this.$http.adornParams({
                    'page': this.pageIndex,
                    'limit': this.pageSize,
                    'key': this.dataForm.key
                })
            }).then(({ data }) => {
                if (data && data.code === 0) {
                    this.dataList = data.page.list
                    this.totalPage = data.page.totalCount
                } else {
                    this.dataList = []
                    this.totalPage = 0
                }
                this.dataListLoading = false
            })
        },
        // 每页数
        sizeChangeHandle(val) {
            this.pageSize = val
            this.pageIndex = 1
            this.getDataList()
        },
        // 当前页
        currentChangeHandle(val) {
            this.pageIndex = val
            this.getDataList()
        },
        // 多选
        selectionChangeHandle(val) {
            this.dataListSelections = val
        },
        // 新增 / 修改
        addOrUpdateHandle(id) {
            this.addOrUpdateVisible = true
            this.$nextTick(() => {
                this.$refs.addOrUpdate.init(id)
            })
        },
        // 删除
        deleteHandle(id) {
            var ids = id ? [id] : this.dataListSelections.map(item => {
                return item.attrId
            })
            this.$confirm(`确定对[id=${ids.join(',')}]进行[${id ? '删除' : '批量删除'}]操作?`, '提示', {
                confirmButtonText: '确定',
                cancelButtonText: '取消',
                type: 'warning'
            }).then(() => {
                this.$http({
                    url: this.$http.adornUrl('/product/attr/delete'),
                    method: 'post',
                    data: this.$http.adornData(ids, false)
                }).then(({ data }) => {
                    if (data && data.code === 0) {
                        this.$message({
                            message: '操作成功',
                            type: 'success',
                            duration: 1500,
                            onClose: () => {
                                this.getDataList()
                            }
                        })
                    } else {
                        this.$message.error(data.msg)
                    }
                })
            })
        }
    },
}
</script>
<style  scoped></style>

获取分类规格参数

接口地址

GET:/product/attr/base/list/{catelogId}

请求参数

{
   page: 1,//当前页码
   limit: 10,//每页记录数
   sidx: 'id',//排序字段
   order: 'asc/desc',//排序方式
   key: '华为'//检索关键字
}

分页数据

响应数据

{
	"msg": "success",
	"code": 0,
	"page": {
		"totalCount": 0,
		"pageSize": 10,
		"totalPage": 0,
		"currPage": 1,
		"list": [{
			"attrId": 0, //属性id
			"attrName": "string", //属性名
			"attrType": 0, //属性类型,0-销售属性,1-基本属性
			"catelogName": "手机/数码/手机", //所属分类名字
			"groupName": "主体", //所属分组名字
			"enable": 0, //是否启用
			"icon": "string", //图标
			"searchType": 0,//是否需要检索[0-不需要,1-需要]
			"showDesc": 0,//是否展示在介绍上;0-否 1-是
			"valueSelect": "string",//可选值列表[用逗号分隔]
			"valueType": 0//值类型[0-为单个值,1-可以选择多个值]
		}]
	}
}

代码实现

catelogNamegroupNameAttrEntity中没有的字段,编写AttrRespVo.java

cfmall-product/src/main/java/com/gyz/cfmall/product/vo/AttrRespVo.java

@Data
public class AttrRespVo extends AttrVo {

    /**
     *
     */
    private String catelogName;

    private String groupName;

    private Long[] catelogPath;
}

cfmall-product/src/main/java/com/gyz/cfmall/product/controller/AttrController.java

    @GetMapping("/base/list/{catelogId}")
    public R queryAttrByCatelogId(@RequestParam Map<String, Object> params, @PathVariable Long catelogId) {
        PageUtils page = attrService.queryAttrByCatelogId(params, catelogId);
        return R.ok().put("page", page);
    }

cfmall-product/src/main/java/com/gyz/cfmall/product/service/impl/AttrServiceImpl.java

    @Override
    public PageUtils queryAttrByCatelogId(Map<String, Object> params, Long catelogId) {
        QueryWrapper<AttrEntity> queryWrapper = new QueryWrapper<>();
        //模糊查询,catelogId 查询
        if (catelogId != 0) {
            queryWrapper.eq("catelog_id", catelogId);
        }
        String key = (String) params.get("key");
        if (!StringUtils.isEmpty(key)) {
            //attr_id  attr_name
            queryWrapper.and((wrapper) -> {
                wrapper.eq("attr_id", key).or().like("attr_name", key);
            });
        }
        IPage<AttrEntity> page = this.page(
                new Query<AttrEntity>().getPage(params),
                queryWrapper
        );
        //封装分页数据
        PageUtils pageUtils = new PageUtils(page);

        //分页数据中加入当前属性的“所属分类”和“所属分组”
        List<AttrEntity> records = page.getRecords();
        List<AttrRespVo> respVos = records.stream().map((attrEntity) -> {
            AttrRespVo attrRespVo = new AttrRespVo();
            BeanUtils.copyProperties(attrEntity, attrRespVo);
            CategoryEntity categoryEntity = categoryDao.selectOne(new QueryWrapper<CategoryEntity>().eq("cat_id", attrEntity.getCatelogId()));

            //没查到的对象就不能getName了,必须防止空指针异常,习惯习惯
            if (categoryEntity != null) {
                attrRespVo.setCatelogName(categoryEntity.getName());
            }
            //查属性分组要从属性与属性分组关联表查
            AttrAttrgroupRelationEntity attrgroupRelationEntity = relationDao.selectOne(new QueryWrapper<AttrAttrgroupRelationEntity>().eq("attr_id", attrEntity.getAttrId()));
            if (attrgroupRelationEntity != null) {
                AttrGroupEntity attrGroupEntity = attrGroupDao.selectOne(new QueryWrapper<AttrGroupEntity>().eq("attr_group_id", attrgroupRelationEntity.getAttrGroupId()));
                if (attrGroupEntity != null){
                    attrRespVo.setGroupName(attrGroupEntity.getAttrGroupName());
                }
            }

            return attrRespVo;
        }).collect(Collectors.toList());
        // 把新的数据传送过去
        pageUtils.setList(respVos);
        return pageUtils;
    }

TODO

修复完成