Authored by jinhu.tung

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

Showing 72 changed files with 2618 additions and 855 deletions
/**
* 品牌
* @author: zxr<xiaoru.zhang@yoho.cn>
* @date: 2016/7/8
*/
'use strict';
const index = (req, res) => {
res.display('index', {
module: 'brand',
page: 'index',
title: '品牌',
brand: {
nav: [
{
link: '//guang.yohobuy.com/index/index?type=0',
pathTitle: '首页',
name: 'MEN首页'
},
{
link: '/',
pathTitle: '品牌',
name: 'Brand品牌'
}
],
tabs: [
{
url: '#',
name: '',
src: '#'
},
{
url: '#',
name: '',
src: '#'
},
{
url: '#',
name: '',
src: '#'
}
],
navigation: [
{
name: 'A'
},
{
name: 'B'
},
{
name: 'B'
},
{
name: 'A'
},
{
name: 'B'
},
{
name: 'B'
},
{
name: 'B'
}
],
category: [
{
key: 'A',
brandList: [
{
key: 'A',
href: '#',
name: 'edhwke'
},
{
key: 'A',
href: '#',
name: 'edhwke'
},
{
key: 'A',
href: '#',
name: 'edhwke'
},
{
key: 'A',
href: '#',
name: 'edhwke'
},
{
key: 'A',
href: '#',
name: 'edhwke'
},
{
key: 'A',
href: '#',
name: 'edhwke'
}
]
},
{
key: 'A',
brandList: [
{
key: 'A',
href: '#',
name: 'edhwke'
},
{
key: 'A',
href: '#',
name: 'edhwke'
},
{
key: 'A',
href: '#',
name: 'edhwke'
},
{
key: 'A',
href: '#',
name: 'edhwke'
},
{
key: 'A',
href: '#',
name: 'edhwke'
},
{
key: 'A',
href: '#',
name: 'edhwke'
}
]
}
]
},
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/8
*/
'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
// 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: global.yoho.helpers
}));
// router
app.use(require('./router'));
module.exports = app;
... ...
'use strict';
... ...
/**
* 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 brand = require(cRoot + '/brand');
router.get('/', brand.index); // 品牌首页
module.exports = router;
... ...
<div class="brand-page blk-page center-content">
{{# brand}}
{{> path-nav}}
<div class="brands-tabs height-initial">
<ul class="clearfix">
{{#each tabs}}
<li>
<a href="{{url}}" target="_blank">
<div class="g-mask"></div>
<p class="tips">{{name}}</p>
<img class="lazy" data-original="{{src}}"/>
</a>
</li>
{{/each}}
</ul>
</div>
<div class="brands-category">
<div class="category-nav">
{{#each navigation}}
<a href="#{{name}}">{{name}}</a>
{{/each}}
</div>
</div>
<div class="brands-list" >
{{> list}}
</div>
{{/ brand}}
</div>
\ No newline at end of file
... ...
{{#each category}}
<dl class="clearfix" name="{{key}}">
<dt>{{key}}</dt>
<dd>
<ul class="clearfix">
{{#each brandList}}
<li>
<a data-key="{{key}}" href="{{href}}" target="_blank">
<img class="lazy" data-original="{{href}}">
<span>{{name}}</span>
</a>
</li>
{{/each}}
</ul>
</dd>
</dl>
{{/each}}
\ No newline at end of file
... ...
... ... @@ -6,97 +6,139 @@
'use strict';
const index = (req, res) => {
var pageNum = req.query.page || 1;
const editorialModel = require('../models/editorial');
res.display('index', {
module: 'editorial',
page: 'index',
title: '资讯',
editorial: {
nav: [
{
link: '/editorial?type=0',
pathTitle: '首页',
name: 'MEN首页'
},
{
link: '/editorial?type=1',
pathTitle: '资讯',
name: '咨询'
},
{
link: '/',
pathTitle: '资讯',
name: '咨询'
}
],
msgTypes: [
{
typeId: '0',
isActive: true,
href: '#',
type: '最新'
},
{
typeId: '1',
isActive: false,
href: '#',
type: '话题'
},
{
typeId: '2',
isActive: false,
href: '#',
type: '搭配'
},
{
typeId: '3',
isActive: false,
href: '#',
type: '潮人'
},
{
typeId: '4',
isActive: false,
href: '#',
type: '潮品'
}
],
msg: [
{
id: '1',
msgLeft: '潮品',
msgTitle: '很到位和范围的恢复文件和的减肥了晚餐费',
img: '',
msgContent: '鞋款定价回复即可老地方了服务',
time: '2016/05/25 19:36',
liked: true,
like: '8'
},
{
id: '2',
msgLeft: '潮品',
msgTitle: '很到位和范围的恢复文件和的减肥了晚餐费',
img: '',
msgContent: '鞋款定价回复即可老地方了服务',
time: '2016/05/25 19:36',
liked: true,
like: '8'
const index = (req, res, next) => {
let pageNum = req.query.page || 1;
let type = req.query.type || 0;
editorialModel.getIndexData(type).then((result) => {
res.display('index', {
module: 'editorial',
page: 'index',
title: '资讯',
editorial: {
nav: [
{
link: '/editorial?type=0',
pathTitle: '首页',
name: 'MEN首页'
},
{
link: '/editorial?type=1',
pathTitle: '资讯',
name: '资讯'
},
{
link: '/',
pathTitle: '资讯',
name: '资讯'
}
],
msgTypes: result.msgTypes,
msg: result.msg,
paginationOpts: {
page: pageNum, // current page: http://host/?page=2
limit: 20, // per_page records' number
total: 300, // total page number
queryParams: req.query
}
],
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
}
},
helpers: {
// import component, path depends on your project
pagination: require('../../../doraemon/components/pagination/pagination').createPagination
}
});
}).catch(next);
});
// res.display('index', {
// module: 'editorial',
// page: 'index',
// title: '资讯',
// editorial: {
// nav: [
// {
// link: '/editorial?type=0',
// pathTitle: '首页',
// name: 'MEN首页'
// },
// {
// link: '/editorial?type=1',
// pathTitle: '资讯',
// name: '咨询'
// },
// {
// link: '/',
// pathTitle: '资讯',
// name: '咨询'
// }
// ],
// msgTypes: [
// {
// typeId: '0',
// isActive: true,
// href: '#',
// type: '最新'
// },
// {
// typeId: '1',
// isActive: false,
// href: '#',
// type: '话题'
// },
// {
// typeId: '2',
// isActive: false,
// href: '#',
// type: '搭配'
// },
// {
// typeId: '3',
// isActive: false,
// href: '#',
// type: '潮人'
// },
// {
// typeId: '4',
// isActive: false,
// href: '#',
// type: '潮品'
// }
// ],
// msg: [
// {
// id: '1',
// msgLeft: '潮品',
// msgTitle: '很到位和范围的恢复文件和的减肥了晚餐费',
// img: '',
// msgContent: '鞋款定价回复即可老地方了服务',
// time: '2016/05/25 19:36',
// liked: true,
// like: '8'
// },
// {
// id: '2',
// 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
// }
// });
};
const list = (req, res) => {
... ... @@ -128,29 +170,30 @@ const list = (req, res) => {
msg: [
{
id: '1',
msgLeft: '潮品',
msgTitle: '很到位和范围的恢复文件和的减肥了晚餐费',
categoryName: '潮品',
title: '很到位和范围的恢复文件和的减肥了晚餐费',
img: '',
msgContent: '鞋款定价回复即可老地方了服务',
time: '2016/05/25 19:36',
liked: true,
like: '8'
intro: '鞋款定价回复即可老地方了服务',
publishTime: '2016/05/25 19:36',
isPraise: true,
praiseNum: '8'
},
{
id: '2',
msgLeft: '潮品',
msgTitle: '很到位和范围的恢复文件和的减肥了晚餐费',
id: '1',
categoryName: '潮品',
title: '很到位和范围的恢复文件和的减肥了晚餐费',
img: '',
msgContent: '鞋款定价回复即可老地方了服务',
time: '2016/05/25 19:36',
liked: true,
like: '8'
intro: '鞋款定价回复即可老地方了服务',
publishTime: '2016/05/25 19:36',
isPraise: true,
praiseNum: '8'
}
],
paginationOpts: {
page: pageNum, // current page: http://host/?page=2
limit: 10, // per_page records' number
totalRows: 100 // total page number
page: pageNum, // current page: http://host/?page=2
limit: 10, // per_page records' number
total: 100, // total page number
queryParams: req.query
}
},
... ...
// 'use strict';
// const serviceAPI = new ServiceAPI();
// const _processIndexData = (list) => {
// const formatData = [];
// list = list || {};
// list = camelCase(list);
// if (list.ads) {
// _.forEach(list.data, (data) => {
// formatData.ads.push({
// href:
// });
// });
// }
// }
// const getIndexData = () => {
// return serviceAPI.get('guang/api/v1/category/get', sign.apiSign().then((result) => {
// if (result && result.code === 200) {
// return _processIndexData(result.data);
// } else {
// logger.error('资讯首页数据返回 code 不是 200');
// return {};
// }
// });
// };
// module.exports = {
// getIndexData: getIndexData
// };
'use strict';
const serviceAPI = global.yoho.ServiceAPI;
// const api = global.yoho.API;
const camelCase = global.yoho.camelCase;
const _ = require('lodash');
// const moment = require('moment');
const logger = global.yoho.logger;
// const helpers = global.yoho.helpers;
const _processNavData = (list, type) => {
let formatData = [];
list = list || [];
list = camelCase(list);
_.forEach(list, (data, index) => {
data.url = `//127.0.0.1:6003/editorial?type=${data.id}`;
data.isActive = index === parseInt(type, 10) ? true : false;
formatData.push(data);
});
return formatData;
};
const _processListData = (list) => {
list = list || [];
list = camelCase(list);
// let data = moment('2016年06月02日 15:56', 'YYYY年MM月DD日 HH:mm').format('YYYY/MM/DD HH:mm');
let artList = list.list.artList.map(data =>{
data.publishTime = data.publishTime.replace(/年|月/g, '/');
data.publishTime = data.publishTime.replace(/日/g, '');
return data;
});
return artList;
};
const _getResources = (type) => {
return serviceAPI.get('guang/api/v1/category/get', {}).then((result) => {
if (result && result.code === 200) {
return _processNavData(result.data, type);
} else {
logger.error('资讯首页导航数据返回 code 不是 200');
return {};
}
});
};
const _getBreakingSort = () => {
return serviceAPI.get('guang/api/*/article/getList', {}).then((result) => {
if (result && result.code === 200) {
return _processListData(result.data);
} else {
logger.error('资讯列表数据返回 code 不是 200');
return {};
}
});
};
const getIndexData = (type) => {
return Promise.all([_getResources(type), _getBreakingSort()])
.then((result) => {
return {
msgTypes: result[0],
msg: result[1]
};
});
};
module.exports = {
getIndexData
};
... ...
... ... @@ -5,8 +5,8 @@
<div class="index-content">
<ul class="msg-nav">
{{# msgTypes}}
<li data-type="{{typeId}}" {{#if isActive}}class="active"{{/if}}>
<a class="pjax-link" href="{{href}}">{{type}}</a>
<li data-type="{{id}}" {{#if isActive}}class="active"{{/if}}>
<a class="pjax-link" href="{{url}}">{{name}}</a>
</li>
{{/ msgTypes}}
</ul>
... ...
<div class="content-msg clearfix" data-id="{{id}}">
<div class="msg-left">{{msgLeft}}</div>
<div class="msg-left">{{categoryName}}</div>
<div class="msg-right">
<a class="msg-title" href="{{url}}" target="_blank">{{msgTitle}}</a>
<a class="msg-title" href="{{url}}" target="_blank">{{title}}</a>
<a href="{{url}}" target="_blank">
<img class="lazy" data-original="{{img}}">
<img class="lazy" data-original="{{src}}">
</a>
<div class="content">{{msgContent}}</div>
<div class="content">{{intro}}</div>
<div class="msg-app">
<span class="time">
<i class="iconfont">&#xe606;</i>
<b class="time-word">{{time}}</b>
<b class="time-word">{{publishTime}}</b>
</span>
<span class="like-comment">
<i class="iconfont like-icon{{#if liked}} liked{{/if}}">&#xe60e;</i>
<b class="like-num">{{like}}</b>
<i class="iconfont like-icon{{#if isPraise}} liked{{/if}}">&#xe60e;</i>
<b class="like-num">{{praiseNum}}</b>
</span>
</div>
</div>
... ...
/**
* [个人中心]收货地址
* @author: jiangmin
* @date: 2016/07/05
*/
'use strict';
const mcHandler = require('../models/menu-crumb-handler');
const addressModel = require('../models/address');
/**
* 收货地址页面加载
*/
const index = (req, res) => {
addressModel.getAddressDataAsync('123456', 20).then(result => {
for (let i = 0; i < result.data.length; i++) {
result.data[i].default = result.data[i].is_default === 'Y';
}
result.data.leftLength = 20 - result.data.length;
res.render('index', {
module: 'me',
page: 'address',
isMe: true,
content: {
nav: mcHandler.getMeCrumb(),
navigation: mcHandler.getSideMenu('收货地址'),
banner: 'http://placehold.it/150x120',
address: true,
title: '收货地址',
data: result.data
}
});
});
};
/**
* 添加地址
*/
const addAddressData = (req, res) => {
let uid = req.body.uid;
let address = req.body.address;
let areaCode = req.body.area_code;
let consignee = req.body.consignee;
let mobile = req.body.mobile;
let phone = req.body.phone;
addressModel.addAddressData(uid, address, areaCode, consignee, mobile, phone).then(result => {
res.send(result);
});
};
/**
* 修改地址
*/
const updateAddressData = (req, res) => {
let id = req.body.id;
let uid = req.body.uid;
let address = req.body.address;
let areaCode = req.body.area_code;
let consignee = req.body.consignee;
let mobile = req.body.mobile;
let phone = req.body.phone;
addressModel.updateAddressData(id, uid, address, areaCode, consignee, mobile, phone).then(result => {
res.send(result);
});
};
/**
* 删除地址
*/
const delAddressData = (req, res) => {
let id = req.body.id;
let uid = req.body.uid;
addressModel.delAddressData(id, uid).then(result => {
res.send(result);
});
};
/**
* 设置默认地址
*/
const setDefaultAddress = (req, res) => {
let id = req.body.id;
let uid = req.body.uid;
addressModel.setDefaultAddress(id, uid).then(result => {
res.send(result);
});
};
module.exports = {
index,
addAddressData,
updateAddressData,
delAddressData,
setDefaultAddress
};
... ...
... ... @@ -10,22 +10,41 @@ const mcHandler = require('../models/menu-crumb-handler');
const orderModel = require('../models/order');
/**
* 订单
* 我的订单
*/
const index = (req, res) => {
const orderData = orderModel.getOrderData();
const type = req.query.type;
const page = req.query.page;
res.render('index', {
page: 'order',
isMe: true,
content: Object.assign({
nav: mcHandler.getMeCrumb(),
navigation: mcHandler.getSideMenu('我的订单'),
banner: 'http://placehold.it/{width}x{height}'
}, orderData)
orderModel.getOrderData(type, page).then(result => {
res.render('index', {
page: 'order',
isMe: true,
content: Object.assign({
nav: mcHandler.getMeCrumb(),
navigation: mcHandler.getSideMenu('我的订单'),
banner: 'http://placehold.it/{width}x{height}'
}, result)
});
});
};
const getOrderList = (req, res) => {
const type = req.query.type;
const page = req.query.page;
orderModel.getOrderData(type, page).then(result => {
res.render('order-table', {
layout: false,
page: 'order',
isMe: true,
orderList: result.order.orderList,
paginationOpts: result.order.paginationOpts
});
});
};
module.exports = {
index
index: index,
getOrderList: getOrderList
};
... ...
/**
* [个人中心]收货地址
* @author: jiangmin
* @date: 2016/07/05
*/
'use strict';
const api = global.yoho.API;
/**
* 地址列表数据
*
* @param uid 用户ID
* @param limit 分页大小参数(默认10条)
* @return array 地址接口返回的数据
*/
const getAddressDataAsync = (uid, limit) => {
return api.get('', {
method: 'app.address.gethidden',
uid: uid,
limit: limit
}).then(result => {
// console.log('列表结果result', result);
if (result.code === '200') {
return result.data;
}
return result;
});
};
/**
* 保存地址数据
*
* @param uid 用户ID
* @param address 地址信息
* @param areaCode 城市码
* @param consignee 收货人
* @param mobile 手机号码
* @param phone 电话号码
* @return array 地址接口返回的数据
*/
const addAddressData = (uid, address, areaCode, consignee, mobile, phone) => {
return api.get('', {
method: 'app.address.add',
uid: uid,
address: address,
area_code: areaCode,
consignee: consignee,
mobile: mobile,
phone: phone
}).then(result => {
// console.log("添加result",result);
return result;
});
};
/**
* 修改地址数据
*
* @param id 地址id
* @param uid 用户ID
* @param address 地址信息
* @param areaCode 城市码
* @param consignee 收货人
* @param mobile 手机号码
* @param phone 电话号码
* @return array 地址接口返回的数据
*/
const updateAddressData = (id, uid, address, areaCode, consignee, mobile, phone) => {
return api.get('', {
method: 'app.address.update',
id: id,
uid: uid,
address: address,
area_code: areaCode,
consignee: consignee,
mobile: mobile,
phone: phone
}).then(result => {
// console.log("修改result", result);
return result;
});
};
/**
* 删除地址数据
*
* @param id 地址id
* @param uid 用户ID
* @return array 地址接口返回的数据
*/
const delAddressData = (id, uid) => {
return api.get('', {
method: 'app.address.del',
id: id,
uid: uid
}).then(result => {
// console.log("删除result",result);
return result;
});
};
/**
* 设置默认地址
*
* @param id 地址id
* @param uid 用户ID
* @return array 地址接口返回的数据
*/
const setDefaultAddress = (id, uid) => {
return api.get('', {
method: 'app.address.setdefault',
id: id,
uid: uid
}).then(result => {
// console.log('设置默认result', result);
return result;
});
};
module.exports = {
getAddressDataAsync: getAddressDataAsync,
addAddressData: addAddressData,
updateAddressData: updateAddressData,
delAddressData: delAddressData,
setDefaultAddress: setDefaultAddress
};
... ...
const getOrderData = () => {
return {
order: {
title: '我的订单',
tabs: [
{
text: '全部订单',
isActive: true,
type: 'all'
},
{
text: '待付款',
type: 'paying'
},
{
text: '待发货',
type: 'delivering'
}
],
showSearch: true,
orders: [
{
orderTime: '2016-07-10 12:30:11',
validLeftTime: '1时35分',
serialNumber: '887625272',
showMobile: true,
cost: '1200.00',
status: '待付款',
payVia: '在线支付',
goods: [
{
img: '//placehold.it/{width}x{height}',
name: '一件非常非常潮的衣服,因为刚从洗衣机里拿出来',
price: '32000.00',
color: '雪白',
size: '39码',
quantity: 5
},
{
img: '//placehold.it/{width}x{height}',
name: '一件非常非常潮的衣服,因为刚从洗衣机里拿出来',
price: '32000.00',
color: '雪白',
size: '39码',
quantity: 5
},
{
img: '//placehold.it/{width}x{height}',
name: '一件非常非常潮的衣服,因为刚从洗衣机里拿出来',
price: '32000.00',
color: '雪白',
size: '39码',
quantity: 5
}
]
},
{
orderTime: '2016-07-10 12:30:11',
validLeftTime: '1时35分',
serialNumber: '887625272',
showMobile: true,
cost: '1200.00',
status: '待付款',
payVia: '在线支付',
goods: [
{
img: '//placehold.it/{width}x{height}',
name: '一件非常非常潮的衣服,因为刚从洗衣机里拿出来',
price: '32000.00',
color: '雪白',
size: '39码',
quantity: 5
},
{
img: '//placehold.it/{width}x{height}',
name: '一件非常非常潮的衣服,因为刚从洗衣机里拿出来',
price: '32000.00',
color: '雪白',
size: '39码',
quantity: 5
},
{
img: '//placehold.it/{width}x{height}',
name: '一件非常非常潮的衣服,因为刚从洗衣机里拿出来',
price: '32000.00',
color: '雪白',
size: '39码',
quantity: 5
}
]
}
]
'use strict';
const api = global.yoho.API;
const camelCase = global.yoho.camelCase;
const _getUserOrder = (type, page) => {
return api.get('', {
method: 'app.SpaceOrders.get',
uid: '10931021',
type: type || 1,
page: page || 1,
limit: 10
}).then(result => {
let orderList = [];
let total = false;
let curPage = 1;
if (result && result.data) {
orderList = result.data.order_list;
total = result.data.total;
curPage = result.data.page;
}
return {
orderList: camelCase(orderList),
total: total,
curPage: curPage
};
});
};
const navBar = {
tabs: [
{
text: '全部订单',
isActive: true,
type: 'all'
},
{
text: '待付款',
type: 'paying'
},
{
text: '待发货',
type: 'delivering'
}
};
]
};
const getOrderData = (type, page) => {
return _getUserOrder(type, page).then(result => {
const fakeData = {
title: '我的订单',
showSearch: true
};
const order = Object.assign(fakeData, {
orderList: result.orderList.length && result.orderList || false
}, navBar);
const paginationOpts = {
paginationOpts: {
total: result.total,
page: result.curPage,
limit: 10
}
};
return {
order: Object.assign(order, paginationOpts)
};
});
};
module.exports = {
... ...
... ... @@ -11,8 +11,17 @@ const cRoot = './controllers';
// 订单
const order = require(`${cRoot}/order`);
const address = require(`${cRoot}/address`);
// 个人中心首页/订单
router.get(['/', '/order'], order.index);
router.get('/getOrderList', order.getOrderList);
// 个人中心首页/收货地址
router.get('/address', address.index);
router.post('/address/add', address.addAddressData);
router.post('/address/update', address.updateAddressData);
router.post('/address/del', address.delAddressData);
router.post('/address/default', address.setDefaultAddress);
module.exports = router;
... ...
{{> order/table-body}}
... ...
<div class="user-order">
{{> common/subtitle}}
{{> address/content}}
{{> address/table}}
</div>
... ...
<form id="address-form" name="address-form">
<div class="address-page">
<span class="blue tip">新增地址 电话为选填项,其他均为必填项</span>
<div class="add-address-detail">
<div class="form-group">
<label class="label-name">&nbsp;&nbsp;收货人:</label>
<input id="address_id" type="hidden" value="">
<input id="consignee" class="input width-190" type="text" placeholder="请输入您的姓名" maxlength="10">
<span class="blue error-tips">{{> icon/error-round}}收件人不能为空</span>
</div>
<div class="form-group">
<label class="label-name">所在区域:</label>
<div id="address"></div>
<span class="blue error-tips">{{> icon/error-round}}所在区域不能为空</span>
</div>
<div class="form-group">
<label class="label-name">详细地址:</label>
<input id="addressDetail" class="input width-275" type="text" placeholder="街道名称或小区名称" maxlength="60">
<span class="blue error-tips">{{> icon/error-round}}详细地址不能为空</span>
</div>
<div class="form-group">
<label class="label-name">手机号码:</label>
<input id="mobile" class="input width-190" type="text" placeholder="请输入手机号码(重要必填)" maxlength="11">
<span class="blue error-tips">{{> icon/error-round}}手机号码不能为空</span>
</div>
<div class="form-group">
<label class="label-name">电话号码:</label>
<input id="phone" class="input width-190" type="text" placeholder="请输入电话号码(选填)">
</div>
<div class="form-group ">
<label class="label-name"></label>
<span class="iconfont radio default-address opreation">&#xe604;</span>
<label class="radio-lable">设置为默认收货地址</label>
</div>
<div class="form-group">
<span class="btn opreation" id="save-address">保存</span>
</div>
</div>
</div>
</form>
... ...
<div class="address-table">
<span class="blue table-title">已保存了{{data.length}}条地址,还能保存{{data.leftLength}}条地址</span>
<table class="a-table">
<tr class="table-head">
<th class="width-80">收货人</th>
<th class="width-195">所在区域</th>
<th class="width-280">详细地址</th>
<th class="width-120">手机/电话</th>
<th class="width-260">操作</th>
</tr>
{{#each data}}
<tr class="table-body">
<input type="hidden" id="tr_{{address_id}}" value="{{address_id}}">
<td class="width-80">{{consignee}}</td>
<td class="width-195">{{area}}</td>
<td class="width-255">{{address}}</td>
<td class="width-120"><p>{{mobile}}</p><p>{{phone}}</p></td>
<td class="width-260">
<div>
<span class="blue opreation update-address" data-id="{{address_id}}">修改</span>
|
<span class="blue opreation del-address" data-id="{{address_id}}">删除</span>
{{#if default}}
<span class="btn set-default opreation current-default ">默认地址</span>
{{else}}
<span class="btn set-default opreation " data-id="{{address_id}}">设为默认</span>
{{/if}}
</div>
</td>
</tr>
{{/each}}
</table>
</div>
... ...
<div class="user-order">
{{#order}}
{{> common/subtitle}}
{{#if tabs}}
{{> order/tabs}}
{{/if}}
{{> order/nav}}
{{> order/table-header}}
{{#if orders}}
{{> order/table-body}}
{{/if}}
{{> order/table-body}}
{{/order}}
</div>
... ...
<ul class="tabs clearfix">
{{#tabs}}
<li class="{{#if isActive}}active{{/if}}" data-type="{{type}}">{{text}}</li>
{{/tabs}}
</ul>
<div class="order-nav">
<ul class="tabs clearfix">
{{#tabs}}
<li class="{{#if isActive}}active{{/if}}" data-type="{{type}}">{{text}}</li>
{{/tabs}}
</ul>
<div class="search-bar">
<input class="search-ctrl" type="text" placeholder="商品名称和订单号">
<button class="search-ctrl">搜索订单</button>
</div>
</div>
... ...
{{#orders}}
<div class="table">
<ul class="header">
<li class="content">下单时间:{{orderTime}}</li>
<li class="content">订单编号:{{serialNumber}}</li>
{{#if showMobile}}
<li class="content">手机订单</li>
{{/if}}
</ul>
<div class="table-body">
<div class="goods-container special-border">
{{#goods}}
<div class="good-info {{#if @last}}last{{/if}}">
<img src="{{image img 65 90}}">
<div class="detail">
<p class="with-bottom-space">{{name}}</p>
<span class="with-space">颜色:{{color}}</span>
<span>尺码:{{size}}</span>
<p>{{> icon/error-round}}{{quantity}}</p>
<div class="table table-body{{#unless orderList}} empty{{/unless}}">
{{#if orderList}}
{{#orderList}}
<div class="order">
<ul class="header">
<li class="content">下单时间:{{createTime}}</li>
<li class="content">订单编号:{{orderCode}}</li>
{{#if showMobile}}
<li class="content">手机订单</li>
{{/if}}
</ul>
<div class="table-body">
<div class="goods-container special-border">
{{#orderGoods}}
<div class="good-info {{#if @last}}last{{/if}}">
<img src="{{image goodsImage 65 90}}">
<div class="detail">
<p class="with-bottom-space">{{productName}}</p>
<span class="with-space">颜色:{{colorName}}</span>
<span>尺码:
<span class="bold">{{sizeName}}</span>
</span>
<p class="bold">{{> icon/error-round}}{{buyNumber}}</p>
</div>
</div>
<div class="price bold">
<p class="{{#if @last}}last{{/if}}">{{goodsAmount}}</p>
</div>
{{/orderGoods}}
</div>
<div class="price">
<p>{{price}}</p>
<div class="common-column special-border">
<p class="bold">{{amount}}</p>
<p class="subtext">{{paymentTypeStr}}</p>
</div>
<div class="common-column special-border">
<p class="bold">{{statusStr}}</p>
<p class="subtext">查看详情</p>
</div>
<div class="common-column special-border">
{{#if payLeftTime}}
<p class="left-time">剩余{{payLeftTime}}</p>
{{/if}}
{{#if showPayButton}}
<button>立即付款</button>
{{/if}}
{{#if showEditOption}}
<p class="subtext">修改订单</p>
<p class="subtext no-space">删除订单</p>
{{^}}
<p class="subtext">查看详情</p>
{{/if}}
</div>
{{/goods}}
</div>
<div class="common-column special-border">
<p>{{cost}}</p>
</div>
<div class="common-column special-border">
<p>{{status}}</p>
</div>
<div class="common-column special-border">
<p>{{validLeftTime}}</p>
</div>
</div>
{{/orderList}}
{{{ pagination paginationOpts }}}
{{^}}
<div class="bg"></div>
<div class="msg">
<p class="msg-zh bold">您暂时还没有订单</p>
<p class="msg-en">You do not have an order for the time being</p>
<span class="btn">去购物</span>
</div>
{{/if}}
</div>
{{/orders}}
... ...
<div class="table">
<div class="table column-category">
<ul class="table-header header">
<li class="big-width">商品信息</li>
<li class="normal-width">单价</li>
... ...
'use strict';
const _ = require('lodash');
const Search = require('../models/list');
const Search = require('../models/search');
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
};
}
function getNav(channel, sort, sorts) {
let nav = [{
link: '#',
pathTitle: '',
name: 'MEN首页'
}];
if (sort) {
sorts.forEach(s => {
if (s.relationParameter.sort === sort) {
nav.push({
link: '#',
pathTitle: '',
name: s.categoryName
});
} else if (s.sub) {
s.sub.forEach(m => {
if (m.relationParameter.sort === sort) {
nav.push({
link: '#',
pathTitle: '',
name: s.categoryName
});
nav.push({
link: '#',
pathTitle: '',
name: m.categoryName
});
}
});
}
});
}
return nav;
}
const DateHelper = require('../models/helpers');
const list = {
index: (req, res, next) => {
... ... @@ -99,6 +16,12 @@ const list = {
let color = req.query.color || '';
let order = req.query.order || '';
let retDate = {
module: 'product',
page: 'list',
title: '列表'
};
Search.queryProduct({
page: page,
brand: brand,
... ... @@ -112,108 +35,21 @@ const list = {
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,
navPath: {
nav: getNav('', sort, sorts)
}
};
retDate.filter = DateHelper.filterHandle(data.filter, req.query);
}
let pagination = {
retDate.paginationData = {
page: page,
limit: data.limit || 45,
total: data.total
};
console.log(pagination);
res.display('list', _.assign(ret, {
letters: brandLetters(),
total: data.total,
pageTotal: data.pageTotal,
pageNo: data.page,
queryParams: req.query
};
res.display('list', _.assign(retDate, {
products: data.productList,
pagination: pagination,
order: order,
module: 'product',
page: 'list',
title: '列表'
order: order
}));
} else {
return Promise.reject('query product error');
... ...
/**
* 店铺相关页面
*
* 首页、列表页
*
* @author: jiangfeng<jeff.jiang@yoho.cn>
*/
'use strict';
const _ = require('lodash');
const camelCase = global.yoho.camelCase;
const BrandData = require('../models/brand-service');
const Search = require('../models/search');
const DateHelper = require('../models/helpers');
function bannerFormat(banner) {
return {
bgImg: banner.brandBanner,
brandIntro: {
text: '品牌介绍'
},
height: 150
};
}
function shopMenu() {
let menus = [
{name: '店铺首页', href: '/'},
{name: '全部商品', href: '/shop', icon: '&#xe60a;'},
{name: '人气单品', href: '/list?order=xxx'},
{name: '新品上架', href: '/list?order=s_t_desc'}
];
return menus;
}
const shop = {
list(req, res, next) {
let data = {
module: 'product',
page: 'shop-list',
title: '店铺列表'
};
let domain = req.query.domain;
let q = req.query;
q.page = q.page || 1;
data.shopMenu = shopMenu();
BrandData.getBrandByDomainAsync(domain).then(result => {
data.brandBanner = bannerFormat(result);
q.brand = result.id;
q.shop_id = q.shopId || '';
}).then(() => {
return Search.queryProductOfBrand(q).then(result => {
if (result && result.code === 200 && result.data) {
let ret = camelCase(result.data);
if (ret.filter) {
data.filter = DateHelper.filterHandle(ret.filter, req.query);
}
data.paginationData = {
page: q.page,
limit: ret.limit || 45,
total: ret.total,
pageTotal: ret.pageTotal,
queryParams: req.query
};
res.display('shop-list', _.assign(data, {
products: ret.productList,
order: q.order
}));
} else {
return Promise.reject('query product error');
}
});
}).catch(next);
}
};
module.exports = shop;
... ...
/**
* @author: jiangfeng<jeff.jiang@yoho.cn>
*/
'use strict';
const api = global.yoho.API;
const getBannerInfoAsync = bid => {
return api.get('', {
method: 'web.brand.banner',
brand_id: bid
});
};
const getBrandLogoByDomainAsync = domain => {
return api.get('', {
domain: domain,
method: 'web.brand.byDomain'
});
};
module.exports = {
getBannerInfoAsync,
getBrandLogoByDomainAsync
};
... ...
/**
* Created by TaoHuang on 2016/6/14.
*/
'use strict';
const Promise = require('bluebird');
const co = Promise.coroutine;
const api = require('./brand-api');
const camelCase = global.yoho.camelCase;
const getBrandByDomainAsync = domain => {
return co(function*() {
let brandInfo = yield api.getBrandLogoByDomainAsync(domain);
if (!brandInfo.data || brandInfo.code !== 200) {
return {};
}
return camelCase(brandInfo.data);
})();
};
const getBannerInfoAsync = bid => {
return co(function*() {
let brandInfo = yield api.getBannerInfoAsync(bid);
if (!brandInfo.data || brandInfo.code !== 200) {
return {};
}
return camelCase(brandInfo.data);
})();
};
module.exports = {
getBrandByDomainAsync,
getBannerInfoAsync: getBannerInfoAsync
};
... ...
'use strict';
const _ = require('lodash');
const helpers = {
brandLetters(numberIndex) {
let letters = [];
numberIndex = numberIndex || 0;
for (let i = 'A'.charCodeAt(0); i <= 'Z'.charCodeAt(0); i++) {
letters.push({
letter: String.fromCharCode(i),
selected: false
});
}
if (numberIndex === -1) {
letters.push({
letter: '0-9',
selected: false
});
} else if (numberIndex === 0) {
letters.unshift({
letter: '0-9',
selected: false
});
}
return letters;
},
genders() {
return [
{
name: '男士',
value: '1,3'
}, {
name: '女士',
value: '2,3'
}];
},
colorConvert(colors) {
return colors.map((c) => {
return {
id: c.colorId,
title: c.colorName,
rgb: c.colorValue ? `url(${c.colorValue})` : '#' + c.colorCode
};
});
},
getNav(channel, sort, sorts) {
let nav = [{
link: '#',
pathTitle: '',
name: 'MEN首页'
}];
if (sort) {
sorts.forEach(s => {
if (s.relationParameter.sort === sort) {
nav.push({
link: '#',
pathTitle: '',
name: s.categoryName
});
} else if (s.sub) {
s.sub.forEach(m => {
if (m.relationParameter.sort === sort) {
nav.push({
link: '#',
pathTitle: '',
name: s.categoryName
});
nav.push({
link: '#',
pathTitle: '',
name: m.categoryName
});
}
});
}
});
}
return nav;
},
newFilter(key, value, name) {
return {
key: key,
value: value,
name: name
};
},
filterHandle(filter, q) {
let priceRange = filter.priceRange;
let sizeInfo = filter.size;
let genders = this.genders();
let brands = filter.brand;
let colors = this.colorConvert(filter.color);
let sorts = filter.groupSort;
let filters = [];
genders.forEach(g => {
if (g.value === q.gender) {
g.checked = true;
filters.push(this.newFilter('gender', q.gender, g.name));
}
});
priceRange = Object.keys(priceRange).map((k) => {
let prices = k.split(',');
if (k === q.price) {
filters.push(this.newFilter('price', q.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 (q.size) {
sizeInfo.forEach(s => {
if (s.sizeId === parseInt(q.size, 10)) {
filters.push(this.newFilter('size', q.size, s.sizeName));
}
});
}
if (q.brand) {
let brandNames = brands.filter(b => {
return (',' + q.brand + ',').indexOf(',' + b.id + ',') >= 0;
}).map(b => {
return b.brandName;
}).join('、');
filters.push(this.newFilter('brand', q.brand, brandNames));
}
if (q.color) {
colors.forEach(c => {
if (c.id === parseInt(q.color, 10)) {
c.cur = true;
let fi = this.newFilter('color', q.color, c.title);
fi.color = c;
filters.push(fi);
}
});
}
return {
people: genders,
sortData: sorts,
brandData: brands,
colors: colors,
size: sizeInfo,
priceRange: priceRange,
filters: filters,
showFilters: filters.length > 0,
letters: this.brandLetters(),
navPath: {
nav: this.getNav('', q.sort, sorts)
}
};
}
};
module.exports = helpers;
... ...
'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) {
... ... @@ -17,26 +13,22 @@ function clearEmptyVal(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',
method: 'app.search.li',
limit: 45,
productSize: '384x511',
yh_channel: 1
};
Object.assign(finalParams, clearEmptyVal(params));
return api.get('', finalParams);
},
queryProductOfBrand(params) {
let finalParams = {
method: 'app.search.li',
limit: 45,
productSize: '384x511',
yh_channel: 1
... ...
... ... @@ -10,10 +10,13 @@ const router = require('express').Router(); // eslint-disable-line
const cRoot = './controllers';
const list = require(cRoot + '/list');
const item = require(cRoot + '/item');
const shop = require(cRoot + '/shop');
// Your controller here
router.get('/list', list.index); // 组件demo页
router.get('/list', list.index); // 列表页面
router.get(/\/item\/([\d]+)_([\d]+).html/, item.index); // 商品详情页
router.get('/shop/list', shop.list);
module.exports = router;
... ...
<div class="blk-page yoho-product-list">
<div class="center-content">
{{# navPath}}
{{# filter.navPath}}
{{> path-nav}}
{{/ navPath}}
{{/ filter.navPath}}
</div>
<div class="center-content clearfix">
<div class="left">
{{!-- 筛选区域 --}}
{{#filter}}
{{> list/filter}}
{{/filter}}
</div>
<div class="right">
{{!-- 已选中条件 --}}
{{#filter}}
{{> list/filter-area}}
{{/filter}}
{{!-- 排序 --}}
{{> list/order-area}}
{{!-- 商品列表 --}}
{{> list/goods-box}}
{{!-- 分页 --}}
{{{ pagination pagination }}}
{{{ pagination paginationData }}}
</div>
</div>
</div>
\ No newline at end of file
... ...
<div class="blk-page yoho-product-list">
<div class="center-content">
{{# filter.navPath}}
{{> path-nav}}
{{/ filter.navPath}}
</div>
<div class="center-content clearfix">
{{> brand-banner-list }}
{{> list/shop-menu }}
</div>
<div class="center-content clearfix">
<div class="left">
{{!-- 筛选区域 --}}
{{#filter}}
{{> list/filter}}
{{/filter}}
</div>
<div class="right">
{{!-- 已选中条件 --}}
{{#filter}}
{{> list/filter-area}}
{{/filter}}
{{!-- 排序 --}}
{{> list/order-area}}
{{!-- 商品列表 --}}
{{> list/goods-box}}
{{!-- 分页 --}}
{{{ pagination paginationData }}}
</div>
</div>
</div>
... ...
{{# brandBanner}}
<div class="brand-banner" style="background-image: url('{{image bgImg 1150 150}}')">
<p class="opts">
{{# brandIntro}}
<a href="{{link}}">
<i class="iconfont">&#xe631;</i>
{{text}}
</a>
{{/ brandIntro}}
<span id="brand-fav" class="brand-fav{{#if coled}} coled{{/if}}">
{{> icon/collection}}
</span>
</p>
</div>
{{/brandBanner}}
... ...
... ... @@ -30,4 +30,4 @@
</div>
</div>
</div>
{{/ brandBanner}}
\ No newline at end of file
{{/ brandBanner}}
... ...
... ... @@ -50,7 +50,11 @@
{{#each brandData}}
<div class="input-radio" data-value="{{id}}">
{{> icon/radio}}
<label>{{brandNameEn}}</label>
{{#if brandNameEn}}
<label>{{brandNameEn}}</label>
{{^}}
<label>{{brandName}}</label>
{{/if}}
</div>
{{/each}}
</div>
... ... @@ -111,4 +115,4 @@
{{/each}}
</div>
</div>
</div>
\ No newline at end of file
</div>
... ...
... ... @@ -7,20 +7,22 @@
<span class="iconfont down s_p_desc {{#isEqual order 's_p_desc'}}selected{{/isEqual}}">&#xe616;</span>
</div>
{{#paginationData}}
<div class="right">
<label>
<span>{{total}}</span>件商品
</label>
<label class="page-info"><span class="cur-page">{{pageNo}}</span>/<span class="total-page">{{pageTotal}}</span></label>
{{#isEqual pageNo 1}}
<label class="page-info"><span class="cur-page">{{page}}</span>/<span class="total-page">{{pageTotal}}</span></label>
{{#isEqual page 1}}
<span class="iconfont page disable page-pre">&#xe607;</span>
{{^}}
<span class="iconfont page page-pre">&#xe607;</span>
{{/isEqual}}
{{#isEqual pageNo pageTotal}}
{{#isEqual page pageTotal}}
<span class="iconfont page disable page-next">&#xe61e;</span>
{{^}}
<span class="iconfont page page-next">&#xe61e;</span>
{{/isEqual}}
</div>
{{/paginationData}}
</div>
\ No newline at end of file
... ...
<ul class="shop-menu">
{{#each shopMenu}}
<li>
<a href="{{href}}">
{{name}}
{{#icon}}
<i class="iconfont">&#xe60a;</i>
{{/icon}}
</a>
</li>
{{/each}}
</ul>
... ...
... ... @@ -19,7 +19,7 @@ module.exports = {
},
cookieDomain: 'yohoblk.com',
domains: {
api: 'http://api.yoho.yohoops.org/', // devapi.yoho.cn:58078 testapi.yoho.cn:28078 devapi.yoho.cn:58078
api: 'http://devapi.yoho.cn:58078/', // 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/'
},
... ...
... ... @@ -15,4 +15,6 @@ module.exports = app => {
app.use('/', require('./apps/channel')); // 频道页
app.use('/me', require('./apps/me')); // 个人中心
app.use('/editorial', require('./apps/editorial')); // 资讯
app.use('/product', require('./apps/product'));
app.use('/brand', require('./apps/brand')); // 资讯
};
... ...
... ... @@ -14,26 +14,28 @@ order: {
// 是否显示搜索
showSearch: true/false,
// 订单数据
orders: [
// 订单列表
orderList: [
{
orderTime: '' // 下单时间
validLeftTime: '', // 订单剩余有效时间
serialNumber: '' // 订单编码
createTime: '' // 下单时间
payLeftTime: '', // 订单剩余有效时间
orderCode: '' // 订单编码
showMobile: true/false, // 是否是手机下单
cost: '', // 订单花费
status: '', // 订单状态
payVia: '', // 支付方式
amount: '', // 订单花费
statusStr: '', // 订单状态
paymentTypeStr: '', // 支付方式
showPayButton: true/false, // 是否显示立即付款按钮
showEditOption: true/false // 是否显示编辑项
// 订单中的商品
goods: [
orderGoods: [
{
img: '',
name: '',
price: '',
color: '',
size: '',
quantity: ''
goodsImage: '',
productName: '',
goodsAmount: '',
colorName: '',
sizeName: '',
buyNumber: ''
}
]
}
... ...
... ... @@ -33,7 +33,7 @@ exports.createPagination = function(pagination, options) {
queryParams = '', // paginate with query parameter
page = parseInt(pagination.page, 10), // current page number
leftText = '<i class="iconfont">&#xe607;</i>', // prev
rightText = '<i class="iconfont">&#xe606;</i>', // next
rightText = '<i class="iconfont">&#xe61e;</i>', // next
paginationClass = 'blk-pagination'; // pagination <ul> default class
var pageCount,
... ...
... ... @@ -102,7 +102,7 @@
"yoho-jquery-accordion": "0.0.2",
"yoho-jquery-lazyload": "^1.9.7",
"yoho-jquery-placeholder": "^2.3.1",
"yoho-jquery-qrcode": "0.0.2",
"yoho-jquery-qrcode": "0.0.3",
"yoho-slider": "0.0.2"
}
}
... ...
No preview for this file type
... ... @@ -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>
Created by FontForge 20120731 at Thu Jul 7 09:08:20 2016
<<<<<<< HEAD
Created by FontForge 20120731 at Thu Jul 7 17:43:49 2016
=======
Created by FontForge 20120731 at Fri Jul 8 14:37:44 2016
>>>>>>> feature/product
By admin
</metadata>
<defs>
... ... @@ -19,7 +23,11 @@ Created by FontForge 20120731 at Thu Jul 7 09:08:20 2016
bbox="0 -224 1303 896.303"
underline-thickness="50"
underline-position="-100"
unicode-range="U+0078-E632"
<<<<<<< HEAD
unicode-range="U+0078-E638"
=======
unicode-range="U+0078-E63B"
>>>>>>> feature/product
/>
<missing-glyph horiz-adv-x="374"
d="M34 0v682h272v-682h-272zM68 34h204v614h-204v-614z" />
... ... @@ -130,8 +138,11 @@ d="M361 194q45 -63 81 -152h143q42 68 75 152l82 -29q-32 -69 -70 -123h202v-71h-724
<glyph glyph-name="uniE624" unicode="&#xe624;"
d="M897 -212h-770q-44 0 -71 34.5t-21 82.5l89 598q3 31 30 52.5t61 21.5h51q4 111 73 173t171.5 62t171 -62t73.5 -173h54q34 0 61 -21.5t30 -52.5l89 -598q6 -48 -21 -82.5t-71 -34.5zM230 406q0 -25 18 -43t43 -18t42.5 18t17.5 43t-17.5 42.5t-42.5 17.5t-43 -17.5
t-18 -42.5zM510 767q-87 0 -144.5 -49t-61.5 -141h412q-4 92 -61.5 141t-144.5 49zM736 466q-25 0 -42.5 -17.5t-17.5 -42.5t17.5 -43t42.5 -18t43 18t18 43t-18 42.5t-43 17.5z" />
<<<<<<< HEAD
=======
<glyph glyph-name="uniE625" unicode="&#xe625;"
d="M519 847l-398 -398h120v-398h159v213h212v-213h159v398h146zM519 847z" />
d="M43 0h938l-469 811zM555 128h-86v85h86v-85zM555 299h-86v170h86v-170z" />
>>>>>>> feature/product
<glyph glyph-name="uniE626" unicode="&#xe626;"
d="M139 233q-24 -59 -27.5 -108t15.5 -60q13 -7 32.5 7.5t38.5 45.5q16 -66 72 -116q-29 -11 -45.5 -28.5t-16.5 -37.5q0 -34 43.5 -57.5t105.5 -23.5q56 0 97.5 19.5t50.5 48.5h18q8 -29 50 -48.5t98 -19.5q62 0 105.5 23.5t43.5 57.5q0 20 -16.5 37.5t-45.5 28.5
q56 50 71 116q20 -31 39 -45.5t32 -7.5q19 11 16 60t-27 108q-19 46 -42 78t-43 40q1 7 1 12q0 35 -17 64v4q0 16 -7 30q-5 125 -77.5 207t-190 82t-189.5 -82t-77 -207q-7 -14 -7 -30v-4q-17 -29 -17 -64q0 -5 1 -12q-20 -8 -43.5 -40t-41.5 -78z" />
... ... @@ -166,10 +177,34 @@ t-15.5 36.5t-24.5 22t-28.5 11.5t-26.5 3t-19 -0.5l-8 -1q-9 0 -16 -7t-7 -16t7 -16t
q18 2 30 7q5 0 16.5 1.5t31 -3.5t39 -12.5t40.5 -25t35 -41.5q25 -57 10 -109q-6 -17 -6 -32q0 -14 9 -22t23 -8t21.5 5t10.5 23q17 53 13 96.5t-18.5 75.5t-40.5 55.5t-52 37t-54 20.5z" />
<glyph glyph-name="uniE62F" unicode="&#xe62f;"
d="M756 -133h-488q-21 0 -36.5 13t-15.5 32v780q0 19 15.5 32t36.5 13h488q21 0 36.5 -13t15.5 -32v-780q0 -19 -15.5 -32t-36.5 -13zM512 -88q14 0 24.5 9t10.5 21t-10.5 21t-24.5 9t-24.5 -9t-10.5 -21t10.5 -21t24.5 -9zM756 647h-488v-630h488v630z" />
<glyph glyph-name="uniE630" unicode="&#xe630;"
d="M513 857q98 0 184.5 -37t151 -102t102 -151.5t37.5 -185.5t-37.5 -185t-102 -151t-151 -102t-184.5 -37q-100 0 -186.5 37t-151 102t-102 151t-37.5 185t37.5 185.5t102 151.5t151 102t186.5 37zM784 316q28 0 47.5 20t19.5 48t-19.5 47t-47.5 19h-202v203q0 28 -20 48
t-48 20t-47.5 -20t-19.5 -48v-203h-203q-28 0 -47.5 -19t-19.5 -47t19.5 -48t47.5 -20h203v-202q0 -28 19.5 -48t47.5 -20t48 20t20 48v202h202z" />
<glyph glyph-name="uniE631" unicode="&#xe631;"
d="M831 612q-2 12 -11 20t-21 8h-160v32q0 66 -47 113t-113 47t-112.5 -47t-46.5 -113v-32h-160q-12 0 -21.5 -8t-10.5 -20l-64 -576q-1 -15 8.5 -25.5t23.5 -10.5h767q14 0 23.5 10.5t7.5 25.5zM351.5 448q-13.5 0 -23 9.5t-9.5 22.5t9.5 22.5t23 9.5t22.5 -9.5t9 -22.5
t-9 -22.5t-22.5 -9.5zM575 640h-192v32q0 40 28.5 68t68 28t67.5 -28t28 -68v-32zM607.5 448q-13.5 0 -23 9.5t-9.5 22.5t9.5 22.5t23 9.5t22.5 -9.5t9 -22.5t-9 -22.5t-22.5 -9.5z" />
<glyph glyph-name="uniE632" unicode="&#xe632;"
d="M684 670q-23 96 -68.5 153t-103.5 57t-103.5 -57t-68.5 -153h-178l-69 -798h838l-69 798h-178zM406 670q18 67 47 107t59 40t59 -40t47 -107h-212z" />
<glyph glyph-name="uniE633" unicode="&#xe633;"
d="M512 764q-94 0 -180 -36.5t-148.5 -99t-99 -148.5t-36.5 -180t36.5 -180t99 -148.5t148.5 -99t180 -36.5t180 36.5t148.5 99t99 148.5t36.5 180t-36.5 180t-99 148.5t-148.5 99t-180 36.5zM724 244h-424q-23 0 -39.5 16.5t-16.5 39.5t16.5 39.5t39.5 16.5h424
q23 0 39 -16.5t16 -39.5t-16 -39.5t-39 -16.5z" />
<glyph glyph-name="uniE634" unicode="&#xe634;"
d="M500 775l-348 -298q-16 -14 -16 -35v-386q0 -25 17.5 -42.5t42.5 -17.5h197v257h238v-257h197q25 0 42.5 17.5t17.5 42.5v386q0 21 -16 35l-348 298q-12 10 -24 0z" />
<glyph glyph-name="uniE635" unicode="&#xe635;"
d="M556 -209l-292 507l3 2l-3 2l292 507h211l-293 -509l293 -509h-211z" />
<glyph glyph-name="uniE636" unicode="&#xe636;"
d="M468 -209l292 507l-3 2l3 2l-292 507h-211l293 -509l-293 -509h211z" />
<glyph glyph-name="uniE637" unicode="&#xe637;"
d="M512 -212q-104 0 -199 40.5t-163.5 109t-109 163.5t-40.5 199t40.5 199t109 163.5t163.5 109t199 40.5t199 -40.5t163.5 -109t109 -163.5t40.5 -199t-40.5 -199t-109 -163.5t-163.5 -109t-199 -40.5zM512 684q-159 0 -271.5 -112.5t-112.5 -271.5t112.5 -271.5
t271.5 -112.5t271.5 112.5t112.5 271.5t-112.5 271.5t-271.5 112.5z" />
<glyph glyph-name="uniE638" unicode="&#xe638;"
d="M511 833q-91 0 -174 -35.5t-143 -95.5t-95.5 -143t-35.5 -174t35.5 -174t95.5 -143t143 -95t174 -35t174 35t143 95t95.5 143t35.5 174t-35.5 174t-95.5 143t-143 95.5t-174 35.5z" />
<<<<<<< HEAD
=======
<glyph glyph-name="uniE63A" unicode="&#xe63a;"
d="M963 564l-117 -190h92v-43h-107v-58h107v-42h-107v-85h-55v85h-112v42h112v58h-112v43h95l-115 190h62q81 -142 98 -180h1q6 16 33 63l66 117h59z" />
<glyph glyph-name="uniE63B" unicode="&#xe63b;"
d="M0 -128h1024v1024zM826 301l-250 -282l-122 122q-9 9 -9 22t9.5 22.5t22.5 9.5t22 -9l77 -77l198 230q10 10 23 10t22 -10q10 -5 13 -16.5t-6 -21.5z" />
>>>>>>> feature/product
</font>
</defs></svg>
... ...
No preview for this file type
No preview for this file type
/**
* 品牌页
* @author: zxr<xiaoru.zhang@yoho.cn>
* @date: 2016/07/09
*/
var $ = require('yoho-jquery'),
lazyLoad = require('yoho-jquery-lazyload');
require('../common/header');
require('../common/return-top');
lazyLoad($('#msg-list img.lazy'));
... ...
... ... @@ -7,26 +7,22 @@
var $ = require('yoho-jquery'),
lazyLoad = require('yoho-jquery-lazyload');
// var prising;
require('../common/header');
require('../common/return-top');
lazyLoad($('#msg-list img.lazy'));
$('.msg-nav li').on('click', function() {
// var activeTab = $(this).attr('data-type'),
// href = $(this).find('a').attr('href');
$('.msg-nav li').removeClass('active');
$(this).addClass('active');
});
$('.editorial-index-page').on('click', '.like-icon', function() {
var $this = $(this);
// msgId = $this.closest('.content-msg').data().id;
$this.toggleClass('liked');
var $this = $(this),
num = parseInt($this.next().html(), 10);
if ($this.hasClass('liked')) {
$this.removeClass('liked');
num = num - 1;
} else {
$this.addClass('liked');
num = num + 1;
console.log(num);
}
$this.next().html(num);
});
require('../common/header');
require('../common/return-top');
... ...
/**
* [个人中心]收货地址
* @author: jiangmin
* @date: 2016/07/05
*/
var cascadingAddress = require('../plugins/cascading-address');
var dialog = require('../plugins/dialog');
var _confirm = dialog.Confirm;
var $addressId = $('#address_id');
var $consignee = $('#consignee');
var $address = $('#addressDetail');
var $mobile = $('#mobile');
var $phone = $('#phone');
var currentLength = $('.a-table').find('tr').length - 1;// 当前地址条数
var leftLength = 20 - currentLength;// 还剩地址条数
var Bll = {
// 获取输入框输入的值
getInfo() {
// todo uid
var uid = '123456';
return {
id: $addressId.val(),
uid: uid,
consignee: $consignee.val(),
// todo 地址码
address: $address.val(),
mobile: $mobile.val(),
phone: $phone.val()
// todo 设置默认值
};
},
// 清空输入框
clearInput() {
$consignee.val('');
// todo 省市区清空
$address.val('');
$mobile.val('');
$phone.val('');
},
// 校验
check(info) {
let flag = true;
let reg = new RegExp(/^(0|86|17951)?(13[0-9]|15[012356789]|17[678]|18[0-9]|14[57])[0-9]{8}$/);
if (info.consignee === '' || info.address === '' || info.mobile === '') {
flag = '有必填项为空';
} else if (!reg.test(info.mobile)) {
flag = '手机号码格式不对';
}
return flag;
},
// 拼接一条数据的html
getHtml(info) {
var html = '<tr class="table-body">';
html += '<input type="hidden" id="tr_' + info.address_id + '" value="' + info.address_id + '">' +
'<td class=\'width-80\'>' + info.consignee + '</td>' +
'<td class=\'width-195\'>' + info.area + '</td>' +
'<td class=\'width-280\'>' + info.address + '</td>' +
'<td class=\'width-120\'><p>' + info.mobile + '</p><p>' + info.phone + '</p></td>' +
'<td class=\'width-260\'><div><span class=\'blue opreation update-address\'>修改</span>\n|\n' +
'<span class=\'blue opreation del-address\' data-id=\'' + info.address_id + '\'>删除</span>\n' +
'<span class=\'btn set-default opreation \' data-id=\'' + info.address_id + '\'>设为默认</span></div></td>';
html += '</tr>';
return html;
},
// 获取一条数据
setInfo(id, td) {
$addressId.val(id);
$consignee.val(td.eq(0).text());
// todo 省市区逆向展示
// $areaCode.val(td.eq(1).text());
$address.val(td.eq(2).text());
$mobile.val(td.eq(3).children().eq(0).text());
$phone.val(td.eq(3).children().eq(1).text());
},
// 设置表格头部
setTableTile() {
$('.table-title').text('已保存了' + currentLength +
'条地址,还能保存' + leftLength + '条地址');
}
};
require('./me');
// 设置收货地址
$('.default-address').click(function() {
if ($(this).hasClass('checked')) {
$(this).removeClass('checked');
$(this).html('&#xe604;');
} else {
$(this).addClass('checked');
$(this).html('&#xe603;');
}
});
// 校验
$consignee.keydown(function() {
$(this).next().hide();
});
$consignee.blur(function() {
if ($(this).val().trim() === '') {
$(this).next().show();
}
});
$address.keydown(function() {
$(this).next().hide();
});
$address.blur(function() {
if ($(this).val().trim() === '') {
$(this).next().show();
}
});
$mobile.keydown(function() {
$(this).next().hide();
});
$mobile.blur(function() {
if ($(this).val().trim() === '') {
$(this).next().show();
} else {
let reg = new RegExp(/^(0|86|17951)?(13[0-9]|15[012356789]|17[678]|18[0-9]|14[57])[0-9]{8}$/);
if (!reg.test(($(this).val().trim()))) {
$(this).next().show();
$(this).next().html('手机号码格式不正确');
}
}
});
// 保存收货地址
$(document).on('click', '#save-address', function() {
var info = Bll.getInfo();
var area = $('#address-form').serialize();
info.area_code = area.substring(area.length - 6);
if (Bll.check(info) === true) {
// 新增
if (info.id === '') {
$.ajax({
type: 'POST',
url: '/me/address/add',
dataType: 'json',
data: info,
success: function(data) {
let html = Bll.getHtml(data.data);
currentLength++;
leftLength--;
$('tbody').append(html);
Bll.setTableTile();
Bll.clearInput();
}
});
} else { // 修改
console.log('上传info', info);
$.ajax({
type: 'POST',
url: '/me/address/update',
dataType: 'json',
data: info,
success: function(data) {
if (data.code === 200) {
$('#tr_' + info.id).parent().before(Bll.getHtml(info)).remove();
Bll.clearInput();
} else {
// alert('修改出错!');
}
}
});
}
} else {
alert(Bll.check(info));
}
});
// 修改收货地址
$('.update-address').click(function() {
let id = $(this).data('id');
let tr = $(this).parents('.table-body');
let td = tr.find('td');
Bll.setInfo(id, td);
});
// 删除收货地址
$('.del-address').click(function() {
let id = $(this).data('id');
var tr = $(this).parents('.table-body');
var a = new _confirm({
content: '您确定要删除收货地址吗?',
cb: function() {
$.ajax({
type: 'POST',
url: '/me/address/del',
dataType: 'json',
data: {
// todo uid
uid: '123456',
id: id
},
success: function() {
currentLength--;
leftLength++;
tr.remove();
Bll.setTableTile();
a.close();
}
});
}
}).show();
});
// 设置默认收货地址
$(document).on('click', '.set-default', function() {
var tr = $(this).parents('.table-body');
var tbody = tr.parent();
let id = $(this).data('id');
var self = this;
$.ajax({
type: 'POST',
url: '/me/address/default',
dataType: 'json',
data: {
// todo uid
uid: '123456',
id: id
},
success: function() {
$('.current-default').removeClass('current-default').text('设为默认');
$(self).addClass('current-default').text('默认地址');
tbody.find('.table-body').eq(0).before('<tr class=\'table-body\'>' + tr.html() + '</tr>');
tr.remove();
}
});
});
$(function() {
// 运行此demo
// 1. 安装 npm i -g json-server
// 2. json-server --watch mock/address.json
cascadingAddress({
el: '#address',
url: 'http://localhost:3000/areas/0',
resource: 'areas'
});
});
... ...
... ... @@ -4,13 +4,87 @@
* @date: 2016/07/04
*/
var tableOperation = {
$header: $('.table.column-category'),
$body: $('.table.table-body'),
removeBody: function() {
this.$body = $('.table.table-body');
this.$body.remove();
},
appendBody: function(htmlStr) {
$(htmlStr).appendTo(this.$header);
}
};
require('./me');
function getOrderList(type, page) {
tableOperation.removeBody();
$.ajax({
url: 'getOrderList',
data: {
type: type,
page: page
}
}).done(function(res) {
tableOperation.appendBody(res);
bindPaginationClick(); // eslint-disable-line
}).fail(function(err) {
console.log(err);
});
}
function getQueryString() {
var queryArr = location.search.substr(1).split('&');
var query = {};
queryArr.forEach(function(pair) {
var arr = pair.split('=');
query[arr[0]] = arr[1];
});
return query;
}
function bindPaginationClick() {
$('.blk-pagination li').off('click').on('click', function(e) {
var $this = $(this);
var page = $this.find('a').attr('href').split('=')[1];
var type = getQueryString().type;
e.preventDefault();
if (!$this.hasClass('active')) {
$('.blk-pagination li.active').removeClass('active');
$this.addClass('active');
getOrderList(type, page);
}
});
}
$('.tabs li').on('click', function() {
var $this = $(this);
var typeMap = {
all: 1,
paying: 2,
delivering: 3
};
var type = typeMap[$this.data('type')];
var page = getQueryString().page;
if (!$this.hasClass('active')) {
$('.tabs li.active').removeClass('active');
$this.addClass('active');
getOrderList(type, page);
}
});
bindPaginationClick();
... ...
... ... @@ -5,9 +5,7 @@
*/
var $ = require('yoho-jquery'),
regx = require('../common/mail-phone-regx'),
emailReg = regx.emailRegx,
phoneRegx = regx.phoneRegx;
regx = require('../common/mail-phone-regx');
var emailAc = require('../common/ac-email'); // 邮箱自动完成
... ... @@ -23,6 +21,8 @@ var $cr = $('#country-code-hide'),
hasPh = false,
hasCa = false;
var emailReg = regx.emailRegx,
phoneRegx = regx.phoneRegx;
require('yoho-jquery-placeholder');
... ...
... ... @@ -124,6 +124,10 @@ function pwdKeyupEvt() {
$pwdParent.addClass('green').removeClass('yellow red');
$pwdIntensity.addClass('color');
break;
default:
$pwdParent.removeClass('red yellow green');
$pwdIntensity.removeClass('color');
break;
}
// 提示框
... ...
... ... @@ -54,7 +54,7 @@ var jQuery = require('yoho-jquery');
$(this).each(function() {
var options = $(this).data('options');
check._uncheck(this, options);
check._unCheck(this, options);
});
},
_check: function(ele, options) {
... ... @@ -70,7 +70,7 @@ var jQuery = require('yoho-jquery');
}
}
},
_uncheck: function(ele, options) {
_unCheck: function(ele, options) {
var icon = $(ele).find('.' + options.type);
var checked = $(icon).hasClass('checked');
... ...
... ... @@ -45,8 +45,8 @@ var $ = require('yoho-jquery'),
_createOrient: function() {
var orientHtml = '<div class="slide-switch">' +
'<a class="prev" href="javascript:;"><span class="iconfont">&#xe607;</span></a>' +
'<a class="next" href="javascript:;"><span class="iconfont">&#xe606;</span></a>' +
'<a class="prev" href="javascript:;"><span class="iconfont">&#xe635;</span></a>' +
'<a class="next" href="javascript:;"><span class="iconfont">&#xe636;</span></a>' +
'</div>';
if (this.$element.find('.slide-switch').length > 0) {
... ...
var $ = require('yoho-jquery');
var common = require('../common');
var query = common.queryString();
var YohoListPage = {
rootDoc: $('.yoho-product-list'),
brandsDoc: $('.yoho-product-list .brand-list'),
mulitBrand: false,
goodsWrapper: $('.goods-area .goods-wrapper'),
goodsWrapperState: false,
page: query.page || 1,
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);
});
$('.order-area .page').click(function() {
if (!$(this).hasClass('disable')) {
if ($(this).hasClass('page-pre')) {
YohoListPage.go({
page: YohoListPage.page - 1
});
} else {
YohoListPage.go({
page: YohoListPage.page + 1
});
}
}
});
$('.order-area .order').click(function() {
var order = $(this).data('order');
var target = $(this).data('target');
var orders = order.split(',');
var newOrder = '';
if (query.order === orders[0]) {
newOrder = orders[1] || '';
} else {
newOrder = orders[0];
}
$('.order-area .order').removeClass('selected');
$(this).addClass('selected');
$('.' + target).find('.iconfont').each(function() {
if ($(this).hasClass(newOrder)) {
$(this).addClass('selected');
} else {
$(this).removeClass('selected');
}
});
YohoListPage.go({
order: newOrder
});
});
},
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();
require('./list/list-search');
... ...
var $ = require('yoho-jquery');
var common = require('../../common');
var query = common.queryString();
var YohoListPage = {
rootDoc: $('.yoho-product-list'),
brandsDoc: $('.yoho-product-list .brand-list'),
mulitBrand: false,
goodsWrapper: $('.goods-area .goods-wrapper'),
goodsWrapperState: false,
page: query.page || 1,
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);
});
$('.sex-body .input-radio', this.rootDoc).check({
type: 'radio',
onChange: function(ele, checked, value) {
YohoListPage.go({
gender: checked ? value : ''
});
}
});
$('.list-body .input-radio', this.rootDoc).check({
type: 'radio',
onChange: function(ele, checked, value) {
YohoListPage.go({
sort: checked ? value : ''
});
}
});
$('.price-body .input-radio', this.rootDoc).check({
type: 'radio',
onChange: function(ele, checked, value) {
YohoListPage.go({
price: checked ? value : ''
});
}
});
$('.size-body .input-radio', this.rootDoc).check({
type: 'radio',
onChange: function(ele, checked, value) {
YohoListPage.go({
size: checked ? value : ''
});
}
});
$('.brand-list .input-radio', this.rootDoc).check({
type: 'radio',
onChange: function(ele, checked, value) {
if (!YohoListPage.mulitBrand) {
YohoListPage.go({brand: value});
} else {
YohoListPage.showBrandMulitBtn();
}
}
});
$('.color-body .input-radio', this.rootDoc).check({
type: 'radio',
onChange: function(ele, checked, value) {
YohoListPage.go({
color: checked ? value : ''
});
}
});
YohoListPage.eventBind();
},
eventBind: function() {
$('.mulit-choose', this.rootDoc).click(function() {
YohoListPage.openBrandMulitChoose();
});
$('.brand-btns .cancel', this.rootDoc).click(function() {
YohoListPage.closeBrandMulitChoose();
});
$('.brand-btns .confirm', this.rootDoc).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);
});
$('.order-area .page').click(function() {
if (!$(this).hasClass('disable')) {
if ($(this).hasClass('page-pre')) {
YohoListPage.go({
page: YohoListPage.page - 1
});
} else {
YohoListPage.go({
page: YohoListPage.page + 1
});
}
}
});
$('.order-area .order').click(function() {
var order = $(this).data('order');
var target = $(this).data('target');
var orders = order.split(',');
var newOrder = '';
if (query.order === orders[0]) {
newOrder = orders[1] || '';
} else {
newOrder = orders[0];
}
$('.order-area .order').removeClass('selected');
$(this).addClass('selected');
$('.' + target).find('.iconfont').each(function() {
if ($(this).hasClass(newOrder)) {
$(this).addClass('selected');
} else {
$(this).removeClass('selected');
}
});
YohoListPage.go({
order: newOrder
});
});
},
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 (letter === '0-9') {
var first = $('label', this).text().toLowerCase().charAt(0); // eslint-disable-line
if ((first >= 'a' && first <= 'z') || (first >= 'A' && first <= 'Z')) {
$(this).hide();
} else {
$(this).show();
}
} else {
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();
module.exports = YohoListPage;
... ...
require('./list/list-search');
... ...
.brand-page {
padding-bottom: 80px;
.brands-tabs {
position: relative;
a {
display: block;
width: 370px;
height: 304px;
img {
width: 100%;
height: 100%;
display: block;
}
.g-mask {
width: 100%;
height: 100%;
display: block;
position: absolute;
z-index: 1;
background: #ffec07;
border: 1px solid #ffec07;
opacity: 0;
}
}
li {
float: left;
margin-left: 20px;
position: relative;
p {
display: block;
font-size: 30px;
text-align: center;
color: #ffec07;
position: absolute;
top: 50%;
width: 100%;
margin-top: -15px;
z-index: 3;
}
}
li:first-child {
margin-left: 0;
}
li:hover {
.g-mask {
opacity: 0.3;
}
}
}
.category-nav {
margin-top: 20px;
border-top: 1px solid #eee;
border-bottom: 1px solid #eee;
padding-left: 16px;
height: 44px;
line-height: 44px;
font-size: 12px;
font-weight: bold;
position: relative;
z-index: 100;
background-color: #fff;
a {
display: inline-block;
padding: 0 7px;
text-align: center;
color: #222;
cursor: pointer;
}
a:hover {
color: #379ed6;
}
}
.brands-list {
dt {
height: 70px;
line-height: 70px;
font-weight: bold;
font-size: 24px;
}
dd {
li {
float: left;
display: block;
width: 275px;
height: 250px;
margin-right: 15px;
border: 1px solid #eee;
margin-top: 20px;
}
li:nth-child(4n) {
margin-right: 0;
}
li:nth-child(-n+4) {
margin-top: 0;
}
a {
font-size: 16px;
display: block;
width: 100%;
height: 100%;
img {
width: 275px;
height: 190px;
}
span {
display: block;
height: 60px;
line-height: 60px;
text-align: center;
font-size: 16px;
}
}
}
}
}
... ...
... ... @@ -13,7 +13,5 @@
@import "product/index";
@import "channel/index";
@import "passport/index";
/* 资讯 */
@import "editorial/index";
@import "brand/brand";
... ...
.address-page {
.title {
font-size: 30px;
height: 100px;
line-height: 100px;
text-align: left;
}
.tip {
font-size: 14px;
}
.add-address-detail {
padding: 15px 0 0;
.form-group {
clear: both;
margin-bottom: 20px;
.default-address,
#address,
.btn {
margin-left: 83px;
}
.label-name {
font-size: 14px;
text-align: left;
float: left;
line-height: 26px;
}
.width-190 {
width: 190px;
margin-left: 20px;
}
.width-275 {
width: 275px;
margin-left: 20px;
}
.iconfont {
font-size: 14px;
}
.radio-lable {
font-size: 14px;
}
.error-tips {
font-size: 12px;
height: 26px;
line-height: 26px;
margin-left: 20px;
.iconfont {
font-size: 12px;
margin-right: 5px;
}
}
.opreation {
cursor: pointer;
}
}
}
}
.address-table {
.table-title {
font-size: 10px;
height: 40px;
line-height: 40px;
}
.a-table {
tr,
th,
td {
font-size: 15px;
border: 1px solid #eee;
padding: 0 5px;
text-align: left;
}
.opreation {
cursor: pointer;
}
.table-head {
background: #f5f5f5;
height: 30px;
}
.table-body td {
padding: 8px 5px;
}
.width-80 {
width: 80px;
}
.width-195 {
width: 195px;
}
.width-255 {
width: 255px;
word-break: break-all;
}
.width-120 {
width: 120px;
p:first-child {
margin-bottom: 5px;
}
}
.width-260 {
width: 260px;
}
.current-default,
.set-default {
display: inline-block;
margin-left: 20px;
}
}
}
... ...
... ... @@ -101,4 +101,5 @@
}
}
@import "address";
@import "order/index";
... ...
@import "tabs";
@import "nav";
@import "table";
... ...
.tabs {
.order-nav {
$liWidth: 120px;
$liHeight: 40px;
$liBorderColor: #e6e6e6;
$fontColor: #616161;
height: calc($liHeight + 2px);
line-height: calc($liHeight + 2px);
border-bottom: 1px solid $liBorderColor;
z-index: 0;
li {
width: $liWidth;
.tabs {
display: inline-block;
height: $liHeight;
line-height: $liHeight;
float: left;
font-size: 16px;
text-align: center;
background-color: #fff;
&.active {
li {
width: $liWidth;
height: $liHeight;
line-height: $liHeight;
float: left;
font-size: 16px;
text-align: center;
background-color: #fff;
color: $fontColor;
cursor: pointer;
&.active {
border: 1px solid $liBorderColor;
height: calc($liHeight + 1px);
line-height: calc($liHeight - 2px);
position: relative;
top: 1px;
border-bottom: none;
color: #515151;
font-weight: bold;
z-index: 3;
}
}
}
.search-bar {
$height: 30px;
$buttonWidth: 67px;
height: calc($liHeight);
float: right;
position: relative;
font-size: 12px;
.search-ctrl {
height: $height;
position: absolute;
top: 50%;
margin-top: -calc($height/2);
}
input {
width: 170px;
padding: 0 5px;
position: absolute;
right: $buttonWidth;
border: 1px solid $liBorderColor;
height: calc($liHeight + 1px);
line-height: calc($liHeight - 2px);
position: relative;
top: 1px;
border-bottom: none;
z-index: 3;
border-right: none;
color: $fontColor;
}
button {
width: $buttonWidth;
background-color: #3a3a3a;
color: #fff;
border: none;
right: 0;
cursor: pointer;
}
}
}
... ...
... ... @@ -7,14 +7,21 @@
$bigWidth: 355px;
$normalWidth: 138px;
$goodImgWidth: 65px;
$goodImgHeight: 90px;
$normalSize: 14px;
$bigSize: 16px;
$smallSpace: 8px;
$space: 20px;
$bigSpace: 30px;
margin-bottom: $space;
color: $fontColor;
.bold {
color: #222;
}
.table-header {
margin: $space 0;
... ... @@ -27,7 +34,6 @@
font-size: $normalSize;
background-color: $headerColor;
border: 1px solid $borderColor;
color: $fontColor;
li {
height: 100%;
... ... @@ -51,6 +57,7 @@
.table-body {
display: table;
font-size: $normalSize;
}
.goods-container {
... ... @@ -60,7 +67,7 @@
img {
width: $goodImgWidth;
height: 90px;
height: $goodImgHeight;
display: inline-block;
box-sizing: border-box;
margin: $bigSpace $space;
... ... @@ -114,9 +121,20 @@
.price {
width: calc($normalWidth - 4px);
display: inline-block;
margin-top: $bigSpace;
text-align: center;
vertical-align: top;
p {
width: $normalWidth;
height: calc(2 * $bigSpace + $goodImgHeight + 4px);
float: right;
padding-top: $bigSpace;
border-bottom: 1px solid $borderColor;
&.last {
border-bottom: none;
}
}
}
}
... ... @@ -130,10 +148,69 @@
display: table-cell;
text-align: center;
vertical-align: top;
padding-top: $bigSpace;
.left-time {
margin-bottom: 14px !important;
}
button {
width: 70px;
height: 25px;
border: none;
background-color: #d1021c;
color: #fff;
cursor: pointer;
margin-bottom: 14px;
}
p {
margin-top: $bigSpace;
margin-bottom: $space;
}
.subtext {
font-size: 12px;
cursor: pointer;
}
.no-space {
margin: 0;
}
}
&.empty {
width: 100%;
.bg {
height: 250px;
background-image: resolve('me/no-order.png');
background-repeat: no-repeat;
background-position: center bottom;
background-size: 100px 125px;
}
.msg {
margin-top: 50px;
text-align: center;
.msg-zh {
font-size: $bigSize;
margin-bottom: $space;
}
.msg-en {
margin-bottom: 40px;
}
.btn {
display: inline-block;
}
}
}
.blk-pagination {
margin: $bigSpace auto -$bigSpace;
text-align: center;
}
}
... ...
... ... @@ -25,7 +25,7 @@
.title {
float: left;
margin: 0px;
margin: 0;
font-size: 22px;
line-height: 40px;
color: #000;
... ... @@ -122,7 +122,7 @@
}
.no-find {
margin: 10px 0 0 0;
margin: 10px 0 0;
line-height: 20px;
color: #a5a4a4;
text-align: center;
... ...
... ... @@ -2,10 +2,9 @@
line-height: 0; /* remove line-height */
display: inline-block; /* circle wraps image */
margin: 5px;
border: 0.5px solid rgba(255,255,255,0.4);
border: 0.5px solid white;
border-radius: 50%; /* relative value */
/*box-shadow: 0px 0px 5px rgba(0,0,0,0.4);*/
transition: linear 0.25s;
height: 100px;
width: 100px;
}
\ No newline at end of file
}
... ...
@import "slider";
@import "tips";
@import "avatar";
\ No newline at end of file
@import "avatar";
... ...
@import 'list';
@import 'item';
@import 'shop-list';
/* 组件 */
@import 'brand-banner';
... ...
... ... @@ -11,18 +11,19 @@
}
}
.input-radio {
padding: 10px 0;
padding: 10px 1px;
.round-color {
width: 16px;
height: 15px;
width: 22px;
height: 21px;
vertical-align: middle;
.iconfont {
font-size: 16px;
font-size: 22px;
}
.iconfont.icon-cover {
font-size: 16px;
font-size: 22px;
}
}
}
... ... @@ -192,13 +193,16 @@
.filter-item {
display: inline-block;
margin: 12px 10px;
padding: 10px 5px;
font-size: 14px;
border: 1px solid #adacad;
background-color: #fff;
padding: 8px;
span {
font-size: 14px;
display: inline-block;
height: 21px;
line-height: 21px;
}
span.label {
... ... @@ -210,15 +214,17 @@
}
.round-color {
width: 16px;
height: 15px;
width: 22px;
height: 20px;
vertical-align: middle;
margin-left: 5px;
.iconfont {
font-size: 16px;
font-size: 22px;
}
.iconfont.icon-cover {
font-size: 16px;
font-size: 22px;
}
}
}
... ... @@ -389,14 +395,6 @@
}
}
.c-blue {
color: blue;
}
.c-red {
color: red;
}
.blk-pagination {
text-align: center;
margin: 20px 0 40px;
... ...
.yoho-product-list {
.brand-banner {
width: 100%;
height: 150px;
background-size: 100% 100%;
position: relative;
p.opts {
display: block;
position: absolute;
right: 20px;
bottom: 30px;
font-size: 14px;
a,
.brand-fav {
color: #fff;
border: 1px solid #fff;
padding: 10px;
margin-left: 10px;
.iconfont {
font-size: 14px;
}
}
}
}
.shop-menu {
border-bottom: 1px solid #eee;
margin-bottom: 30px;
li {
display: inline-block;
margin: 10px 30px;
a {
font-size: 12px;
}
.iconfont {
font-size: 14px;
}
}
}
}
... ...