Authored by yyq

Merge branch 'feature/product' of git.yoho.cn:fe/yoho-blk into feature/product

Showing 56 changed files with 1355 additions and 268 deletions
const model = require('../models');
exports.index = (req, res) => {
res.render('index', Object.assign({
module: 'channel',
page: 'home'
}, model.getContent()));
};
... ...
/**
* sub app channel
* @author: 赵彪<bill.zhao@yoho.cn>
* @date: 2016/06/09
*/
'use strict';
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
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: [path.join(__dirname, 'views/partial'), `${doraemon}/partial`],
helpers: global.yoho.helpers
}));
// router
app.use(require('./router'));
module.exports = app;
... ...
const getContent = () => {
const content = {
/* eslint-disable */
content: [
{
slider: [
... ... @@ -231,6 +232,7 @@ const getContent = () => {
}
]
};
/* eslint-enable */
return content;
};
... ...
/**
* router of sub app channel
* @author: biao<bill.zhao@yoho.cn>
* @date: 2016/06/29
*/
'use strict';
const router = require('express').Router(); // eslint-disable-line
const cRoot = './controllers';
// Your controller here
const index = require(`${cRoot}`).index;
router.get('/', index);
module.exports = router;
... ...
<div class="editorial-container">
{{> floor-header}}
<div class="news-container">
{{# editorial}}
<div class="news left">
{{# big}}
... ... @@ -8,8 +9,9 @@
</div>
<div class="news right">
{{# small}}
<img class="{{#if bottomSpace}}bottomSpace{{/if}} {{#if rightSpace}}rightSpace{{/if}}" src="{{image img 260 176}}" alt="">
<img class="{{#if bottomSpace}}bottom-space{{/if}} {{#if rightSpace}}right-space{{/if}}" src="{{image img 260 176}}" alt="">
{{/ small}}
</div>
{{/ editorial}}
</div>
</div>
... ...
<div class="slide-container {{#if pagination}}slide-thumb-container{{/if}}">
<div class="slide-wrapper">
<ul>
{{# slider}}
<li style="{{#if bgColor}}background:{{bgColor}}{{/if}}">
<a href="{{url}}" target= "_blank">
{{#if @first}}
<img src="{{image img 1150 450}}">
{{^}}
<img class="lazy" data-original="{{image img 1150 450}}" alt="">
{{/if}}
</a>
{{# tips}}
<div class="slide-tips">
<div class="g-mark"></div>
<p>{{.}}</p>
</div>
{{/ tips}}
</li>
{{/ slider}}
</ul>
</div>
{{#if pagination}}
<div class="thumb-pagination">
<ul class="clearfix">
{{# pagination}}
<li>
<a href="{{url}}" target="_blank"></a>
<img src="{{image img 138 54}}" alt="">
</li>
{{/ pagination}}
</ul>
</div>
{{/if}}
</div>
... ...
/**
* 资讯
* @author: zxr<xiaoru.zhang@yoho.cn>
* @date: 2016/7/4
*/
'use strict';
const index = (req, res) => {
var pageNum = req.query.page || 1;
res.display('index', {
module: 'editorial',
page: 'index',
title: '资讯',
editorial: {
nav: [
{
link: '//guang.yohobuy.com/index/index?type=0',
pathTitle: '首页',
name: 'MEN首页'
},
{
link: '/',
pathTitle: '资讯',
name: '咨询'
},
{
link: '/',
pathTitle: '资讯',
name: '咨询'
}
],
msgTypes: [
{
typeId: '0',
isActive: true,
type: '最新'
},
{
typeId: '1',
isActive: false,
type: '话题'
},
{
typeId: '2',
isActive: false,
type: '搭配'
},
{
typeId: '3',
isActive: false,
type: '潮人'
},
{
typeId: '4',
isActive: false,
type: '潮品'
}
],
msg: [
{
msgLeft: '潮品',
msgTitle: '很到位和范围的恢复文件和的减肥了晚餐费',
img: '',
msgContent: '鞋款定价回复即可老地方了服务',
time: '2016/05/25 19:36',
liked: true,
like: '8'
},
{
msgLeft: '潮品',
msgTitle: '很到位和范围的恢复文件和的减肥了晚餐费',
img: '',
msgContent: '鞋款定价回复即可老地方了服务',
time: '2016/05/25 19:36',
liked: true,
like: '8'
}
],
paginationOpts: {
page: pageNum, // current page: http://host/?page=2
limit: 10, // per_page records' number
totalRows: 100 // total page number
}
},
helpers: {
// import component, path depends on your project
pagination: require('../../../doraemon/components/pagination/pagination').createPagination
}
});
};
module.exports = {
index // 组件demo页
};
... ...
/**
* sub app partial
* @author: zhangxiaoru<xiaoru.zhang@yoho.cn>
* @date: 2016/07/4
*/
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: [path.join(__dirname, 'views/partial'), `${doraemon}/partial`],
helpers: 'helpers'
}));
// router
app.use(require('./router'));
module.exports = app;
... ...
/**
* router of sub app channel
* @author: zhangxiaoru<xiaoru.zhang@yoho.cn>
* @date: 2016/07/04
*/
'use strict';
const router = require('express').Router(); // eslint-disable-line
const cRoot = './controllers';
const editorial = require(cRoot + '/editorial');
router.get('/', editorial.index); // 咨询首页
// router.get('/list', editorial.list); // 咨询列表页
module.exports = router;
... ...
<div class="editorial-index-page">
{{# editorial}}
{{> path-nav}}
<div class="index-content">
<ul class="msg-nav">
{{# msgTypes}}
<li data-type="{{typeId}}" {{#if isActive}}class="active"{{/if}}>
<a class="pjax-link" href="{{navUrl}}">{{type}}</a>
</li>
{{/ msgTypes}}
</ul>
<div id="msg-list" class="msg-list">
{{# msg}}
{{> msg}}
{{/ msg}}
</div>
<div class="paging">
{{{ pagination paginationOpts }}}
</div>
</div>
{{/ editorial}}
</div>
\ No newline at end of file
... ...
<div class="content-msg clearfix" data-id="{{id}}">
<div class="msg-left">{{msgLeft}}</div>
<div class="msg-right">
<a class="msg-title">{{msgTitle}}</a>
<img class="lazy" data-original="{{img}}">
<div class="content">{{msgContent}}</div>
<div class="msg-app">
<span class="time">
<i class="iconfont">&#xe61b;</i>
<b class="time-word">{{time}}</b>
</span>
<span class="like-comment">
<i class="iconfont like-icon{{#if liked}} liked{{/if}}">&#xe60e;</i>
<b class="like-num">{{like}}</b>
</span>
</div>
</div>
</div>
\ No newline at end of file
... ...
/**
* [个人中心]首页/我的订单
* @author: xuqi<qi.xu@yoho.cn>
* @date: 2016/07/04
*/
'use strict';
const mcHandler = require('../models/menu-crumb-handler');
/**
* 订单
*/
const index = (req, res) => {
res.render('index', {
module: 'me',
page: 'order',
isMe: true,
content: {
nav: mcHandler.getMeCrumb(),
navigation: mcHandler.getSideMenu('我的订单'),
banner: 'http://placehold.it/150x120'
}
});
};
module.exports = {
index
};
... ...
/**
* sub app me
* @author: xuqi<qi.xu@yoho.cn>
* @date: 2016/07/04
*/
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
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: [path.join(__dirname, 'views/partial'), `${doraemon}/partial`],
helpers: 'helpers'
}));
// router
app.use(require('./router'));
module.exports = app;
... ...
/**
* 个人中心布局(顶部面包屑和左侧导航)
* @author: xuqi<qi.xu@yoho.cn>
* @date: 2016/7/5
*/
'use strict';
const _ = require('lodash');
const blk = global.yoho;
const url = blk.helpers.urlFormat;
// 左侧菜单
const navigation = [
{
link: url('/me/order'),
name: '我的订单'
},
{
link: url('/me/return'),
name: '我的退/换货'
},
{
link: url('/me/collection'),
name: '我的收藏'
},
{
link: url('/me/message'),
name: '我的消息'
},
{
link: url('/me/currency'),
name: '我的YOHO币'
},
{
link: url('/me/setting'),
name: '个人设置'
},
{
link: url('/me/address'),
name: '收货地址'
}
];
// 头部导航面包屑
const getMeCrumb = name => {
return [
{
link: blk.config.sitUrl,
name: 'YOHO!BLK首页'
},
{
link: url('/me'),
name: '个人中心'
},
{
name: name ? name : '我的订单'
}
];
};
// 侧栏菜单
const getSideMenu = focus => {
let copiedNav = _.cloneDeep(navigation);
if (focus && _.some(copiedNav, {name: focus})) {
Object.assign(_.find(copiedNav, {name: focus}), {
focus: true
});
} else {
// 若没有传focus || focus不在navigation中,则默认focus第1个菜单
copiedNav[0].focus = true;
}
return copiedNav;
};
module.exports = {
getMeCrumb,
getSideMenu
};
... ...
/**
* router of sub app me
* @author: xuqi<qi.xu@yoho.cn>
* @date: 2016/07/04
*/
'use strict';
const router = require('express').Router(); // eslint-disable-line
const cRoot = './controllers';
// 订单
const order = require(`${cRoot}/order`);
// 个人中心首页/订单
router.get('/', order.index);
module.exports = router;
... ...
<div class="me-page blk-page">
<div class="center-content clearfix">
{{# content}}
{{!-- 头部面包屑 --}}
{{> path-nav}}
{{!-- 左侧菜单导航 --}}
<div class="me-navigation left">
<p class="title bold">MY YOHO!BLK</p>
<ul class="nav">
{{#each navigation}}
<li class="nav-row{{#if focus}} focus{{/if}}">
<a href="{{link}}">{{name}}</a>
</li>
{{/each}}
</ul>
{{#if banner}}
<img class="banner-img" data-original="{{banner}}">
{{/if}}
</div>
{{!-- 右侧页面内容 --}}
<div class="me-main left">
{{!-- 我的订单 --}}
{{#if order}}
{{> order}}
{{/if}}
{{!-- 我的退换货 --}}
{{#if return}}
{{> return}}
{{/if}}
{{!-- 我的收藏 --}}
{{#if collection}}
{{> collection}}
{{/if}}
{{!-- 我的消息 --}}
{{#if message}}
{{> message}}
{{/if}}
{{!-- 我的YOHO币 --}}
{{#if currency}}
{{> curency}}
{{/if}}
{{!-- 个人设置 --}}
{{#if setting}}
{{> setting}}
{{/if}}
{{!-- 收货地址 --}}
{{#if address}}
{{> address}}
{{/if}}
</div>
{{/ content}}
</div>
{{!-- 在线客服和返回顶部 --}}
<div class="service-top">
<a class="service" href="" target="_blank">
<span class="iconfont">&#xe61c;</span>
<span class="hover-text hide">在线<br>客服</span>
</a>
<div class="return-top hide">
<span class="iconfont bold">&#xe617;</span>
<span class="hover-text hide">返回<br>顶部</span>
</div>
</div>
</div>
\ No newline at end of file
... ...
I am order
\ No newline at end of file
... ...
... ... @@ -44,20 +44,19 @@ const index = (req, res) => {
price: '1015.00'
},
navPath: {
nav: true,
pathNav: [
nav: [
{
href: '',
link: '',
pathTitle: '',
name: 'MEN首页'
},
{
href: '',
link: '',
pathTitle: '',
name: '咨询'
},
{
href: '',
link: '',
pathTitle: '',
name: '咨询'
}
... ...
... ... @@ -80,7 +80,17 @@
</div>
<p class="title">9. 分页组件</p>
<div style="border: 1px solid #000; height: 40px; padding: 5px;">
<div style="border: 1px solid #000; height: 200px; padding: 5px;">
<pre>
全局安装json-server
npm i -g json-server
启动
json-server --watch mock/address.json
</pre>
{{{ pagination paginationOpts }}}
</div>
... ...
'use strict';
const _ = require('lodash');
const Search = require('../models/list');
const camelCase = global.yoho.camelCase;
function brandLetters() {
let letters = [];
... ... @@ -34,51 +35,8 @@ function peopleChoose(channel) {
}];
}
function brandData() {
function randomLetter(len) {
let words = [];
for (let i = 0; i < len; i++) {
words.push(String.fromCharCode(_.random(65, 122)));
}
return words.join('');
}
let brands = [];
for (let i = 0; i < 1000; i++) {
brands.push({
name: randomLetter(_.random(3, 15)),
checked: false,
id: i
});
}
return brands;
}
function colorData() {
return [
{
name: '黑色',
color: '#000',
checked: false
},
{
name: '蓝色',
color: 'blue',
checked: false
},
{
name: '红色',
color: 'red',
checked: false
}
];
}
const list = {
index: (req, res) => {
index: (req, res, next) => {
let channel = req.query.channel || req.cookies._Channel;
let sex = req.query.sex;
... ... @@ -88,35 +46,65 @@ const list = {
channel = 'women';
}
res.display('list', {
letters: brandLetters(),
people: peopleChoose(channel),
brandData: brandData(),
colors: colorData(),
navPath: {
nav: true,
pathNav: [
{
link: true,
href: '',
pathTitle: '',
name: 'MEN首页'
},
{
link: true,
href: '',
pathTitle: '',
name: '咨询'
Search.queryProduct({}).then(result => {
if (result && result.code === 200 && result.data) {
let data = camelCase(result.data);
let priceRange = data.filter.priceRange;
priceRange = Object.keys(priceRange).map((k) => {
let prices = k.split(',');
return {
lower: prices[0],
higher: prices[1]
};
}).sort((a, b) => {
return a.lower - b.lower;
});
res.display('list', {
letters: brandLetters(),
people: peopleChoose(channel),
sortData: data.filter.groupSort,
brandData: data.filter.brand,
colors: data.filter.color,
size: data.filter.size,
priceRange: priceRange,
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: '咨询'
}
]
},
{
link: false,
href: '',
pathTitle: '',
name: '咨询'
}
]
module: 'product',
page: 'list',
title: '列表'
});
} else {
throw 'query product error';
}
});
}).catch(next);
}
};
... ...
'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');
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, params);
return api.get('', finalParams);
}
};
module.exports = Search;
... ...
... ... @@ -25,6 +25,53 @@
</div>
<div class="order-area">
<span>综合</span>
<span>上新时间</span>
<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">&#xe606;</span>
</div>
</div>
<div class="goods-area">
{{#each products}}
<div class="goods" data-id="{{productId}}">
<div class="goods-img">
<img src="{{defaultImages}}" 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>{{imagesUrl}}</i>
{{/each}}
</div>
</div>
{{/each}}
<div class="goods-wrapper">
<div class="goods">
</div>
<div class="goods-img-list">
</div>
</div>
</div>
\ No newline at end of file
... ...
... ... @@ -13,59 +13,20 @@
<div class="blank-div"></div>
<div class="title">全部品类</div>
<div class="yoho-ui-accordion">
<h3>上衣</h3>
<div class="body">
<div class="input-radio">
<span class="iconfont radio checked">&#xe603;</span>
<label>男士</label>
</div>
<div class="input-radio">
<span class="iconfont radio">&#xe604;</span>
<label>女士</label>
</div>
</div>
<h3>裤装</h3>
<div class="body">
<div class="list-body">
<div class="input-radio">
<span class="iconfont radio checked">&#xe603;</span>
<label>男士</label>
</div>
<div class="input-radio">
<span class="iconfont radio">&#xe604;</span>
<label>女士</label>
</div>
<div class="input-radio">
<span class="iconfont radio">&#xe604;</span>
<label>女士</label>
</div>
<div class="input-radio">
<span class="iconfont radio">&#xe604;</span>
<label>女士</label>
</div>
<div class="input-radio">
<span class="iconfont radio">&#xe604;</span>
<label>女士</label>
</div>
<div class="input-radio">
<span class="iconfont radio">&#xe604;</span>
<label>女士</label>
</div>
<div class="input-radio">
<span class="iconfont radio">&#xe604;</span>
<label>女士</label>
<div class="yoho-ui-accordion no-active">
{{#each sortData}}
<h3>{{categoryName}}</h3>
<div class="body" data-msort="{{categoryId}}">
<div class="list-body">
{{#each sub}}
<div class="input-radio" data-misort="{{categoryId}}">
{{> icon/radio }}
<label>{{categoryName}}</label>
</div>
<div class="input-radio">
<span class="iconfont radio">&#xe604;</span>
<label>女士</label>
</div>
<div class="input-radio">
<span class="iconfont radio">&#xe604;</span>
<label>女士</label>
{{/each}}
</div>
</div>
</div>
{{/each}}
</div>
<div class="blank-div"></div>
... ... @@ -77,13 +38,9 @@
<input type="text" class="brand-search" placeholder="输入您要查找的品牌">
</div>
<div class="brand-letter-items">
<span class="item-all">全部</span>
<span class="item item-all" data-value="">全部</span>
{{#each letters}}
{{#if selected}}
<span class="item selected">{{letter}}</span>
{{^}}
<span class="item">{{letter}}</span>
{{/if}}
<span class="item" data-value="{{letter}}">{{letter}}</span>
{{/each}}
<span class="mulit-choose">
多选 +
... ... @@ -93,7 +50,7 @@
{{#each brandData}}
<div class="input-radio" data-value="{{id}}">
{{> icon/radio}}
<label>{{name}}</label>
<label>{{brandNameEn}}</label>
</div>
{{/each}}
</div>
... ... @@ -107,18 +64,12 @@
<div class="yoho-ui-accordion">
<h3>价格</h3>
<div class="body">
<div class="input-radio">
<span class="iconfont radio checked">&#xe603;</span>
<label>¥0-¥1000</label>
</div>
<div class="input-radio">
<span class="iconfont radio">&#xe604;</span>
<label>¥1001-¥2000</label>
</div>
<div class="input-radio">
<span class="iconfont radio">&#xe604;</span>
<label>¥2001-¥4000</label>
{{#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>
... ... @@ -138,18 +89,12 @@
<h3>尺码</h3>
<div class="body">
<div class="size-body">
<div class="input-radio">
<span class="iconfont radio checked">&#xe603;</span>
<label>M</label>
</div>
<div class="input-radio">
<span class="iconfont radio">&#xe604;</span>
<label>L</label>
</div>
<div class="input-radio">
<span class="iconfont radio">&#xe604;</span>
<label>XL</label>
{{#each size}}
<div class="input-radio" data-value="{{sizeId}}">
{{> icon/radio }}
<label>{{sizeName}}</label>
</div>
{{/each}}
</div>
</div>
</div>
... ... @@ -158,18 +103,12 @@
<h3>颜色</h3>
<div class="body">
<div class="color-body">
<div class="input-radio">
<span class="iconfont radio checked">&#xe610;</span>
<label>黑色</label>
</div>
<div class="input-radio">
<span class="iconfont radio c-blue">&#xe611;</span>
<label>蓝色</label>
</div>
<div class="input-radio">
<span class="iconfont radio c-red">&#xe611;</span>
<label>红色</label>
{{#each colors}}
<div class="input-radio" data-value="{{colorId}}">
{{> icon/radio }}
<label>{{colorName}}</label>
</div>
{{/each}}
</div>
</div>
</div>
\ No newline at end of file
... ...
... ... @@ -13,7 +13,10 @@ 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
service: 'http://devservice.yoho.cn:58077/', // testservice.yoho.cn:28077 devservice.yoho.cn:58077
... ...
... ... @@ -12,4 +12,10 @@ 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')); // 个人中心
// 资讯
app.use('/editorial', require('./apps/editorial'));
};
... ...
<div class="yoho-footer">
<div class="blk-footer">
<div class="center-content">
<ul class="about-us clearfix">
<li><a href="#">BLK首页</a></li>
... ...
{{#if nav}}
<p class="path-nav">
{{#each pathNav}}
{{#if href}}
<a {{#if @last}}class="last"{{/if}} href="{{href}}" title="{{pathTitle}}">{{{name}}}</a>
{{#each nav}}
{{#if link}}
<a {{#if @last}}class="last"{{/if}} href="{{link}}" title="{{pathTitle}}">{{{name}}}</a>
{{^}}
<span {{#if @last}}class="last"{{/if}} title="{{pathTitle}}">{{{name}}}</span>
{{/if}}
... ...
... ... @@ -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",
... ...
... ... @@ -2,7 +2,11 @@
<!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>
<<<<<<< HEAD
Created by FontForge 20120731 at Tue Jul 5 16:22:47 2016
=======
Created by FontForge 20120731 at Mon Jul 4 15:42:03 2016
>>>>>>> develop
By admin
</metadata>
<defs>
... ...
... ... @@ -2,7 +2,7 @@ require('../plugins/slider');
$('.slide-container').slider();
$('.card').mouseenter(function() {
var $this = $(this);
var $this = $(this); // eslint-disable-line
if ($this.hasClass('active')) {
return false;
... ...
# common使用规范
## 页面公共使用的前端资源
### header为页面通用头部
### return-top为返回页面顶部(通用,除个人中心页面)
* returnTopShowOrNot 是否显示返回顶部的按钮
### index暴露一些通用api,通过require('path/to/common')引用即可
* cookie 获取cookie
* setCookie 设置cookie
* queryString 解析url query
**请按需require**。此处与之前的项目不一样,接口将不直接暴露到window,需通过require去获取暴露的方法。
\ No newline at end of file
... ...
/**
* 页面公共逻辑和接口
* @author: xuqi<qi.xu@yoho.cn>
* @date: 2015/11/23
* @date: 2017/7/5
*/
function cookie(name) {
... ... @@ -56,8 +56,8 @@ function queryString() {
return vars;
}
window.cookie = cookie;
window.setCookie = setCookie;
window.queryString = queryString;
module.exports = {
cookie: cookie, // 获取cookie
setCookie: setCookie, // 设置cookie
queryString: queryString // query参数解析
};
... ...
/**
* 公共底部
* @author: yyq<yanqing.yang@yoho.cn>
* @date: 2016/7/4
* [公共底部]返回页面顶部
* @author: xuqi<qi.xu@yoho.cn>
* @date: 2016/07/05
*/
var $ = require('yoho-jquery');
var $returnTop = $('.return-top');
function rePosReturn() {
if ($(window).height() > $(document).height()) {
function showOrNot() {
if ($(window).height() >= $(document).height()) {
$returnTop.addClass('hide');
}
// 只在窗口高度大于文档高度的时候,隐藏返回顶部
// else {
// $returnTop.removeClass('hide');
// }
}
// 返回顶部
$returnTop.click(function() {
$('html,body').animate({
scrollTop: 0
... ... @@ -31,10 +28,9 @@ $(window).scroll(function() {
}
});
// 如果初始是隐藏的,监听图片加载,重新确定return-top的高度
// 页面图片加载完成后根据页面高度决定是否显示
if ($returnTop.hasClass('hide')) {
$('img').load(rePosReturn);
$('img').load(showOrNot);
}
// 暴露给有可能通AJAX改变内容的页面去用
window.rePosReturnTop = rePosReturn;
exports.returnTopShowOrNot = showOrNot;
... ...
/**
* 资讯首页
* @author: zxr<xiaoru.zhang@yoho.cn>
* @date: 2016/07/05
*/
// var $ = require('yoho-jquery'),
// lazyLoad = require('yoho-jquery-lazyload');
// lazyLoad($('#msg-list img.lazy'));
... ...
/**
* 个人中心布局
* @author: xuqi<qi.xu@yoho.cn>
* @date: 2016/07/04
*/
var $ = require('yoho-jquery'),
lazyLoad = require('yoho-jquery-lazyload');
var $st = $('.service-top');
function reposServiceTop() {
if ($(window).width() < 1380) {
$st.addClass('for-min');
} else {
$st.removeClass('for-min');
}
}
$('.blk-footer .return-top').remove(); // 移除通用的返回顶部组件
require('../common/return-top'); // return-top
// 左侧banner图片lazyload
lazyLoad($('.banner-img'));
// 浮动在线客服和返回顶部的鼠标移入移出切换效果
$('.service, .return-top').hover(function() {
$(this).find('.iconfont').addClass('hide').end().find('.hover-text').removeClass('hide');
}, function() {
$(this).find('.iconfont').removeClass('hide').end().find('.hover-text').addClass('hide');
});
// repos service-return when window resize
$(window).resize(reposServiceTop);
reposServiceTop();
... ...
/**
* [个人中心]首页/我的订单
* @author: xuqi<qi.xu@yoho.cn>
* @date: 2016/07/04
*/
require('./me');
... ...
... ... @@ -5,13 +5,22 @@ 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('../common');
require('../plugins/check');
$('.yoho-ui-accordion', this.rootDoc).accordion({
collapsible: true,
heightStyle: 'content'
$('.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({
... ... @@ -57,10 +66,18 @@ var YohoListPage = {
YohoListPage.filterBrand($(this).val().toLowerCase());
});
$('.yoho-product-list .brand-letter-items .item').on('click', function() {
$('.yoho-product-list .brand-letter-items .item').hover(function() {
$('.yoho-product-list .brand-letter-items .item').removeClass('select');
$(this).addClass('select');
YohoListPage.filterBrand($(this).text().toLowerCase());
YohoListPage.filterBrand($(this).data('value').toLowerCase());
});
$('.goods-area > .goods').mouseenter(function(e) {
YohoListPage.showGoodsWrapper(e);
});
$('.goods-wrapper').mouseleave(function(e) {
YohoListPage.hideGoodsWrapper(e);
});
},
openBrandMulitChoose: function() {
... ... @@ -102,6 +119,37 @@ var YohoListPage = {
});
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(window.queryString(), q);
... ...
... ... @@ -196,6 +196,11 @@ a {
-moz-osx-font-smoothing: grayscale;
}
/* 单一布局 */
.blk-page {
min-width: 1150px;
}
.body-mask {
position: absolute;
z-index: 100;
... ... @@ -219,7 +224,7 @@ a {
}
.hide {
display: none;
display: none !important;
}
.vhide {
... ...
... ... @@ -3,6 +3,8 @@
margin-top: 15px;
img {
@extend .cursor-pointer;
width: 100%;
height: 100%;
border: none;
... ...
... ... @@ -6,7 +6,6 @@
background-color: #fff;
.ad {
display: inline-block;
float: left;
width: 50%;
height: 100%;
... ... @@ -18,7 +17,6 @@
}
img {
display: inline-block;
float: left;
width: 50%;
height: 100%;
... ...
... ... @@ -11,7 +11,6 @@
float: right;
}
img {
float: left;
}
... ...
... ... @@ -3,7 +3,6 @@
$line-height: 1.8;
$lines-to-show: 3;
display: inline-block;
float: left;
height: 100%;
width: 50%;
... ...
... ... @@ -6,18 +6,27 @@
@extend .resource-container;
.news-container {
height: calc($smallImgHeight*2+$space+2px);
}
.news {
display: inline-block;
box-sizing: border-box;
.bottomSpace {
.bottom-space {
margin-bottom: $space;
}
.rightSpace {
.right-space {
margin-right: $space;
}
img {
@extend .cursor-pointer;
display: inline-block;
}
&.left {
width: $bigImgWidth;
float: left;
... ...
... ... @@ -146,7 +146,6 @@
right: 0;
top: 0;
bottom: 0;
/*background: #000;*/
}
span {
... ... @@ -443,7 +442,6 @@
}
}
.categorys-list {
ul {
width: 1158px;
... ...
... ... @@ -5,57 +5,55 @@
@extend .resource-container;
height: calc($textHeight+$imgHeight+60px);/* 60px is the height of the floor header*/
height: calc($textHeight+$imgHeight+60px);/* 60px is the height of the floor header */
.arrival-item-box {
box-sizing: border-box;
}
.arrival-item {
width: 245px;
display: inline-block;
.arrival-item {
width: 245px;
display: inline-block;
.brand-name {
height: $textHeight;
text-align: center;
font-size: 12px;
.brand-name {
height: $textHeight;
text-align: center;
font-size: 12px;
span {
@extend .cursor-pointer;
span {
@extend .cursor-pointer;
padding-bottom: 3px;
border-bottom: 1px solid #000;
padding-bottom: 3px;
border-bottom: 1px solid #000;
&.top {
line-height: 20px;
}
&.top {
line-height: 20px;
}
&.bottom {
line-height: 40px;
}
&.bottom {
line-height: 40px;
}
}
}
img {
@extend .cursor-pointer;
img {
@extend .cursor-pointer;
width: 100%;
height: $imgHeight;
}
&.normal {
float: left;
margin-right: 18px;
}
width: 100%;
height: $imgHeight;
}
&.last {
float: right;
}
&.normal {
float: left;
margin-right: 18px;
}
&.small-img {
width: 160px;
}
&.last {
float: right;
}
&.small-img {
width: 160px;
}
}
}
... ...
... ... @@ -2,6 +2,7 @@
$width: 164px;
$height: 240px;
$space: 15px;
$buttonWidth: 105px;
@extend .resource-container;
... ... @@ -14,16 +15,13 @@
.card {
height: $height;
display: inline-block;
float: left;
position: relative;
box-sizing: border-box;
.img {
width: $width;
height: 100%;
display: inline-block;
float: left;
margin-right: $space;
background-size: 100% 100%;
... ... @@ -44,7 +42,6 @@
width: 0;
border: none;
p {
height: calc($size*$line-height*$lines-to-show);
width: calc($width-2*$space);
... ... @@ -58,7 +55,7 @@
}
button {
left: calc($width/2-105px/2);
left: calc($width/2-$buttonWidth/2); /* stylelint-disable-line */
}
* {
... ... @@ -77,7 +74,6 @@
.brand-text-box {
width: $width;
height: 100%;
display: inline-block;
float: left;
padding: 25px 0 25px $space;
border: 1px solid #404040;
... ... @@ -92,6 +88,5 @@
}
}
}
}
... ...
.floor-header {
margin: 50px 0 30px;
}
.floor-title {
margin: 0 auto;
line-height: 27px;
... ...
.yoho-footer {
.blk-footer {
background: #fff;
.center-content {
... ...
.path-nav {
font-size: 14px;
height: 48px;
line-height: 48px;
height: 50px;
line-height: 50px;
a {
color: #666;
... ...
.editorial-index-page {
width: 1150px;
margin: 0 auto;
.index-content {
width: 1150px;
margin: 0 auto;
}
.msg-nav {
height: 35px;
border-bottom: 1px solid #eee;
padding-left: 300px;
padding-bottom: 5px;
li {
float: left;
height: 30px;
width: 120px;
line-height: 35px;
text-align: center;
font-size: 14px;
display: list-item;
list-style-type: none;
color: #999;
a {
display: block;
height: 100%;
width: 100%;
text-decoration: none;
color: #999;
}
&.active {
a {
color: #000;
}
}
}
}
.paging {
margin: 20px auto;
width: 300px;
height: 40px;
}
}
@import "msg";
... ...
.content-msg {
margin-top: 40px;
margin-left: 110px;
}
.msg-left {
position: relative;
float: left;
width: 200px;
height: 30px;
margin-right: 80px;
line-height: 30px;
text-align: center;
border-bottom: 1px solid #bbb;
}
.msg-right {
float: left;
width: 643px;
border-bottom: 1px solid #eee;
margin-top: 2px;
padding-bottom: 5px;
}
.msg-title {
font-size: 20px;
color: #333;
line-height: 30px;
max-height: 64px;
word-wrap: break-word;
overflow: hidden;
text-overflow: ellipsis;
display: -webkit-box;
-webkit-line-clamp: 2;
-webkit-box-orient: vertical;
}
.lazy {
width: 640px;
height: 430px;
margin-top: 15px;
}
.content {
display: block;
font-size: 14px;
line-height: 24px;
word-wrap: break-word;
margin-top: 10px;
overflow: hidden;
word-wrap: break-word;
text-overflow: ellipsis;
display: -webkit-box;
-webkit-line-clamp: 2;
-webkit-box-orient: vertical;
}
.msg-app {
height: 45px;
line-height: 45px;
font-size: 14px;
}
.time {
color: #a6a6a6;
margin-left: 3px;
}
.iconfont {
font-size: 14px;
margin-top: 0;
}
.time-word {
font-weight: normal;
}
.like-comment {
margin-left: 40px;
color: #a6a6a6;
cursor: pointer;
font-size: 14px;
.like-icon {
cursor: pointer;
&.liked {
color: #000;
}
}
}
.like-num {
font-weight: normal;
}
... ...
@charset "utf-8";
/* 公共 */
@import "base";
@import "components/index";
@import "plugin/index";
/* 模块 */
@import "me/index";
@import "channel/index";
@import "base";
@import "components/index";
@import "product/index";
@import "channel/index";
/* 资讯 */
@import "editorial/index";
... ...
.me-page {
padding-bottom: 30px;
background: #f5f5f5;
/* 个人中心布局下重置默认的底部样式 */
+ .blk-footer .center-content {
border-top: none;
}
/* 左侧导航 */
.me-navigation {
width: 150px;
margin-right: 10px;
.title {
height: 60px;
line-height: 60px;
text-align: center;
background: #fff;
}
.nav-row {
height: 40px;
line-height: 40px;
color: #cecece;
background: #fff;
a {
display: block;
height: 100%;
width: 100%;
padding-left: 20px;
border-left: 2px solid #fff;
}
&.focus {
background: #eee;
color: #000;
a {
border-color: #000;
}
}
}
.banner-img {
width: 150px;
height: 120px;
margin-top: 10px;
}
}
.me-main {
width: 990px;
}
.service-top {
position: fixed;
left: 50%;
bottom: 20px;
border: 1px solid #eee;
background: #fff;
cursor: pointer;
z-index: 2;
margin-left: 625px;
&.for-min {
right: 20px;
left: initial;
margin-left: auto;
}
.service,
.return-top {
display: block;
width: 50px;
height: 50px;
padding-top: 13px;
text-align: center;
&:hover {
padding-top: 8px;
}
}
.return-top {
border-top: 1px solid #eee;
}
.hover-text {
font-size: 12px;
}
}
}
... ...
.yoho-product-list {
font-size: 14px;
.center-content {
.left {
width: 250px;
... ... @@ -31,8 +34,9 @@
.list-body,
.size-body,
.color-body {
max-height: 260px;
.color-body,
.brand-list {
max-height: 240px;
overflow-y: auto;
}
.brand-body {
... ... @@ -66,10 +70,6 @@
padding: 5px 10px;
}
}
.brand-list {
max-height: 260px;
overflow-y: auto;
}
.brand-btns {
text-align: center;
margin-top: 10px;
... ... @@ -194,6 +194,167 @@
.order-area {
border-top: 1px solid #eee;
border-bottom: 1px solid #eee;
margin-top: 30px;
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: #000;
}
.iconfont.up {
top: -2px;
}
.iconfont.down {
top: 8px;
}
}
.order.selected {
color: #000;
}
.right {
width: auto;
height: 24px;
line-height: 24px;
margin-top: 12px;
label {
color: #000;
font-weight: 700;
display: inline-block;
}
label.page-info {
margin: 0 25px;
}
.page {
color: #000;
font-weight: 700;
border: 2px solid #000;
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 {
... ...