[TOC]
1 商品分类
1.1 需求分析
商品分类一共分三级管理,主要作用是在网站首页中显示商品导航,以及在管理后台管理商品时使用。
前端交互方式见管理后台->商品管理->类型管理
1.2 表结构分析
category_ 表 (商品分类)
字段名称 | 字段含义 | 字段类型 | 字段长度 | 备注 |
---|---|---|---|---|
id_ | 分类ID | INT | ||
title_ | 分类名称 | VARCHAR | ||
order_ | 排序 | INT | ||
parentid | 上级ID | INT | ||
isparent | 是否为根节点 | boolean | ||
expand_ | 是否默认展开 | boolean |
商品分类与模板是多对一关系
1.3 实现
1.3.1 实体类
legou-item/legou-item-instance/src/main/java/com/lxs/legou/item/po/Category.java:
package com.lxs.legou.item.po;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableName;
import com.lxs.legou.core.po.BaseTreeEntity;
import lombok.Data;
/**
* @Title: 商品分类
*/
@Data
@TableName("category_")
public class Category extends BaseTreeEntity {
@TableField("is_parent_")
private Boolean isParent = false; //是否为父节点
@TableField(exist = false)
private Integer isRoot = 0; //值=1 : 查询根节点条件
public String getLabel() {
//treeselect需要的属性
return this.getTitle();
}
}
注意因为Category分类是树状结构,所以这里需要继承BaseTreeEntity
1.3.2 持久层
legou-item/legou-item-service/src/main/java/com/lxs/legou/item/dao/CategoryDao.java:
package com.lxs.legou.item.dao;
import com.lxs.legou.core.dao.ICrudDao;
import com.lxs.legou.item.po.Category;
/**
* @file 分类Dao
*/
public interface CategoryDao extends ICrudDao<Category> {
}
这里不需要动态SQL语句查询,所以此处不用谢映射文件
1.3.3 业务层
(1)业务层接口
legou-item/legou-item-service/src/main/java/com/lxs/legou/item/service/ICategoryService.java:
package com.lxs.legou.item.service;
import com.lxs.legou.core.service.ICrudService;
import com.lxs.legou.item.po.Category;
import org.springframework.stereotype.Service;
import java.util.List;
/**
* @Title:
*/
@Service
public interface ICategoryService extends ICrudService<Category> {
}
(2)业务层接口实现类
legou-item/legou-item-service/src/main/java/com/lxs/legou/item/service/impl/CategoryServiceImpl.java:
package com.lxs.legou.item.service.impl;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.lxs.legou.core.service.impl.CrudServiceImpl;
import com.lxs.legou.item.po.Category;
import com.lxs.legou.item.service.ICategoryService;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;
import java.util.List;
import java.util.stream.Collectors;
/**
* @Title:
*/
@Service
public class CategoryServiceImpl extends CrudServiceImpl<Category> implements ICategoryService {
@Override
public List<Category> list(Category entity) {
QueryWrapper<Category> queryWrapper = Wrappers.query();
if (StringUtils.isNotEmpty(entity.getTitle())) {
queryWrapper.like("title_", entity.getTitle());
}
if (null != entity.getParentId()) {
queryWrapper.eq("parent_id_", entity.getParentId());
}
if (null != entity.getIsRoot() && entity.getIsRoot().equals(1)) {
queryWrapper.isNull("parent_id_");
}
return getBaseMapper().selectList(queryWrapper);
}
}
1.3.4 控制层
legou-item/legou-item-service/src/main/java/com/lxs/legou/item/controller/CategoryController.java:
package com.lxs.legou.item.controller;
import com.lxs.legou.core.controller.BaseController;
import com.lxs.legou.item.po.Category;
import com.lxs.legou.item.service.ICategoryService;
import io.swagger.annotations.ApiOperation;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import java.util.List;
/**
* @Title: 分类控制器
*/
@RestController
@RequestMapping("/category")
public class CategoryController extends BaseController<ICategoryService, Category> {
}
1.3.5 测试
1.3.6 前端组件
1.3.6.1 树状组件基类
src/libs/crud/base-tree.js:
base-tree组件继承base-list完成树状数据的列表页的基本方法和逻辑的重用
import Qs from 'qs'
import { listToTree } from '@/libs/util'
import instance from '@/libs/api/index'
import {baseList} from './base-list'
export const baseTree = {
mixins: [baseList],
// 表格各行的数据
data () {
return {
// 初始化信息总条数
total: 0,
// 每页显示多少条
pageSize: 10,
// 显示的数据
rows: []
}
},
methods: {
renderContent (h, { root, node, data }) {
return h('span', {
style: {
display: 'inline-block',
width: '100%'
}
}, [
h('span', [
h('Icon', {
props: {
type: 'ios-paper-outline'
},
style: {
marginRight: '8px'
}
}),
h('span', data.title)
]),
h('span', {
style: {
display: 'inline-block',
float: 'right',
marginRight: '32px'
}
}, [
h('Button', {
props: Object.assign({}, this.buttonProps, {
icon: 'md-add'
}),
style: {
marginRight: '8px'
},
on: {
click: () => { this.addChild(data.id) }
}
}),
h('Button', {
props: Object.assign({}, this.buttonProps, {
icon: 'md-copy'
}),
style: {
marginRight: '8px'
},
on: {
click: () => { this.edit(data.id) }
}
}),
h('Button', {
props: Object.assign({}, this.buttonProps, {
icon: 'md-remove'
}),
on: {
click: () => { this.remove(data.id) }
}
})
])
]);
},
// 查询
query () {
instance.post(`/${this.namespace}/${this.entityName}/list`, Qs.stringify(this.formData)).then(response => {
this.rows = listToTree(response.data)
}).catch(error => {
console.log(error)
})
},
addRoot () {
this.$router.push({
name: `edit_${this.namespace}_${this.entityName}`
})
},
// 添加
addChild (id) {
this.$router.push({
name: `edit_${this.namespace}_${this.entityName}`,
query: {parentId: id}
})
}
}
}
src/libs/crud/base-tree-edit.js
继承base-edit组件,实现树状节点的修改,添加页面的基本方法的重用
import {baseEdit} from './base-edit'
export const baseTreeEdit = {
mixins: [baseEdit],
created () {
let arrays = this.$route.name.split('-')
this.namespace = arrays[1]
this.entityName = arrays[2]
let id = this.$route.query.id
this.formData.parentId = this.$route.query.parentId
if (id) {
this.get(id)
}
}
}
1.3.6.2 分类列表组件
src/view/item/category/list.vue
继承base-tree实现,树状结构数据的增删改查操作
<template>
<div>
<div>
<Form ref="formData" :model="formData" :label-width="80">
<Row style="margin-top: 10px;">
<Col span="16">
<FormItem label="名称" prop="title">
<Input v-model="formData.title" placeholder="名称"></Input>
</FormItem>
</Col>
<Col span="8">
<Divider type="vertical" />
<Button type="primary" @click="addRoot">添加</Button>
<Button type="primary" @click="query" style="margin-left: 8px">查询</Button>
</Col>
</Row>
</Form>
</div>
<div>
<Tree :data="rows" :render="renderContent"></Tree>
</div>
</div>
</template>
<style scoped>
.paging {
float: right;
margin-top: 10px;
}
</style>
<script>
import {baseTree} from '@/libs/crud/base-tree'
export default {
mixins: [baseTree],
// 表格各行的数据
data () {
return {
formData: {
title: ''
}
}
}
}
</script>
1.3.6.3:添加修改组件
src/view/item/category/edit.vue
继承base-tree-edit组件,实现分类节点的添加,修改操作
<template>
<Form ref="form" :model="formData" :rules="ruleValidate" :label-width="80">
<input type="hidden" v-model="formData.id"/>
<input type="hidden" v-model="formData.parentId"/>
<FormItem label="名称" prop="title">
<Input v-model="formData.title"></Input>
</FormItem>
<Row>
<Col span="12">
<FormItem label="排序" prop="order">
<Input v-model="formData.order"></Input>
</FormItem>
</Col>
<Col span="12">
<FormItem label="是否展开" prop="expand">
<Checkbox v-model="formData.expand"></Checkbox>
</FormItem>
</Col>
</Row>
<FormItem>
<Button type="primary" @click="handleSubmit('form')">保存</Button>
<Button type="primary" @click="go2list()" style="margin-left: 8px">关闭</Button>
</FormItem>
</Form>
</template>
<script>
import {baseTreeEdit} from '@/libs/crud/base-tree-edit'
export default {
mixins: [baseTreeEdit],
data () {
return {
formData: {
id: '',
parentId: '',
title: '',
order: '',
expand: false
},
ruleValidate: {
title: [
{required: true, message: '名称不能为空', trigger: 'blur'}
]
}
}
}
}
</script>
2 规格参数
2.1 需求分析
2.1.1 SPU和SKU
乐购商城是一个全品类的电商网站,因此商品的种类繁多,每一件商品,其属性又有差别。为了更准确描述商品及细分差别,抽象出两个概念:SPU和SKU,了解一下:
SPU:Standard Product Unit (标准产品单位) ,一组具有共同属性的商品集
SKU:Stock Keeping Unit(库存量单位),SPU商品集因具体特性不同而细分的每个商品
以图为例来看:
- 本页的 华为Mate10 就是一个商品集(SPU)
- 因为颜色、内存等不同,而细分出不同的Mate10,如亮黑色128G版。(SKU)
可以看出:
- SPU是一个抽象的商品集概念,为了方便后台的管理。
- SKU才是具体要销售的商品,每一个SKU的价格、库存可能会不一样,用户购买的是SKU而不是SPU
2.1.2 分析规格参数
仔细查看每一种商品的规格你会发现:
虽然商品规格千变万化,但是同一类商品(如手机)的规格是统一的,有图为证:
华为的规格:
三星的规格:
也就是说,商品的规格参数应该是与分类绑定的。每一个分类都有统一的规格参数模板,但不同商品其参数值可能不同。
如下图所示:
2.1.3 SKU的特有规格
SPU中会有一些特殊属性,用来区分不同的SKU,我们称为SKU特有规格。如华为META10的颜色、内存属性。
不同种类的商品,一个手机,一个衣服,其SKU属性不相同。
同一种类的商品,比如都是衣服,SKU属性基本是一样的,都是颜色、尺码等。
这样说起来,似乎SKU的特有属性也是与分类相关的?事实上,仔细观察你会发现,SKU的特有规格是商品规格参数的一部分:
也就是说,我们没必要单独对SKU的特有属性进行设计,它可以看做是规格参数中的一部分。这样规格参数中的属性可以标记成两部分:
- 所有sku共享的规格属性(称为通用规格)
- 每个sku不同的规格属性(称为特有规格)
2.1.4 搜索属性
打开一个搜索页,我们来看看过滤的条件:
你会发现,过滤条件中的屏幕尺寸、运行内存、网路、机身内存、电池容量、CPU核数等,在规格参数中都能找到:
也就是说,规格参数中的数据,将来会有一部分作为搜索条件来使用。我们可以在设计时,将这部分属性标记出来,将来做搜索的时候,作为过滤条件。要注意的是,无论是SPU的全局属性,还是SKU的特有属性,都有可能作为搜索过滤条件的,并不冲突,而是有一个交集:
2.1.5 功能展示
前端交互方式见管理后台-> 商品管理-> 规格参数
2.2 表结构分析
specgroup 表(规格参数分组)
字段名称 | 字段含义 | 字段类型 | 字段长度 | 备注 |
---|---|---|---|---|
id_ | ID | INT | ||
cid_ | 外键(分类ID) | INT | ||
name_ | 规格参数分组名称 | VARCHAR |
specparam 表( 规格具体项)
字段名称 | 字段含义 | 字段类型 | 字段长度 | 备注 |
---|---|---|---|---|
id_ | ID | INT | ||
cid_ | 外键(分类ID) | INT | ||
groupid | 外键(分组ID) | INT | ||
name_ | 规格项名称 | |||
numeric_ | 是否为数字 | |||
unit_ | 单位 | |||
generic_ | 是否为sku参数 | VARCHAR | false:为sku参数 | |
searching_ | 是否为搜索项 | VARCHAR | 搜索范围选择 | |
sements_ | 排序 | INT |
通过上面需求分析得出商品分类、规格分组、规格参数的关系分别是一对多
2.3 规格参数管理
2.3.1 实体类
legou-item/legou-item-instance/src/main/java/com/lxs/legou/item/po/SpecGroup.java:
package com.lxs.legou.item.po;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableName;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import com.lxs.legou.core.po.BaseEntity;
import lombok.Data;
import java.util.List;
@Data
@TableName("spec_group_")
@JsonIgnoreProperties(value = {
"handler"})
public class SpecGroup extends BaseEntity {
@TableField("cid_")
private Long cid;
@TableField("name_")
private String name;
@TableField(exist = false)
private List<SpecParam> params; // 该组下的所有规格参数集合
}
legou-item/legou-item-instance/src/main/java/com/lxs/legou/item/po/SpecParam.java:
package com.lxs.legou.item.po;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableName;
import com.lxs.legou.core.po.BaseEntity;
import lombok.Data;
@Data
@TableName("spec_param_")
public class SpecParam extends BaseEntity {
@TableField("cid_")
private Long cid;
@TableField("group_id_")
private Long groupId;
@TableField("name_")
private String name;
@TableField("numeric_")
private Boolean numeric;
@TableField("unit_")
private String unit;
@TableField("generic_")
private Boolean generic;
@TableField("searching_")
private Boolean searching;
@TableField("segments_")
private String segments;
}
2.3.2 持久层
DAO
legou-item/legou-item-service/src/main/java/com/lxs/legou/item/dao/SpecGroupDao.java:
package com.lxs.legou.item.dao;
import com.lxs.legou.core.dao.ICrudDao;
import com.lxs.legou.item.po.SpecGroup;
import java.util.List;
public interface SpecGroupDao extends ICrudDao<SpecGroup> {
/**
* 根据实体条件动态查询分组
* @param specGroup
* @return
*/
public List<SpecGroup> selectList(SpecGroup specGroup);
}
legou-item/legou-item-service/src/main/java/com/lxs/legou/item/dao/SpecParamDao.java:
package com.lxs.legou.item.dao;
import com.lxs.legou.core.dao.ICrudDao;
import com.lxs.legou.item.po.SpecParam;
import org.apache.ibatis.annotations.Select;
import java.util.List;
public interface SpecParamDao extends ICrudDao<SpecParam> {
@Select("select * from spec_param_ where group_id_ = #{groupId}")
public List<SpecParam> findByGroupId(Integer groupId);
}
映射文件
legou-item/legou-item-service/src/main/resources/mybatis/item/SpecGroupDao.xml
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.lxs.legou.item.dao.SpecGroupDao">
<sql id="selectSql">
SELECT
*
FROM
spec_group_
</sql>
<select id="selectList" resultMap="groupMap">
<include refid="selectSql"></include>
<where>
<if test="cid != null">
cid_ = #{cid}
</if>
<if test="name !=null and name.trim() != ''">
and rname like '%${name}%'
</if>
</where>
</select>
<resultMap id="groupMap" type="specGroup">
<id column="id_" property="id"></id>
<result property="cid_" column="cid"></result>
<result property="name_" column="name"></result>
<collection property="params" javaType="java.util.List" ofType="specParam" select="com.lxs.legou.item.dao.SpecParamDao.findByGroupId" column="id_">
<id column="id_" property="id"></id>
<result column="cid_" property="cid"></result>
<result column="group_id_" property="groupId"></result>
<result column="name_" property="name"></result>
<result column="numeric_" property="numeric"></result>
<result column="unit_" property="unit"></result>
<result column="generic_" property="generic"></result>
<result column="searching_" property="searching"></result>
</collection>
</resultMap>
<select id="selectById" resultMap="groupMap">
<include refid="selectSql"></include>
where
id_ = #{id}
</select>
</mapper>
2.3.3 业务层
(1)业务层接口
legou-item/legou-item-service/src/main/java/com/lxs/legou/item/service/ISpecGroupService.java:
package com.lxs.legou.item.service;
import com.lxs.legou.core.service.ICrudService;
import com.lxs.legou.item.po.SpecGroup;
import java.util.List;
/**
* @Title: 商品规格参数分组
*/
public interface ISpecGroupService extends ICrudService<SpecGroup> {
/**
* 根据前台传递的规格参数列表,保存规格参数
* @param cid
* @param groups
*/
public void saveGroup(Long cid, List<SpecGroup> groups);
}
legou-item/legou-item-service/src/main/java/com/lxs/legou/item/service/ISpecParamService.java
package com.lxs.legou.item.service;
import com.lxs.legou.core.service.ICrudService;
import com.lxs.legou.item.po.SpecParam;
/**
* @Title: 商品规格参数
* @Description:
*
* @Copyright 2019 lxs - Powered By 雪松
* @Author: lxs
* @Date: 2019/10/9
* @Version V1.0
*/
public interface ISpecParamService extends ICrudService<SpecParam> {
}
(2)业务层实现类
legou-item/legou-item-service/src/main/java/com/lxs/legou/item/service/impl/SpecGroupServiceImpl.java:
package com.lxs.legou.item.service.impl;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.lxs.legou.core.service.impl.CrudServiceImpl;
import com.lxs.legou.item.dao.SpecGroupDao;
import com.lxs.legou.item.dao.SpecParamDao;
import com.lxs.legou.item.po.SpecGroup;
import com.lxs.legou.item.po.SpecParam;
import com.lxs.legou.item.service.ISpecGroupService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.util.List;
@Service
public class SpecGroupServiceImpl extends CrudServiceImpl<SpecGroup> implements ISpecGroupService {
@Autowired
private SpecParamDao specParamDao;
@Override
public List<SpecGroup> list(SpecGroup entity) {
return ((SpecGroupDao) getBaseMapper()).selectList(entity);
}
@Override
@Transactional
public void saveGroup(Long cid, List<SpecGroup> groups) {
//根据cid删除所有规格参数的分组和规格参数
getBaseMapper().delete(Wrappers.<SpecGroup>query().eq("cid_", cid));
specParamDao.delete(Wrappers.<SpecParam>query().eq("cid_", cid));
//逐个添加规格参数分组和规格参数
for (SpecGroup group : groups) {
getBaseMapper().insert(group);
for (SpecParam specParam : group.getParams()) {
specParam.setGroupId(group.getId()); //页面groupId是防止重复自动+1,保存时要保存数据库中groupId
specParamDao.insert(specParam);
}
}
}
}
legou-item/legou-item-service/src/main/java/com/lxs/legou/item/service/impl/SpecParamServiceImpl.java:
package com.lxs.legou.item.service.impl;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.lxs.legou.core.service.impl.CrudServiceImpl;
import com.lxs.legou.item.po.SpecParam;
import com.lxs.legou.item.service.ISpecParamService;
import org.springframework.stereotype.Service;
import java.util.List;
@Service
public class SpecParamServiceImpl extends CrudServiceImpl<SpecParam> implements ISpecParamService {
@Override
public List<SpecParam> list(SpecParam entity) {
QueryWrapper<SpecParam> queryWrapper = Wrappers.<SpecParam>query();
//根据分类id查询规格参数
if (null != entity.getCid()) {
queryWrapper.eq("cid_", entity.getCid());
}
if (null != entity.getSearching()) {
queryWrapper.eq("searching_", entity.getSearching());
}
return getBaseMapper().selectList(queryWrapper);
}
}
2.3.4 控制层
legou-item/legou-item-service/src/main/java/com/lxs/legou/item/controller/SpecGroupController.java:
package com.lxs.legou.item.controller;
import com.lxs.legou.core.controller.BaseController;
import com.lxs.legou.core.po.ResponseBean;
import com.lxs.legou.item.po.SpecGroup;
import com.lxs.legou.item.service.ISpecGroupService;
import io.swagger.annotations.ApiOperation;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.List;
/**
* @Title:
*/
@RestController
@RequestMapping(value = "/group")
public class SpecGroupController extends BaseController<ISpecGroupService, SpecGroup> {
@ApiOperation(value="保存规格参数", notes="保存规格参数")
@PostMapping("/save-group")
public ResponseBean saveGroup(@RequestBody List<SpecGroup> specGroup) throws Exception {
ResponseBean rm = new ResponseBean();
try {
if (specGroup != null && specGroup.size() > 0) {
service.saveGroup(specGroup.get(0).getCid(), specGroup);
}
} catch (Exception e) {
e.printStackTrace();
rm.setSuccess(false);
rm.setMsg("保存失败");
}
return rm;
}
}
legou-item/legou-item-service/src/main/java/com/lxs/legou/item/controller/SpecParamController.java:
package com.lxs.legou.item.controller;
import com.lxs.legou.core.controller.BaseController;
import com.lxs.legou.item.po.SpecParam;
import com.lxs.legou.item.service.ISpecParamService;
import io.swagger.annotations.ApiOperation;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.List;
/**
* @Title:
*/
@RestController
@RequestMapping(value = "/param")
public class SpecParamController extends BaseController<ISpecParamService, SpecParam> {
@ApiOperation(value="查询", notes="根据实体条件查询参数")
@PostMapping(value = "/select-param-by-entity")
public List<SpecParam> selectSpecParamApi(@RequestBody SpecParam entity) {
return service.list(entity);
}
}
2.3.5 功能演示
访问http://localhost:9005/item/group/list?cid=76
2.3.6 前端组件
再次强调,前端vue代码不是我们java程序员的菜,虽然有的小公司JAVA程序员也写前端代码,但是java程序员一般关注在后台Java的实现,前端vue代码了解掌握即可,不必要从0到1,一步一步的写出来,了解语法逻辑,真的有需要,写前端代码,能上手即可,这里规格参数前端组件逻辑比较复杂,给大家讲一下思路,拷贝即可
<template>
<div>
<Tree :data="rows"></Tree>
<Modal v-model="modal" width="800px">
<p slot="header">
<span>{
{category.title}}规格参数</span>
</p>
<Card v-for="(groupItem, groupIndex) in groups" :key="groupIndex">
<p slot="title">
{
{groupItem.name}}
</p>
<a href="#" slot="extra">
<Icon type="ios-trash" @click="deleteGroup(groupItem.id)"></Icon>
</a>
<Collapse>
<Panel v-for="(paramItem, paramIndex) in groupItem.params" :name="`${groupIndex}-${paramIndex}`" :key="paramIndex">
{
{paramItem.name}}
<Icon type="ios-trash" style="float: right;margin-top: 10px" @click="deleteParam(groupItem.id, paramItem.id)"></Icon>
<div slot="content" style="height: 40px;">
<Col span="4">
<Input v-model="paramItem.unit" placeholder="单位"></Input>
</Col>
<Col span="4" style="margin-left: 20px;">
<Input v-model="paramItem.segments" placeholder="搜索范围"></Input>
</Col>
<Col span="4" style="margin-top: 5px; margin-left: 20px;">
数字参数:<i-switch v-model="paramItem.numeric"/>
</Col>
<Col span="4" style="margin-top: 5px; margin-left: 20px;">
搜索参数:<i-switch v-model="paramItem.searching" />
</Col>
<Col span="4" style="margin-top: 5px; margin-left: 20px;">
SKU参数:<i-switch v-model="paramItem.generic"/>
</Col>
</div>
</Panel>
</Collapse>
<br>
<Button @click="addParam(groupItem.id)">添加新属性</Button>
</Card>
<div slot="footer">
<Button type="primary" @click="saveGroup">保存规格模板</Button>
<Button @click="addGroup">添加新分组</Button>
</div>
</Modal>
</div>
</template>
<script>
import {baseTree} from '@/libs/crud/base-tree'
import {listToTree} from '@/libs/util'
import instance from '@/libs/api/index'
import Qs from 'qs'
export default {
mixins: [baseTree],
// 表格各行的数据
data() {
return {
modal: false, //分组对话框弹出标记
category:{},//当前分类,弹出对话框是,显示的分类
groups:[] //规格分组,格式[{id:1,cid:76,name:'主体',params:[...]},{}...]
}
},
methods: {
//保存规格参数
saveGroup() {
instance.post(`/item/group/save-group`,this.groups ,{
headers: {
'Content-Type': 'application/json;charset=UTF-8'
}
}).then(response => {
this.$Message.success(response.data.msg)
this.modal = false
}).catch(error => {
console.log(error)
})
},
//删除参数
deleteParam(gid, pid) {
this.groups.find(item => item.id == gid).params.splice(
this.groups.find(item => item.id == gid).params.findIndex(item => item.id == pid), 1
)
},
//添加新参数
addParam(gid) {
let pname = ''
this.$Modal.confirm({
render: (h) => {
return h('Input', {
props: {
value: pname,
autofocus: true,
placeholder: '请输入分组名称'
},
on: {
input: (val) => {
pname = val;
}
}
})
},
onOk: () => {
this.groups.find(item => item.id == gid).params.push({
name: pname,
cid: this.category.id,
groupId: gid
})
}
})
},
//删除分组
deleteGroup(gid) {
this.groups.splice(this.groups.findIndex(item => item.id == gid), 1)
},
//添加新分组
addGroup() {
let gname = ''
this.$Modal.confirm({
render: (h) => {
return h('Input', {
props: {
value: gname,
autofocus: true,
placeholder: '请输入分组名称'
},
on: {
input: (val) => {
gname = val;
}
}
})
},
onOk: () => {
let mid = 0
if (this.groups && this.groups.length > 0) {
mid = this.groups.map(o => o.id).reduce((a,b) => {
return b > a ? b : a;
}) + 1
}
console.log(mid)
this.groups.push({id: mid, name: gname, cid: this.category.id, params:[]})
}
})
},
// 查询分组
queryGroup(cid) {
instance.post(`/item/group/list`, Qs.stringify({"cid": cid})).then(response => {
this.groups = response.data;
}).catch(error => {
console.log(error)
})
instance.get(`/item/category/edit/${cid}`).then(response => {
this.category = response.data;
}).catch(error => {
console.log(error)
})
},
// 查询分类
query() {
instance.post(`/item/category/list`).then(response => {
this.rows = this.readerLeaf(listToTree(response.data));
}).catch(error => {
console.log(error)
})
},
readerLeaf(data) {
data.forEach(item => {
if (!item.children) {
item = Object.assign(item, {render: this.renderContent});
} else {
this.readerLeaf(item.children)
}
});
return data;
},
renderContent(h, {root, node, data}) {
return h('span', {
style: {
display: 'inline-block',
width: '100%'
}
}, [
h('span', [
h('Icon', {
props: {
type: 'ios-paper-outline'
},
style: {
marginRight: '8px'
}
}),
h('span', data.title)
]),
h('span', {
style: {
display: 'inline-block',
float: 'right',
marginRight: '32px'
}
}, [
h('Button', {
props: Object.assign({}, this.buttonProps, {
icon: 'ios-aperture-outline'
}),
style: {
marginRight: '8px'
},
on: {
click: () => {
this.queryGroup(data.id);
this.modal = true
}
}
})
])
]);
}
}
}
</script>
前端发送的数据