We can create products related to a specific merchant type user.

Update product.xml

Copy and paste the following content into ProductMapper.java under the service/src/resources/mapper directory:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
<?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="co.dongchen.shop.mapper.ProductMapper">
    <sql id="productFields">
        p.id, p.created_at, p.updated_at, p.sku, p.name, p.stock, p.price, p.is_enabled, p.images, p.description, p.user_id
    </sql>
    <sql id="whereCondition">
        <where>
            <if test="productCondition.id != null and productCondition.id != 0">
                and p.id = #{productCondition.id}
            </if>
            <!-- NEWLY ADDED CODE 1 BEGIN -->
            <if test="productCondition.userId != null and productCondition.userId != 0">
                and p.user_id = #{productCondition.userId}
            </if>
            <!-- NEWLY ADDED CODE 1 END -->
            <if test="productCondition.isEnabled != null and productCondition.isEnabled == true">
                and p.is_enabled = 1
            </if>
            <if test="productCondition.isEnabled != null and productCondition.isEnabled == false">
                and p.is_enabled = 0
            </if>
            <if test="productCondition.name != null and productCondition.name != ''">
                <bind name="likeName" value="'%' + productCondition.name + '%'"/>
                and p.name like #{likeName}
            </if>
            <if test="productCondition.ids != null and productCondition.ids.size() > 0 ">
                and p.id in
                <foreach collection="productCondition.ids" item="item" index="index" open="(" separator="," close=")" >
                    #{item}
                </foreach>
            </if>
        </where>
    </sql>
    <select id="queryPagedProducts" resultType="product">
        select <include refid="productFields"/>
        from product p
        <include refid="whereCondition"/>
        <choose>
            <when test="productCondition.orderBy != null and productCondition.orderBy == 'created_at'">
                order by p.created_at desc
            </when>
        </choose>
        <if test="pageHelperCondition.offSet != null and pageHelperCondition.limit != null">
            limit #{pageHelperCondition.offSet},#{pageHelperCondition.limit}
        </if>
        <if test="pageHelperCondition.offSet == null and pageHelperCondition.limit != null">
            limit #{pageHelperCondition.limit}
        </if>
    </select>
    <select id="queryPagedCount" resultType="long">
        select count(id)
        from product p
        <include refid="whereCondition"/>
    </select>

    <!-- NEWLY ADDED CODE 2 BEGIN -->
    <insert id="insert" useGeneratedKeys="true" keyProperty="id" >
        insert into product(
            created_at, updated_at, sku, name, stock, price, images, description, user_id
        ) value (
            #{createdAt}, #{updatedAt}, #{sku}, #{name}, #{stock}, #{price}, #{images}, #{description}, #{userId}
        )
    </insert>
    <!-- NEWLY ADDED CODE 2 END -->
</mapper>

Update UserService

Replace the original content with the following one in the UserService.java file under the service/src/main/java/co.dongchen.shop/service directory:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
package co.dongchen.shop.service;

import co.dongchen.shop.common.model.User;
import co.dongchen.shop.common.util.BeanHelper;
import co.dongchen.shop.mapper.UserMapper;
import com.google.common.collect.Lists;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;

@Service
public class UserService {

    @Value("${fileserver.img_path}")
    private String imgPath;

    @Autowired
    private BCryptPasswordEncoder bCryptPasswordEncoder;

    @Autowired
    private MailService mailService;

    @Autowired
    private UserMapper userMapper;

    @Autowired
    private FileService fileService;

    public List<User> getUsers() {
        return userMapper.queryUsers();
    }

    @Transactional(rollbackFor = Exception.class)
    public boolean register(User user) {
        user.setPassword(bCryptPasswordEncoder.encode(user.getPassword()));
        List<String> imgs = fileService.getImgPath(Lists.newArrayList(user.getAvatarFile()));
        if ( ! imgs.isEmpty() ) {
            System.out.println(imgs.get(0));
            user.setAvatar(imgs.get(0));
        }
        BeanHelper.setDefaultProp(user, User.class);
        BeanHelper.onInsert(user);
        user.setIsEnabled(0);
        user.setType(1);
        userMapper.insert(user);
        mailService.registerNotification(user.getEmail());
        return true;
    }

