文章目录
- 前言
- 一、商品详情⻚⾯
- 1.业务逻辑
- 2.涉及的接口数据
- 3. 关键技术
- 二、商品详情⻚⾯相关代码
- 1.页面代码
- 2.效果
前言
商品详情页是展示商品详细信息的一个页面,承载在网站的大部分流量和订单的入口。京东商城目前有通用版、全球购、闪购、易车、惠买车、服装、拼购、今日抄底等许多套模板。各套模板的元数据是一样的,只是展示方式不一样。目前商品详情页个性化需求非常多,数据来源也是非常多的,而且许多基础服务做不了的都放我们这,因此我们需要一种架构能快速响应和优雅的解决这些需求问题。因此我们重新设计了商品详情页的架构,主要包括三部分:商品详情页系统、商品详情页统一服务系统和商品详情页动态服务系统;商品详情页系统负责静的部分,而统一服务负责动的部分,而动态服务负责给内网其他系统提供一些数据服务。
一、商品详情⻚⾯
1.业务逻辑
- 渲染商品详情数据
- 点击图⽚,调出图⽚画廊,进⾏预览
- 点击收藏
- 联系客服
- 分享功能
- 加⼊购物⻋
2.涉及的接口数据
- 获取详情数据接⼝
{
"message": {
"goods_id": 6,
"cat_id": 1000,
"goods_name": "美国惠而浦(Whirlpool) 车载空气净化器WA-JM5005FK 三重过滤 内置负离子发生器",
"goods_price": 999,
"goods_number": 100,
"goods_weight": 100,
"goods_introduce": "",
"goods_big_logo": "http://image3.suning.cn/uimg/b2c/newcatentries/0000000000-000000000697223938_1_800x800.jpg",
"goods_small_logo": "http://image3.suning.cn/uimg/b2c/newcatentries/0000000000-000000000697223938_1_400x400.jpg",
"goods_state": 2,
"is_del": "0",
"add_time": 1516326502,
"upd_time": 1516326502,
"delete_time": null,
"hot_mumber": 0,
"is_promote": false,
"cat_one_id": 962,
"cat_two_id": 981,
"cat_three_id": 1000,
"goods_cat": "962,981,1000",
"pics": [
{
"pics_id": 27,
"goods_id": 6,
"pics_big": "http://image3.suning.cn/uimg/b2c/newcatentries/0000000000-000000000697223938_1_800x800.jpg",
"pics_mid": "http://image3.suning.cn/uimg/b2c/newcatentries/0000000000-000000000697223938_1_400x400.jpg",
"pics_sma": "http://image3.suning.cn/uimg/b2c/newcatentries/0000000000-000000000697223938_1_200x200.jpg",
"pics_big_url": "http://image3.suning.cn/uimg/b2c/newcatentries/0000000000-000000000697223938_1_800x800.jpg",
"pics_mid_url": "http://image3.suning.cn/uimg/b2c/newcatentries/0000000000-000000000697223938_1_400x400.jpg",
"pics_sma_url": "http://image3.suning.cn/uimg/b2c/newcatentries/0000000000-000000000697223938_1_200x200.jpg"
},
{
"pics_id": 28,
"goods_id": 6,
"pics_big": "http://image2.suning.cn/uimg/b2c/newcatentries/0000000000-000000000697223938_2_800x800.jpg",
"pics_mid": "http://image2.suning.cn/uimg/b2c/newcatentries/0000000000-000000000697223938_2_400x400.jpg",
"pics_sma": "http://image2.suning.cn/uimg/b2c/newcatentries/0000000000-000000000697223938_2_200x200.jpg",
"pics_big_url": "http://image2.suning.cn/uimg/b2c/newcatentries/0000000000-000000000697223938_2_800x800.jpg",
"pics_mid_url": "http://image2.suning.cn/uimg/b2c/newcatentries/0000000000-000000000697223938_2_400x400.jpg",
"pics_sma_url": "http://image2.suning.cn/uimg/b2c/newcatentries/0000000000-000000000697223938_2_200x200.jpg"
},
{
"pics_id": 29,
"goods_id": 6,
"pics_big": "http://image1.suning.cn/uimg/b2c/newcatentries/0000000000-000000000697223938_3_800x800.jpg",
"pics_mid": "http://image1.suning.cn/uimg/b2c/newcatentries/0000000000-000000000697223938_3_400x400.jpg",
"pics_sma": "http://image1.suning.cn/uimg/b2c/newcatentries/0000000000-000000000697223938_3_200x200.jpg",
"pics_big_url": "http://image1.suning.cn/uimg/b2c/newcatentries/0000000000-000000000697223938_3_800x800.jpg",
"pics_mid_url": "http://image1.suning.cn/uimg/b2c/newcatentries/0000000000-000000000697223938_3_400x400.jpg",
"pics_sma_url": "http://image1.suning.cn/uimg/b2c/newcatentries/0000000000-000000000697223938_3_200x200.jpg"
},
{
"pics_id": 30,
"goods_id": 6,
"pics_big": "http://image5.suning.cn/uimg/b2c/newcatentries/0000000000-000000000697223938_4_800x800.jpg",
"pics_mid": "http://image5.suning.cn/uimg/b2c/newcatentries/0000000000-000000000697223938_4_400x400.jpg",
"pics_sma": "http://image5.suning.cn/uimg/b2c/newcatentries/0000000000-000000000697223938_4_200x200.jpg",
"pics_big_url": "http://image5.suning.cn/uimg/b2c/newcatentries/0000000000-000000000697223938_4_800x800.jpg",
"pics_mid_url": "http://image5.suning.cn/uimg/b2c/newcatentries/0000000000-000000000697223938_4_400x400.jpg",
"pics_sma_url": "http://image5.suning.cn/uimg/b2c/newcatentries/0000000000-000000000697223938_4_200x200.jpg"
},
{
"pics_id": 31,
"goods_id": 6,
"pics_big": "http://image4.suning.cn/uimg/b2c/newcatentries/0000000000-000000000697223938_5_800x800.jpg",
"pics_mid": "http://image4.suning.cn/uimg/b2c/newcatentries/0000000000-000000000697223938_5_400x400.jpg",
"pics_sma": "http://image4.suning.cn/uimg/b2c/newcatentries/0000000000-000000000697223938_5_200x200.jpg",
"pics_big_url": "http://image4.suning.cn/uimg/b2c/newcatentries/0000000000-000000000697223938_5_800x800.jpg",
"pics_mid_url": "http://image4.suning.cn/uimg/b2c/newcatentries/0000000000-000000000697223938_5_400x400.jpg",
"pics_sma_url": "http://image4.suning.cn/uimg/b2c/newcatentries/0000000000-000000000697223938_5_200x200.jpg"
}
],
"attrs": [
{
"goods_id": 6,
"attr_id": 8568,
"attr_value": "",
"add_price": 0,
"attr_name": "主体-品牌",
"attr_sel": "only",
"attr_write": "manual",
"attr_vals": ""
},
{
"goods_id": 6,
"attr_id": 8569,
"attr_value": "除臭功能,杀菌功能,滤尘功能",
"add_price": 0,
"attr_name": "功能参数-附加功能",
"attr_sel": "only",
"attr_write": "manual",
"attr_vals": "除臭功能,杀菌功能,滤尘功能,芳香功能"
},
{
"goods_id": 6,
"attr_id": 8573,
"attr_value": "0.6千克",
"add_price": 0,
"attr_name": "规格-重量",
"attr_sel": "only",
"attr_write": "manual",
"attr_vals": "0.5千克"
}
]
},
"meta": {
"msg": "获取成功",
"status": 200
}
}
3. 关键技术
- swiper组件
- 本地存储实现 收藏功能
- 联系客服 ⼩程序管理后台中 直接添加即可
- 富⽂本标签 渲染 富⽂本
- ⼩程序 预览图⽚接⼝
二、商品详情⻚⾯相关代码
1.页面代码
代码语言:javascript复制<view class="detail_swiper">
<swiper
autoplay
circular
indicator-dots
>
<swiper-item
wx:for="{{goodsObj.pics}}"
wx:key="pics_id"
bindtap="handlePrevewImage"
data-url="{{item.pics_mid}}"
>
<image mode="widthFix" src="{{item.pics_mid}}" ></image>
</swiper-item>
</swiper>
</view>
<view class="goods_price">¥{{goodsObj.goods_price}}</view>
<view class="goods_name_row">
<view class="goods_name">{{goodsObj.goods_name}}{{goodsObj.goods_name}}</view>
<view class="goods_collect" bindtap="handleCollect" >
<text class="iconfont {{isCollect?'icon-shoucang1':'icon-shoucang'}} "></text>
<view class="collect_text">收藏</view>
</view>
</view>
<view class="goods_info">
<view class="goods_info_title">图文详情</view>
<view class="goods_info_content">
<!-- 富文本 -->
<!-- {{goodsObj.goods_introduce}} -->
<rich-text nodes="{{goodsObj.goods_introduce}}"></rich-text>
</view>
</view>
<view class="btm_tool">
<view class="tool_item">
<view class="iconfont icon-kefu"></view>
<view>客服</view>
<button open-type="contact"></button>
</view>
<view class="tool_item">
<view class="iconfont icon-yixianshi-"></view>
<view>分享</view>
<button open-type="share"></button>
</view>
<navigator open-type="switchTab" url="/pages/cart/index" class="tool_item">
<view class="iconfont icon-gouwuche"></view>
<view>购物车</view>
</navigator>
<view class="tool_item btn_cart " bindtap="handleCartAdd">
加入购物车
</view>
<view class="tool_item btn_buy">
立即购买
</view>
</view>
代码语言:javascript复制/*
1 发送请求获取数据
2 点击轮播图 预览大图
1 给轮播图绑定点击事件
2 调用小程序的api previewImage
3 点击 加入购物车
1 先绑定点击事件
2 获取缓存中的购物车数据 数组格式
3 先判断 当前的商品是否已经存在于 购物车
4 已经存在 修改商品数据 执行购物车数量 重新把购物车数组 填充回缓存中
5 不存在于购物车的数组中 直接给购物车数组添加一个新元素 新元素 带上 购买数量属性 num 重新把购物车数组 填充回缓存中
6 弹出提示
4 商品收藏
1 页面onShow的时候 加载缓存中的商品收藏的数据
2 判断当前商品是不是被收藏
1 是 改变页面的图标
2 不是 。。
3 点击商品收藏按钮
1 判断该商品是否存在于缓存数组中
2 已经存在 把该商品删除
3 没有存在 把商品添加到收藏数组中 存入到缓存中即可
*/
import { request } from "../../request/index.js";
import regeneratorRuntime from '../../lib/runtime/runtime';
Page({
/**
* 页面的初始数据
*/
data: {
goodsObj: {},
// 商品是否被收藏
isCollect:false
},
// 商品对象
GoodsInfo: {},
/**
* 生命周期函数--监听页面加载
*/
onShow: function () {
let pages = getCurrentPages();
let currentPage = pages[pages.length - 1];
let options = currentPage.options;
const { goods_id } = options;
this.getGoodsDetail(goods_id);
},
// 获取商品详情数据
async getGoodsDetail(goods_id) {
const goodsObj = await request({ url: "/goods/detail", data: { goods_id } });
this.GoodsInfo = goodsObj;
// 1 获取缓存中的商品收藏的数组
let collect = wx.getStorageSync("collect") || [];
// 2 判断当前商品是否被收藏
let isCollect = collect.some(v => v.goods_id === this.GoodsInfo.goods_id);
this.setData({
goodsObj: {
goods_name: goodsObj.goods_name,
goods_price: goodsObj.goods_price,
// iphone部分手机 不识别 webp图片格式
// 最好找到后台 让他进行修改
// 临时自己改 确保后台存在 1.webp => 1.jpg
goods_introduce: goodsObj.goods_introduce.replace(/.webp/g, '.jpg'),
pics: goodsObj.pics
},
isCollect
})
},
// 点击轮播图 放大预览
handlePrevewImage(e) {
// 1 先构造要预览的图片数组
const urls = this.GoodsInfo.pics.map(v => v.pics_mid);
// 2 接收传递过来的图片url
const current = e.currentTarget.dataset.url;
wx.previewImage({
current,
urls
});
},
// 点击 加入购物车
handleCartAdd() {
// 1 获取缓存中的购物车 数组
let cart = wx.getStorageSync("cart") || [];
// 2 判断 商品对象是否存在于购物车数组中
let index = cart.findIndex(v => v.goods_id === this.GoodsInfo.goods_id);
if (index === -1) {
//3 不存在 第一次添加
this.GoodsInfo.num = 1;
this.GoodsInfo.checked = true;
cart.push(this.GoodsInfo);
} else {
// 4 已经存在购物车数据 执行 num
cart[index].num ;
}
// 5 把购物车重新添加回缓存中
wx.setStorageSync("cart", cart);
// 6 弹窗提示
wx.showToast({
title: '加入成功',
icon: 'success',
// true 防止用户 手抖 疯狂点击按钮
mask: true
});
},
// 点击 商品收藏图标
handleCollect(){
let isCollect=false;
// 1 获取缓存中的商品收藏数组
let collect=wx.getStorageSync("collect")||[];
// 2 判断该商品是否被收藏过
let index=collect.findIndex(v=>v.goods_id===this.GoodsInfo.goods_id);
// 3 当index!=-1表示 已经收藏过
if(index!==-1){
// 能找到 已经收藏过了 在数组中删除该商品
collect.splice(index,1);
isCollect=false;
wx.showToast({
title: '取消成功',
icon: 'success',
mask: true
});
}else{
// 没有收藏过
collect.push(this.GoodsInfo);
isCollect=true;
wx.showToast({
title: '收藏成功',
icon: 'success',
mask: true
});
}
// 4 把数组存入到缓存中
wx.setStorageSync("collect", collect);
// 5 修改data中的属性 isCollect
this.setData({
isCollect
})
}
})
代码语言:javascript复制page {
padding-bottom: 90rpx;
}
.detail_swiper swiper {
height: 65vw;
text-align: center;
}
.detail_swiper swiper image {
width: 60%;
}
.goods_price {
padding: 15rpx;
font-size: 32rpx;
font-weight: 600;
color: var(--themeColor);
}
.goods_name_row {
border-top: 5rpx solid #dedede;
border-bottom: 5rpx solid #dedede;
padding: 10rpx 0;
display: flex;
}
.goods_name_row .goods_name {
flex: 5;
color: #000;
font-size: 30rpx;
padding: 0 10rpx;
display: -webkit-box;
overflow: hidden;
-webkit-box-orient: vertical;
-webkit-line-clamp: 2;
}
.goods_name_row .goods_collect {
flex: 1;
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
border-left: 1rpx solid #000;
}
.goods_name_row .goods_collect .icon-shoucang1 {
color: orangered;
}
.goods_info .goods_info_title {
font-size: 32rpx;
color: var(--themeColor);
font-weight: 600;
padding: 20rpx;
}
.btm_tool {
border-top: 1rpx solid #ccc;
position: fixed;
left: 0;
bottom: 0;
width: 100%;
height: 90rpx;
background-color: #fff;
display: flex;
}
.btm_tool .tool_item {
flex: 1;
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
font-size: 24rpx;
position: relative;
}
.btm_tool .tool_item button {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
opacity: 0;
}
.btm_tool .btn_cart {
flex: 2;
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
background-color: #ffa500;
color: #fff;
font-size: 30rpx;
font-weight: 600;
}
.btm_tool .btn_buy {
flex: 2;
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
background-color: #eb4450;
color: #fff;
font-size: 30rpx;
font-weight: 600;
}