商品列表功能 +商品列表详情

GoodsController

  1. package com.duing.controller;
  2. import com.duing.model.Goods;
  3. import com.duing.service.GoodsService;
  4. import com.duing.vo.GoodsDetailVo;
  5. import com.duing.vo.GoodsVo;
  6. import org.springframework.beans.factory.annotation.Autowired;
  7. import org.springframework.stereotype.Controller;
  8. import org.springframework.ui.Model;
  9. import org.springframework.web.bind.annotation.GetMapping;
  10. import org.springframework.web.bind.annotation.PathVariable;
  11. import org.springframework.web.bind.annotation.RestController;
  12. import java.util.List;
  13. @Controller
  14. public class GoodsController {
  15. @Autowired
  16. private GoodsService goodsService;
  17. @GetMapping("/")
  18. public String list(Model model) {
  19. List<GoodsVo> voList = goodsService.getGoods();
  20. model.addAttribute("voList",voList);
  21. return "list";
  22. }
  23. @GetMapping("/goodsDetail/{goodsId}")
  24. public String goodsDetail(Model model, @PathVariable String goodsId){
  25. GoodsDetailVo goodsDetailVo= goodsService.goodsDetail(goodsId);
  26. Date startTime=goodsDetailVo.getStartTime();
  27. Date endTime=goodsDetailVo.getEndTime();
  28. Date nowTime=new Date();
  29. int status,remainSeconds=-1;
  30. if (nowTime.before(startTime)){
  31. status=0;
  32. remainSeconds=(int)((startTime.getTime()- nowTime.getTime())/1000);
  33. }else if (nowTime.after(endTime)){
  34. status=2;
  35. remainSeconds=(int)((endTime.getTime()- nowTime.getTime())/1000);
  36. }else {
  37. status=1;
  38. }
  39. model.addAttribute("detailVo",goodsDetailVo);
  40. model.addAttribute("status",status);
  41. model.addAttribute("remainSeconds",remainSeconds);
  42. return "detail";
  43. }
  44. }

GoodsMapper

  1. package com.duing.mapper;
  2. import com.duing.model.Goods;
  3. import org.apache.ibatis.annotations.Mapper;
  4. import java.util.List;
  5. @Mapper
  6. public interface GoodsMapper {
  7. List<Goods> getGoods();
  8. Goods getGoodsById(String goodsId);
  9. }

SeckillGoodsMapper

  1. package com.duing.mapper;
  2. import com.duing.model.SeckillGoods;
  3. import org.apache.ibatis.annotations.Mapper;
  4. @Mapper
  5. public interface SeckillGoodsMapper {
  6. SeckillGoods getSeckillGoodsById(String goodsId);
  7. }

Goods

  1. package com.duing.model;
  2. import lombok.AllArgsConstructor;
  3. import lombok.Data;
  4. import lombok.NoArgsConstructor;
  5. @Data
  6. @AllArgsConstructor
  7. @NoArgsConstructor
  8. public class Goods {
  9. private long id;
  10. private String goodsId;
  11. private String goodsName;
  12. private String goodsType;
  13. private Double price;
  14. private String imgPath;
  15. }

SeckillGoods

  1. package com.duing.model;
  2. import lombok.AllArgsConstructor;
  3. import lombok.Data;
  4. import lombok.NoArgsConstructor;
  5. import java.util.Date;
  6. @Data
  7. @AllArgsConstructor
  8. @NoArgsConstructor
  9. public class SeckillGoods {
  10. private long id;
  11. private String goodsId;
  12. private Double seckillPrice;
  13. private int stockNum;
  14. private Date startTime;
  15. private Date endTime;
  16. }