    public boolean enable(String key) {
        return mailService.enable(key);
    }

    public User authenticate(String email, String password) {
        User user = new User();
        user.setEmail(email);
        user.setIsEnabled(1);
        List<User> list = queryUserByCondition(user);
        if ( ! list.isEmpty() && bCryptPasswordEncoder.matches(password, list.get(0).getPassword()) ) {
            return list.get(0);
        }
        return null;
    }

    public List<User> queryUserByCondition(User user) {
        List<User> list = userMapper.queryUsersByCondition(user);
        list.forEach(u -> u.setAvatar(imgPath + u.getAvatar()));
        return list;
    }

    public void update(User user, String email) {
        user.setEmail(email);
        BeanHelper.onUpdate(user);
        userMapper.update(user);
    }

    // NEWLY ADDED CODE BEGIN
    public List<User> queryUsers(User user) {
        return userMapper.queryUsersByCondition(user);
    }
    // NEWLY ADDED CODE END

}

Update ProductService

Replace the original content with the following one in the ProductService.java file under the service/src/main/java/co.dongchen.shop/service directory:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
package co.dongchen.shop.service;

import co.dongchen.shop.common.model.Product;
import co.dongchen.shop.common.util.BeanHelper;
import co.dongchen.shop.common.util.PageHelper;
import co.dongchen.shop.common.util.pager.PagingData;
import co.dongchen.shop.mapper.ProductMapper;
import com.google.common.base.Joiner;
import com.google.common.collect.Lists;
import org.apache.commons.collections.CollectionUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import java.util.List;
import java.util.stream.Collectors;

@Service
public class ProductService {

    @Value("${fileserver.img_path}")
    private String imgPath;

    // NEWLY ADDED CODE 1 BEGIN
    @Autowired
    private FileService fileService;
    // NEWLY ADDED CODE 1 END

    @Autowired
    private ProductMapper productMapper;

    public PagingData<Product> getProducts(Product productCondition, PageHelper pageHelper) {
        List<Product> products = Lists.newArrayList();
        products = queryWithImgs(productCondition, pageHelper);
        Long count = productMapper.queryPagedCount(productCondition);
        return PagingData.initPaging(products, count, pageHelper.getPageSize(), pageHelper.getPageNumber());
    }

    public List<Product> queryWithImgs(Product productCondition, PageHelper pageHelper) {
        List<Product> products = productMapper.queryPagedProducts(productCondition, pageHelper);
        products.forEach(p -> {
            p.setMainImage(imgPath + p.getMainImage());
            p.setImageList(p.getImageList().stream().map(img -> imgPath + img).collect(Collectors.toList()));
        });
        return products;
    }

    public Product getProductById(Long id) {
        Product productCondition = new Product();
        productCondition.setId(id);
        List<Product> products = queryWithImgs(productCondition, PageHelper.init(1, 1));
        if (! products.isEmpty()) {
            return products.get(0);
        }
        return null;
    }

    // NEWLY ADDED CODE 2 BEGIN
    public void addProduct(Product product) {
        if (CollectionUtils.isNotEmpty(product.getImageFiles())) {
            String imagePaths = Joiner.on(",").join(fileService.getImgPath(product.getImageFiles()));
            product.setImages(imagePaths);
        }
        BeanHelper.setDefaultProp(product, Product.class);
        BeanHelper.onInsert(product);
        productMapper.insert(product);
    }
    // NEWLY ADDED CODE 2 END
}

Update ProductController

Replace the original content with the following one in the ProductController.java file under the controller/src/main/java/co.dongchen.shop/controller directory:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
package co.dongchen.shop.controller;

import co.dongchen.shop.common.model.Product;
import co.dongchen.shop.common.model.User;
import co.dongchen.shop.common.util.PageHelper;
import co.dongchen.shop.common.util.pager.PagingData;
import co.dongchen.shop.interceptor.UserContext;
import co.dongchen.shop.service.MerchantService;
import co.dongchen.shop.service.ProductService;
import co.dongchen.shop.service.TopProductService;
import co.dongchen.shop.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.RequestMapping;

import java.util.List;

@Controller
public class ProductController {

    @Autowired
    private ProductService productService;

    @Autowired
    private MerchantService merchantService;

