Ver Fonte

商品详情1

chao há 4 anos atrás
pai
commit
bf7013a2e6

+ 58 - 1
src/main/java/com/caimei/www/controller/ProductController.java

@@ -1,9 +1,15 @@
 package com.caimei.www.controller;
 package com.caimei.www.controller;
 
 
+import com.caimei.module.base.entity.bo.JsonModel;
+import com.caimei.www.pojo.product.ProductDetail;
+import com.caimei.www.pojo.product.ProductParameter;
+import com.caimei.www.service.ProductService;
+import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Controller;
 import org.springframework.stereotype.Controller;
 import org.springframework.ui.Model;
 import org.springframework.ui.Model;
 import org.springframework.web.bind.annotation.GetMapping;
 import org.springframework.web.bind.annotation.GetMapping;
 import org.springframework.web.bind.annotation.RequestParam;
 import org.springframework.web.bind.annotation.RequestParam;
+import org.springframework.web.bind.annotation.ResponseBody;
 
 
 /**
 /**
  *cription
  *cription
@@ -17,23 +23,74 @@ public class ProductController extends BaseController {
 	private static final String PRODUCT_LIST_PATH = "product/list";
 	private static final String PRODUCT_LIST_PATH = "product/list";
 	private static final String PRODUCT_DETAIL_PATH = "product/detail";
 	private static final String PRODUCT_DETAIL_PATH = "product/detail";
 
 
+    private ProductService productService;
+    @Autowired
+    public void setProductService(ProductService productService) {
+        this.productService = productService;
+    }
+
+    /**
+     * 商品分类列表页
+     */
     @GetMapping("/product/list.html")
     @GetMapping("/product/list.html")
     public String hello(final Model model) {
     public String hello(final Model model) {
         model.addAttribute("searchFlag", "0");
         model.addAttribute("searchFlag", "0");
         return PRODUCT_LIST_PATH;
         return PRODUCT_LIST_PATH;
     }
     }
 
 
+    /**
+     * 商品搜索结果页
+     */
     @GetMapping("/product/search.html")
     @GetMapping("/product/search.html")
     public String hello2(final Model model) {
     public String hello2(final Model model) {
         model.addAttribute("searchFlag", "1");
         model.addAttribute("searchFlag", "1");
         return PRODUCT_LIST_PATH;
         return PRODUCT_LIST_PATH;
     }
     }
 
 
+    /**
+     * 商品详情页
+     */
     @GetMapping("/product/detail.html")
     @GetMapping("/product/detail.html")
     public String listPage(final Model model, @RequestParam("pid") Integer productId) {
     public String listPage(final Model model, @RequestParam("pid") Integer productId) {
-        model.addAttribute("msg", productId);
+        ProductDetail detail = productService.getProductDetailById(productId);
+        model.addAttribute("product", detail);
         return PRODUCT_DETAIL_PATH;
         return PRODUCT_DETAIL_PATH;
     }
     }
 
 
+    /**
+     * 详情-图片
+     * @return
+     */
+    @GetMapping("/product/images")
+    @ResponseBody
+    public JsonModel getProductDetailImages(Integer productId) {
+        return productService.getProductDetailImages(productId);
+    }
+
+
+    /**
+     * 详情-相关推荐
+     * @return
+     */
+    @GetMapping("/product/recommend")
+    @ResponseBody
+    public JsonModel getProductDetailRecommends(Integer productId, Integer recommendType) {
+        return productService.getProductDetailRecommends(productId, recommendType);
+    }
+
+    /**
+     * 详情-相关参数
+     * @return
+     */
+    @GetMapping("/product/parameter")
+    @ResponseBody
+    public JsonModel getProductParameters(Integer productId) {
+        return productService.getProductParameters(productId);
+    }
+
+
+
+
+
 
 
 }
 }

+ 1 - 1
src/main/java/com/caimei/www/mapper/HomeDao.java

@@ -2,7 +2,7 @@ package com.caimei.www.mapper;
 
 
 import com.caimei.www.pojo.HomeFloor;
 import com.caimei.www.pojo.HomeFloor;
 import com.caimei.www.pojo.ImageLink;
 import com.caimei.www.pojo.ImageLink;