GoodsServiceImpl

  1. package com.duing.service.impl;
  2. import com.duing.mapper.GoodsMapper;
  3. import com.duing.mapper.SeckillGoodsMapper;
  4. import com.duing.model.Goods;
  5. import com.duing.model.SeckillGoods;
  6. import com.duing.service.GoodsService;
  7. import com.duing.vo.GoodsDetailVo;
  8. import com.duing.vo.GoodsVo;
  9. import org.springframework.beans.BeanUtils;
  10. import org.springframework.beans.factory.annotation.Autowired;
  11. import org.springframework.stereotype.Service;
  12. import java.util.ArrayList;
  13. import java.util.List;
  14. @Service
  15. public class GoodsServiceImpl implements GoodsService {
  16. @Autowired
  17. private GoodsMapper goodsMapper;
  18. @Autowired
  19. private SeckillGoodsMapper seckillGoodsMapper;
  20. @Override
  21. public List<GoodsVo> getGoods() {
  22. List<Goods> goodsList=goodsMapper.getGoods();
  23. List<GoodsVo> voList=new ArrayList<>();
  24. for (Goods goods:goodsList){
  25. GoodsVo vo=new GoodsVo();
  26. BeanUtils.copyProperties(goods,vo);
  27. System.out.println(vo.getGoodsId());
  28. SeckillGoods seckillGoods= seckillGoodsMapper.getSeckillGoodsById(vo.getGoodsId());
  29. BeanUtils.copyProperties(seckillGoods,vo);
  30. voList.add(vo);
  31. }
  32. return voList;
  33. }
  34. @Override
  35. public GoodsDetailVo goodsDetail(String goodsId) {
  36. Goods goods= goodsMapper.getGoodsById(goodsId);
  37. SeckillGoods seckillGoods= seckillGoodsMapper.getSeckillGoodsById(goodsId);
  38. GoodsDetailVo vo=new GoodsDetailVo();
  39. BeanUtils.copyProperties(goods,vo);
  40. BeanUtils.copyProperties(seckillGoods,vo);
  41. return vo;
  42. }
  43. }

GoodsService

  1. package com.duing.service;
  2. import com.duing.vo.GoodsDetailVo;
  3. import com.duing.vo.GoodsVo;
  4. import java.util.List;
  5. public interface GoodsService {
  6. List<GoodsVo> getGoods();
  7. GoodsDetailVo goodsDetail(String goodsId);
  8. }

GoodsDetailVo

package com.duing.vo;

// 商品详情的展示数据

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

import java.util.Date;

@Data
@AllArgsConstructor
@NoArgsConstructor
public class GoodsDetailVo {

    private String name;
    private String goodsId;
    private String imgPath;
    private Double price;
    private Double seckillPrice;
    private int stockNum;
    private Date startTime;
    private Date endTime;
}

GoodsVo

package com.duing.vo;

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

@Data
@AllArgsConstructor
@NoArgsConstructor
public class GoodsVo {

    private String goodsId;
    private String goodsName;
    private String goodsType;
    private Double price;
    private String imgPath;
    private Double seckillPrice;
    private int stockNum;

}

GoodsMapper.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.duing.mapper.GoodsMapper">

    <resultMap id="single" type="com.duing.model.Goods">
        <id property="id" column="id"/>
        <result property="goodsId" column="goods_id"/>
        <result property="goodsName" column="goods_name"/>
        <result property="goodsType" column="goods_type"/>
        <result property="price" column="price"/>
        <result property="imgPath" column="img_path"/>
    </resultMap>

    <select id="getGoods" resultType="com.duing.model.Goods" resultMap="single">
        select id, goods_id, goods_name, goods_type, price, img_path
        from goods
    </select>

    <select id="getGoodsById" resultType="com.duing.model.Goods" resultMap="single">
        select id, goods_id, goods_name, goods_type, price, img_path
        from goods where goods_id = #{goodsId}
    </select>

</mapper>

