• 【畅购商城】详情页详情之商品详情


    1.构建详情页

    步骤0:确定访问路径

    http://localhost:3000/Goods?id=1

     

    步骤二:复制 ~/static/goods.html 内容,导入第三方资源(css、js) 

    1. head: {
    2. title: '列表页面',
    3. link: [
    4. {rel:'stylesheet',href: '/style/goods.css'},
    5. {rel:'stylesheet',href: '/style/common.css'},
    6. {rel:'stylesheet',href: '/style/bottomnav.css'},
    7. {rel:'stylesheet',href: '/style/jqzoom.css'},
    8. ],
    9. script: [
    10. { type: 'text/javascript', src: '/js/header.js' },
    11. { type: 'text/javascript', src: '/js/goods.js' },
    12. { type: 'text/javascript', src: '/js/jqzoom-core.js' },
    13. ]
    14. },

    步骤三:导入公共资源

    步骤四:添加原页面js特效

     

    2.详情

    2.1分析

    2.2接口

    GET http://localhost:10010/web-service/sku/goods/2600242

    返回值

    1. {
    2.    skuid:"商品ID,skuid",
    3.   spuid:"商品ID,skuid",
    4.    goods_name:"商品名称",
    5.    price:"价格",
    6.    on_sale_date:"上架时间",
    7.    comment_count:"评论数量",
    8.    comment_level:"评论级别(1-5)",
    9.    cat1_info:{
    10.        id:"分类ID",
    11.        cat_name:"分类名称"
    12.   },
    13.    cat2_info:{
    14.        id:"分类ID",
    15.        cat_name:"分类名称"
    16.   },
    17.    cat3_info:{
    18.        id:"分类ID",
    19.        cat_name:"分类名称"
    20.   },
    21.    logo:{
    22.        smlogo:"小LOGO(50x50)",
    23.        biglogo:"大LOGO(350x350)",
    24.        xbiglogo:"超大LOGO(800x800)"
    25.   },
    26.    photos:[
    27.       {
    28.            smimg:"商品图片(50x50)",
    29.            bigimg:"商品图片(350x350)",
    30.            xbigimg:"商品图片(800x800)"
    31.       },
    32.        ...
    33.   ],
    34.    description:"商品描述",
    35.    aftersale:"售后",
    36.    stock:"库存量",
    37.    spec_list:[
    38.       {
    39.            id:"规格ID",
    40.            spec_name:"规格名称",
    41.            options:[
    42.               {
    43.                    id:"选项ID",
    44.                    option_name:"选项名称"
    45.               }
    46.                ...
    47.           ]
    48.       }
    49.        ...
    50.   ],
    51.    spec_info:{
    52.            id_list:"规格ID:选项ID|规格ID:选项ID|...",
    53.            id_txt:"规格名称:规格选项|规格名称:规格选项|..."
    54.   },
    55.    sku_list:[
    56.       {
    57.            skuid:"SKUID",
    58.            id_list:"规格ID:选项ID|规格ID:选项ID|..."
    59.       },
    60.        ...
    61.   ]
    62. }

     

    ​​​​​​2.3​初始化数据

    1. insert into tb_sku_photo(sku_id,url) values(2600242,'http://img12.360buyimg.com/n1/s450x450_jfs/t1/100605/24/7603/222062/5dfc6d30Ec375bf0a/e29b6690731acb24.jpg');
    2. insert into tb_sku_photo(sku_id,url) values(2600242,'http://img12.360buyimg.com/n1/s450x450_jfs/t1/110371/2/1323/189888/5dfc6d30E073c3495/cb256ec2d3cf9ae2.jpg');
    3. insert into tb_sku_photo(sku_id,url) values(2600242,'http://img12.360buyimg.com/n1/s450x450_jfs/t1/95005/38/7465/139593/5dfc6d2fEd2317126/63b5253237353618.jpg');

    ​​​​​​2.4​后端实现:JavaBean

    SkuPhoto : sku对应的所有图片

    OneSkuResult:用于封装sku详情

    步骤一:创建SkuPhoto,根据tb_sku_photo表编写内容

     

    1. package com.czxy.changgou4.pojo;
    2. import com.baomidou.mybatisplus.annotation.IdType;
    3. import com.baomidou.mybatisplus.annotation.TableField;
    4. import com.baomidou.mybatisplus.annotation.TableId;
    5. import com.baomidou.mybatisplus.annotation.TableName;
    6. import com.fasterxml.jackson.annotation.JsonProperty;
    7. import lombok.Data;
    8. /**
    9. * Created by liangtong.
    10. */
    11. @TableName("tb_sku_photo")
    12. @Data
    13. public class SkuPhoto {
    14. @TableId(type = IdType.AUTO)
    15. private Integer id;
    16. //外键
    17. @TableField(value="sku_id")
    18. @JsonProperty("sku_id")
    19. private Integer skuId;
    20. @TableField(exist = false)
    21. private Sku sku;
    22. @TableField(value="url")
    23. private String url;
    24. }

    步骤二:创建OneSkuResult,根据接口返回结果编写内容

    1. package com.czxy.changgou4.vo;
    2. import com.czxy.changgou4.pojo.Category;
    3. import com.czxy.changgou4.pojo.Specification;
    4. import com.fasterxml.jackson.annotation.JsonProperty;
    5. import lombok.Data;
    6. import java.util.Date;
    7. import java.util.List;
    8. import java.util.Map;
    9. /**
    10. * @author 桐叔
    11. * @email liangtong@itcast.cn
    12. */
    13. @Data
    14. public class OneSkuResult {
    15. private Integer skuid;
    16. private Integer spuid;
    17. @JsonProperty("goods_name")
    18. private String goodsName;
    19. private Double price;
    20. @JsonProperty("on_sale_date")
    21. private Date onSaleDate;
    22. @JsonProperty("comment_count")
    23. private Integer commentCount;
    24. @JsonProperty("comment_level")
    25. private Integer commentLevel;
    26. @JsonProperty("cat1_info")
    27. private Category cat1Info;
    28. @JsonProperty("cat2_info")
    29. private Category cat2Info;
    30. @JsonProperty("cat3_info")
    31. private Category cat3Info;
    32. private Map logo;
    33. private List photos;
    34. private String description;
    35. private String aftersale;
    36. private Integer stock;
    37. @JsonProperty("spec_list")
    38. private List specList;
    39. // id_list:'规格ID:选项ID|规格ID:选项ID|...',
    40. // id_txt:'规格名称:选项名称|规格名称:选项名称|...'
    41. @JsonProperty("spec_info")
    42. private Map specInfo;
    43. @JsonProperty("sku_list")
    44. private List> skuList;
    45. }

    ​​​​​​​2.5后端实现:Mapper

    步骤一:修改skuCommentMapper,完成“评论级别”功能

    1. /**
    2. * 通过spu查询评论打分(星星)的平均数
    3. * @param spuId
    4. * @return
    5. */
    6. @Select("SELECT AVG(star) FROM tb_sku_comment WHERE spu_id = #{spuId}")
    7. public Integer findAvgStarBySpuId(@Param("spuId") Integer spuId);

    步骤二:创建SkuPhotoMapper,完成“通过skuId查询对应的所有的图片”功能

    1. package com.czxy.changgou4.mapper;
    2. import com.baomidou.mybatisplus.core.mapper.BaseMapper;
    3. import com.czxy.changgou4.pojo.SkuPhoto;
    4. import org.apache.ibatis.annotations.Mapper;
    5. import org.apache.ibatis.annotations.Result;
    6. import org.apache.ibatis.annotations.Results;
    7. import org.apache.ibatis.annotations.Select;
    8. import java.util.List;
    9. /**
    10. * Created by liangtong.
    11. */
    12. @Mapper
    13. public interface SkuPhotoMapper extends BaseMapper {
    14. /**
    15. * 通过skuId查询对应的所有的图片
    16. * @param spuId
    17. * @return
    18. */
    19. @Select("select * from tb_sku_photo where sku_id = #{spuId}")
    20. @Results({
    21. @Result(property="id", column="id"),
    22. @Result(property="skuId", column="sku_id"),
    23. @Result(property="url", column="url")
    24. })
    25. public List findSkuPhotoBySkuId(Integer spuId);
    26. }

    步骤三:修改SkuMapper,添加“查询指定spuId的所有sku”功能

    1. /**
    2. * 查询指定spuId的所有sku
    3. * @param spuId
    4. * @return
    5. */
    6. @Select("select * from tb_sku where spu_id = #{spuId}")
    7. @ResultMap("skuResult")
    8. public List findSkuBySpuId(Integer spuId);

     

    2.6后端实现

    步骤一:修改SkuService,添加findSkuById 方法

    1. /**
    2. * 查询详情
    3. * @param skuid
    4. * @return
    5. */
    6. public OneSkuResult findSkuById(Integer skuid);

    步骤二:修改SkuServiceImpl,完成“查询详情”功能

    1. package com.czxy.changgou4.service.impl;
    2. import com.alibaba.fastjson.JSON;
    3. import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
    4. import com.czxy.changgou4.mapper.*;
    5. import com.czxy.changgou4.pojo.Sku;
    6. import com.czxy.changgou4.pojo.SkuPhoto;
    7. import com.czxy.changgou4.pojo.Specification;
    8. import com.czxy.changgou4.pojo.Spu;
    9. import com.czxy.changgou4.service.SkuService;
    10. import com.czxy.changgou4.vo.ESData;
    11. import com.czxy.changgou4.vo.OneSkuResult;
    12. import org.springframework.stereotype.Service;
    13. import org.springframework.transaction.annotation.Transactional;
    14. import javax.annotation.Resource;
    15. import java.util.ArrayList;
    16. import java.util.HashMap;
    17. import java.util.List;
    18. import java.util.Map;
    19. /**
    20. * @author 桐叔
    21. * @email liangtong@itcast.cn
    22. */
    23. @Service
    24. @Transactional
    25. public class SkuServiceImpl extends ServiceImpl implements SkuService {
    26. @Resource
    27. private SkuCommentMapper skuCommentMapper;
    28. @Resource
    29. private SpuMapper spuMapper;
    30. @Resource
    31. private CategoryMapper categoryMapper;
    32. @Resource
    33. private SkuPhotoMapper skuPhotoMapper;
    34. @Resource
    35. private SpecificationMapper specificationMapper;
    36. @Override
    37. public List findESData() {
    38. //1 查询所有详情sku
    39. List skulist = baseMapper.findAllSkus();
    40. //2 将SKU 转换成 ESData
    41. List esDataList = new ArrayList<>();
    42. for (Sku sku:skulist){
    43. ESData esData = new ESData();
    44. // id
    45. esData.setId(sku.getId());
    46. // 图片地址
    47. esData.setLogo(sku.getSpu().getLogo());
    48. // 商品名称
    49. esData.setSkuName(sku.getSkuName());
    50. // all “华为xx {"机身颜色":"白色","内存":"3GB","机身存储":"16GB"} 荣耀 ”
    51. esData.setAll(sku.getSkuName()+" " + sku.getSpecInfoIdTxt() + " " +sku.getSpu().getBrand().getBrandName());
    52. // on_sale_time
    53. esData.setOnSaleTime(sku.getSpu().getOnSaleTime());
    54. // brand_id
    55. esData.setBrandId(sku.getSpu().getBrandId());
    56. // cat_id
    57. esData.setCatId(sku.getSpu().getCat3Id());
    58. // Map specs;// 可搜索的规格参数,key是参数名,值是参数值
    59. Map specs = JSON.parseObject(sku.getSpecInfoIdTxt(), Map.class);
    60. // Map newSpecs = new HashMap();
    61. // for(String key : specs.keySet()){
    62. // newSpecs.put("spec" + key , specs.get(key));
    63. // }
    64. esData.setSpecs(specs);
    65. // price 价格
    66. esData.setPrice(sku.getPrice());
    67. // spu_name
    68. esData.setSpuName(sku.getSpu().getSpuName());
    69. // stock 库存
    70. esData.setStock(sku.getStock());
    71. // description
    72. esData.setDescription(sku.getSpu().getDescription());
    73. // packages;//规格与包装
    74. esData.setPackages(sku.getSpu().getPackages());
    75. // aftersale;//售后保障
    76. esData.setAftersale(sku.getSpu().getAftersale());
    77. // midlogo;
    78. esData.setMidlogo(sku.getSpu().getLogo());
    79. // comment_count; 评价数
    80. Integer comment_count = skuCommentMapper.findNumBySpuId(sku.getSpu().getId());
    81. esData.setCommentCount(comment_count);
    82. //销售量
    83. esData.setSellerCount(10);
    84. esDataList.add(esData);
    85. }
    86. return esDataList;
    87. }
    88. @Override
    89. public OneSkuResult findSkuById(Integer skuid) {
    90. OneSkuResult skuResult = new OneSkuResult();
    91. // 1 查找sku基本信息
    92. Sku sku = baseMapper.selectById(skuid);
    93. // 2 根据sku查找spu信息
    94. Spu spu = spuMapper.findSpuById(sku.getSpuId());
    95. // 3 赋值
    96. // skuid;
    97. skuResult.setSkuid(sku.getId());
    98. // spuid;
    99. skuResult.setSpuid(sku.getSpuId());
    100. // 商品名称
    101. skuResult.setGoodsName(sku.getSkuName());
    102. // 价格
    103. skuResult.setPrice(sku.getPrice());
    104. // 上架时间
    105. skuResult.setOnSaleDate(spu.getOnSaleTime());
    106. // 评价数
    107. Integer comment_count = skuCommentMapper.findNumBySpuId(spu.getId());
    108. skuResult.setCommentCount(comment_count);
    109. // 评论级别
    110. skuResult.setCommentLevel(skuCommentMapper.findAvgStarBySkuId(sku.getId()));
    111. // 一级分类
    112. skuResult.setCat1Info(categoryMapper.selectById(spu.getCat1Id()));
    113. // 二级分类
    114. skuResult.setCat2Info(categoryMapper.selectById(spu.getCat2Id()));
    115. // 三级分类
    116. skuResult.setCat3Info(categoryMapper.selectById(spu.getCat3Id()));
    117. // 第一张图片
    118. Map logo = new HashMap();
    119. logo.put("smlogo",spu.getLogo());
    120. logo.put("biglogo",spu.getLogo());
    121. logo.put("xbiglogo",spu.getLogo());
    122. skuResult.setLogo(logo);
    123. // 通过skuId查询对应的所有的图片
    124. List skuPhotoList = skuPhotoMapper.findSkuPhotoBySkuId(sku.getId());
    125. List photos = new ArrayList<>();
    126. for(SkuPhoto sp:skuPhotoList){
    127. Map map = new HashMap();
    128. map.put("smimg",sp.getUrl());
    129. map.put("bigimg",sp.getUrl());
    130. map.put("xbigimg",sp.getUrl());
    131. photos.add(map);
    132. }
    133. skuResult.setPhotos(photos);
    134. // 商品描述
    135. skuResult.setDescription(spu.getDescription());
    136. // 售后
    137. skuResult.setAftersale(spu.getAftersale());
    138. // 库存量
    139. skuResult.setStock(sku.getStock());
    140. // List spec_list; 根据分类查找规格和规格选项
    141. List spec_list = specificationMapper.findSpecificationByCategoryId(spu.getCat3Id());
    142. skuResult.setSpecList(spec_list);
    143. // //id_list:'规格ID:选项ID|规格ID:选项ID|...',
    144. // //id_txt:'规格名称:选项名称|规格名称:选项名称|...'
    145. // Map spec_info;
    146. Map spec_info = new HashMap<>();
    147. spec_info.put("id_list",sku.getSpecInfoIdList());
    148. spec_info.put("id_txt",sku.getSpecInfoIdTxt());
    149. skuResult.setSpecInfo(spec_info);
    150. // List> sku_list;
    151. List skuBySpuIdList = baseMapper.findSkuBySpuId(spu.getId());
    152. List> sku_list = new ArrayList<>();
    153. for(Sku s : skuBySpuIdList){
    154. Map map = new HashMap<>();
    155. map.put("skuid",s.getId().toString());
    156. map.put("id_list",s.getSpecInfoIdList());
    157. sku_list.add(map);
    158. }
    159. skuResult.setSkuList(sku_list);
    160. // 返回结果
    161. return skuResult;
    162. }
    163. }

    1. /**
    2. * 查询详情
    3. * @param skuid
    4. * @return
    5. */
    6. @GetMapping("/goods/{skuid}")
    7. public BaseResult findSkuById(@PathVariable("skuid") Integer skuid){
    8. OneSkuResult sku = skuService.findSkuById(skuid);
    9. return BaseResult.ok("查询成功", sku);
    10. }

    2.7前端实现

    详情页面需要进行SSR

    步骤一:修改 “apiserver.js”,查询详情

    步骤二:修改 Goods.vue 页面,使用asyncData进行查询

    步骤三:修改 Goods.vue 页面,显示当前位置

     

    步骤四:修改 Goods.vue 页面,处理放大镜图片

            

    步骤五:修改 Goods.vue 页面,商品详情

    编写specOptionSelect方法

    1. methods: {
    2. specOptionSelect(spec,option) {
    3. // 拼接标记符,规格id:选项id
    4. let flag = spec.id + ':' + option.id
    5. // 判断id_list中是否有‘标记符’,如果没有返回-1
    6. return this.goodsInfo.spec_info.id_list.indexOf(flag) != -1
    7. }
    8. },

    步骤六:修复bug,图片大小的原因,导致“放大镜”中等图太大,遮盖小图

    问题图示

    解决

    3.规格操作

    点击“规格”时,切换SKU的id

    步骤一:修改 Goods.vue 页面,给每一个规格选项绑定点击事件

     

    步骤二:修改 Goods.vue 页面,完成 selectSpec 函数

    ​​​​​​​

  • 相关阅读:
    Python学习记录 模块的发布和安装
    动态背景下目标跟踪算法的实现及源代码
    java计算机毕业设计水果商城设计源码+系统+mysql数据库+lw文档+部署
    【通关MySQL】Java的JDBC编程
    OpenCV_Mat类对象常用的构造方法及初始化方法
    TiDB系列之:认识TiDB数据库,使用TiUP部署TiDB集群,同时部署TiCDC的详细步骤
    Java 程序猿看完这些面试题,想斩获 BAT 的 offer 都很难!
    以太坊终于要合并了
    十五、Lua 协同程序(coroutine)的学习
    全球创见者共话企业韧性 金蝶“数字员工”惊艳亮相
  • 原文地址:https://blog.csdn.net/weixin_45481821/article/details/127870773