Authored by 姜枫

merge from feature/product

/**
* 商品详情页controller
* @author: yyq<yanqing.yang@yoho.cn>
* @date: 2016/7/4
*/
'use strict';
const index = (req, res) => {
let data = {
goodInfo: {
name: 'Spring 2016NEWT-Shirt 2016迷彩蝴蝶夹克',
brandName: 'Supreme',
intro: '2016最新发布',
img: 'http://placehold.it/{width}x{height}',
sellPrice: 3199,
marketPrice: 4009,
colors: [
{
name: '黑色',
title: '黑色',
focus: true,
thumbs: [
'http://placehold.it/{width}x{height}',
'http://placehold.it/{width}x{height}',
'http://placehold.it/{width}x{height}',
'http://placehold.it/{width}x{height}',
'http://placehold.it/{width}x{height}'
],
sizes: [
{
name: 'S',
title: 'S',
sku: '12313',
num: 10
},
{
name: 'M',
title: 'M',
sku: '12314',
num: 14
},
{
name: 'L',
title: 'L',
sku: '12315',
num: 0
},
{
name: 'XL',
title: 'XL',
sku: '12316',
num: 0
}
],
rgb: '#000'
},
{
name: '黄色',
title: '黄色',
thumbs: [
'http://placehold.it/{width}x{height}',
'http://placehold.it/{width}x{height}'
],
rgb: '#efdc0e',
sizes: [
{
name: 'S',
title: 'S',
sku: '12313',
num: 0
},
{
name: 'M',
title: 'M',
sku: '12314',
num: 14
},
{
name: 'L',
title: 'L',
sku: '12315',
num: 0
},
{
name: 'XL',
title: 'XL',
sku: '12316',
num: 23
}
]
},
{
name: '蓝色',
title: '蓝色',
thumbs: [
'http://placehold.it/{width}x{height}',
'http://placehold.it/{width}x{height}',
'http://placehold.it/{width}x{height}',
'http://placehold.it/{width}x{height}'
],
rgb: '#2ea8e6'
},
{
name: '绿色',
title: '绿色',
thumbs: [
'http://placehold.it/{width}x{height}',
'http://placehold.it/{width}x{height}',
'http://placehold.it/{width}x{height}',
'http://placehold.it/{width}x{height}'
],
rgb: '#85b2ef'
}
]
}
};
res.display('item', data);
};
module.exports = {
index // 组件demo页
};
... ...
'use strict';
const _ = require('lodash');
const Search = require('../models/list');
const camelCase = global.yoho.camelCase;
function brandLetters() {
let letters = [];
letters.push({
letter: '0-9',
selected: false
});
for (let i = 'A'.charCodeAt(0); i <= 'Z'.charCodeAt(0); i++) {
letters.push({
letter: String.fromCharCode(i),
selected: false
});
}
return letters;
}
function peopleChoose() {
return [
{
name: '男士',
value: '1,3'
}, {
name: '女士',
value: '2,3'
}];
}
function colorConver(colors) {
return colors.map(c => {
return {
id: c.colorId,
title: c.colorName,
rgb: c.colorValue || '#' + c.colorCode
};
});
}
function newFilter(key, value, name) {
return {
key: key,
value: value,
name: name
};
}
const list = {
index: (req, res, next) => {
let page = req.query.page || 1;
let brand = req.query.brand || 0;
let sort = req.query.sort || '';
let gender = req.query.gender || '';
let price = req.query.price || '';
let size = req.query.size || '';
let color = req.query.color || '';
Search.queryProduct({
page: page,
brand: brand,
sort: sort,
gender: gender,
size: size,
price: price,
color: color
}).then(result => {
if (result && result.code === 200 && result.data) {
let data = camelCase(result.data);
let ret = {};
if (data.filter) {
let priceRange = data.filter.priceRange;
let sizeInfo = data.filter.size;
let genders = peopleChoose(gender);
let brands = data.filter.brand;
let colors = colorConver(data.filter.color);
let sorts = data.filter.groupSort;
let filters = [];
genders.forEach(g => {
if (g.value === gender) {
g.checked = true;
filters.push(newFilter('gender', gender, g.name));
}
});
priceRange = Object.keys(priceRange).map((k) => {
let prices = k.split(',');
if (k === price) {
filters.push(newFilter('price', price, ${prices[0]}-¥${prices[1]}`));
}
return {
lower: prices[0],
higher: prices[1]
};
}).sort((a, b) => {
return a.lower - b.lower;
});
if (!_.isArray(sizeInfo)) {
sizeInfo.checked = true;
sizeInfo = [sizeInfo];
}
if (size) {
sizeInfo.forEach(s => {
if (s.sizeId === parseInt(size)) {
filters.push(newFilter('size', size, s.sizeName));
}
});
}
if (brand) {
let brandNames = brands.filter(b => {
return (',' + brand + ',').indexOf(',' + b.id + ',') >= 0;
}).map(b => {
return b.brandName;
}).join('、');
filters.push(newFilter('brand', brand, brandNames));
}
if (color) {
colors.forEach(c => {
if (c.id === parseInt(color)) {
c.cur = true;
let fi = newFilter('color', color, c.title);
fi.color = c;
filters.push(fi);
}
});
}
ret = {
people: genders,
sortData: sorts,
brandData: brands,
colors: colors,
size: sizeInfo,
priceRange: priceRange,
filters: filters,
showFilters: filters.length > 0
};
}
res.display('list', _.assign(ret, {
letters: brandLetters(),
total: data.total,
pageTotal: data.pageTotal,
pageNo: data.page,
products: data.productList,
navPath: {
nav: true,
pathNav: [
{
link: true,
href: '',
pathTitle: '',
name: 'MEN首页'
},
{
link: true,
href: '',
pathTitle: '',
name: '咨询'
},
{
link: false,
href: '',
pathTitle: '',
name: '咨询'
}
]
},
module: 'product',
page: 'list',
title: '列表'
}));
} else {
throw 'query product error';
}
}).catch(next);
}
};
module.exports = list;
... ...
/**
* sub app product
* @author: jiangfeng<jeff.jiang@yoho.cn>
* @date: 2016/07/02
*/
var express = require('express'),
path = require('path'),
hbs = require('express-handlebars');
var app = express();
// set view engin
var doraemon = path.join(__dirname, '../../doraemon/views'); // parent view root
var partials = path.join(__dirname, './views'); // parent view root
app.on('mount', function(parent) {
delete parent.locals.settings; // 不继承父 App 的设置
Object.assign(app.locals, parent.locals);
});
app.set('views', path.join(__dirname, 'views/action'));
app.engine('.hbs', hbs({
extname: '.hbs',
defaultLayout: 'layout',
layoutsDir: doraemon,
partialsDir: [`${partials}/partial`, `${doraemon}/partial`],
helpers: global.yoho.helpers
}));
// router
app.use(require('./router'));
module.exports = app;
... ...
'use strict';
const SearchAPI = global.yoho.SearchAPI;
const api = global.yoho.API;
const logger = global.yoho.logger;
const camelCase = global.yoho.camelCase;
const _ = require('lodash');
function clearEmptyVal(obj) {
_.keys(obj).forEach(k => {
if (obj[k] === null || obj[k] === '') {
_.unset(obj, k);
}
});
return obj;
}
const Search = {
querySort(query) {
return SearchAPI.get('sortgroup.json', _.assign({
sales: 'Y',
status: 1,
stocknumber: 1
}, query)).then(data => {
if (data && data.code === 200 && data.data) {
return camelCase(data.data.sort);
} else {
return [];
}
}).catch(e => {
logger.error(e);
return Promise.resolve([]);
});
},
queryProduct(params) {
let finalParams = {
method: 'app.search.sales',
limit: 45,
order: 's_t_desc',
productSize: '384x511',
yh_channel: 1
};
Object.assign(finalParams, clearEmptyVal(params));
return api.get('', finalParams);
}
};
module.exports = Search;
... ...
/**
* router of sub app partial
* @author: xuqi<qi.xu@yoho.cn>
* @date: 2016/06/30
*/
'use strict';
const router = require('express').Router(); // eslint-disable-line
const cRoot = './controllers';
const list = require(cRoot + '/list');
const item = require(cRoot + '/item');
// Your controller here
router.get('/list', list.index); // 组件demo页
router.get(/\/item\/([\d]+)_([\d]+).html/, item.index); // 商品详情页
module.exports = router;
... ...
<div class="product-item-page yoho-page">
<div class="center-content">
{{> path-nav}}
{{# goodInfo}}
<div class="product-main clearfix">
<div class="thumbs left clearfix">
<div class="thumb-list">
{{# colors}}
<div class="thumb-wrap{{#unless focus}} hide{{/unless}}">
{{#if focus}}
{{# thumbs}}
<img class="thumb" src="{{image . 75 100}}" data-shower="{{image . 482 643}}">
{{/ thumbs}}
{{^}}
{{# thumbs}}
<img class="thumb" data-original="{{image . 75 100}}" data-shower="{{image . 482 643}}">
{{/ thumbs}}
{{/if}}
</div>
{{/ colors}}
</div>
<div class="thumb-show right">
<img id="main-thumb" src="{{image img 482 643}}" style="display: block;">
</div>
</div>
<div class="infos left clearfix">
<p class="brand-name">{{brandName}}</p>
<p class="name">{{name}}</p>
<p class="intro">{{intro}}</p>
<p class="sell-price">¥{{round sellPrice 2}}</p>
{{#if marketPrice}}
<p class="market-price">¥{{round marketPrice 2}}</p>
{{/if}}
<div class="trade-wrapper">
<div class="option-content">
<p class="choose-color">
<label class="title">Color:</label>
<span class="color">蓝色</span>
</p>
<div class="color-list">
{{# colors}}
{{> round-color}}
{{/ colors}}
</div>
<p class="choose-size">
<label class="title">Size:</label>
<span class="size">M</span>
</p>
<div class="sizes">
{{# colors}}
<ul class="size-list {{#unless focus}}hide{{/unless}} clearfix">
{{# sizes}}
<li {{#unless num}}class="disable"{{/unless}} data-title="{{title}}" data-sku="{{sku}}" data-num="{{num}}">{{name}}</li>
{{/ sizes}}
</ul>
{{/ colors}}
</div>
</div>
<p class="btns">
{{# fashionTopGoods}}
{{#if buyNow}}
<span class="btn">立即购买</span>
{{/if}}
{{#if openSoon}}
<span class="btn">即将开售</span>
{{/if}}
{{^}}
<span class="btn">加入购物袋</span>
{{/ fashionTopGoods}}
<span class="btn disable">已售罄</span>
<span class="btn white">收藏商品</span>
</p>
</div>
</div>
</div>
{{/ goodInfo}}
</div>
</div>
\ No newline at end of file
... ...
<div class="yoho-product-list">
<div class="center-content">
{{# navPath}}
{{> path-nav}}
{{/ navPath}}
</div>
<div class="center-content clearfix">
<div class="left">
{{> list/filter}}
</div>
<div class="right">
{{> list/filter-area}}
</div>
</div>
</div>
\ No newline at end of file
... ...
{{#if showFilters}}
<div class="filter-area">
<label>已选条件:</label>
{{#each filters}}
<div class="filter-item" data-key="{{key}}">
{{#color}}
{{> round-color}}
{{/color}}
<span class="label">{{name}}</span>
<span class="iconfont cancel">&#xe61d;</span>
</div>
{{/each}}
<label class="cancel">清空筛选条件</label>
</div>
{{/if}}
<div class="order-area">
<div class="order selected">综合</div>
<div class="order">上新时间</div>
<div class="order">价格</div>
<div class="dest">
<span class="iconfont up">&#xe617;</span>
<span class="iconfont down selected">&#xe616;</span>
</div>
<div class="right">
<label>
<span>{{total}}</span>件商品
</label>
<label class="page-info">{{pageNo}}/{{pageTotal}}</label>
<span class="iconfont page disable page-pre">&#xe607;</span>
<span class="iconfont page page-next">&#xe61e;</span>
</div>
</div>
<div class="goods-area">
{{#each products}}
<div class="goods" data-id="{{productId}}">
<div class="goods-img">
<img src="{{image defaultImages 265 344}}" width="265" height="344" alt="">
</div>
<div class="goods-brand">
{{brandName}}
</div>
<div class="goods-name">
{{productName}}
</div>
<div class="goods-price">
<span>¥{{salesPrice}}</span>
{{#if marketPrice}}
<b>¥{{marketPrice}}</b>
{{/if}}
</div>
<div class="goods-list hide">
{{#each goodsList}}
<i>{{image imagesUrl 265 344}}</i>
{{/each}}
</div>
</div>
{{/each}}
<div class="goods-wrapper">
<div class="goods">
</div>
<div class="goods-img-list">
</div>
</div>
</div>
{{{ pagination paginationOpts }}}
\ No newline at end of file
... ...
<div class="yoho-ui-accordion">
<h3>适用人群</h3>
<div class="body sex-body">
{{#each people}}
<div class="input-radio" data-value="{{value}}">
{{> icon/radio}}
<label>{{name}}</label>
</div>
{{/each}}
</div>
</div>
<div class="blank-div"></div>
<div class="title">全部品类</div>
<div class="yoho-ui-accordion no-active">
{{#each sortData}}
<h3>{{categoryName}}</h3>
<div class="body" data-value="{{categoryId}}">
<div class="list-body">
{{#each sub}}
<div class="input-radio" data-value="{{categoryId}}">
{{> icon/radio }}
<label>{{categoryName}}</label>
</div>
{{/each}}
</div>
</div>
{{/each}}
</div>
<div class="blank-div"></div>
<div class="yoho-ui-accordion">
<h3>品牌</h3>
<div class="body">
<div class="brand-body">
<input type="text" class="brand-search" placeholder="输入您要查找的品牌">
</div>
<div class="brand-letter-items">
<span class="item item-all" data-value="">全部</span>
{{#each letters}}
<span class="item" data-value="{{letter}}">{{letter}}</span>
{{/each}}
<span class="mulit-choose">
多选 +
</span>
</div>
<div class="brand-list">
{{#each brandData}}
<div class="input-radio" data-value="{{id}}">
{{> icon/radio}}
<label>{{brandNameEn}}</label>
</div>
{{/each}}
</div>
<div class="brand-btns hide">
<span class="btn disable large confirm">确定</span>
<span class="btn large cancel">取消</span>
</div>
</div>
</div>
<div class="yoho-ui-accordion">
<h3>价格</h3>
<div class="body price-body">
{{#each priceRange}}
<div class="input-radio" data-value="{{lower}},{{higher}}">
{{> icon/radio }}
<label>¥{{lower}}{{higher}}</label>
</div>
{{/each}}
<div class="price-btns">
<div class="price-input inline-block">
<span>¥</span>
<input type="text">
</div>
<span></span>
<div class="price-input inline-block">
<span>¥</span>
<input type="text">
</div>
<span class="btn large">确定</span>
</div>
</div>
</div>
<div class="yoho-ui-accordion">
<h3>尺码</h3>
<div class="body">
<div class="size-body">
{{#each size}}
<div class="input-radio" data-value="{{sizeId}}">
{{> icon/radio }}
<label>{{sizeName}}</label>
</div>
{{/each}}
</div>
</div>
</div>
<div class="yoho-ui-accordion">
<h3>颜色</h3>
<div class="body">
<div class="color-body">
{{#each colors}}
<div class="input-radio" data-value="{{id}}">
{{> round-color}}
<label>{{title}}</label>
</div>
{{/each}}
</div>
</div>
</div>
\ No newline at end of file
... ...
... ... @@ -13,9 +13,12 @@ module.exports = {
app: 'web',
appVersion: '4.6.0', // 调用api接口版本
port: 6003,
siteUrl: 'http://www.yohoblk.com',
siteUrl: '//www.yohoblk.com',
subDomains: {
default: '//www.yohoblk.com'
},
domains: {
api: 'http://devapi.yoho.cn:58078/', // devapi.yoho.cn:58078 testapi.yoho.cn:28078 devapi.yoho.cn:58078
api: 'http://api.yoho.yohoops.org/', // devapi.yoho.cn:58078 testapi.yoho.cn:28078 devapi.yoho.cn:58078
service: 'http://devservice.yoho.cn:28077/', // testservice.yoho.cn:28077 devservice.yoho.cn:58077
search: 'http://192.168.102.216:8080/yohosearch/'
},
... ...
... ... @@ -11,6 +11,7 @@ module.exports = app => {
// 业务模块
// app.use('/passport', require('./apps/passport'));
app.use('/product', require('./apps/product'));
app.use('/', require('./apps/channel')); // 频道页
app.use('/me', require('./apps/me')); // 个人中心
... ...
<label class="round-color{{#if cur}} cur{{/if}}" title="{{title}}" data-color="{{color}}" data-color="{{total}}" style="background: {{rgb}}">
<span class="iconfont icon-cover">&#xe61b;</span>
<span class="iconfont icon-round">&#xe620;</span>
</label>
\ No newline at end of file
... ...
... ... @@ -52,7 +52,7 @@
"uuid": "^2.0.2",
"winston": "^2.2.0",
"winston-daily-rotate-file": "^1.1.4",
"yoho-node-lib": "0.0.11"
"yoho-node-lib": "0.0.17"
},
"devDependencies": {
"autoprefixer": "^6.3.6",
... ... @@ -92,6 +92,7 @@
"webpack-stream": "^3.1.0",
"yoho-handlebars": "^4.0.5",
"yoho-jquery": "^1.12.4",
"yoho-jquery-accordion": "0.0.1",
"yoho-jquery-lazyload": "^1.9.7",
"yoho-jquery-placeholder": "^2.3.1",
"yoho-slider": "0.0.2"
... ...
No preview for this file type
... ... @@ -2,7 +2,7 @@
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd" >
<svg xmlns="http://www.w3.org/2000/svg">
<metadata>
Created by FontForge 20120731 at Wed Jul 6 11:07:02 2016
Created by FontForge 20120731 at Wed Jul 6 16:36:19 2016
By admin
</metadata>
<defs>
... ... @@ -19,7 +19,7 @@ Created by FontForge 20120731 at Wed Jul 6 11:07:02 2016
bbox="0 -212 1303 896.303"
underline-thickness="50"
underline-position="-100"
unicode-range="U+0078-E620"
unicode-range="U+0078-E621"
/>
<missing-glyph horiz-adv-x="374"
d="M34 0v682h272v-682h-272zM68 34h204v614h-204v-614z" />
... ... @@ -114,8 +114,12 @@ q87 0 167 -34.5t138 -92t92 -137.5t34 -168v-113h-129q-15 0 -24.5 -10t-9.5 -25v-31
d="M783 526l-45 45l-226 -226l-226 226l-45 -45l226 -226l-226 -226l45 -46l226 227l226 -227l45 46l-226 226z" />
<glyph glyph-name="uniE61E" unicode="&#xe61e;"
d="M384 570l48 50l338 -335l-338 -335l-48 49l284 286z" />
<glyph glyph-name="uniE61F" unicode="&#xe61f;" horiz-adv-x="1000"
d="M459 850h55h54v-120v-142v-120h191h191v-109h-191h-191v-191v-190h-109v190v191h-191h-190q-1 37 -1 109h191h191v382z" />
<glyph glyph-name="uniE620" unicode="&#xe620;"
d="M512 886q-102 0 -195 -39.5t-160.5 -107t-107 -160.5t-39.5 -195t39.5 -195t107 -160.5t160.5 -107t195 -39.5t195 39.5t160.5 107t107 160.5t39.5 195t-39.5 195t-107 160.5t-160.5 107t-195 39.5zM512 -79q-94 0 -180 36.5t-148 98.5t-98.5 148t-36.5 180t36.5 180
t98.5 148t148 98.5t180 36.5t180 -36.5t148 -98.5t98.5 -148t36.5 -180t-36.5 -180t-98.5 -148t-148 -98.5t-180 -36.5z" />
<glyph glyph-name="uniE621" unicode="&#xe621;" horiz-adv-x="1000"
d="M77 468h873v-109h-873v109z" />
</font>
</defs></svg>
... ...
No preview for this file type
No preview for this file type
var jQuery = require('yoho-jquery');
((function($) {
var defaultsHtml = {
radio: {
uncheckedHtml: '&#xe604;',
checkedHtml: '&#xe603;'
},
checkbox: {
uncheckedHtml: '&#xe604;',
checkedHtml: '&#xe603;'
}
};
var defaults = {
type: 'radio',
single: false
};
var check = {
init: function(options) {
var type = options.type || defaults.type;
var ele = this;
options = $.extend({}, defaults, defaultsHtml[type], options);
$(this).data('options', options);
$(this).off().on('click', function() {
var icon = $(this).find('.' + options.type);
var checked = $(icon).hasClass('checked');
if (checked) {
$(icon).removeClass('checked');
$(icon).html(options.uncheckedHtml);
} else {
$(icon).addClass('checked');
$(icon).html(options.checkedHtml);
}
if (typeof options.onChange === 'function') {
options.onChange(ele, !checked, $(ele).data('value'));
}
});
},
checkAll: function() {
$(this).each(function() {
var options = $(this).data('options');
check._check(this, options);
});
},
unCheckAll: function() {
$(this).each(function() {
var options = $(this).data('options');
check._uncheck(this, options);
});
},
_check: function(ele, options) {
var icon = $(ele).find('.' + options.type);
var checked = $(icon).hasClass('checked');
if (!checked) {
$(icon).addClass('checked');
$(icon).html(options.checkedHtml);
if (typeof options.onChange === 'function') {
options.onChange(ele, !checked, $(ele).data('value'));
}
}
},
_uncheck: function(ele, options) {
var icon = $(ele).find('.' + options.type);
var checked = $(icon).hasClass('checked');
if (checked) {
$(icon).removeClass('checked');
$(icon).html(options.uncheckedHtml);
if (typeof options.onChange === 'function') {
options.onChange(ele, !checked, $(ele).data('value'));
}
}
}
};
$.fn.check = function(options, param) {
if (typeof options === 'string') {
return check[options].call(this, param);
} else {
return $(this).each(function() {
check.init.call(this, options);
});
}
};
})(jQuery));
... ...
var $ = require('yoho-jquery');
var common = require('../common');
var YohoListPage = {
rootDoc: $('.yoho-product-list'),
brandsDoc: $('.yoho-product-list .brand-list'),
mulitBrand: false,
goodsWrapper: $('.goods-area .goods-wrapper'),
goodsWrapperState: false,
init: function() {
require('yoho-jquery-accordion');
require('../plugins/check');
$('.yoho-ui-accordion', this.rootDoc).each(function() {
var opts = {
collapsible: true,
heightStyle: 'content'
};
if ($(this).hasClass('no-active')) {
opts.active = false;
}
$(this).accordion(opts);
});
$('.yoho-product-list .sex-body .input-radio').check({
type: 'radio',
onChange: function(ele, checked, value) {
YohoListPage.go({
gender: checked ? value : ''
});
}
});
$('.yoho-product-list .list-body .input-radio').check({
type: 'radio',
onChange: function(ele, checked, value) {
YohoListPage.go({
sort: checked ? value : ''
});
}
});
$('.yoho-product-list .price-body .input-radio').check({
type: 'radio',
onChange: function(ele, checked, value) {
YohoListPage.go({
price: checked ? value : ''
});
}
});
$('.yoho-product-list .size-body .input-radio').check({
type: 'radio',
onChange: function(ele, checked, value) {
YohoListPage.go({
size: checked ? value : ''
});
}
});
$('.yoho-product-list .brand-list .input-radio').check({
type: 'radio',
onChange: function(ele, checked, value) {
if (!YohoListPage.mulitBrand) {
YohoListPage.go({brand: value});
} else {
YohoListPage.showBrandMulitBtn();
}
}
});
$('.yoho-product-list .color-body .input-radio').check({
type: 'radio',
onChange: function(ele, checked, value) {
YohoListPage.go({
color: checked ? value : ''
});
}
});
YohoListPage.eventBind();
},
eventBind: function() {
$('.yoho-product-list .mulit-choose').click(function() {
YohoListPage.openBrandMulitChoose();
});
$('.yoho-product-list .brand-btns .cancel').click(function() {
YohoListPage.closeBrandMulitChoose();
});
$('.yoho-product-list .brand-btns .confirm').click(function() {
if (!$(this).hasClass('disable')) {
YohoListPage.go({
brand: YohoListPage.getSelectBrands().join(',')
});
}
});
$('.yoho-product-list .brand-body input').on('keyup', function() {
YohoListPage.filterBrand($(this).val().toLowerCase());
});
$('.yoho-product-list .brand-letter-items .item').hover(function() {
$('.yoho-product-list .brand-letter-items .item').removeClass('select');
$(this).addClass('select');
YohoListPage.filterBrand($(this).data('value').toLowerCase());
});
$('.goods-area > .goods').mouseenter(function(e) {
YohoListPage.showGoodsWrapper(e);
});
$('.goods-wrapper').mouseleave(function(e) {
YohoListPage.hideGoodsWrapper(e);
});
$('.filter-area .filter-item').click(function() {
var key = $(this).data('key');
var data = {};
data[key] = '';
YohoListPage.go(data);
});
$('.filter-area .cancel').click(function() {
var data = {};
$('.filter-area .filter-item').each(function() {
var key = $(this).data('key');
data[key] = '';
});
YohoListPage.go(data);
});
},
openBrandMulitChoose: function() {
$('.yoho-product-list .mulit-choose').hide();
YohoListPage.mulitBrand = true;
YohoListPage.showBrandMulitBtn();
},
closeBrandMulitChoose: function() {
$('.yoho-product-list .mulit-choose').show();
$('.yoho-product-list .brand-btns').addClass('hide');
$('.yoho-product-list .brand-list .input-radio').check('unCheckAll');
YohoListPage.mulitBrand = false;
},
showBrandMulitBtn: function() {
$('.brand-btns', this.rootDoc).removeClass('hide');
if (YohoListPage.getSelectBrands().length > 0) {
$('.brand-btns .confirm', this.rootDoc).removeClass('disable');
} else {
$('.brand-btns .confirm', this.rootDoc).addClass('disable');
}
},
filterBrand: function(letter) {
$('.yoho-product-list .brand-list .input-radio').each(function() {
if ($('label', this).text().toLowerCase().indexOf(letter) === 0) {
$(this).show();
} else {
$(this).hide();
}
});
},
getSelectBrands: function() {
let brands = [];
$('.input-radio .radio', this.brandsDoc).each(function() {
if ($(this).hasClass('checked')) {
brands.push($(this).parent().data('value'));
}
});
return brands;
},
showGoodsWrapper: function(e) {
var position = $(e.currentTarget).position();
var productId = $(e.currentTarget).data('id');
if (YohoListPage.goodsWrapperState && YohoListPage.productId !== productId) {
YohoListPage.goodsWrapperState = false;
}
if (!YohoListPage.goodsWrapperState) {
YohoListPage.productId = productId;
position.top += 10;
$(this.goodsWrapper).css(position);
$('.goods', this.goodsWrapper).html($(e.currentTarget).html());
$('.goods-img-list', this.goodsWrapper).empty();
$(e.currentTarget).find('.goods-list i').each(function() {
$('.goods-img-list', this.goodsWrapper).append(
'<img src="' + $(this).text() + '" width="60" height="80" alt="">');
});
$(this.goodsWrapper).show();
YohoListPage.goodsWrapperState = true;
$('.goods-img-list img', this.goodsWrapper).hover(function() {
$('.goods .goods-img img', YohoListPage.goodsWrapper).attr('src', $(this).attr('src'));
});
}
},
hideGoodsWrapper: function() {
YohoListPage.goodsWrapperState = false;
$('.goods-area .goods-wrapper').hide();
},
go: function(q) {
var qs = $.extend(common.queryString(), q);
location.search = $.param(qs);
}
};
YohoListPage.init();
... ...
... ... @@ -7,3 +7,4 @@
@import "floor"; /* 楼层头部 */
@import "cascading-address"; /* 区域/地址组件 */
@import "dialog"; /* 对话框组件 */
@import "round-color"; /* 色彩选择组件 */
... ...
.round-color {
width: 30px;
height: 30px;
text-align: center;
display: inline-block;
cursor: pointer;
position: relative;
.iconfont {
font-size: 30px;
}
.icon-cover {
color: #fff;
}
.icon-round {
color: #eee;
top: 0;
left: 0;
position: absolute;
}
&.cur .icon-round {
color: #1d1d1d;
font-weight: bold;
}
}
... ...
... ... @@ -10,6 +10,8 @@
@import "channel/index";
@import "base";
@import "components/index";
@import "product/index";
@import "channel/index";
/* 资讯 */
@import "editorial/index";
... ...
@import 'list';
@import 'item';
... ...
.product-item-page {
.thumbs {
width: 596px;
height: 643px;
.thumb-list {
width: 75px;
display: inline-block;
vertical-align: middle;
}
}
.infos {
width: 554px;
> p {
text-align: center;
}
.brand-name {
font-size: 24px;
font-weight: bold;
}
.name {
font-size: 14px;
font-weight: bold;
line-height: 1.5;
margin: 16px 0 8px;
}
.intro {
font-size: 12px;
}
.sell-price {
font-size: 20px;
font-weight: bold;
margin-top: 38px;
}
.market-price {
color: #c1c1c1;
font-size: 12px;
margin-top: 6px;
text-decoration: line-through;
}
.option-content {
width: 226px;
margin: 0 auto;
padding: 40px 0;
> p {
line-height: 50px;
}
.title {
color: #c1c1c1;
}
}
.color-list {
width: 246px;
.round-color {
margin-right: 20px;
}
}
.size-list {
width: 236px;
li {
height: 34px;
line-height: 34px;
float: left;
padding: 0 12px;
margin-right: 10px;
text-align: center;
border: 1px solid #f0f0f0;
font-weight: bold;
cursor: pointer;
}
.cur {
border: 2px solid #1d1d1d;
}
.disable {
color: #f0f0f0;
cursor: default;
border-color: #f0f0f0 !important;
}
}
.btns {
.btn {
width: 300px;
height: 46px;
line-height: 46px;
margin: 0 auto 20px;
}
}
}
}
... ...
.yoho-product-list {
font-size: 14px;
.center-content {
.left {
width: 250px;
}
.right {
width: 850px;
}
}
.input-radio {
padding: 10px 0;
.round-color {
width: 16px;
height: 15px;
.iconfont {
font-size: 16px;
}
.iconfont.icon-cover {
font-size: 16px;
}
}
}
.input-radio span {
margin-left: 0;
font-size: 14px;
display: inline-block;
}
.input-radio label {
font-size: 14px;
font-weight: 700;
margin-left: 10px;
display: inline-block;
}
.input-radio label.round-color {
margin-left: 0;
}
.blank-div {
height: 70px;
}
.title {
font-size: 14px;
font-weight: 700;
height: 40px;
line-height: 40px;
border-bottom: 1px solid #eee;
}
.list-body,
.size-body,
.color-body,
.brand-list {
max-height: 240px;
overflow-y: auto;
}
.brand-body {
margin: 5px 0;
.brand-search {
border: 0;
background-color: #eae9e9;
width: 100%;
height: 40px;
padding: 0 8px;
color: #333;
font-weight: 700;
}
}
.brand-letter-items {
margin: 15px 0;
font-size: 12px;
font-weight: bolder;
span {
padding: 5px 0;
margin: 5px 11px 5px 0;
display: inline-block;
}
.select {
color: #379ed6;
}
.mulit-choose {
border: 1px solid #1b1b1b;
padding: 5px 10px;
}
}
.brand-btns {
text-align: center;
margin-top: 10px;
.btn {
margin: 0 10px;
}
}
.btn {
display: inline-block;
}
.btn.large {
height: 38px;
line-height: 38px;
font-size: 14px;
}
.price-btns {
.price-input {
background-color: #eee;
width: 72px;
height: 38px;
line-height: 38px;
span {
height: 36px;
line-height: 36px;
margin-top: 1px;
display: inline-block;
padding: 0 3px;
}
input {
border: 0;
background-color: transparent;
width: 50px;
height: 38px;
line-height: 38px;
padding: 0;
font-size: 14px;
font-family: 'BrownStd', '黑体';
}
}
.btn {
margin-left: 4px;
}
}
.yoho-ui-accordion {
h3 {
font-size: 14px;
font-weight: 700;
height: 40px;
line-height: 40px;
border-bottom: 1px solid #eee;
display: block;
cursor: pointer;
position: relative;
.ui-accordion-header-icon {
position: absolute;
right: 0.5em;
top: 50%;
margin-top: -20px;
}
.ui-accordion-header-icon:after {
font-family: "iconfont" !important;
display: inline-block;
content: "\e616";
}
}
h3.ui-accordion-header-active {
.ui-accordion-header-icon:after {
font-family: "iconfont" !important;
display: inline-block;
content: "\e617";
}
}
> .body {
padding: 10px 0;
border-bottom: 1px solid #eee;
}
}
.filter-area {
background-color: #eae9e9;
margin-bottom: 30px;
label {
font-size: 14px;
font-weight: 700;
margin-left: 20px;
}
label.cancel {
float: right;
color: #878787;
margin: 22px 20px 0 0;
}
.filter-item {
display: inline-block;
margin: 12px 10px;
padding: 10px 5px;
font-size: 14px;
border: 1px solid #adacad;
background-color: #fff;
span {
font-size: 14px;
}
span.label {
margin: 0 4px;
}
span.cancel {
font-size: 14px;
}
.round-color {
width: 16px;
height: 15px;
.iconfont {
font-size: 16px;
}
.iconfont.icon-cover {
font-size: 16px;
}
}
}
}
.order-area {
border-top: 1px solid #eee;
border-bottom: 1px solid #eee;
color: #878787;
font-weight: 700;
.order {
display: inline-block;
margin: 14px 15px;
height: 24px;
line-height: 24px;
}
.dest {
display: inline-block;
position: relative;
width: 15px;
height: 24px;
line-height: 24px;
margin: 14px 15px;
margin-left: -10px;
margin-bottom: -10px;
.iconfont {
display: block;
font-size: 12px;
height: 12px;
line-height: 12px;
position: absolute;
}
.iconfont.selected {
color: #1b1b1b;
}
.iconfont.up {
top: -2px;
}
.iconfont.down {
top: 8px;
}
}
.order.selected {
color: #1b1b1b;
}
.right {
width: auto;
height: 24px;
line-height: 24px;
margin-top: 12px;
label {
color: #1b1b1b;
font-weight: 700;
display: inline-block;
}
label.page-info {
margin: 0 25px;
}
.page {
color: #1b1b1b;
font-weight: 700;
border: 2px solid #1b1b1b;
width: 24px;
height: 24px;
line-height: 24px;
display: inline-block;
font-size: 14px;
text-align: center;
margin-right: 8px;
}
.page.disable {
color: #878787;
border: 2px solid #878787;
}
}
}
.goods-area {
margin: 0 -12px;
position: relative;
.goods {
margin: 10px 0;
padding: 10px;
display: inline-block;
text-align: center;
border: 2px solid #fff;
.goods-brand {
font-weight: 700;
padding: 10px;
}
.goods-img {
position: relative;
overflow: hidden;
width: 265px;
height: 344px;
.label {
background-color: #408ccc;
height: 24px;
width: 100%;
position: absolute;
bottom: 0;
z-index: 1;
line-height: 24px;
color: #fff;
}
}
.goods-name {
padding: 5px;
width: 265px;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
.goods-price {
padding: 15px;
font-size: 16px;
font-weight: 700;
b {
font-size: 12px;
color: #878787;
margin-left: 15px;
text-decoration: line-through;
}
}
}
.goods-wrapper {
border: 2px solid #eae9e9;
position: absolute;
background: #fff;
z-index: 10;
top: 10px;
padding-right: 10px;
min-width: 383px;
display: none;
.goods {
margin: 0;
border: 0;
}
.goods-img-list {
float: right;
margin: 2px 10px;
img {
margin: 8px 0;
}
}
}
}
.c-blue {
color: blue;
}
.c-red {
color: red;
}
}
... ...
... ... @@ -23,7 +23,8 @@ shelljs.ls(path.join(__dirname, '/js/**/*.page.js')).forEach((f) => {
'yoho-handlebars',
'yoho-jquery',
'yoho-jquery-lazyload',
'yoho-slider'
'yoho-slider',
'yoho-jquery-accordion'
];
});
... ...