-import com.caimei.www.pojo.ProductList;
+import com.caimei.www.pojo.product.ProductList;
 import com.caimei.www.pojo.base.HeadCart;
 import com.caimei.www.pojo.base.HeadCart;
 import org.apache.ibatis.annotations.Mapper;
 import org.apache.ibatis.annotations.Mapper;
 import org.apache.ibatis.annotations.Param;
 import org.apache.ibatis.annotations.Param;

+ 47 - 0
src/main/java/com/caimei/www/mapper/ProductDao.java

@@ -0,0 +1,47 @@
+package com.caimei.www.mapper;
+
+import com.caimei.www.pojo.product.ProductDetail;
+import com.caimei.www.pojo.product.ProductList;
+import com.caimei.www.pojo.product.ProductParameter;
+import org.apache.ibatis.annotations.Mapper;
+import org.apache.ibatis.annotations.Param;
+
+import java.util.List;
+
+/**
+ * Description
+ *
+ * @author : Charles
+ * @date : 2020/7/8
+ */
+@Mapper
+public interface ProductDao {
+    /**
+     * 根据商品Id获取详情
+     * @param productId
+     * @return
+     */
+    ProductDetail getProductDetailById(Integer productId);
+
+    /**
+     * 详情-相关推荐
+     * @param productId
+     * @return
+     */
+    List<ProductList> getProductRecommendsById(Integer productId);
+    List<ProductList> getAutoProductRecommends(Integer productId);
+
+    /**
+     * 详情-相关参数
+     * @param productId
+     * @return
+     */
+    List<ProductParameter> getProductParameters(Integer productId);
+
+    /**
+     * 详情-图片
+     * @param productId
+     * @return
+     */
+    List<String> getProductDetailImages(Integer productId);
+}

+ 45 - 0
src/main/java/com/caimei/www/pojo/product/ProductDetail.java

@@ -0,0 +1,45 @@
+package com.caimei.www.pojo.product;
+
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+
+import java.util.List;
+
+/**
+ * Description
+ *
+ * @author : Charles
+ * @date : 2020/7/8
+ */
+@EqualsAndHashCode(callSuper = true)
+@Data
+public class ProductDetail extends ProductList {
+	private Integer minBuyNumber;
+	private Integer stock;
+    private Integer step;
+    private Integer recommendType;
+    private Integer validFlag;
+	private String productCode;
+	private String tags;
+	private String[] tagList;
+	private String remarks;
+	/** 详情 */
+	private String detailInfo;
+	private String orderInfo;
+	private String serviceInfo;
+	/** 品牌 */
+    private Integer brandId;
+	private String brandName;
+	/** 分类 */
+    private Integer tinyTypeId;
+	private String tinyTypeText;
+    private Integer smallTypeId;
+	private String smallTypeText;
+    private Integer bigTypeId;
+	private String bigTypeText;
+	/** 供应商 */
+    private Integer shopId;
+	private String shopTitle;
+	private String businessScope;
+	private String shopAddress;
+}

+ 6 - 2
src/main/java/com/caimei/www/pojo/ProductList.java → src/main/java/com/caimei/www/pojo/product/ProductList.java

@@ -1,7 +1,9 @@
-package com.caimei.www.pojo;
+package com.caimei.www.pojo.product;
 
 
 import lombok.Data;
 import lombok.Data;
 
 
+import java.io.Serializable;
+
 /**
 /**
  * Description
  * Description
  *
  *
@@ -9,7 +11,7 @@ import lombok.Data;
  * @date : 2020/6/22
  * @date : 2020/6/22
  */
  */
 @Data
 @Data