SeckillGoodsMapper.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.duing.mapper.SeckillGoodsMapper">

    <resultMap id="single" type="com.duing.model.SeckillGoods">
        <id property="id" column="id"/>
        <result property="goodsId" column="goods_id"/>
        <result property="seckillPrice" column="seckill_price"/>
        <result property="stockNum" column="stock_num"/>
        <result property="startTime" column="start_time"/>
        <result property="endTime" column="end_time"/>
    </resultMap>

    <select id="getSeckillGoodsById" resultType="com.duing.model.SeckillGoods" resultMap="single">
        select id, goods_id, seckill_price, stock_num, start_time, end_time
        from seckill_goods where goods_id = #{goodsId}
    </select>
</mapper>

detail.html

<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <link rel="stylesheet" th:href="@{/css/bootstrap.css}">
    <link rel="stylesheet" type="text/css" th:href="@{/css/detail.css}"/>

    <script type="text/javascript" th:src="@{/js/jquery-3.6.0.min.js}"></script>
</head>
<body>
<h1> 商品详情 </h1>

<br/><br/>

<table class="table table-hover">
<tr>
<td>商品名称</td>
<td clospan="3" th:text="${detailVo.name}"></td>
</tr>

<tr>
<td>商品图片</td>
<td clospan="3">
<img th:src="@{${detailVo.imgPath}}" width="200" height="200"/>
</td>
</tr>

<td>秒杀开始时间</td>
<td colspan="3" th:text="${#dates.format(detailVo.startTime,'yyyy-MM-dd HH:mm:ss')}"></td>
<td id="seckillTip">
<input type="hidden" id="remainSeconds" th:value="${remainSeconds}">
<input type="hidden" id="status" th:value="${status}">
<span th:if="${status eq 0}">秒杀倒计时:
<span id="countDown" th:text="${remainSeconds}"></span>秒
</span>
<span th:if="${status eq 1}">秒杀进行中</span>
<span th:if="${status eq 2}">秒杀已结束</span>
</td>

<td>
<form id="seckillForm" method="post" action="/toSeckill">
<input type="hidden" name="goodsId" th:value="${detailVo.goodsId}">
<button type="submit" id="buyButton">抢购</button>
</form>
</td>

<tr>
<td>商品原价</td>
<td clospan="3" th:text="${detailVo.price}"></td>
</tr>

<tr>
<td>商品秒杀价</td>
<td clospan="3" th:text="${detailVo.seckillPrice}"></td>
</tr>

<tr>
<td>库存数量</td>
<td clospan="3" th:text="${detailVo.stockNum}"></td>
</tr>

</table>
</body>
</html>

list.html

<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="UTF-8">
    <title>秒杀商品列表</title>
    <link rel="stylesheet" th:href="@{/css/bootstrap.css}">
    <link rel="stylesheet" type="text/css" th:href="@{/css/goods.css}"/>
</head>
<body>

<div class="seckill_content">
    <div class="title"><h2>秒杀商品列表</h2></div>
    <div class="all_seckill_goods">
        <div class="seckill_goods" th:each="goodsVo: ${voList}">
            <h4 th:text="${goodsVo.goodsName}"></h4>
            <img th:src="@{${goodsVo.imgPath}}" width="250" height="270"/>
            <br/><br/>
            <div class="seckill_price">
                <p th:text="${goodsVo.goodsType}"></p>
                <p>
                    <span class="price1" th:text="${goodsVo.seckillPrice}+'元  '"></span>
                    <del><span class="price2" th:text="${goodsVo.price}+'元'"></span></del>
                </p>
                <a th:href="'/goodsDetail/'+${goodsVo.goodsId}">
                    <button class="btn btn-default" type="submit">进入详情页...</button>
                </a>

            </div>
        </div>
    </div>

</div>



</body>
</html>

application.yml

spring:
  datasource:
    url: jdbc:mysql://localhost:3306/seckill
    username: root
    password: cy414ljh212,,,
    driver-class-name: com.mysql.cj.jdbc.Driver

mybatis:
  mapper-locations: classpath*:/mappers/*.xml
  type-aliases-package: com.duing.model

image.png
bootstrap.cssdetail.cssgoods.css111.png222.png333.pngjquery-3.6.0.min.jspom.xml
image.png