Authored by 沈志敏

product部分

... ... @@ -6,7 +6,6 @@
'use strict';
const api = global.yoho.API;
const camelCase = global.yoho.camelCase;
const _ = require('lodash');
/**
... ... @@ -154,4 +153,4 @@ exports.getCancelReason = () => {
return api.get('', {
method: 'app.SpaceOrders.closeReasons'
});
};
\ No newline at end of file
};
... ...
... ... @@ -52,17 +52,6 @@ const component = {
res.json(result);
}).catch(next);
},
brand(req, res, next) {
const brandId = req.params[0];
model.brand({
uid: req.user.uid || 0,
brand_id: brandId,
gender: req.query.gender || '1,2,3'
}).then(result => {
res.json(result);
}).catch(next);
},
/**
* 加入购物车接口
... ... @@ -164,4 +153,4 @@ const component = {
}
};
module.exports = component;
\ No newline at end of file
module.exports = component;
... ...
... ... @@ -6,7 +6,6 @@
'use strict';
const api = global.yoho.API;
const camelCase = global.yoho.camelCase;
/**
* 商品详情
... ... @@ -34,18 +33,13 @@ const model = {
}
return result;
}).then(camelCase);
});
},
intro(params) {
return api.get('', Object.assign({
method: 'h5.product.intro'
}, params));
},
brand(params) {
return api.get('', Object.assign({
method: 'app.shop.queryShopsByBrandId'
}, params)).then(camelCase);
},
/**
* 加入购物车接口
... ... @@ -88,4 +82,4 @@ const model = {
}
};
module.exports = model;
\ No newline at end of file
module.exports = model;
... ...
... ... @@ -46,7 +46,6 @@ const detail = require(`${cRoot}/detail`);
router.get(/\/product\/pro_([\d]+)_([\d]+)\/(.*).html/, detail.index); // 商品详情routers
router.get(/\/product\/product_([\d]+)\.json/, detail.product);
router.get(/\/product\/intro_([\d]+)\.json/, detail.intro);
router.get(/\/product\/brand_([\d]+)\.json/, detail.brand);
router.post(/\product\/cart.json/, detail.addToCart);
router.post(/\product\/favorite.json/, auth, detail.favorite);
router.get(/\/product\/cart-count.json/, detail.getCartCount);
... ... @@ -68,4 +67,4 @@ router.get('/search.json', search.fetchProducts); // ajax
module.exports = router;
\ No newline at end of file
module.exports = router;
... ...
... ... @@ -5,8 +5,8 @@
<img :src="selection.thumbnail | resize 45 60"/>
</div>
<div class="text-box">
<h3 class="line-clamp-2">{{entity.productName}}</h3>
<h4>{{entity.formatSalesPrice !== '0' ? entity.formatSalesPrice : entity.formatMarketPrice}}</h4>
<h3 class="line-clamp-2">{{entity.product_name}}</h3>
<h4>{{entity.format_sales_price !== '0' ? entity.format_sales_price : entity.format_market_price}}</h4>
</div>
</div>
... ... @@ -67,7 +67,6 @@
margin-left: 24px;
max-width: 512px;
}
}
hr {
... ... @@ -100,7 +99,6 @@
line-height: 88px;
display: inline-block;
}
}
.add-to-cart {
... ... @@ -112,7 +110,6 @@
&.slide-in {
transform: translate3d(0, 0, 0);
}
}
.rotate-animation-target {
... ... @@ -231,54 +228,55 @@
const self = this;
// 更新颜色
this.colors = this.entity.goodsList.filter((goods)=> {
this.colors = this.entity.goods_list.filter((goods)=> {
// 确保商品启用
return goods.status !== 0;
}).map((goods)=> {
// 缩略图
thumbnails[goods.colorId] = goods.colorImage;
thumbnails[goods.color_id] = goods.color_image;
// 生成colorId 与 size的 映射
colorSizes[goods.colorId] = goods.sizeList.map((size)=> {
if (!stocks[goods.colorId]) {
stocks[goods.colorId] = 0;
// 生成color_id 与 size的 映射
colorSizes[goods.color_id] = goods.size_list.map((size)=> {
if (!stocks[goods.color_id]) {
stocks[goods.color_id] = 0;
}
// 默认选中有库存的第一个颜色尺码
if (size.storageNumber > 0) {
if (size.storage_number > 0) {
if (!selection.color) {
self.selection.color = selection.color = {
text: goods.colorName,
value: goods.colorId,
text: goods.color_name,
value: goods.color_id,
disabled: false
};
}
if (!selection.size && size.storageNumber > 0) {
if (!selection.size && size.storage_number > 0) {
self.selection.size = selection.size = {
text: size.sizeName,
value: size.productSku,
goodsId: goods.goodsId,
text: size.size_name,
value: size.product_sku,
goodsId: goods.goods_id,
disabled: false
};
}
}
// 计算所有尺码的库存
stocks[goods.colorId] += size.storageNumber;
stocks[goods.color_id] += size.storage_number;
return {
text: size.sizeName,
value: size.productSku,
disabled: size.storageNumber === 0,
goodsId: goods.goodsId
text: size.size_name,
value: size.product_sku,
disabled: size.storage_number === 0,
goodsId: goods.goods_id
};
});
return {
text: goods.colorName,
value: goods.colorId,
disabled: stocks[goods.colorId] === 0 // 是否售完
text: goods.color_name,
value: goods.color_id,
disabled: stocks[goods.color_id] === 0 // 是否售完
};
});
... ... @@ -383,7 +381,7 @@
return;
}
const param = Object.assign({goodsId: this.entity.productId}, this.selection);
const param = Object.assign({goodsId: this.entity.product_id}, this.selection);
this.onAddToCart(param, this);
},
... ...
... ... @@ -3,7 +3,7 @@
<swipe :continuous="false" :auto="0" :show-indicators="goods && goods.length > 1" v-ref:swipe>
<swipe-item v-for="item in goods">
<img title="{{item.title}}"
:src="item.colorImage | resize 750 1000"
:src="item.color_image | resize 750 1000"
width="100%" alt=""
@click.prevent="showcase()">
</swipe-item>
... ... @@ -60,7 +60,7 @@
showcase: function() {
const opts = {
images: this.goods.map((item) => {
return item.colorImage;
return item.color_image;
}).filter(image => image),
index: this.$refs.swipe.index
};
... ...
<template>
<top-nav v-if="isApp" :title="entity.productName" :img="firstImage | resize 300 300"></top-nav>
<top-nav v-if="isApp" :title="entity.product_name" :img="firstImage | resize 300 300"></top-nav>
<show-box :is-first="true">
<image-carousel :goods="entity.goodsList"></image-carousel>
<image-carousel :goods="entity.goods_list"></image-carousel>
<div class="title-box">
<h1 class="line-clamp-2">{{entity.productName}}</h1>
<i class="price" v-if="entity.marketPrice > entity.salesPrice"
:class="{'strike-through': entity.salesPrice > 0}">{{entity.formatMarketPrice}}</i>
<h1 class="line-clamp-2">{{entity.product_name}}</h1>
<i class="price" v-if="entity.market_price > entity.sales_price"
:class="{'strike-through': entity.sales_price > 0}">{{entity.format_market_price}}</i>
<i v-if="entity.salesPrice > 0"
:class="{price: true, highlight: entity.marketPrice > entity.salesPrice}">
{{entity.formatSalesPrice !== '0' ? entity.formatSalesPrice : entity.formatMarketPrice}}
<i v-if="entity.sales_price > 0"
:class="{price: true, highlight: entity.market_price > entity.sales_price}">
{{entity.format_sales_price !== '0' ? entity.format_sales_price : entity.format_market_price}}
</i>
</div>
</show-box>
<show-box class="brand" v-if="brand">
<img :src="brand.brandIco | resize 110 68"/>
<img :src="brand.brand_ico | resize 110 68"/>
<h2>{{brand.brandName}}</h2>
<h2>{{brand.brand_name}}</h2>
<div class="brand-go">
<span>进入店铺</span>
<span class="icon icon-right"></span>
</div>
<a :href="brand.brandDomain | brandUrl"></a>
<a :href="brand.brand_domain | brandUrl"></a>
</show-box>
<show-box v-if="intro.productDescBo">
... ... @@ -153,7 +153,7 @@
<h2>商品详情</h2>
<i>DETAILS</i>
<p v-if="brand && brand.brandIntro" v-lazy-html="brand.brandIntro">
<p v-if="brand && brand.brand_intro" v-lazy-html="brand.brand_intro">
</p>
<p v-if="brand && intro.productIntroBo" v-lazy-html="intro.productIntroBo.productIntro">
... ... @@ -169,7 +169,7 @@
</span>
</button>
<button class="button control-button" @click="toggleFavorite()">
<span v-if="entity.isCollect === 'Y' " class="icon icon-focused"></span>
<span v-if="entity.is_collect === 'Y' " class="icon icon-focused"></span>
<span v-else class="icon icon-focus"></span>
</button>
<button class="button button-solid add-to-cart"
... ... @@ -413,11 +413,7 @@
intro: {},
firstImage: '',
brand: null,
entity: {
productPriceBo: {
formatMarketPrice: ''
}
},
entity: {},
showFeatureSelector: false,
cartCount: 0,
... ... @@ -476,12 +472,12 @@
*/
toggleFavorite: function() {
$.post('/product/favorite.json', {
operation: this.entity.isCollect === 'Y' ? 'remove' : 'add',
id: this.entity.productId
operation: this.entity.is_collect === 'Y' ? 'remove' : 'add',
id: this.entity.product_id
}).then((result)=> {
if (result.code === 200) {
tip(this.entity.isCollect === 'Y' ? '取消收藏成功' : '收藏成功');
this.entity.isCollect = this.entity.isCollect === 'Y' ? 'N' : 'Y';
tip(this.entity.is_collect === 'Y' ? '取消收藏成功' : '收藏成功');
this.entity.is_collect = this.entity.is_collect === 'Y' ? 'N' : 'Y';
yoho.store.set('productReload', true);
} else if (result.code === 401) {
yoho.goLogin('', () => {
... ... @@ -517,20 +513,21 @@
return;
}
this.entity = result.data;
this.brand = result.data.brand_info;
if (this.entity.storage === 0 || this.entity.status === 0) {
this.isSoldOut = true;
}
const goodsList = this.entity.goodsList || [];
const goodsList = this.entity.goods_list || [];
goodsList.forEach((goods)=> {
if (!this.firstImage && goods.colorImage) {
this.firstImage = goods.colorImage;
if (!this.firstImage && goods.color_image) {
this.firstImage = goods.color_image;
}
});
share({
title: this.entity.productName,
title: this.entity.product_name,
link: location.href,
desc: '我在BLK发现了一个不错的商品,快来看看吧!',
imgUrl: this.firstImage.replace(/(\{width}|\{height}|\{mode})/g, function($0) {
... ... @@ -548,18 +545,12 @@
}).then((data)=> {
if (data) {
// 读取商品详情
$.get(`/product/product/intro_${pid}.json`, {skn: data.productSkn}).then(intro => {
$.get(`/product/product/intro_${pid}.json`, {skn: data.product_skn}).then(intro => {
this.intro = intro;
if (this.intro.sizeImage) {
this.intro.sizeImage = this.intro.sizeImage.replace(/https?:/, '');
}
});
if (data.brandInfo && data.brandInfo.brandId) {
$.get(`/product/product/brand_${data.brandInfo.brandId}.json`).then(brand => {
this.brand = brand.data && brand.data.length ? brand.data[0] : {};
});
}
}
})
.always(() => {
... ...