Shopping mall practice project (middle)

1 product specification data structure

1.1spu and sku

SPU: standard product uint, a set of commodities with common properties
SKU: stock keeping unit. Each product in the spu product set is subdivided according to its specific characteristics

1.2. Database design and analysis

1.2.1. Thinking and finding problems

``
id: primary key
Title: title
Description: description
specification: specification
packaging_list: packaging
after_service: after sales service
Comment: comment
category_id: commodity classification
brand_id: brand

Look at SKU again. What fields should it have?

id: primary key
spu_id: associated SPU
Price: price
images: Pictures
Stock: stock
Color?
Memory?
Hard disk?

###1.2.2. Analysis specification parameters
 Take a closer look at the specifications of each product and you will find:

Although the specifications of goods vary greatly, the specifications of the same kind of goods (such as mobile phones) are unified, as shown in the figure:

>Huawei specifications:

 [failed to transfer the pictures in the external link. The source station may have anti-theft chain mechanism. It is recommended to save the pictures and upload them directly (img-9zqCt1Q8-1592723403536)(assets/1526087063700.png))



>Samsung specifications:

 [failed to transfer the pictures in the external link. The source station may have anti-theft chain mechanism. It is recommended to save the pictures and upload them directly (img-woWCwwsB-1592723403540)(assets/1526087142454.png))



###1.2.3. Unique attributes of SKU

There are some special attributes in SPU to distinguish different SKUs. We call them SKU specific attributes. For example, Huawei META10's color and memory attributes.

The SKU attributes of different kinds of goods, a mobile phone and a garment are different.

The same kind of goods, such as clothes, SKU attributes are basically the same, all are colors, sizes, etc.

In this way, it seems that the unique attributes of SKU are also related to classification? In fact, if you look closely, you will find that the unique attributes of * * SKU are part of the product specification parameters * *:

[failed to transfer the pictures in the external link. The source station may have anti-theft chain mechanism. It is recommended to save the pictures and upload them directly (img-z4ywjpqb-1592723403560)(assets/1526088981953.png))

That is to say, we don't need to design the unique attributes of SKU separately. It can be regarded as a part of specification parameters. In this way, the attributes in the specification parameters can be marked in two parts:

-Specification attributes shared by all SKUs under spu (called global attributes)
-Each sku has different specification attributes (called unique attributes)



###1.2.4. Search properties

Open a search page, let's look at the filter conditions:

[failed to transfer the pictures in the external link. The source station may have anti-theft chain mechanism. It is recommended to save the pictures and upload them directly (img-LTm9Gygz-1592723403567)(assets/1526090072535.png))

You will find that the screen size, running memory, network, body memory, battery capacity, CPU cores, etc. in the filter conditions can be found in the specification parameters:

 [failed to transfer the pictures in the external link. The source station may have anti-theft chain mechanism. It is recommended to save the pictures and upload them directly (img-CDRdiwwi-1592723403571)(assets/1526090228171.png))

In other words, some data in the specification parameters will be used as search criteria in the future. We can mark these attributes at design time and use them as filter conditions for future search. It should be noted that both the global attributes of SPU and the unique attributes of SKU can be used as search filter criteria, which are not conflicting, but have an intersection:

 [failed to transfer the pictures in the external link. The source station may have anti-theft chain mechanism. It is recommended to save the pictures and upload them directly (img-0Q7adfjg-1592723403575)(assets/1526091216124.png))



##1.3. Specification and parameter table

###1.3.1. Table structure

Let's look at the format of the specifications:

 [failed to transfer the pictures in the external link. The source station may have anti-theft chain mechanism. It is recommended to save the pictures and upload them directly (img-GxW0Dy1j-1592723403579)(assets/1526092179381.png))

You can see that the specification parameters are grouped, and each group has multiple parameter key value pairs. However, for the template of specification parameter, its value is uncertain now. Different product values must be different. In the template, only the group information and parameter information within the group can be saved.

So we designed two tables:

- tb_spec_group: group, associated with commodity classification
 - tb_spec_param: parameter name, associated with group, one to many



###1.3.2. Specification Group

Specification parameter grouping table: tb_spec_group