-public class ProductList {
+public class ProductList implements Serializable {
 	private Integer pid;
 	private Integer pid;
 	private String name;
 	private String name;
 	private String image;
 	private String image;
@@ -21,4 +23,6 @@ public class ProductList {
 	private Integer pricegrade;
 	private Integer pricegrade;
 	/** 活动图标 */
 	/** 活动图标 */
 	private Integer acttype;
 	private Integer acttype;
+
+    private static final long serialVersionUID = 1L;
 }
 }

+ 26 - 0
src/main/java/com/caimei/www/pojo/product/ProductParameter.java

@@ -0,0 +1,26 @@
+package com.caimei.www.pojo.product;
+
+import lombok.Data;
+
+import java.io.Serializable;
+
+/**
+ * Description
+ *
+ * @author : Charles
+ * @date : 2020/7/8
+ */
+@Data
+public class ProductParameter implements Serializable {
+    private Integer id;
+    /** 商品ID */
+    private Integer productId;
+    /** 参数名称 */
+    private String paramsName;
+    /** 参数内容 */
+    private String paramsContent;
+    /** 删除标记 0否 其余是 */
+    private String delFlag;
+
+    private static final long serialVersionUID = 1L;
+}

+ 41 - 0
src/main/java/com/caimei/www/service/ProductService.java

@@ -0,0 +1,41 @@
+package com.caimei.www.service;
+
+import com.caimei.module.base.entity.bo.JsonModel;
+import com.caimei.www.pojo.product.ProductDetail;
+
+/**
+ * Description
+ *
+ * @author : Charles
+ * @date : 2020/7/8
+ */
+public interface ProductService {
+    /**
+     * 根据商品Id获取详情
+     * @param productId
+     * @return
+     */
+    ProductDetail getProductDetailById(Integer productId);
+
+    /**
+     * 详情-相关推荐
+     * @param productId
+     * @param recommendType
+     * @return
+     */
+    JsonModel getProductDetailRecommends(Integer productId, Integer recommendType);
+
+    /**
+     * 详情-相关参数
+     * @param productId
+     * @return
+     */
+    JsonModel getProductParameters(Integer productId);
+
+    /**
+     * 详情-图片
+     * @param productId
+     * @return
+     */
+    JsonModel getProductDetailImages(Integer productId);
+}

+ 1 - 1
src/main/java/com/caimei/www/service/impl/HomeServiceImpl.java

@@ -4,7 +4,7 @@ import com.caimei.module.base.entity.bo.JsonModel;
 import com.caimei.www.mapper.HomeDao;
 import com.caimei.www.mapper.HomeDao;
 import com.caimei.www.pojo.HomeFloor;
 import com.caimei.www.pojo.HomeFloor;
 import com.caimei.www.pojo.ImageLink;
 import com.caimei.www.pojo.ImageLink;
-import com.caimei.www.pojo.ProductList;
+import com.caimei.www.pojo.product.ProductList;
 import com.caimei.www.pojo.base.HeadCart;
 import com.caimei.www.pojo.base.HeadCart;
 import com.caimei.www.service.HomeService;
 import com.caimei.www.service.HomeService;
 import com.caimei.www.utils.ImageUtil;
 import com.caimei.www.utils.ImageUtil;

+ 105 - 0
src/main/java/com/caimei/www/service/impl/ProductServiceImpl.java

@@ -0,0 +1,105 @@
+package com.caimei.www.service.impl;
+
+import com.caimei.module.base.entity.bo.JsonModel;
+import com.caimei.module.base.entity.po.Product;
+import com.caimei.www.mapper.ProductDao;
+import com.caimei.www.pojo.ImageLink;
+import com.caimei.www.pojo.product.ProductDetail;
+import com.caimei.www.pojo.product.ProductList;
+import com.caimei.www.pojo.product.ProductParameter;
+import com.caimei.www.service.ProductService;
+import com.caimei.www.utils.ImageUtil;
+import com.caimei.www.utils.PriceUtil;
+import io.netty.util.internal.StringUtil;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.stereotype.Service;
+
+import javax.annotation.Resource;
+import java.util.List;
+
+/**
+ * Description
+ *
+ * @author : Charles
+ * @date : 2020/7/8
+ */
+@Service
+public class ProductServiceImpl implements ProductService {
+    @Resource
+    private ProductDao productDao;
+    @Value("${caimei.wwwDomain}")
+    private String domain;
+    /**
+     * 根据商品Id获取详情
+     *
+     * @param productId
+     * @return
+     */
+    @Override
+    public ProductDetail getProductDetailById(Integer productId) {
+        ProductDetail product = productDao.getProductDetailById(productId);
+        if(!StringUtil.isNullOrEmpty(product.getTags())){
+            product.setTagList(product.getTags().split(","));
+        }
+        // 价格等级
+        if (product.getPrice() > 50 * 5000) {
+            product.setPricegrade(5);
+        } else if (product.getPrice() > 25 * 5000) {
+            product.setPricegrade(4);
+        } else if (product.getPrice() > 10 * 5000) {
+            product.setPricegrade(3);
+        } else if (product.getPrice() > 2.5 * 5000) {
+            product.setPricegrade(2);
+        } else {
+            product.setPricegrade(1);
+        }
+        return product;
+    }
+
+    /**
+     * 详情-相关推荐
+     *
+     * @return
+     */
+    @Override
+    public JsonModel getProductDetailRecommends(Integer productId, Integer recommendType) {
+        List<ProductList> list = null;
+        //相关推荐类型 0自动选择; 1手动推荐
+        if (1 == recommendType) {
+            list = productDao.getProductRecommendsById(productId);
+        } else {
+            list = productDao.getAutoProductRecommends(productId);
+        }
+		return JsonModel.newInstance().success(list);
+    }
+
+    /**
+     * 详情-相关参数
+     *
+     * @param productId
+     * @return
+     */
+    @Override
+    public JsonModel getProductParameters(Integer productId) {
+        List<ProductParameter> list = productDao.getProductParameters(productId);
+		return JsonModel.newInstance().success(list);
+    }
+
+    /**
+     * 详情-图片
+     *
+     * @param productId
+     * @return
+     */
+    @Override
+    public JsonModel getProductDetailImages(Integer productId) {
+        List<String> list = productDao.getProductDetailImages(productId);
+        if (list.size() > 0) {
+            // 设置价格等级 及 老图片路径
+            list.forEach(image -> {
+                image = ImageUtil.getImageURL("product", image, 0, domain);
+            });
+        }
+		return JsonModel.newInstance().success(list);
+    }
+}

+ 1 - 1
src/main/resources/mapper/HomeMapper.xml

@@ -25,7 +25,7 @@
 		where delFlag = 0
 		where delFlag = 0
 		order by sort, createDate desc
 		order by sort, createDate desc
 	</select>
 	</select>
-	<select id="getRecommendeds" resultType="com.caimei.www.pojo.ProductList">
+	<select id="getRecommendeds" resultType="com.caimei.www.pojo.product.ProductList">
 		select
 		select
 			p.productID as pid,
 			p.productID as pid,
 			p.`name` as `name`,
 			p.`name` as `name`,

+ 92 - 0
src/main/resources/mapper/ProductMapper.xml

@@ -0,0 +1,92 @@
+<?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.caimei.www.mapper.ProductDao">
+	<select id="getProductDetailById" resultType="com.caimei.www.pojo.product.ProductDetail">
+		select
+			p.productID as pid,
+			p.`name` as `name`,
+			p.mainImage as image,
+			p.price1 as price,
+			p.unit as unit,
+			p.price1TextFlag as priceflag,
+
+			p.tags as tags,
+			p.productRemarks as remarks,
+			p.validFlag as validFlag,
+			p.stock as stock,
+			p.productCode as productCode,
+			p.minBuyNumber as minBuyNumber,
+			p.step as step,
+			p.recommendType as recommendType,
+
+			d.detailInfo as detailInfo,
+			d.orderInfo as orderInfo,
+			d.serviceInfo as serviceInfo,
+
+			p.brandID as brandId,
+			br.name as brandName,
+			p.tinyTypeID as tinyTypeId,
+			t.name as tinyTypeText,
+			t.smallTypeID as smallTypeId,
+			s.name as smallTypeText,
+			s.bigTypeID as bigTypeId,
+			b.name as bigTypeText,
+
+			p.shopID as shopId,
+			sh.name as shopTitle,
+			sh.businessScope as businessScope,
+			CONCAT(pr.name, ci.name) as shopAddress
+
+
+		from product p
+
+		left join productdetailinfo d on p.productID=d.productID
+		left join brand as br on p.brandID = br.brandID
+
+        left join tinytype as t on p.tinyTypeID = t.tinyTypeID
+        left join smalltype as s on t.smallTypeID = s.smallTypeID
+        left join bigtype as b on s.bigTypeID = b.bigTypeID
+
+        left join shop as sh on p.shopID = sh.shopID
+        left join town as tn on sh.townId = tn.townID
+        left join city as ci on tn.cityID = ci.cityID
+        left join province as pr on ci.provinceID = pr.provinceID
+
+		where p.productID = #{productId}
+	</select>
+	<select id="getProductRecommendsById" resultType="com.caimei.www.pojo.product.ProductList">
+        select
+			p.productID as pid,
+			p.`name` as `name`,
+			p.mainImage as image
+        from product as p
+        left join cm_product_recommend as pr on pr.recommendProductID = p.productID
+        where
+            p.productID = #{productId} and validFlag  = 2
+        order by pr.sort desc
+	</select>
+	<select id="getAutoProductRecommends" resultType="com.caimei.www.pojo.product.ProductList">
+        select
+			p.productID as pid,
+			p.`name` as `name`,
+			p.mainImage as image
+        from product as p
+        where
+			p.validFlag  = 2 and
+			p.tinyTypeID = (select tinyTypeID from product as p1 where p1.productID = #{productId})
+        order by p.sellNumber desc limit 0,7
+	</select>
+	<select id="getProductParameters" resultType="com.caimei.www.pojo.product.ProductParameter">
+		select id, productId, paramsName, paramsContent, delFlag
+		from cm_product_related_parameters
+		where productId = #{productId} and delFlag='0'
+	</select>
+	<select id="getProductDetailImages" resultType="java.lang.String">
+		select image
+		from productimage
+		where productID = #{productId}
+		order by mainFlag desc ,sortIndex is null,sortIndex
+	</select>
+
+
+</mapper>

+ 38 - 0
src/main/resources/static/css/product/detail.pc.css

@@ -2,3 +2,41 @@
 /**
 /**
  * PC端
  * PC端
  */
  */
+li{list-style:none;}
+.productBox{width:100%;margin:16px 0;background:#FFF;box-sizing:border-box;padding:15px}
+.productBox .imageBox{float:left;width:452px;height:545px;position:relative}
+.productBox .detailBox{float:right;width:686px}
+.productBox img{width:100%;height:100%;display:block}
+.productBox .bigImage{width:452px;height:452px;background:#F3F7FE}
+.productBox .bigImage .mask{display:none;position:absolute;left:0;top:0;width:215px;height:215px;border:1px solid #aaa;background:rgba(255,208,22,.4);opacity:.5;filter:alpha(opacity:50);cursor:move}
+.productBox .smallImage{height:79px;padding-top:14px;overflow:hidden}
+.productBox .smallImage ul{width:452px}
+.productBox .smallImage li{float:left;box-sizing:border-box;width:79px;height:79px;margin-left:14px;background:#F3F7FE;opacity:.5;-moz-transition:.5s;-webkit-transition:.5s;transition:.5s}
+.productBox .smallImage li.on{opacity:1;border:1px solid #E15616}
+.productBox .smallImage li:first-child{margin-left:0}
+.productBox .zoomImage{display:none;overflow:hidden;position:absolute;right:-466px;top:0;width:452px;height:452px;border:1px solid #e4e4e4;z-index:9999;background:#FFF}
+.productBox .zoomImage img{width:950px;height:950px;margin-right:10px;display:block}
+
+.productBox .detailBox .crumbs{height:28px;line-height:28px;font-size:14px;overflow:hidden;color:#93979F}
+.productBox .detailBox .crumbs a{color:#93979F}
+.productBox .detailBox .crumbs a:hover{color:#E15616}
+.productBox .detailBox .title{font-size:18px;font-weight:bold;line-height:24px;padding:5px 0;color:#4A4F58}
+.productBox .detailBox .tags{padding:2px 0}
+.productBox .detailBox .tags span{display:inline-block;height:16px;line-height:16px;padding:0 6px;font-size:12px;color:#FFF;background:#86B2FF;border-radius:2px;margin-right:10px}
+.productBox .detailBox .detail{box-sizing:border-box;padding:14px 20px;font-size:14px;color:#93979F;background:#F3F7FE;border-radius:2px;margin:10px 0}
+.productBox .detailBox .detail hr{border:none;border-top:1px dashed #BEC2C9;margin:12px 0}
+.productBox .detailBox .row{position:relative;padding:3px 0 3px 62px;line-height:24px}
+.productBox .detailBox .row .l{position:absolute;left:0;top:3px;display:inline-block;width:60px;height:24px;text-align:justify}
+.productBox .detailBox .row .l:after{content:'';display:inline-block;width:100%}
+.productBox .detailBox .row>i{font-style:normal;margin-right:14px}
+.productBox .detailBox .row em{font-style:normal;color:#4A4F58}
+.productBox .detailBox .row em.ser{color:#93979F;display:inline-block;margin-right:20px}
+.productBox .detailBox .row em.ser:before{content:'\2713';display:inline-block;width:12px;height:12px;text-align:center;line-height:12px;font-size:12px;background:#E15616;border-radius:6px;color:#FFF;margin-right:5px}
+.productBox .detailBox .price{height:24px}
+.productBox .detailBox .price .icon{display:inline-block;font-size:0;width:24px;height:24px;line-height:24px;position:relative;vertical-align:top}
+.productBox .detailBox .price .icon.on{position:absolute;left:0;top:0;margin:0}
+.productBox .detailBox .price .icon:before{width:24px;height:24px;background-position:-146px -251px}
+.productBox .detailBox .price .icon.on:before{background-position:-116px -251px}
+.productBox .detailBox .number{display:inline-block;width:130px;line-height:24px;height:24px;box-sizing:border-box;background:#dae0f3;border-radius:2px;font-size:0;white-space:nowrap;text-align:center}
+.productBox .detailBox .number>em{display:inline-block;width:24px;font-size:20px;line-height:20px;vertical-align:top;cursor:pointer}
+.productBox .detailBox .number input{width:80px;border:1px solid #dae0f3;line-height:22px;font-size:14px;vertical-align:top;text-align:center}

+ 56 - 0
src/main/resources/static/js/product/detail.js

@@ -0,0 +1,56 @@
+/**
+ * Created by ZHJY on 2020/6/18.
+ */
+var productDetail = new Vue({
+    el: "#container",
+    data: {
+        userId: '',
+        images: [],
+
+    },
+    computed: {},
+    methods: {
+        getImages: function(){
+            var _self = this;
+            $.getJSON("/product/images",{productId:5216}).done(function (r) {
+                if (r.code === 0 && r.data) {
+                    _self.images = r.data;
+                    setTimeout(function(){
+                        if (isPC) {
+                            var magnifier = new ImageMagnifier(
+                                '#imgShown .smallImage li'
+                                ,'#imgShown .bigImage'
+                                ,'#imgShown .zoomImage'
+                                ,'#imgShown .mask'
+                                ,'#imgShown .zoom'
+                                ,"on"
+                            ).init();
+                        } else {
+                            /*var swiper = new Swiper('#swiper-container', {
+                                loop : true,
+                                autoplay: {
+                                    delay: 2000,
+                                    disableOnInteraction: false
+                                },
+                                pagination: {
+                                    el: '.swiper-pagination',
+                                    clickable :true
+                                }
+                            });*/
+                        }
+                    },500);
+                }
+            });
+        },
+    },
+    created: function () {
+        var userInfo = localStorage.getItem('userInfo');
+        if(userInfo){
+            this.userId = JSON.parse(userInfo).userId;
+        }
+        this.getImages();
+    },
+    mounted: function () {
+
+    }
+});

+ 88 - 0
src/main/resources/static/lib/magnifier.js

@@ -0,0 +1,88 @@
+/**
+ * 商品详情图片放大器
+ *
+ *  imgItem --缩小版的框
+ *  showBox      --正常状态的框
+ *  zoomBox   --放大的框的盒子
+ *  zoomMask      --放大的区域(黑色遮罩)
+ *  zoomItem   --放大的框
+ *
+ * var obj = new ImageMagnifier('.imgItem', '.showBox','.zoomBox','.zoomMask','.zoomItem','activeClass').init();
+ */
+function ImageMagnifier(imgItem, showBox, zoomBox, zoomMask, zoomItem, activeClass) {
+    this.showBox = showBox;
+    this.zoomBox = zoomBox;
+    this.imgItem = imgItem;
+    this.zoomMask = zoomMask;
+    this.zoomItem = zoomItem;
+    this.activeClass = activeClass;
+}
+ImageMagnifier.prototype = {
+    init: function () {
+        var that = this;
+        that.start();
+        this.showHover();
+        this.smallImgHover();
+        this.showMove();
+    },
+    start: function () {
+        var that = this;
+        $(that.imgItem ).eq(0).addClass(that.activeClass);
+    },
+    showHover: function () {
+        var that = this;
+        $(that.showBox).hover(function(){
+            $(that.zoomBox).show();
+            $(that.zoomMask).show();
+        },function(){
+            $(that.zoomBox).hide();
+            $(that.zoomMask).hide();
+        });
+    },
+    smallImgHover: function () {
+        var that = this;
+        $('body').on("mouseover", that.imgItem, function(){
+            console.log(1);
+            var src=$(this).find('img').attr("src");
+            console.log(src);
+            if($(this).hasClass(that.activeClass)){
+	    		return;
+	    	}
+            $(this).addClass(that.activeClass).siblings().removeClass(that.activeClass);
+            $(that.showBox + '>img').attr("src",src);
+            $(that.zoomItem+ '>img').attr("src",src);
+        });
+    },
+    showMove:function(){
+        var that = this;
+        $('body').on("mousemove", that.showBox, function(e){
+            var bigx=$(this).offset().left;
+            var bigy=$(this).offset().top;
+            var x= e.clientX;
+            var y= e.clientY;
+            var scrollx=$(window).scrollLeft();
+            var scrolly=$(window).scrollTop();
+            var ox=x+scrollx-bigx-$(that.zoomMask).width()/2;
+            var oy=y+scrolly-bigy-$(that.zoomMask).height()/2;
+            if(ox<=0){
+                ox=0
+            }
+            if(ox>$(that.showBox).width()-$(that.zoomMask).width()){
+                ox=$(that.showBox).width()-$(that.zoomMask).width();
+            }
+            if(oy<=0){
+                oy=0
+            }
+            if(oy>$(that.showBox).height()-$(that.zoomMask).height()){
+                oy=$(that.showBox).height()-$(that.zoomMask).height();
+            }
+            $(that.zoomMask).css({left:ox});
+            $(that.zoomMask).css({top:oy});
+            var bei=$(that.showBox).width()/$(that.zoomMask).width();
+            $(that.zoomItem+ '>img').css(
+                { marginLeft:-bei*ox,
+                    marginTop:-bei*oy
+                })
+        });
+    }
+};

+ 93 - 1
src/main/resources/templates/product/detail.html

@@ -13,14 +13,106 @@
 
 
 <!--页面主体数据-->
 <!--页面主体数据-->
 <div id="container">
 <div id="container">
+    <div class="wrap">
+        <div class="productBox clear">
+            <div class="imageBox" id="imgShown">
+                <div class="bigImage">
+                    <img :src="images[0]">
+                    <span class="mask"></span>
+                </div>
+                <div class="smallImage">
+                    <ul class="clear">
+                        <li v-for="img in images"><img :src="img"></li>
+                    </ul>
+                </div>
+                <div class="zoomImage">
+                    <div class="zoom">
+                        <img :src="images[0]">
+                    </div>
+                </div>
+            </div>
+            <div class="detailBox" th:object="${product}">
+                <div class="crumbs">
+                    <span>所属分类:</span>
+                    <a th:href="@{'/product/list.html?category=' + *{bigTypeId} + '-0-0'}" th:text="*{bigTypeText}"></a>
+                    <span>&gt;</span>
+                    <a th:href="@{'/product/list.html?category=' + *{bigTypeId} + '-' + *{smallTypeId} + '-0'}" th:text="*{smallTypeText}"></a>
+                    <span>&gt;</span>
+                    <a th:href="@{'/product/list.html?category=' + *{bigTypeId} + '-' + *{smallTypeId} + '-' + *{tinyTypeId}}" th:text="*{tinyTypeText}"></a>
+                </div>
+                <h1 class="title" th:text="*{name}">商品名称</h1>
+                <p class="tags">
+                    <span th:each="tag: *{tagList}" th:text="${tag}"></span>
+                </p>
+                <div class="detail">
+                    <p class="row"><span class="l">价格</span><i>:</i>
+                        <!--<em class="price" th:text="*{price}"></em>-->
+                        <em class="price"><i class="icon mIcon" th:each="i:${#numbers.sequence(1,5)}">
+                                <i th:if="*{pricegrade}>=${i} or ${i}==1" class="icon mIcon on"></i>
+                        </i></em>
+                    </p>
+                    <p class="row"><span class="l">品牌</span><i>:</i><em th:text="*{brandName}"></em></p>
+                    <p class="row"><span class="l">包装规格</span><i>:</i><em th:text="*{unit}"></em></p>
+                    <p class="row"><span class="l">商品编码</span><i>:</i><em th:text="*{productCode}"></em></p>
+                    <p class="row"><span class="l">库存</span><i>:</i><em th:text="*{stock}"></em></p>
+                    <p class="row"><span class="l">起批量</span><i>:</i><em th:text="*{minBuyNumber}"></em></p>
+                    <p class="row"><span class="l">采购量</span><i>:</i>
+                        <span class="number">
+                            <em class="sub">-</em>
+                            <input type="number" th:value="*{minBuyNumber}">
+                            <em class="add">+</em>
+                        </span>
+                    </p>
+                    <hr>
+                    <p class="row"><span class="l">服务</span><i>:</i>
+                        <em class="ser">无忧退货</em>
+                        <em class="ser">急速退款</em>
+                        <em class="ser">正品保证</em>
+                    </p>
+                </div>
+            </div>
+        </div>
+    </div>
+
+
     <hr>
     <hr>
-    <h1>商品详情</h1>
+<div th:text="${product.pid}"></div>
+
+<div th:text="${product.priceflag}"></div>
+<div th:text="${product.remarks}"></div>
+<div th:text="${product.validFlag}"></div>
+
+
+
+<div th:text="${product.step}"></div>
+
+<div th:utext="${product.detailInfo}"></div>
+<div th:utext="${product.orderInfo}"></div>
+<div th:utext="${product.serviceInfo}"></div>
+
+<div th:text="${product.brandId}"></div>
+
+
+
+
+<div th:text="${product.shopId}"></div>
+<div th:text="${product.shopTitle}"></div>
+<div th:text="${product.businessScope}"></div>
+<div th:text="${product.shopAddress}"></div>
+
     <hr>
     <hr>
+
+
+
+
+
+
 </div>
 </div>
 
 
 <!-- 引入底部 -->
 <!-- 引入底部 -->
 <template th:replace="components/footer"></template>
 <template th:replace="components/footer"></template>
 <template th:replace="components/footLink"></template>
 <template th:replace="components/footLink"></template>
+<script charset="utf-8" type="text/javascript" src="/lib/magnifier.js"></script>
 <script charset="utf-8" type="text/javascript" th:src="@{/js/product/detail.js(v=${version})}"></script>
 <script charset="utf-8" type="text/javascript" th:src="@{/js/product/detail.js(v=${version})}"></script>
 </body>
 </body>
 </html>
 </html>

+ 2 - 2
src/main/resources/templates/product/list.html

@@ -24,9 +24,9 @@
             <a href="/">首页</a>
             <a href="/">首页</a>
             <template v-if="params.bid && params.bid>0">
             <template v-if="params.bid && params.bid>0">
                 <template v-if="params.sid && params.sid>0">
                 <template v-if="params.sid && params.sid>0">
-                    <span>&gt;</span> <a :href="'/product/category.shtml?category='+params.bid+'-0-0'" v-text="bigType"></a>
+                    <span>&gt;</span> <a :href="'/product/list.html?category='+params.bid+'-0-0'" v-text="bigType"></a>
                     <template v-if="params.tid && params.tid>0">
                     <template v-if="params.tid && params.tid>0">
-                        <span>&gt;</span> <a :href="'/product/category.shtml?category='+params.bid+'-'+params.sid+'-0'" v-text="smallType"></a>
+                        <span>&gt;</span> <a :href="'/product/list.html?category='+params.bid+'-'+params.sid+'-0'" v-text="smallType"></a>
                         <span>&gt;</span> <span v-text="tinyType"></span>
                         <span>&gt;</span> <span v-text="tinyType"></span>
                     </template>
                     </template>
                     <template v-else>
                     <template v-else>

+ 10 - 4
src/test/java/com/caimei/www/WwwApplicationTests.java

@@ -1,16 +1,14 @@
 package com.caimei.www;
 package com.caimei.www;
 
 
 import lombok.Data;
 import lombok.Data;
+import org.assertj.core.internal.Maps;
 import org.junit.jupiter.api.Test;
 import org.junit.jupiter.api.Test;
 import org.springframework.boot.test.context.SpringBootTest;
 import org.springframework.boot.test.context.SpringBootTest;
 import reactor.core.publisher.Flux;
 import reactor.core.publisher.Flux;
 
 
 import java.time.Duration;
 import java.time.Duration;
 import java.time.temporal.ChronoUnit;
 import java.time.temporal.ChronoUnit;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.List;
-import java.util.Random;
+import java.util.*;
 import java.util.stream.Collectors;
 import java.util.stream.Collectors;
 
 
 @SpringBootTest
 @SpringBootTest
@@ -98,4 +96,12 @@ class WwwApplicationTests {
         System.out.println(names);
         System.out.println(names);
     }
     }
 
 
+    @Test
+    void test4(){
+        Map<Integer, Integer> map =  new LinkedHashMap<>();
+        System.out.println(map.get(0));
+
+
+    }
+
 }
 }