    @Autowired
    private TopProductService topProductService;

    // NEWLY ADDED CODE 1 BEGIN
    @Autowired
    private UserService userService;
    // NEWLY ADDED CODE 1 END

    @RequestMapping("/product/pagination")
    public String pagination(PageHelper pageHelper, Product productCondition, ModelMap modelMap) {
        PagingData<Product> pageData = productService.getProducts(productCondition, PageHelper.init(pageHelper.getPageSize(), pageHelper.getPageNumber()));
        modelMap.put("pageData", pageData);
        modelMap.put("productCondition", productCondition);
        return "/product/pagination";
    }

    @RequestMapping("product/info")
    public String productInfo(Long id, ModelMap modelMap) {
        Product product = productService.getProductById(id);
        topProductService.increase(id);
        if (product.getUserId() != null && ! product.getUserId().equals(0L)) {
            modelMap.put("merchant", merchantService.getMerchantById(product.getUserId()));
        }
        List<Product> topProducts = topProductService.getTopProducts(5);
        modelMap.put("topProducts", topProducts);
        modelMap.put("product", product);
        return "/product/info";
    }

    // NEWLY ADDED CODE 2 BEGIN
    @RequestMapping("product/add")
    public String add(ModelMap modelMap) {
        User user = new User();
        user.setType(2);    // Only list Merchants
        modelMap.put("users", userService.queryUsers(user));
        return "/product/add";
    }

    @RequestMapping("product/addAction")
    public String addAction(Product product) {
        productService.addProduct(product);
        return "redirect:/product/merchant_product?userId=" + product.getUserId();
    }

    @RequestMapping("product/merchant_product")
    public String merchant_product(PageHelper pageHelper, Product product, ModelMap modelMap) {
        modelMap.put("pageData", productService.getProducts(product, PageHelper.init(pageHelper.getPageSize(), pageHelper.getPageNumber())));
        return "/product/merchant_product";
    }
    // NEWLY ADDED CODE 2 END
}

Create Add Product Template

  • Right click controller/src/main/resources/templates/product directory: New > File
  • Fill in “add.ftl”
  • Press Enter key to continue
img

After inputting the name, press Enter.

Copy and paste the following content into add.ftl:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
<html lang="en-NZ">
<@common.header/>
<body>
<form method="post" enctype="multipart/form-data" action="/product/addAction">
    <div>
        <label>Sku</label>
        <input type="text" name="sku" required>
    </div>
    <div>
        <label>Name</label>
        <input type="text" name="name" required>
    </div>
    <div>
        <label>Stock</label>
        <input type="number" name="stock" required>
    </div>
    <div>
        <label>Price</label>
        <input type="number" name="price" required>
    </div>
    <div>
        <label>Merchant</label>
        <select name="userId">
            <#foreach user in users>
                <option value="${user.id}">${user.firstName} ${user.lastName}</option>
            </#foreach>
        </select>
    </div>
    <div>
        <label>Images</label>
        <input type="file" accept="image/jpeg,image/png" name="imageFiles" multiple="true" required>
    </div>
    <div>
        <label>Description</label>
        <input type="text" name="description" required>
    </div>
    <div>
        <button type="submit">Add</button>
    </div>
</form>
</body>
<@common.footer/>
</html>

Create Merchant Product Template

  • Right click controller/src/main/resources/templates/product directory: New > File
  • Fill in “merchant_product.ftl”
  • Press Enter key to continue
img

After inputting the name, press Enter.

Copy and paste the following content into merchant_product.ftl:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
<h1>Merchant's Product</h1>
<div>
    <#foreach product in pageData.list>
        <div>
            <p>${product.name}</p>
        </div>
    </#foreach>
</div>
<div>
    <@common.paging pageData.pagination/>
</div>
<@common.js/>

Verify

Run the App

1
2
// Short Cut for "Run the Program"
Alt + Shift + F10
img

Choose the correspondent option and press enter.

View Add Product Page in the Browser

1
http://localhost:8080/product/add
  • Fill in the Information:
img
  • Click the “Merchant” dropdown select menu, select the second user:
img
  • Click on “Add” button and it should redirect us to Merchant’s Product page:
img

Buy me a coffeeBuy me a coffee