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

﹏ヽ暗。殇╰゛Y 2024-04-01 18:59 172阅读 0赞

1.构建详情页

步骤0:确定访问路径

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

7ea16401d9d9412fbd10ce5e807dc824.png

6949d0fd089049279bdb82435a5dab70.png

步骤二:复制 ~/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. },

步骤三:导入公共资源

  1. <script>
  2. import TopNav from '@/components/TopNav'
  3. import HeaderSearch from '@/components/HeaderSearch'
  4. import BottomNav from '@/components/BottomNav'
  5. import Footer from '@/components/Footer'
  6. export default {
  7. components: {
  8. TopNav,
  9. HeaderSearch,
  10. BottomNav,
  11. Footer,
  12. },
  13. }
  14. </script>

e8614301f8f543cdb65dbafa05217e25.png

9443b1bde55741ee891f6fbda2220d2b.png

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

8b95511f87c14b3aa0bd46774c5f0cb3.png

2.详情

2.1分析

e9c5079638334638b8021df2755489ca.png

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. }

5266552e6a564027b4c5bab1ea2b5de6.png

01ea49b5bed24fab8510e12da5ecac5c.png

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

5891b5e0c5984b4fa3a96bdfb7126c1d.png

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<String, String> logo;
  33. private List<Map> photos;
  34. private String description;
  35. private String aftersale;
  36. private Integer stock;
  37. @JsonProperty("spec_list")
  38. private List<Specification> specList;
  39. // id_list:'规格ID:选项ID|规格ID:选项ID|...',
  40. // id_txt:'规格名称:选项名称|规格名称:选项名称|...'
  41. @JsonProperty("spec_info")
  42. private Map<String, String> specInfo;
  43. @JsonProperty("sku_list")
  44. private List<Map<String, String>> skuList;
  45. }

#

2.5后端实现:Mapper

dd909cdbf4984602bb6f6bb92f220206.png

步骤一:修改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<SkuPhoto> {
  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<SkuPhoto> findSkuPhotoBySkuId(Integer spuId);
  26. }

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

a6cace3debe74966bc90d0e6e630249f.png

  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<Sku> findSkuBySpuId(Integer spuId);

6493bc548ab9415db571065cf9ef8d7a.png

2.6后端实现

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

3084d192ae1c4450ac0f3c6e4ce4d43a.png

  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<SkuMapper, Sku> 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<ESData> findESData() {
  38. //1 查询所有详情sku
  39. List<Sku> skulist = baseMapper.findAllSkus();
  40. //2 将SKU 转换成 ESData
  41. List<ESData> 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<String, Object> specs;// 可搜索的规格参数,key是参数名,值是参数值
  59. Map<String,Object> 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<String,String> 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<SkuPhoto> skuPhotoList = skuPhotoMapper.findSkuPhotoBySkuId(sku.getId());
  125. List<Map> photos = new ArrayList<>();
  126. for(SkuPhoto sp:skuPhotoList){
  127. Map<String,String> 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<SpecResult> spec_list; 根据分类查找规格和规格选项
  141. List<Specification> spec_list = specificationMapper.findSpecificationByCategoryId(spu.getCat3Id());
  142. skuResult.setSpecList(spec_list);
  143. // //id_list:'规格ID:选项ID|规格ID:选项ID|...',
  144. // //id_txt:'规格名称:选项名称|规格名称:选项名称|...'
  145. // Map<String, String> spec_info;
  146. Map<String,String> 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<Map<String, String>> sku_list;
  151. List<Sku> skuBySpuIdList = baseMapper.findSkuBySpuId(spu.getId());
  152. List<Map<String, String>> sku_list = new ArrayList<>();
  153. for(Sku s : skuBySpuIdList){
  154. Map<String,String> 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. }

4aa5308222414952b2024bed68a72355.png

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

2.7前端实现

详情页面需要进行SSR

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

13076b19eb7f423fae46ad66a5416f02.png

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

b9fcb7556ea64bd1945b1c01460cba82.png

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

720a833ebd814ce8a51438b5726a630b.png

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

27aca095e73f42e9a3009999ba731ea5.png

35bef280a58f49adb003aaa613eefb9d.png

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

9a8da57916a04b79822c7dac807e0b3a.png

编写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,图片大小的原因,导致“放大镜”中等图太大,遮盖小图

问题图示

d2d2151141494160818cfbfe9d2d9e48.png

解决

  1. <style>
  2. .midpic img {
  3. width: 100%;
  4. }
  5. </style>

3.规格操作

点击“规格”时,切换SKU的id28064b36bc5d4ceb9402e7a9de739a6f.png

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

820378e028e747c58d100b8b6f550547.png

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

20acd009286e46be9ca33686ba1991b3.png

发表评论

表情:
评论列表 (有 0 条评论,172人围观)

还没有评论,来说两句吧...

相关阅读