```mysql
CREATE TABLE `tb_spec_group` (
  `id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT 'primary key',
  `cid` bigint(20) NOT NULL COMMENT 'commodity classification id, there are multiple specification groups under one classification',
  `name` varchar(50) NOT NULL COMMENT 'the name of the Specification Group',
  PRIMARY KEY (`id`),
  KEY `key_category` (`cid`)
) ENGINE=InnoDB AUTO_INCREMENT=14 DEFAULT CHARSET=utf8 COMMENT = 'grouping table of specification parameters. There are multiple specification parameter groups under each product classification';

The specification group has three fields:

  • id: primary key
  • cid: commodity classification id. there are multiple templates under one classification
  • Name: the name of the specification group.

1.3.2. Specifications

Specification parameter table: tb_spec_param

CREATE TABLE `tb_spec_param` (
  `id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT 'Primary key',
  `cid` bigint(20) NOT NULL COMMENT 'Commodity classification id',
  `group_id` bigint(20) NOT NULL,
  `name` varchar(255) NOT NULL COMMENT 'Parameter name',
  `numeric` tinyint(1) NOT NULL COMMENT 'Is it a numeric type parameter, true or false',
  `unit` varchar(255) DEFAULT '' COMMENT 'The unit of the number type parameter. Non number type can be blank',
  `generic` tinyint(1) NOT NULL COMMENT 'Yes no sku General properties, true or false',
  `searching` tinyint(1) NOT NULL COMMENT 'Is it used for search filtering, true or false',
  `segments` varchar(1000) DEFAULT '' COMMENT 'Numeric type parameter, if you need to search, add the value of segmentation interval, such as CPU Frequency interval: 0.5-1.0',
  PRIMARY KEY (`id`),
  KEY `key_group` (`group_id`),
  KEY `key_category` (`cid`)
) ENGINE=InnoDB AUTO_INCREMENT=24 DEFAULT CHARSET=utf8 COMMENT='Parameter name under specification parameter group';

General properties

Use a boolean type field to mark whether it is universal:

  • generic to mark whether it is a general property:
    • true: for general properties
    • false: represents sku specific properties

Search filtering

There are two fields associated with the search:

  • searching: whether the tag is used for filtering
    • true: used to filter search
    • false: not used for filtering
  • segments: some parameters of numerical type need to be divided according to the interval when searching. Here, the interval should be determined in advance
    • For example, battery capacity, 0200mah, 2000mAh3000mAh, 3000mAh~4000mAh

value type

Some specification parameters may be of numerical type. Only such data needs to be divided into intervals. We have two fields to describe:

  • Numeric: whether it is a numeric type
    • true: value type
    • false: not a numeric type
  • Unit: unit of parameter

2. Commodity specification parameter management

2.1. Page layout

2.1.1. Overall layout

Open the specification parameter page and see the following:
We have done the product classification tree before, so it can be directly displayed here.

Because the specification is bound to the commodity classification, the commodity classification tree will be displayed first, and you will be prompted to select the commodity classification to see the template of the specification parameter. Learn about the implementation of the following pages:
Page structure:
Here, v-layout is used to complete the page layout, and row attribute is added to represent that the next content is row layout (left and right).

You can see that the page is divided into two parts:

  • < v-flex xs3 >: on the left side, the interior is divided into two parts: commodity classification tree and title
    • v-card-title: the title part, here is the prompt message, which tells the user to select the classification first, and then to see the template
    • v-tree: the tree component we talked about before is used to display the commodity classification tree,
  • < v-flex xs9 class = "px-1" >

2.1.2. Right side specification

When we click a category, the final effect is:

You can see that the right side is divided into two parts:

  • Top: breadcrumbs, showing the currently selected category
  • Lower part: table, display specification parameter information

Page implementation:
You can see that the right side is not the familiar v-data-table, but a spec group component (Specification Group) and a spec param component (specification parameter), which are independent components defined by us:
Tables are defined in SpecGroup:

[failed to transfer the pictures in the external link. The source station may have anti-theft chain mechanism. It is recommended to save the pictures and upload them directly (img-iAwJzOJn-1592723403593)(assets/1528427514717.png))

2.2. Query of Specification Group

2.2.1. Click event of tree node

When we click the tree node, to open the v-dialog, we must bind a click event:( Specification.vue )
Let's look at the handleClick method:( Specification.vue )
When the click event occurs, two things happen:

  • Record the currently selected node. The selected node is the commodity classification
  • If showGroup is set to true, the specification group will be displayed.
    At the same time, we pass the id of the selected node (commodity classification) to the SpecGroup component:( Specification.vue )

2.2.2. Page query specification group

Let's see SpecGroup.vue Implementation in:

2.2.3. Back end code

Entity class

Add entity class in item interface:
Content:

@Table(name = "tb_spec_group")
public class SpecGroup {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    private Long cid;

    private String name;

    @Transient
    private List<SpecParam> params;

   // getter and setter omitted
}
@Table(name = "tb_spec_param")
public class SpecParam {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;
    private Long cid;
    private Long groupId;
    private String name;
    @Column(name = "`numeric`")
    private Boolean numeric;
    private String unit;
    private Boolean generic;
    private Boolean searching;
    private String segments;
    
    // getter and setter
}

Write business in l-item-service:

mapper

public interface SpecGroupMapper extends Mapper<SpecGroup> {
}

controller

First, analyze what you need. In the ajax request of the page, you can see:

  • Request method: get

  • The request path is: / spec/groups/{cid}, where the id of the commodity classification is passed through the path placeholder

  • Request parameter: commodity classification id

  • Return result: the page is directly resp.data Assigned to groups:
    Then we should return the set of SpecGroup
    code:

@RestController
@RequestMapping("spec")
public class SpecificationController {

    @Autowired
    private SpecificationService specificationService;

    /**
     * Query grouping according to classification id
     * @param cid
     * @return
     */
    @GetMapping("groups/{cid}")
    public ResponseEntity<List<SpecGroup>> queryGroupsByCid(@PathVariable("cid")Long cid){
        List<SpecGroup> groups = this.specificationService.queryGroupsByCid(cid);
        if (CollectionUtils.isEmpty(groups)){
            return ResponseEntity.notFound().build();
        }
        return ResponseEntity.ok(groups);
    }
}

service

@Service
public class SpecificationService {

    @Autowired
    private SpecGroupMapper groupMapper;

    /**
     * Query grouping according to classification id
     * @param cid
     * @return
     */
    public List<SpecGroup> queryGroupsByCid(Long cid) {
        SpecGroup specGroup = new SpecGroup();
        specGroup.setCid(cid);
        return this.groupMapper.select(specGroup);
    }
}

Page access test:

At present, our database only provides specification groups for mobile phone classification (76):

2.3. Specification parameter query

2.3.1. Table switching

When we click the specification group, we will switch to the specification parameter display. It is certain that the click event is bound in the specification group:
Let's look at the event handling:
You can see that parent-child communication is used here, and the child component triggers the select event:
Let's look at the event binding of the parent component:
Event handling:
Here we record the selected group and set the flag to false, so that the specification group will not be displayed, but will display: SpecParam
In addition, we also pass the group to the spec param component:

2.3.2. Page query specification parameters

Let's see SpecParam.vue Implementation of:

2.3.3. Background implementation

SpecificatinController
analysis:

  • Request method: GET
  • Request path / spec/params
  • Request parameter: gid, group id
  • Return result: List < specparam >

code:

/**
     * Query specification parameters based on criteria
     * @param gid
     * @return
     */
@GetMapping("params")
public ResponseEntity<List<SpecParam>> queryParams(@RequestParam("gid")Long gid){
    List<SpecParam>  params = this.specificationService.queryParams(gid);
    if (CollectionUtils.isEmpty(params)){
        return ResponseEntity.notFound().build();
    }
    return ResponseEntity.ok(params);
}

SpecificationService

@Autowired
private SpecParamMapper paramMapper;

/**
     * Query specification parameters based on criteria
     * @param gid
     * @return
     */
public List<SpecParam> queryParams(Long gid) {
    SpecParam param = new SpecParam();
    param.setGroupId(gid);
    return this.paramMapper.select(param);
}

SpecParamMapper

[failed to transfer the pictures in the external link. The source station may have anti-theft chain mechanism. It is recommended to save the pictures and upload them directly (img-Em744tuG-1592723403641)(assets/1543383516456.png))

public interface SpecParamMapper extends Mapper<SpecParam> {
}

3.SPU and SKU data structure

After the specification is determined, you can add products. First, look at the database table

3.1.SPU table

SPU table:

CREATE TABLE `tb_spu` (
  `id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT 'spu id',
  `title` varchar(255) NOT NULL DEFAULT '' COMMENT 'title',
  `sub_title` varchar(255) DEFAULT '' COMMENT 'subtitle',
  `cid1` bigint(20) NOT NULL COMMENT '1 Class A id',
  `cid2` bigint(20) NOT NULL COMMENT '2 Class A id',
  `cid3` bigint(20) NOT NULL COMMENT '3 Class A id',
  `brand_id` bigint(20) NOT NULL COMMENT 'Brand of goods id',
  `saleable` tinyint(1) NOT NULL DEFAULT '1' COMMENT 'Whether to put it on the rack, 0 to put it off, 1 to put it on the rack',
  `valid` tinyint(1) NOT NULL DEFAULT '1' COMMENT 'Valid, 0 deleted, 1 valid',
  `create_time` datetime DEFAULT NULL COMMENT 'Add time',
  `last_update_time` datetime DEFAULT NULL COMMENT 'Last modified',
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=208 DEFAULT CHARSET=utf8 COMMENT='spu Table, which describes an abstract commodity, such as iphone8';

It seems that some fields are missing, such as product description.
Split the table vertically and put the details of SPU in another table: tb_spu_detail

CREATE TABLE `tb_spu_detail` (
  `spu_id` bigint(20) NOT NULL,
  `description` text COMMENT 'Product description',
  `generic_spec` varchar(10000) NOT NULL DEFAULT '' COMMENT 'General specification parameter data',
  `special_spec` varchar(1000) NOT NULL COMMENT 'Specific specification parameters and optional value information, json format',
  `packing_list` varchar(3000) DEFAULT '' COMMENT 'Packing list',
  `after_service` varchar(3000) DEFAULT '' COMMENT 'after-sale service',
  PRIMARY KEY (`spu_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

The data in this table is relatively large. In order not to affect the query efficiency of the main table, we split this table.

Note these two fields: generic_spec and special_spec.

As mentioned earlier, specification parameters are bound to commodity classification. All spus under one classification have similar specification parameters. SKU s under SPU may have different specification parameter information, so our plan is as follows:

  • General specification parameter information is saved in SPUDetail.
  • Special specification parameters are saved in SKU.

Let's see how our tables store this information.

3.1.1.generic_spec field

First, generic_spec, in which the values of general specification parameter information are saved. In order to facilitate query, json format is used here:

Overall:

[failed to transfer the pictures in the external link. The source station may have anti-theft chain mechanism. It is recommended to save the pictures and upload them directly (img-4QmLqAJ2-1592723403646)(assets/1529554390912.png))

json structure, where are key value pairs:

  • key: spec of the corresponding specification parameter_ id of param
  • Value: the value of the corresponding specification parameter

3.1.2.special_spec field

We say that only general specification parameters are saved in spu, so why there is an extra special_ What about the spec field?
Take mobile phones for example. Brands, operating systems, etc. must be global common attributes, and memory, color, etc. must be unique attributes.
When you determine an SPU, such as Xiaomi's: red rice 4X
Global attribute values are fixed:

Brand: millet
 Model: red rice 4X

Examples of unique attributes:

Color: [champagne gold, cherry powder, frosted black]
Memory: [2G, 3G]
Airframe storage: [16GB, 32GB]

Color, memory and fuselage storage are special attributes of SKUs. Although the key is the same, the values of each SKU under the SPU are different, so there will be many values, forming an array.

In SPU, we will record all the values of the unique attributes to form an array:

What's in it?
The data structure is also a json structure:

  • key: specification parameter id
  • value: array of spu properties
    So the question is: the specific specification parameters should be recorded in sku. Why should they also be recorded in spu?
    Because sometimes we need to query all the specification parameters instead of only one sku property. For example, when the product details page displays optional specification parameters:

3.2 SKU table

CREATE TABLE `tb_sku` (
  `id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT 'sku id',
  `spu_id` bigint(20) NOT NULL COMMENT 'spu id',
  `title` varchar(255) NOT NULL COMMENT 'Product title',
  `images` varchar(1000) DEFAULT '' COMMENT 'Pictures of products, multiple pictures with','division',
  `price` bigint(15) NOT NULL DEFAULT '0' COMMENT 'Sales price in points',
  `indexes` varchar(100) COMMENT 'The specific specification attributes are spu Corresponding subscript combination in attribute template',
  `own_spec` varchar(1000) COMMENT 'sku Specific specifications and parameters of, json format',
  `enable` tinyint(1) NOT NULL DEFAULT '1' COMMENT 'Is it valid, 0 is invalid, 1 is valid',
  `create_time` datetime NOT NULL COMMENT 'Add time',
  `last_update_time` datetime NOT NULL COMMENT 'Last modified',
  PRIMARY KEY (`id`),
  KEY `key_spu_id` (`spu_id`) USING BTREE
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='sku surface,This table represents specific commodity entities,Like the black 64 GB Of iphone 8';

``
//There is also a table representing inventory:

```mysql
CREATE TABLE `tb_stock` (
  `sku_id` bigint(20) NOT NULL COMMENT 'Goods corresponding to inventory sku id',
  `seckill_stock` int(9) DEFAULT '0' COMMENT 'Second kill inventory',
  `seckill_total` int(9) DEFAULT '0' COMMENT 'Total number of seconds',
  `stock` int(9) NOT NULL COMMENT 'Inventory quantity',
  PRIMARY KEY (`sku_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='Inventory table, representing inventory, seckill inventory and other information';

Question: why do you want to separate the inventory into a single table?

Because the write frequency of inventory field is high, and the other fields of SKU are read-only, we separate the two tables, so the read-write will not interfere.
Note in particular the indexes field and own in the SKU table_ Spec field. In sku, the values of specific specification parameters should be saved, just in these two fields.

3.2.1.indexes field

In the SPU table, special specifications and options have been saved. The structure is as follows:

{
    "4": [
        "Champagne gold",
        "Cherry Blossom powder",
        "Matte black"
    ],
    "12": [
        "2GB",
        "3GB"
    ],
    "13": [
        "16GB",
        "32GB"
    ]
}

If these unique attributes are arranged and combined, 12 different SKUs will be generated. The attributes of different SKUs are one of the options above.
For example:

  • Red rice 4X, champagne gold, 2GB memory, 16GB storage
  • Red rice 4X, matte black, 2GB memory, 32GB storage

You will find that each attribute value corresponds to an option of SPUoptions array. If we record the corner mark, it is as follows:

  • Red rice 4X, 0,0,0
  • Red rice 4X, 2,0,1

In this case, can we connect different corner marks in series as the marks of different SKU s under the SPU. This is our indexes field.

3.2.2.own_spec field

See structure:

{"4":"Champagne gold","12":"2GB","13":"16GB"}

The key value pair of the unique attribute is saved.
What is saved in the SPU is optional, but the specific value is not determined, and what is saved in the SKU is the specific value.

3.3. Import picture information

Now, although there is data in the commodity table, all the picture information cannot be accessed. We need to import the picture into the virtual machine:
Then, use the command to extract:

unzip images.zip

Modify nginx configuration to make nginx reverse proxy these image addresses:

vim /opt/nginx/config/nginx.conf

Modify to the following configuration:

server {
    listen       80;
    server_name  image.leyou.com;

    # Those with group in the listening domain name will be handed over to FastDFS module for processing
    location ~/group([0-9])/ {
        ngx_fastdfs_module;
    }
    # Point other image agents to the local / leyou/static directory
    location / {
        root   /leyou/static/;
    }

    error_page   500 502 503 504  /50x.html;
    location = /50x.html {
        root   html;
    }

}

Don't forget to reload nginx configuration

nginx -s reload

4. Commodity query

4.2. Page request

First look at the overall page structure( Goods.vue ):
After the Vue instance is mounted, a query will be initiated (mounted calls the getDataFromServer method to initialize the data):
When we refresh the page, we can see that the browser initiates a request to query the product data

4.3. Interface provided by background

The page is ready. Next, it provides paging query SPU function in the background.

4.3.1. Entity class

Add an entity class to the Leyou item interface project

SPU

@Table(name = "tb_spu")
public class Spu {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;
    private Long brandId;
    private Long cid1;// Class 1
    private Long cid2;// Class 2
    private Long cid3;// Class 3
    private String title;// title
    private String subTitle;// subtitle
    private Boolean saleable;// Is it on the shelf
    private Boolean valid;// Valid or not, for logical deletion
    private Date createTime;// Creation time
    private Date lastUpdateTime;// Last modified
	// Omit getter and setter
}

SPU details

@Table(name="tb_spu_detail")
public class SpuDetail {
    @Id
    private Long spuId;// id of the corresponding SPU
    private String description;// Product description
    private String specialSpec;// Name and optional value template of special product specification
    private String genericSpec;// Global specification properties of goods
    private String packingList;// Packing list
    private String afterService;// after-sale service
    // Omit getter and setter
}

``
### 4.4.2.mapper
```java
public interface SpuMapper extends Mapper<Spu> {
}

4.3.3.controller

Analyze first:

  • Request method: GET

  • Request path / spu/page

  • Request parameters:

    • Page: current page
    • rows: size per page
    • key: filter condition
    • saleable: on or off the shelf
  • Return result: page information of product SPU.

    • It should be noted that the page displays the product classification and brand name, while the database stores the id. what should I do?

      We can create a new class, inherit SPU, extend cname and bname attributes, and write to Leyou item interface

      public class SpuBo extends Spu {
      
          String cname;// Commodity classification name
          
          String bname;// Brand name
          
          // Omitted..
      }
      
      

Write controller code:

We put all the business interfaces related to commodities together, named GoodsController, and so does the business layer

@Controller
public class GoodsController {

    @Autowired
    private GoodsService goodsService;

    @GetMapping("spu/page")
    public ResponseEntity<PageResult<SpuBo>> querySpuBoByPage(
            @RequestParam(value = "key", required = false)String key,
            @RequestParam(value = "saleable", required = false)Boolean saleable,
            @RequestParam(value = "page", defaultValue = "1")Integer page,
            @RequestParam(value = "rows", defaultValue = "5")Integer rows
    ){
        PageResult<SpuBo> pageResult = this.goodsService.querySpuBoByPage(key, saleable, page, rows);
        if(CollectionUtils.isEmpty(pageResult.getItems())){
            return ResponseEntity.notFound().build();
        }
        return ResponseEntity.ok(pageResult);
    }

}

4.4.4.service

All commodity related businesses (including SPU and SKU) are put under one business: GoodsService.

@Service
public class GoodsService {

    @Autowired
    private SpuMapper spuMapper;

    @Autowired
    private CategoryService categoryService;

    @Autowired
    private BrandMapper brandMapper;

    public PageResult<SpuBo> querySpuBoByPage(String key, Boolean saleable, Integer page, Integer rows) {

        Example example = new Example(Spu.class);
        Example.Criteria criteria = example.createCriteria();
        // search criteria
        if (StringUtils.isNotBlank(key)) {
            criteria.andLike("title", "%" + key + "%");
        }
        if (saleable != null) {
            criteria.andEqualTo("saleable", saleable);
        }

        // Paging conditions
        PageHelper.startPage(page, rows);

        // Execute query
        List<Spu> spus = this.spuMapper.selectByExample(example);
        PageInfo<Spu> pageInfo = new PageInfo<>(spus);

        List<SpuBo> spuBos = new ArrayList<>();
        spus.forEach(spu->{
            SpuBo spuBo = new SpuBo();
            // copy the value of the common property to the new object
            BeanUtils.copyProperties(spu, spuBo);
            // Query classification name
            List<String> names = this.categoryService.queryNamesByIds(Arrays.asList(spu.getCid1(), spu.getCid2(), spu.getCid3()));
            spuBo.setCname(StringUtils.join(names, "/"));

            // Query brand name
            spuBo.setBname(this.brandMapper.selectByPrimaryKey(spu.getBrandId()).getName());

            spuBos.add(spuBo);
        });

        return new PageResult<>(pageInfo.getTotal(), spuBos);

    }
}

4.4.5. Expand the function of query name in category

The page needs to query the classification name of goods here, so it needs to provide the function of querying the classification name additionally,

Add features in CategoryService:

public List<String> queryNamesByIds(List<Long> ids) {
    List<Category> list = this.categoryMapper.selectByIdList(ids);
    List<String> names = new ArrayList<>();
    for (Category category : list) {
        names.add(category.getName());
    }
    return names;
    // return list.stream().map(category -> category.getName()).collect(Collectors.toList());
}

The mapper's selectByIdList method comes from the generic mapper. However, we need to inherit a common mapper interface on mapper:

public interface CategoryMapper extends Mapper<Category>, SelectByIdListMapper<Category, Long> { 

}

4.5. Testing

Refresh the page to see the effect

Tags: Vue Nginx Attribute JSON

Posted on Sun, 21 Jun 2020 05:49:22 -0400 by KevMull