Authored by yyq

Merge branch 'develop' into feature/sale

Showing 82 changed files with 1537 additions and 289 deletions
@@ -26,13 +26,19 @@ const pkg = require('./package.json'); @@ -26,13 +26,19 @@ const pkg = require('./package.json');
26 const app = express(); 26 const app = express();
27 const MemcachedStore = memcached(session); 27 const MemcachedStore = memcached(session);
28 28
  29 +// 指定libray目录
  30 +global.library = path.resolve('./library');
  31 +global.middleware = path.resolve('./doraemon/middleware');
  32 +global.utils = path.resolve('./utils');
  33 +
  34 +const seo = require(`${global.middleware}/seo`);
  35 +
  36 +
29 37
30 // 向模板注入变量 38 // 向模板注入变量
31 app.locals.devEnv = app.get('env') === 'development'; 39 app.locals.devEnv = app.get('env') === 'development';
32 app.locals.version = pkg.version; 40 app.locals.version = pkg.version;
33 41
34 -// 指定libray目录  
35 -global.library = path.resolve('./library');  
36 42
37 app.set('view engine', '.hbs'); 43 app.set('view engine', '.hbs');
38 44
@@ -68,9 +74,13 @@ app.use((req, res, next) => { @@ -68,9 +74,13 @@ app.use((req, res, next) => {
68 if (req.session && _.isNumber(req.session._LOGIN_UID)) { 74 if (req.session && _.isNumber(req.session._LOGIN_UID)) {
69 req.user.uid = req.session._LOGIN_UID; 75 req.user.uid = req.session._LOGIN_UID;
70 } 76 }
  77 +
71 next(); 78 next();
72 }); 79 });
73 80
  81 +app.use(seo());
  82 +
  83 +
74 // dispatcher 84 // dispatcher
75 require('./dispatch')(app); 85 require('./dispatch')(app);
76 86
@@ -6,7 +6,6 @@ @@ -6,7 +6,6 @@
6 6
7 'use strict'; 7 'use strict';
8 8
9 -const headerModel = require('../../../doraemon/models/header');  
10 const specialModel = require('../models/special'); 9 const specialModel = require('../models/special');
11 const _ = require('lodash'); 10 const _ = require('lodash');
12 11
@@ -14,12 +13,12 @@ exports.special = (req, res) => { @@ -14,12 +13,12 @@ exports.special = (req, res) => {
14 let id = req.params[0] || 0; 13 let id = req.params[0] || 0;
15 let channel = req.query.channel ? req.query.channel : 'boys'; 14 let channel = req.query.channel ? req.query.channel : 'boys';
16 15
17 - specialModel.getSpecialData(id).then((result) => {  
18 - let headerData = headerModel.setHeaderData(result[0].data, channel); 16 + specialModel.getSpecialData(id, channel).then((result) => {
  17 + let headerData = result[0];
19 18
20 res.render('special', _.merge({ 19 res.render('special', _.merge({
21 - module: 'index',  
22 - page: 'index' 20 + module: 'activity',
  21 + page: 'special'
23 }, headerData, result[1])); 22 }, headerData, result[1]));
24 }).catch((err) => { 23 }).catch((err) => {
25 res.send(err); 24 res.send(err);
@@ -28,6 +28,6 @@ const getstaticFile = (id) => { @@ -28,6 +28,6 @@ const getstaticFile = (id) => {
28 }); 28 });
29 }; 29 };
30 30
31 -exports.getSpecialData = (id) => {  
32 - return Promise.all([headerModel.requestHeaderData(), getstaticFile(id)]); 31 +exports.getSpecialData = (id, type) => {
  32 + return Promise.all([headerModel.requestHeaderData(type), getstaticFile(id)]);
33 }; 33 };
@@ -6,17 +6,54 @@ @@ -6,17 +6,54 @@
6 6
7 'use strict'; 7 'use strict';
8 8
  9 +const _ = require('lodash');
9 10
10 const channelModel = require('../models/index'); 11 const channelModel = require('../models/index');
11 12
12 -exports.boysIndex = (req, res) => {  
13 - channelModel.getContent('boys').then(data => {  
14 - res.render('boys', data); 13 +exports.index = (req, res) => {
  14 + let channelType = req.path.substring(1) || 'boys';
  15 +
  16 + // 将woman转换为girls,以便model层进行处理
  17 + channelType === 'woman' ? channelType = 'girls' : null;
  18 +
  19 + channelModel.getContent(channelType).then(data => {
  20 + res.render('channel', data);
15 }); 21 });
16 }; 22 };
17 23
18 exports.getbrandFloorDataAjax = (req, res) => { 24 exports.getbrandFloorDataAjax = (req, res) => {
19 - channelModel.getbrandFloorDataAjax('boys').then(data => { 25 + const channelType = req.query.channelType || 'boys';
  26 +
  27 + channelModel.getbrandFloorDataAjax(channelType).then(data => {
20 res.json(data); 28 res.json(data);
21 }); 29 });
22 }; 30 };
  31 +
  32 +exports.getNewArrival = (req, res) => {
  33 + let reqBody = req.body,
  34 + pageIndex = reqBody.pageIndex,
  35 + pageCount = reqBody.pageCount,
  36 + channel = reqBody.type,
  37 + goods = [],
  38 + result = {};
  39 +
  40 + if (pageIndex < 0) {
  41 + pageIndex = 0;
  42 + }
  43 + if (pageCount < 0 || pageCount > 50) {
  44 + pageCount = 20;
  45 + }
  46 +
  47 + channelModel.getNewArrival(channel).then(data => {
  48 + goods = _.slice(data, pageIndex, pageIndex + pageCount);
  49 +
  50 + if (goods.length !== 0) {
  51 + result = {
  52 + code: 200,
  53 + goods: goods
  54 + };
  55 + }
  56 + res.send(result);
  57 + });
  58 +};
  59 +
@@ -14,6 +14,7 @@ var app = express(); @@ -14,6 +14,7 @@ var app = express();
14 var doraemon = path.join(__dirname, '../../doraemon/views'); // parent view root 14 var doraemon = path.join(__dirname, '../../doraemon/views'); // parent view root
15 var partials = path.join(__dirname, './views'); // parent view root 15 var partials = path.join(__dirname, './views'); // parent view root
16 16
  17 +
17 app.on('mount', function(parent) { 18 app.on('mount', function(parent) {
18 delete parent.locals.settings; // 不继承父 App 的设置 19 delete parent.locals.settings; // 不继承父 App 的设置
19 Object.assign(app.locals, parent.locals); 20 Object.assign(app.locals, parent.locals);
@@ -28,6 +29,7 @@ app.engine('.hbs', hbs({ @@ -28,6 +29,7 @@ app.engine('.hbs', hbs({
28 helpers: require('../../library/helpers') 29 helpers: require('../../library/helpers')
29 })); 30 }));
30 31
  32 +
31 // router 33 // router
32 app.use(require('./router')); 34 app.use(require('./router'));
33 35
@@ -8,18 +8,43 @@ @@ -8,18 +8,43 @@
8 const _ = require('lodash'); 8 const _ = require('lodash');
9 9
10 const ServiceAPI = require(`${global.library}/api`).ServiceAPI; 10 const ServiceAPI = require(`${global.library}/api`).ServiceAPI;
  11 +const SearchAPI = require(`${global.library}/api`).SearchAPI;
11 const sign = require(`${global.library}/sign`); 12 const sign = require(`${global.library}/sign`);
12 const helpers = require(`${global.library}/helpers`); 13 const helpers = require(`${global.library}/helpers`);
  14 +const images = require(`${global.utils}/images`);
  15 +const log = require(`${global.library}/logger`);
13 16
14 17
15 const serviceApi = new ServiceAPI(); 18 const serviceApi = new ServiceAPI();
  19 +const searchApi = new SearchAPI();
16 20
17 const headerModel = require('../../../doraemon/models/header'); 21 const headerModel = require('../../../doraemon/models/header');
18 22
19 -// 创意生活  
20 -// const CODE_LIFESTYLE_CHANNEL_1 = '380c38155fd8beee10913a3f5b462da6'; 23 +const getShelveTime = duration => {
  24 + let today = new Date(),
  25 + todayMil = today.getTime().toString().substr(0, 10),
  26 + startDayMil = (today.setMonth(today.getMonth() - duration)).toString().substr(0, 10);
21 27
22 -// const CODE_LIFESTYLE_CHANNEL_2 = '665f7c2fb9d037ee820766953ee34bf7'; 28 + return `${startDayMil},${todayMil}`;
  29 +
  30 + // `
  31 +};
  32 +
  33 +// 获取可用的标题
  34 +const getText = data => {
  35 + let text = data.split(' ')[0];
  36 + const regResult = /\w+/.exec(text);
  37 +
  38 + if (data === 'GIRL KIDS' || data === 'BOY KIDS') {
  39 + return data;
  40 + }
  41 +
  42 + if (regResult) {
  43 + text = text.replace(regResult[0], '');
  44 + }
  45 +
  46 + return text;
  47 +};
23 48
24 const channelMap = { 49 const channelMap = {
25 boys: { 50 boys: {
@@ -32,12 +57,226 @@ const channelMap = { @@ -32,12 +57,226 @@ const channelMap = {
32 }, 57 },
33 kids: { 58 kids: {
34 code: 'd71f4b27f2a7229fbb31a4bc490a6f36', 59 code: 'd71f4b27f2a7229fbb31a4bc490a6f36',
35 - gender: 'kids' 60 + gender: '2,3'
36 }, 61 },
37 lifestyle: { 62 lifestyle: {
38 code: '8a341ca7eacc069ba80f02dec80eaf34', 63 code: '8a341ca7eacc069ba80f02dec80eaf34',
39 - gender: 'lifestyle' 64 +
  65 + // code: '380c38155fd8beee10913a3f5b462da6',
  66 + // code: '665f7c2fb9d037ee820766953ee34bf7',
  67 + gender: '2,3'
  68 + }
  69 +};
  70 +
  71 +const sortMap = {
  72 + boys: [
  73 + {sort: 147, viewNum: 5}, // 休闲运动鞋
  74 + {sort: 129, viewNum: 5}, // 休闲裤
  75 + {sort: 152, viewNum: 5}, // 双肩包
  76 + {misort: 11, viewNum: 5}, // T恤
  77 + {sort: 115, viewNum: 5}, // 衬衫
  78 + {sort: 130, viewNum: 5}, // 牛仔裤
  79 + {misort: 60, viewNum: 5}, // 帽子
  80 + {sort: 124, viewNum: 5}, // 夹克
  81 + {sort: 119, viewNum: 5}, // 卫衣
  82 + {sort: 162, viewNum: 5}, // 手表
  83 + {sort: 148, viewNum: 5}, // 靴子
  84 + {misort: 65, viewNum: 5}, // 首饰
  85 + {sort: 151, viewNum: 5}, // 时装鞋
  86 + {misort: 61, viewNum: 5}, // 太阳镜
  87 + {misort: 39, viewNum: 5}, // 袜子
  88 + {sort: 346, viewNum: 5}, // 运动裤
  89 + {sort: 131, viewNum: 5}, // 短裤
  90 + {misort: 66, viewNum: 5}, // 配饰
  91 + {misort: 309, viewNum: 5}, // 内裤
  92 + {misort: 30, viewNum: 5}, // 打底裤/紧身裤
  93 + {sort: 342, viewNum: 5} // 邮差包
  94 + ],
  95 + girls: [
  96 + {misort: 16, viewNum: 4}, // 卫衣
  97 + {misort: 12, viewNum: 4}, // 衬衫
  98 + {misort: 44, viewNum: 4}, // 休闲/运动鞋
  99 + {misort: 11, viewNum: 4}, // T恤
  100 + {misort: 21, viewNum: 4}, // 夹克
  101 + {misort: 257, viewNum: 4}, // 毛衣/针织
  102 + {misort: 22, viewNum: 4}, // 大衣/风衣
  103 + {misort: 26, viewNum: 4}, // 休闲裤
  104 + {misort: 27, viewNum: 4}, // 牛仔裤
  105 + {misort: 31, viewNum: 4}, // 连衣裙
  106 + {misort: 32, viewNum: 4}, // 半身裙
  107 + {misort: 48, viewNum: 4}, // 时装鞋
  108 + {misort: 49, viewNum: 4}, // 双肩包
  109 + {misort: 50, viewNum: 4}, // 手拎包/单肩包
  110 + {misort: 60, viewNum: 4}, // 帽子
  111 + {misort: 65, viewNum: 4}, // 首饰
  112 + {misort: 59, viewNum: 4}, // 手表
  113 + {misort: 61, viewNum: 4}, // 太阳镜
  114 + {misort: 66, viewNum: 4} // 配饰
  115 + ],
  116 + kids: [
  117 + {misort: 366, viewNum: 4}, // T恤
  118 + {misort: 367, viewNum: 4}, // 衬衫
  119 + {misort: 396, viewNum: 4}, // 卫衣
  120 + {misort: 400, viewNum: 4}, // // 毛衣/针织
  121 + {misort: 404, viewNum: 4}, // 夹克
  122 + {misort: 369, viewNum: 4}, // 休闲裤
  123 + {misort: 388, viewNum: 4}, // 牛仔裤
  124 + {misort: 371, viewNum: 4}, // 连衣裙
  125 + {misort: 370, viewNum: 4}, // 半身裙
  126 + {misort: 368, viewNum: 4}, // 休闲/运动鞋
  127 + {misort: 392, viewNum: 4}, // 双肩包
  128 + {misort: 414, viewNum: 4}, // 帽子
  129 + {misort: 372, viewNum: 4}, // 短裤
  130 + {misort: 384, viewNum: 4}, // 打底裤/紧身裤
  131 + {misort: 382, viewNum: 4}, // 凉鞋/拖鞋
  132 + {misort: 402, viewNum: 4}, // 马甲
  133 + {misort: 386, viewNum: 4}, // 背心
  134 + {misort: 406, viewNum: 4}, // 大衣/风衣
  135 + {misort: 430, viewNum: 4}, // 羽绒服
  136 + {misort: 423, viewNum: 4}, // 棉衣
  137 + {misort: 417, viewNum: 4} // 套装
  138 + ],
  139 + lifestyle: [
  140 + {sort: 171, viewNum: 5}, // 耳机
  141 + {sort: 398, viewNum: 5}, // 只能装备
  142 + {sort: 185, viewNum: 5}, // 相机
  143 + {misort: 259, viewNum: 5}, // 美妆
  144 + {sort: 267, viewNum: 5}, // 杯子/水壶
  145 + {sort: 313, viewNum: 5}, // 手机/ipad壳套
  146 + {sort: 211, viewNum: 5}, // 数码配件
  147 + {sort: 292, viewNum: 5}, // 玩偶
  148 + {sort: 272, viewNum: 5}, // 储物收纳
  149 + {sort: 183, viewNum: 5}, // 启用家居
  150 + {sort: 273, viewNum: 5}, // 厨具/餐具
  151 + {sort: 271, viewNum: 5} // 靠枕/靠垫/抱枕
  152 + ]
  153 +};
  154 +
  155 +const getNavs = rawNavs => {
  156 + const navs = rawNavs;
  157 + let list = [];
  158 +
  159 + _.forEach(navs, it => {
  160 + let obj = {};
  161 +
  162 + obj.name = it.name;
  163 + obj.href = it.url;
  164 +
  165 + list.push(obj);
  166 + });
  167 +
  168 + return list;
  169 +};
  170 +
  171 +// 构建url
  172 +const httpBuildQuery = data => {
  173 + return searchApi.get('/search.json', data);
  174 +};
  175 +
  176 +/**
  177 + * 格式化商品信息
  178 + *
  179 + * @param array $productData 需要格式化的商品数据
  180 + * @param bool $showTags 控制是否显示标签
  181 + * @param bool $showNew 控制是否显示NEW图标
  182 + * @param bool $showSale 控制是否显示SALE图标
  183 + * @param int $width 图片的宽度
  184 + * @param int $height 图片的高度
  185 + * @param bool $isApp 判断是不是APP访问
  186 + * @param bool $showPoint 商品价格是否显示小数位,默认显示
  187 + * @return array | false
  188 + */
  189 +const formatProduct = (productData, showTags, showNew, showSale, width, height, isApp, showPoint) => {
  190 + let result = {};
  191 +
  192 + // 默认值
  193 + if (!showTags) {
  194 + showTags = true;
  195 + }
  196 + if (!showNew) {
  197 + showNew = true;
  198 + }
  199 + if (!showSale) {
  200 + showSale = true;
  201 + }
  202 + if (!width) {
  203 + width = 290;
  204 + }
  205 + if (!height) {
  206 + height = 388;
  207 + }
  208 + if (!isApp) {
  209 + isApp = false;
  210 + }
  211 + if (!showPoint) {
  212 + showPoint = true;
  213 + }
  214 +
  215 + // 商品信息有问题,则不显示
  216 + if (!productData.product_skn || !productData.goods_list[0]) {
  217 + return false;
  218 + }
  219 +
  220 + // 市场价和售价一样,则不显示市场价
  221 + if (parseInt(productData.market_price, 0) === parseInt(productData.sales_price, 0)) {
  222 + productData.market_price = false;
  223 + }
  224 +
  225 + // 设置默认图片
  226 + _.forEach(productData.goods_list, item => {
  227 + if (item.is_default === 'Y') {
  228 + productData.default_images = item.images_url;
  229 + }
  230 + });
  231 +
  232 + if (!productData.default_images) {
  233 + productData.default_images = productData.goods_list[0].images_url;
  234 + }
  235 +
  236 + result.id = productData.product_skn;
  237 + result.product_id = productData.product_id;
  238 + result.thumb = images.getImageUrl(productData.default_images, width, height);
  239 + result.name = productData.product_name;
  240 + result.price = !productData.market_price ? false : productData.market_price;
  241 + result.salePrice = productData.sales_price;
  242 + if (showPoint) {
  243 + result.price += '.00';
  244 + result.salePrice += '.00';
  245 + }
  246 +
  247 + result.is_soon_sold_out = (productData.is_soon_sold_out === 'Y');
  248 + result.url = 'http://item.yohobuy.com/product/pro_' +
  249 + productData.product_id + '_' +
  250 + productData.goods_list[0].goods_id + '/' +
  251 + productData.cn_alphabet + '.html';
  252 +
  253 + // APP访问需要加附加的参数
  254 + // 备注:如果以后APP的接口太多,可以把这边参数提取出来,变成一个公共的方法来生成,便于以后管理维护
  255 + if (isApp) {
  256 + result.url += '?openby:yohobuy={"action":"go.productDetail","params":{"product_skn":' +
  257 + productData.product_skn + '}}';
  258 + }
  259 +
  260 + if (showTags) {
  261 + result.tags = {};
  262 + result.tags.is_new = showNew && productData.is_new && productData.is_new === 'Y'; // 新品
  263 + result.tags.is_discount = showSale && productData.is_discount && productData.is_discount === 'Y'; // 在售
  264 + result.tags.is_limited = productData.is_limited && productData.is_limited === 'Y'; // 限量
  265 + result.tags.is_yohood = productData.is_yohood && productData.is_yohood === 'Y'; // YOHOOD
  266 + result.tags.midYear = productData['mid-year'] && productData['mid-year'] === 'Y'; // 年中
  267 + result.tags.yearEnd = productData['year-end'] && productData['year-end'] === 'Y'; // 年末
  268 + result.tags.is_advance = productData.is_advance && productData.is_advance === 'Y'; // 再到着
  269 +
  270 + if (result.is_soon_sold_out && result.tags.is_discount) {
  271 + result.tags.is_new = false;// 打折与即将售完组合显示打折
  272 + } else if (result.tags.is_discount &&
  273 + (result.tags.is_new || result.tags.is_limited || result.tags.is_yohood || result.tags.is_advance)) {
  274 + result.tags.is_discount = false;// 打折与其它组合则隐藏打折
  275 + } else if (result.tags.is_yohood && result.tags.is_new) {
  276 + result.tags.is_new = false;// YOHOOD和新品组合显示YOHOOD
  277 + }
40 } 278 }
  279 + return result;
41 }; 280 };
42 281
43 const getBannerList = data => { 282 const getBannerList = data => {
@@ -56,6 +295,30 @@ const getBannerList = data => { @@ -56,6 +295,30 @@ const getBannerList = data => {
56 return list; 295 return list;
57 }; 296 };
58 297
  298 +
  299 +const getDebrisSlide = data => {
  300 + let floorData = {
  301 + debrisSlider: {
  302 + left: [],
  303 + center: [],
  304 + right: []
  305 + }
  306 + };
  307 +
  308 + _.mapKeys(data, (value, key) => {
  309 + _.forEach(value, slideData => {
  310 + let obj = {};
  311 +
  312 + obj.href = slideData.url;
  313 + obj.img = slideData.img;
  314 +
  315 + floorData.debrisSlider[key].push(obj);
  316 + });
  317 + });
  318 +
  319 + return floorData;
  320 +};
  321 +
59 const getadbannerData = data => { 322 const getadbannerData = data => {
60 const obj = { 323 const obj = {
61 adbanner: { 324 adbanner: {
@@ -80,25 +343,35 @@ const getSlideData = srcData => { @@ -80,25 +343,35 @@ const getSlideData = srcData => {
80 } 343 }
81 }; 344 };
82 345
  346 + if (srcData.big_image) {
83 slideData.slide.list = getBannerList(srcData.big_image); 347 slideData.slide.list = getBannerList(srcData.big_image);
  348 + }
  349 +
  350 + if (srcData.list) {
84 slideData.slide.pagination = getBannerList(srcData.list); 351 slideData.slide.pagination = getBannerList(srcData.list);
  352 + }
  353 +
  354 + if (_.isArray(srcData)) {
  355 + slideData.slide.list = getBannerList(srcData);
  356 + }
85 357
86 return slideData; 358 return slideData;
87 }; 359 };
88 360
89 361
90 const getNewReportFloorData = args => { 362 const getNewReportFloorData = args => {
91 - let item = args[0].data;  
92 - let secondItem = args[1].data;  
93 - let thirdItem = args[2].data;  
94 - let forthItem = args[3]; 363 + const title = args[0].data.text;
  364 + let item = args[1].data;
  365 + let secondItem = args[2].data;
  366 + let thirdItem = args[3].data;
  367 + let forthItem = args[4];
95 368
96 let list = []; 369 let list = [];
97 let obj = {}; 370 let obj = {};
98 371
99 const data = { 372 const data = {
100 newReport: { 373 newReport: {
101 - name: '最新速报', 374 + name: title,
102 list: [] 375 list: []
103 } 376 }
104 }; 377 };
@@ -139,15 +412,20 @@ const getNewReportFloorData = args => { @@ -139,15 +412,20 @@ const getNewReportFloorData = args => {
139 return floorDatas; 412 return floorDatas;
140 }; 413 };
141 414
  415 +const setChannelType = (obj, type) => {
  416 + obj[type + 'Channel'] = true;
  417 +};
  418 +
142 // 优选品牌 419 // 优选品牌
143 -const getPreBrandTopData = args => {  
144 - let item = args[0].data; 420 +const getPreBrandTopData = (args, type) => {
  421 + const title = args[0].data.text;
  422 + let item = args[1].data;
145 423
146 const data = { 424 const data = {
147 preferenceBrands: { 425 preferenceBrands: {
148 - name: '优选品牌', 426 + name: title,
149 imgBrand: [], 427 imgBrand: [],
150 - brandUrl: helpers.urlFormat('getbrandFloorDataAjax') 428 + brandUrl: helpers.urlFormat('getbrandFloorDataAjax?channelType=' + type)
151 } 429 }
152 }; 430 };
153 431
@@ -160,11 +438,13 @@ const getPreBrandTopData = args => { @@ -160,11 +438,13 @@ const getPreBrandTopData = args => {
160 data.preferenceBrands.imgBrand.push(o); 438 data.preferenceBrands.imgBrand.push(o);
161 }); 439 });
162 440
  441 + setChannelType(data.preferenceBrands, type);
  442 +
163 return data; 443 return data;
164 }; 444 };
165 445
166 // 热门品类 446 // 热门品类
167 -const getHotGoodsFloorData = (args) => { 447 +const getHotGoodsFloorData = (args, type) => {
168 let item = args[0]; 448 let item = args[0];
169 let nextItem = args[1]; 449 let nextItem = args[1];
170 450
@@ -175,7 +455,6 @@ const getHotGoodsFloorData = (args) => { @@ -175,7 +455,6 @@ const getHotGoodsFloorData = (args) => {
175 category = [], 455 category = [],
176 brands = [], 456 brands = [],
177 types = [], 457 types = [],
178 - navs = {},  
179 products = []; 458 products = [];
180 459
181 const data = { 460 const data = {
@@ -184,16 +463,16 @@ const getHotGoodsFloorData = (args) => { @@ -184,16 +463,16 @@ const getHotGoodsFloorData = (args) => {
184 } 463 }
185 }; 464 };
186 465
187 -  
188 - _.forEach(item.data.menuNav.list, (it) => { 466 + _.forEach(item.data.menuNav.list, it => {
189 let obj = {}; 467 let obj = {};
190 468
  469 +
191 obj.name = it.name; 470 obj.name = it.name;
192 obj.href = it.url; 471 obj.href = it.url;
193 category.push(obj); 472 category.push(obj);
194 }); 473 });
195 474
196 - _.forEach(item.data.menuNav.blocks, (it) => { 475 + _.forEach(item.data.menuNav.blocks, it => {
197 let obj = {}; 476 let obj = {};
198 477
199 obj.name = it.title; 478 obj.name = it.title;
@@ -209,7 +488,7 @@ const getHotGoodsFloorData = (args) => { @@ -209,7 +488,7 @@ const getHotGoodsFloorData = (args) => {
209 obj.href = it.url; 488 obj.href = it.url;
210 obj.img = it.img; 489 obj.img = it.img;
211 490
212 - if (idx === 0 || idx === 4) { 491 + if (idx === 0 || (idx === 4 && type === 'boys')) {
213 brands.push(obj); 492 brands.push(obj);
214 } else { 493 } else {
215 types.push(obj); 494 types.push(obj);
@@ -226,28 +505,29 @@ const getHotGoodsFloorData = (args) => { @@ -226,28 +505,29 @@ const getHotGoodsFloorData = (args) => {
226 products.push(obj); 505 products.push(obj);
227 }); 506 });
228 507
229 - navs.name = item.data.navs.list[0].name;  
230 - navs.href = item.data.navs.list[0].url;  
231 object.name = item.data.name; 508 object.name = item.data.name;
232 object.keyword = keyword; 509 object.keyword = keyword;
233 object.category = category; 510 object.category = category;
234 object.brands = brands; 511 object.brands = brands;
235 object.types = types; 512 object.types = types;
236 - object.navs = navs; 513 + object.navs = getNavs(item.data.navs.list);
237 object.products = products; 514 object.products = products;
238 list.push(object); 515 list.push(object);
239 516
240 data.recommend.tplrecommend = list; 517 data.recommend.tplrecommend = list;
241 518
  519 + setChannelType(data.recommend, type);
  520 +
  521 +
242 return data; 522 return data;
243 }; 523 };
244 524
245 -// 人气单品  
246 -const getSingleHotFloorData = args => { 525 +
  526 +const getBoysSingleHot = (args, type) => {
247 const len = 10; 527 const len = 10;
248 const data = { 528 const data = {
249 singlehot: { 529 singlehot: {
250 - name: '人气单品', 530 + name: args[0].data.text,
251 imgHot: [] 531 imgHot: []
252 } 532 }
253 }; 533 };
@@ -262,14 +542,14 @@ const getSingleHotFloorData = args => { @@ -262,14 +542,14 @@ const getSingleHotFloorData = args => {
262 let obj = {}; 542 let obj = {};
263 543
264 if (i === 1) { 544 if (i === 1) {
265 - val = args[0].data[0]; // 第二个是大图 545 + val = args[1].data[0]; // 第二个是大图
266 } else if (i === len - 1) { 546 } else if (i === len - 1) {
267 - val = args[0].data[1]; // 最后一个是大图 547 + val = args[1].data[1]; // 最后一个是大图
268 } else { 548 } else {
269 if (pos > 1) { // 小图 549 if (pos > 1) { // 小图
270 pos = pos - 1; 550 pos = pos - 1;
271 } 551 }
272 - val = args[1].data[pos]; 552 + val = args[2].data[pos];
273 } 553 }
274 obj.href = val.url; 554 obj.href = val.url;
275 obj.img = val.src; 555 obj.img = val.src;
@@ -277,17 +557,230 @@ const getSingleHotFloorData = args => { @@ -277,17 +557,230 @@ const getSingleHotFloorData = args => {
277 } 557 }
278 558
279 data.singlehot.imgHot = list; 559 data.singlehot.imgHot = list;
  560 + setChannelType(data.singlehot, type);
280 floorDatas.push(data); 561 floorDatas.push(data);
281 562
282 - if (args[2].template_name === 'single_image') {  
283 - adData = getadbannerData(args[2].data[0]); 563 + if (args[3].template_name === 'single_image') {
  564 + adData = getadbannerData(args[3].data[0]);
284 floorDatas.push(adData); 565 floorDatas.push(adData);
285 } 566 }
286 567
287 return floorDatas; 568 return floorDatas;
288 }; 569 };
289 570
  571 +const getGirlsSingleHot = args => {
  572 + let goods = args[2].data;
  573 + let skns = '';
  574 +
  575 +
  576 + _.forEach(goods, good => {
  577 + skns += good.id + ' ';
  578 + });
  579 +
  580 + return searchApi.get('/search.json', {
  581 + client_type: 'web',
  582 + query: skns,
  583 + order: 'shelve_time:desc',
  584 + status: 1,
  585 + sales: 'Y',
  586 + attribute_not: '2',
  587 + stocknumber: 1,
  588 + page: 1,
  589 + viewNum: 60
  590 + });
  591 +};
  592 +
  593 +
  594 +// 人气单品
  595 +const getSingleHotFloorData = (args, type) => {
  596 + if (type === 'boys') {
  597 + return getBoysSingleHot(args, type);
  598 + } else {
  599 + return getGirlsSingleHot(args, type);
  600 + }
  601 +};
  602 +
  603 +const getAsyncSingleHot = (args, queryResult, type) => {
  604 + const data = {
  605 + singlehot: {
  606 + name: args[0].data.text,
  607 + navs: [],
  608 + imgHot: [],
  609 + brands: []
  610 + }
  611 + };
  612 +
  613 + if (args[3].template_name === 'app_icon_list') {
  614 + _.forEach(args[3].data, it => {
  615 + let obj = {};
  616 +
  617 + obj.href = it.url;
  618 + obj.name = it.title;
  619 + obj.img = it.src;
  620 +
  621 + data.singlehot.brands.push(obj);
  622 + });
  623 + }
  624 +
  625 + _.forEach(queryResult.data.product_list, (it, index) => {
  626 + let obj = {};
  627 + const formatData = formatProduct(it, true, true, true, 280, 373);
  628 +
  629 + if (index > 12) {
  630 + return;
  631 + }
  632 +
  633 +
  634 + obj.price = formatData.salePrice;
  635 + obj.href = formatData.url;
  636 + obj.img = formatData.thumb;
  637 + obj.name = formatData.name;
  638 +
  639 + if (index < 3) {
  640 + obj.tip = 'TOP' + (index + 1);
  641 + }
  642 +
  643 + data.singlehot.imgHot.push(obj);
  644 + });
  645 +
  646 + data.singlehot.navs = getNavs(args[1].data);
  647 + setChannelType(data.singlehot, type);
  648 + return data;
  649 +};
  650 +
  651 +const processFloorDataWithQueryReusult = (rawData, floorData, queryResult, title, type) => {
  652 + let data = {};
  653 +
  654 + _.forEach(rawData, (subData, index) => {
  655 + const text = subData.data.text && getText(subData.data.text);
  656 +
  657 + if (text === title) {
  658 + data = getAsyncSingleHot(rawData.slice(index, index + 4), queryResult, type);
  659 + }
  660 + });
  661 +
  662 + return data;
  663 +};
  664 +
  665 +/**
  666 + * 组装最新上架楼层数据
  667 + *
  668 + * @param string data
  669 + * return obj
  670 + */
  671 +const getNewGoodsFloorData = args => {
  672 + const data = {
  673 + newArrivls: {
  674 + name: args[0].data.text,
  675 + navs: []
  676 + }
  677 + };
  678 +
  679 + data.newArrivls.navs = getNavs(args[1].data);
  680 +
  681 + return data;
  682 +};
  683 +
  684 +
  685 +
  686 +
  687 +/**
  688 + * 获取最新上架商品数据
  689 + *
  690 + * @param string $channel
  691 + * @return array
  692 + */
  693 +exports.getNewArrival = channel => {
  694 + let rel = [],
  695 + sortList = sortMap[channel],
  696 + params = {
  697 + order: 'shelve_time:desc',
  698 + status: 1,
  699 + sales: 'Y',
  700 + attribute_not: 2,
  701 + stocknumber: 3,
  702 + shelve_time: getShelveTime(20)
  703 + };
  704 +
  705 + params.gender = channelMap[channel].gender;
  706 +
  707 +
  708 + _.forEach(sortList, (item) => {
  709 + let data = Object.assign(item, params);
  710 +
  711 + rel.push(httpBuildQuery(data));
  712 + });
  713 +
  714 + return Promise.all(rel).then(res => {
  715 + let data = [],
  716 + result = [];
  717 +
  718 + _.forEach(sortList, (it, index) => {
  719 + if (res[index].data.product_list.length === sortList[index].viewNum) {
  720 + data = data.concat(res[index].data.product_list);
  721 + }
  722 + });
  723 +
  724 + _.forEach(data, (item) => {
  725 + result.push(formatProduct(item, true, true, true, 280, 373));
  726 + });
  727 +
  728 + return result;
  729 + });
  730 +};
  731 +
  732 +
  733 +const getCategoryFloorData = args => {
  734 + const data = {
  735 + category: {
  736 + name: args[0].data.text,
  737 + navs: getNavs(args[1].data),
  738 + list: []
  739 + }
  740 + };
  741 +
  742 + _.forEach(args[2].data, (it, index) => {
  743 + let obj = {};
  744 +
  745 + obj.href = it.url;
  746 + obj.img = it.src;
  747 +
  748 + // 设置图片大小
  749 + if (index === 1) {
  750 + obj.w = '377;';
  751 + obj.h = '504;';
  752 + } else {
  753 + obj.w = '185';
  754 + obj.h = '510';
  755 + }
  756 +
  757 + data.category.list.push(obj);
  758 + });
  759 +
  760 + return data;
  761 +};
  762 +
  763 +const getAccordionFloorData = args => {
  764 + let data = {
  765 + accordion: {
  766 + name: args[0].data.text,
  767 + navs: getNavs(args[1].data),
  768 + slide: []
  769 + }
  770 + };
290 771
  772 + _.forEach(args[2].data, it => {
  773 + let obj = {};
  774 +
  775 + obj.name = it.title;
  776 + obj.img = it.src;
  777 + obj.href = it.url;
  778 +
  779 + data.accordion.slide.push(obj);
  780 + });
  781 +
  782 + return data;
  783 +};
291 784
292 const requestContent = type => { 785 const requestContent = type => {
293 786
@@ -301,7 +794,14 @@ const requestContent = type => { @@ -301,7 +794,14 @@ const requestContent = type => {
301 limit: 1000 794 limit: 1000
302 }); 795 });
303 796
304 - return serviceApi.get('/operations/api/v5/resource/home', data); 797 + return serviceApi.get('/operations/api/v5/resource/home', data).then(res => {
  798 + if (res.code === 200) {
  799 + return res;
  800 + } else {
  801 + log.error('获取资源位接口返回状态码 不是 200');
  802 + return {};
  803 + }
  804 + });
305 }; 805 };
306 806
307 const floorMap = { 807 const floorMap = {
@@ -309,56 +809,138 @@ const floorMap = { @@ -309,56 +809,138 @@ const floorMap = {
309 hot: getHotGoodsFloorData, 809 hot: getHotGoodsFloorData,
310 最新速报: getNewReportFloorData, 810 最新速报: getNewReportFloorData,
311 人气单品: getSingleHotFloorData, 811 人气单品: getSingleHotFloorData,
  812 + 'GIRL KIDS': getSingleHotFloorData,
  813 + 'BOY KIDS': getSingleHotFloorData,
312 优选品牌: getPreBrandTopData, 814 优选品牌: getPreBrandTopData,
313 - ad: getadbannerData 815 + 最新上架: getNewGoodsFloorData,
  816 + ad: getadbannerData,
  817 + category: getCategoryFloorData,
  818 + accordion: getAccordionFloorData,
  819 + debrisSlide: getDebrisSlide
314 }; 820 };
315 821
316 -const processFloorData = rawData => { 822 +
  823 +
  824 +const processFloorData = (rawData, type) => {
317 let floorList = []; 825 let floorList = [];
  826 + let searchPromise = [];
  827 + let singlehotFloorIndex = [];
  828 + let singlehotFloorTitile = [];
  829 +
  830 + const bigFloorLength = 5;
  831 + const normalFloorLength = 3;
  832 + const hotCategoryLength = 2;
  833 +
318 834
319 _.forEach(rawData, (data, index) => { 835 _.forEach(rawData, (data, index) => {
320 let floorData = null; 836 let floorData = null;
321 837
322 - if (data.template_name === 'recommend_content_three') { 838 + if (data.template_name === 'recommend_content_three' ||
  839 + (data.template_intro === '焦点图' && index === 0)) { // 处理banner
323 floorData = floorMap.slide.call(null, data.data); 840 floorData = floorMap.slide.call(null, data.data);
324 - } else if (data.template_intro === '热门品类') {  
325 - floorData = floorMap.hot.call(null, rawData.slice(index, index + 2));  
326 - } else if (data.data.text) {  
327 - floorData = floorMap[data.data.text] &&  
328 - floorMap[data.data.text].call(null, rawData.slice(index + 1, index + 5)); 841 + } else if (data.template_intro === '热门品类') { // 处理热门品类
  842 + floorData = floorMap.hot.call(null, rawData.slice(index, index + hotCategoryLength), type);
  843 + } else if (data.data.text) { // 处理一般楼层
  844 + let text = getText(data.data.text);
  845 + let lastIndex = index + bigFloorLength < rawData.length ?
  846 + index + bigFloorLength : index + (rawData.length - index - 1);
  847 +
  848 +
  849 + floorData = floorMap[text] &&
  850 + floorMap[text].call(null, rawData.slice(index, lastIndex), type);
  851 +
  852 + } else if (data.template_name === 'debrisSlider') { // 处理girls的banner
  853 + floorData = floorMap.debrisSlide.call(null, data.data);
  854 + }
  855 +
  856 + // 处理lifestyle分类楼层
  857 + if (!floorData && index + normalFloorLength < rawData.length &&
  858 + rawData[index + 1].template_name === 'textNav' &&
  859 + rawData[index + 2].template_name === 'floor') {
  860 + floorData = floorMap.category.call(null, rawData.slice(index, index + normalFloorLength));
329 } 861 }
330 862
331 - if (!_.isNil(floorData)) { 863 + // 处理手风琴楼层
  864 + if (!floorData && index + normalFloorLength < rawData.length &&
  865 + rawData[index + 1].template_name === 'textNav' &&
  866 + rawData[index + 2].template_name === 'focus') {
  867 + floorData = floorMap.accordion.call(null, rawData.slice(index, index + normalFloorLength));
  868 + }
  869 +
  870 +
  871 + // 处理promise
  872 + if (floorData && floorData.then && typeof floorData.then === 'function') {
  873 + searchPromise.push(floorData);
  874 +
  875 + // 记住楼层位置, 以便后面promise获取数据后插入楼层数据
  876 + singlehotFloorIndex.push(floorList.length);
  877 +
  878 + // 记住楼层标题, 以便后面promise获取数据后插入楼层数据
  879 + singlehotFloorTitile.push(getText(data.data.text));
  880 + } else if (!_.isNil(floorData)) {
332 _.isArray(floorData) ? 881 _.isArray(floorData) ?
333 floorList = floorList.concat(floorData) : 882 floorList = floorList.concat(floorData) :
334 floorList.push(floorData); 883 floorList.push(floorData);
335 } 884 }
336 }); 885 });
337 886
338 - return floorList; 887 + return {
  888 + floors: floorList,
  889 + promise: _.reverse(searchPromise),
  890 + singlehotFloorTitile: _.reverse(singlehotFloorTitile),
  891 + singlehotFloorIndex: _.reverse(singlehotFloorIndex)
  892 + };
339 }; 893 };
340 894
  895 +
341 /** 896 /**
342 * 获取频道页数据 897 * 获取频道页数据
343 * @param {string} type 传入频道页类型,值可以是: boys, girls, kids, lifestyle 898 * @param {string} type 传入频道页类型,值可以是: boys, girls, kids, lifestyle
344 * @return {object} 899 * @return {object}
345 */ 900 */
346 exports.getContent = type => { 901 exports.getContent = type => {
347 - return Promise.all([headerModel.requestHeaderData(), requestContent(type)]).then(res => { 902 + return Promise.all([headerModel.requestHeaderData(type), requestContent(type)]).then(res => {
348 903
349 - if (res[0].code === 200 && res[1].code === 200) {  
350 - let headerData = res[0].data,  
351 - contentData = res[1].data.list; 904 + let headerData = res[0].data || res[0],
  905 + contentData = res[1].data ? res[1].data.list : res[1];
352 906
353 let data = {}; 907 let data = {};
354 908
355 - data = headerModel.setHeaderData(headerData, type); 909 + const processResult = processFloorData(contentData, type);
  910 +
  911 + data = headerData;
356 data.module = 'channel'; 912 data.module = 'channel';
357 - data.page = type; 913 + data.page = 'channel';
  914 + data.pageType = type;
358 data.footerTop = true; 915 data.footerTop = true;
359 - data.channel = processFloorData(contentData); 916 + data.channel = processResult.floors;
360 917
361 - return data; 918 +
  919 + return {
  920 + rawData: contentData,
  921 + floorData: data,
  922 + searchPromise: processResult.promise,
  923 + singlehotFloorIndex: processResult.singlehotFloorIndex,
  924 + singlehotFloorTitile: processResult.singlehotFloorTitile,
  925 + channelType: type
  926 + };
  927 +
  928 + }).then(result => {
  929 +
  930 + // 如果有promise则做相应处理
  931 + if (result.searchPromise.length) {
  932 + return Promise.all(result.searchPromise).then(res => {
  933 + _.forEach(res, (data, index) => {
  934 + result.floorData.channel
  935 + .splice(result.singlehotFloorIndex[index], 0,
  936 + processFloorDataWithQueryReusult(result.rawData,
  937 + result.floorData, data, result.singlehotFloorTitile[index], result.channelType));
  938 + });
  939 +
  940 + return result.floorData;
  941 + });
  942 + } else {
  943 + return result.floorData || result;
362 } 944 }
363 }); 945 });
364 }; 946 };
@@ -367,15 +949,16 @@ exports.getContent = type => { @@ -367,15 +949,16 @@ exports.getContent = type => {
367 // 优选品牌楼层floorData-ajax 949 // 优选品牌楼层floorData-ajax
368 exports.getbrandFloorDataAjax = type => { 950 exports.getbrandFloorDataAjax = type => {
369 return requestContent(type).then(res => { 951 return requestContent(type).then(res => {
370 - if (res.code === 200) {  
371 - let contentData = res.data.list; 952 + let contentData = res.data ? res.data.list : [];
372 953
373 let data = { 954 let data = {
374 logoBrand: [], 955 logoBrand: [],
375 moreBrand: '' 956 moreBrand: ''
376 }; 957 };
377 958
378 - _.forEach(contentData[6].data, (floorData) => { 959 + _.forEach(contentData, (d, index) => {
  960 + if (d.data.text && d.data.text.indexOf('优选品牌') >= 0) {
  961 + _.forEach(contentData[index + 2].data, (floorData) => {
379 let o = {}; 962 let o = {};
380 963
381 o.href = floorData.url; 964 o.href = floorData.url;
@@ -384,9 +967,10 @@ exports.getbrandFloorDataAjax = type => { @@ -384,9 +967,10 @@ exports.getbrandFloorDataAjax = type => {
384 data.logoBrand.push(o); 967 data.logoBrand.push(o);
385 }); 968 });
386 969
387 - data.moreBrand = contentData[7].data[0].url; 970 + data.moreBrand = contentData[index + 3].data[0].url;
  971 + }
  972 + });
388 973
389 return data; 974 return data;
390 - }  
391 }); 975 });
392 }; 976 };
@@ -12,8 +12,14 @@ const cRoot = './controllers'; @@ -12,8 +12,14 @@ const cRoot = './controllers';
12 // Your controller here 12 // Your controller here
13 const channelController = require(`${cRoot}/index`); 13 const channelController = require(`${cRoot}/index`);
14 14
15 -router.get('/boys', channelController.boysIndex); 15 +// 频道页路由
  16 +router.get('/', channelController.index);
  17 +router.get('/woman', channelController.index);
  18 +router.get('/kids', channelController.index);
  19 +router.get('/lifestyle', channelController.index);
16 20
  21 +// ajax
17 router.get('/getbrandFloorDataAjax', channelController.getbrandFloorDataAjax); 22 router.get('/getbrandFloorDataAjax', channelController.getbrandFloorDataAjax);
  23 +router.post('/common/getNewArrival', channelController.getNewArrival);
18 24
19 module.exports = router; 25 module.exports = router;
1 -<div class="home-page yoho-page boys" data-page="boys">  
2 -{{# channel}}  
3 - {{! 头部banner}}  
4 - {{# slide}}  
5 - {{> banner}}  
6 - {{/ slide}}  
7 -  
8 - {{! 新品速报}}  
9 - {{# newReport}}  
10 - <div class="new-report imgopacity clearfix">  
11 - {{> floor-header}}  
12 -  
13 - <ul class="report-list clearfix">  
14 - {{# list}}  
15 -  
16 - {{#unless @last}}  
17 - <li>  
18 - <a href="{{href}}" target= "_blank">  
19 - {{#if @first}}  
20 - <img class="lazy" data-original="{{image img 377 504}}" alt="" >  
21 - {{^}}  
22 - <img class="lazy" data-original="{{image img 185 248}}" alt="" >  
23 - {{/if}}  
24 - </a>  
25 - </li>  
26 - {{/unless}}  
27 - {{/ list}}  
28 - </ul>  
29 -  
30 - {{# list}}  
31 - {{#if @last}}  
32 - <div class="last-item">  
33 - <a href="{{href}}" target= "_blank">  
34 - <img class="lazy" data-original="{{image img 377 504}}" alt="">  
35 - </a>  
36 - </div>  
37 - {{/if}}  
38 - {{/ list}}  
39 - </div>  
40 - {{/ newReport}}  
41 -  
42 - {{! 优选品牌}}  
43 - {{# preferenceBrands}}  
44 - <div class="preference-brand">  
45 - {{> floor-header}}  
46 - <div class="img-brand">  
47 - <ul class="img-list imgopacity clearfix">  
48 - {{# imgBrand}}  
49 - <li class="img-item">  
50 - <a href="{{href}}" target= "_blank">  
51 - <img src="{{img}}" alt="">  
52 - </a>  
53 - </li>  
54 - {{/ imgBrand}}  
55 - </ul>  
56 - <div class="img-brand-switch">  
57 - <a class="prev" href="javascript:;">  
58 - <span class="iconfont">&#xe60c;</span>  
59 - </a>  
60 - <a class="next" href="javascript:;">  
61 - <span class="iconfont">&#xe60b;</span>  
62 - </a>  
63 - </div>  
64 - </div>  
65 - <div class="logo-brand imgopacity" data-url="{{brandUrl}}"></div>  
66 - </div>  
67 - {{/ preferenceBrands}}  
68 -  
69 - {{! 单品/广告}}  
70 - {{# singlehot}}  
71 - {{> boy-singlehot}}  
72 - {{/ singlehot}}  
73 -  
74 - {{! 广告}}  
75 - {{# adbanner}}  
76 - <div class="floor-ad">  
77 - <a href="{{href}}" target= "_blank"><img class="lazy" data-original="{{image img 1150 129}}"/></a>  
78 - </div>  
79 - {{/ adbanner}}  
80 -  
81 - {{! 品类推荐}}  
82 - {{# recommend}}  
83 - {{> boy-recommend}}  
84 - {{/ recommend}}  
85 -  
86 -  
87 - {{! 新品上架}}  
88 - {{# newArrivls}}  
89 - {{> commodity}}  
90 - {{/ newArrivls}}  
91 -{{/ channel}}  
92 -</div>  
  1 +<div class="home-page yoho-page {{pageType}}" data-page="{{pageType}}">
  2 +{{# channel}}
  3 + {{! 头部banner}}
  4 + {{# slide}}
  5 + {{> banner}}
  6 + {{/ slide}}
  7 + {{! 左中右格式的头部banner}}
  8 + {{# debrisSlider}}
  9 + {{> big-slider}}
  10 + {{/ debrisSlider}}
  11 + {{! 新品速报}}
  12 + {{# newReport}}
  13 + {{> newreport-floor}}
  14 + {{/ newReport}}
  15 + {{! 优选品牌}}
  16 + {{# preferenceBrands}}
  17 + {{> floor-header}}
  18 + {{#if boysChannel}}
  19 + {{>boy-brands}}
  20 + {{/if}}
  21 + {{#if girlsChannel}}
  22 + {{>girl-brands}}
  23 + {{/if}}
  24 + {{#if kidsChannel}}
  25 + {{>girl-brands}}
  26 + {{/if}}
  27 + {{#if lifestyleChannel}}
  28 + {{>girl-brands}}
  29 + {{/if}}
  30 + {{/ preferenceBrands}}
  31 + {{! 人气单品}}
  32 + {{# singlehot}}
  33 + {{#if boysChannel}}
  34 + {{> boy-singlehot}}
  35 + {{/if}}
  36 + {{#if girlsChannel}}
  37 + {{> girl-singlehot}}
  38 + {{/if}}
  39 + {{#if kidsChannel}}
  40 + {{> girl-singlehot}}
  41 + {{/if}}
  42 + {{#if lifestyleChannel}}
  43 + {{> girl-singlehot}}
  44 + {{/if}}
  45 + {{/ singlehot}}
  46 + {{! 广告}}
  47 + {{# adbanner}}
  48 + {{> ad-floor}}
  49 + {{/ adbanner}}
  50 + {{! 品类推荐}}
  51 + {{# recommend}}
  52 + {{#if boysChannel}}
  53 + {{> boy-recommend}}
  54 + {{/if}}
  55 + {{#if girlsChannel}}
  56 + {{> girl-recommend}}
  57 + {{/if}}
  58 + {{#if kidsChannel}}
  59 + {{> girl-recommend}}
  60 + {{/if}}
  61 + {{#if lifestyleChannel}}
  62 + {{> girl-recommend}}
  63 + {{/if}}
  64 + {{/ recommend}}
  65 + {{! 手风琴}}
  66 + {{#accordion}}
  67 + {{> slide-accordion}}
  68 + {{/accordion}}
  69 + {{! 热门分类}}
  70 + {{# category}}
  71 + {{> category-floor}}
  72 + {{/ category}}
  73 + {{! 新品上架}}
  74 + {{# newArrivls}}
  75 + {{> commodity}}
  76 + {{/ newArrivls}}
  77 +{{/ channel}}
  78 +</div>
  1 +<div class="floor-ad">
  2 + <a href="{{href}}" target= "_blank"><img class="lazy" data-original="{{image img 1150 129}}"/></a>
  3 +</div>
  1 +<div class="debris-slider clearfix">
  2 + <div class="left-col col">
  3 + {{# left}}
  4 + <a href="{{href}}" target="_blank">
  5 + <img class="lazy" data-original="{{image img 200 265}}">
  6 + </a>
  7 + {{/ left}}
  8 + </div>
  9 + <div class="center-col col">
  10 + <ul class="slide-wrapper">
  11 + {{# center}}
  12 + <li>
  13 + <a href="{{href}}" target="_blank">
  14 + <img class="lazy" data-original="{{image img 570 633}}">
  15 + </a>
  16 + </li>
  17 + {{/ center}}
  18 + </ul>
  19 + <div class="slide-switch">
  20 + <a class="prev" href="javascript:;">
  21 + <span class="iconfont">&#xe60c;</span>
  22 + </a>
  23 + <a class="next" href="javascript:;">
  24 + <span class="iconfont">&#xe60b;</span>
  25 + </a>
  26 + </div>
  27 + </div>
  28 + <div class="right-col col">
  29 + {{# right}}
  30 + <a href="{{href}}" target="_blank">
  31 + <img class="lazy" data-original="{{image img 200 265}}">
  32 + </a>
  33 + {{/ right}}
  34 + </div>
  35 +</div>
  1 +<div class="preference-brand">
  2 + <div class="img-brand">
  3 + <ul class="img-list imgopacity clearfix">
  4 + {{# imgBrand}}
  5 + <li class="img-item">
  6 + <a href="{{href}}" target= "_blank">
  7 + <img src="{{image img 378 175}}" alt="">
  8 + </a>
  9 + </li>
  10 + {{/ imgBrand}}
  11 + </ul>
  12 + <div class="img-brand-switch">
  13 + <a class="prev" href="javascript:;">
  14 + <span class="iconfont">&#xe60c;</span>
  15 + </a>
  16 + <a class="next" href="javascript:;">
  17 + <span class="iconfont">&#xe60b;</span>
  18 + </a>
  19 + </div>
  20 + </div>
  21 + <div class="logo-brand imgopacity" data-url="{{brandUrl}}"></div>
  22 +</div>
  1 +{{> floor-header}}
  2 +<div class="categorys-list imgopacity">
  3 + <ul class="clearfix">
  4 + {{# list}}
  5 + <li class="cate-item{{@index}}">
  6 + <a href="{{href}}" target= "_blank">
  7 + <img class="lazy" data-original="{{image img w h}}" alt="">
  8 + </a>
  9 + </li>
  10 + {{/ list}}
  11 + </ul>
  12 +</div>
  1 +<div class="preference-brand imgopacity">
  2 + <div class="img-slider-wrapper clearfix" style="background-color:{{sliderColor}};">
  3 + <div class="img-brand-switch">
  4 + <a class="prev iconfont" href="javascript:;">&#xe60f;</a>
  5 + <a class="next iconfont" href="javascript:;">&#xe60e;</a>
  6 + </div>
  7 + <div class="img-container-landscape">
  8 + <ul class="img-list">
  9 + {{# imgBrand}}
  10 + <li class="img-item">
  11 + <a href="{{href}}" target= "_blank"> <img src="{{image img 320 430}}" alt="{{alt}}"></a>
  12 + </li>
  13 + {{/ imgBrand}}
  14 + </ul>
  15 + </div>
  16 + </div>
  17 + <div class="logo-brand " data-url="{{brandUrl}}">
  18 + </div>
  19 +</div>
  1 +{{# tplrecommend}}
  2 +<div class="tpl-recommend clearfix">
  3 + {{> floor-header}}
  4 + <div class="tpl-body clearfix">
  5 + <div class="tpl-nav">
  6 + <div class="tpl-keywords">
  7 + {{#each keyword}}
  8 + <a class="keywords{{@index}}" title="{{name}}" href="{{href}}" target= "_blank"><img class="lazy" data-original="{{image img 185 76}}"/></a>
  9 + {{/each}}
  10 + </div>
  11 + <div class="tpl-category clearfix">
  12 + {{#each category}}
  13 + <a href="{{href}}" target= "_blank">{{name}}</a>
  14 + {{/each}}
  15 + </div>
  16 + </div>
  17 + <div class="tpl-brands imgopacity clearfix">
  18 + {{#each brands}}
  19 + <a title="{{name}}" href="{{href}}" target= "_blank"><img class="lazy" data-original="{{image img 377 504}}"/></a>
  20 + {{/each}}
  21 + </div>
  22 + <div class="tpl-types imgopacity clearfix">
  23 + <ul>
  24 + {{#each types}}
  25 + <li><a title="{{name}}" href="{{href}}" target= "_blank"><img class="lazy" data-original="{{image img 185 504}}"/></a></li>
  26 + {{/each}}
  27 + </ul>
  28 + </div>
  29 + </div>
  30 +</div>
  31 +{{/ tplrecommend}}
  1 +<div class="commodity clearfix">
  2 + {{> floor-header}}
  3 + <div class="commodity-list">
  4 + <ul class="g-list imgopacity clearfix">
  5 + {{#each imgHot}}
  6 + <li>
  7 + <a href="{{href}}" target= "_blank"><div class="commodity-img">
  8 + {{# tip}}
  9 + <i class="top">{{.}}</i>
  10 + {{/ tip}}
  11 + <img class="lazy" data-original="{{image img 280 373}}"/></div>
  12 + <p class="commodity-name">{{name}}</p>
  13 + <p class="commodity-price"><span>¥{{price}}</span></p>
  14 + </a>
  15 + </li>
  16 + {{/each}}
  17 + </ul>
  18 + </div>
  19 + <div class="commodity-brands imgopacity clearfix">
  20 + {{#each brands}}
  21 + <a href="{{href}}" title="{{name}}" target= "_blank"><img class="lazy" data-original="{{image img 185 86}}"/></a>
  22 + {{/each}}
  23 + </div>
  24 +</div>
  1 +<div class="new-report imgopacity clearfix">
  2 + {{> floor-header}}
  3 +
  4 + <ul class="report-list clearfix">
  5 + {{# list}}
  6 +
  7 + {{#unless @last}}
  8 + <li>
  9 + <a href="{{href}}" target= "_blank">
  10 + {{#if @first}}
  11 + <img class="lazy" data-original="{{image img 377 504}}" alt="" >
  12 + {{^}}
  13 + <img class="lazy" data-original="{{image img 185 248}}" alt="" >
  14 + {{/if}}
  15 + </a>
  16 + </li>
  17 + {{/unless}}
  18 + {{/ list}}
  19 + </ul>
  20 +
  21 + {{# list}}
  22 + {{#if @last}}
  23 + <div class="last-item">
  24 + <a href="{{href}}" target= "_blank">
  25 + <img class="lazy" data-original="{{image img 377 504}}" alt="">
  26 + </a>
  27 + </div>
  28 + {{/if}}
  29 + {{/ list}}
  30 +</div>
  1 +{{> floor-header}}
  2 +<div class="slide-accordion clearfix">
  3 + <ul>
  4 + {{#each slide}}
  5 + <li><a title="{{name}}" href="{{href}}" target= "_blank"><div class="g-mask"></div><img class="lazy" data-original="{{image img 650 400}}"/></a></li>
  6 + {{/each}}
  7 + </ul>
  8 +</div>
@@ -33,7 +33,6 @@ exports.index = (req, res) => { @@ -33,7 +33,6 @@ exports.index = (req, res) => {
33 responseData.module = 'product'; 33 responseData.module = 'product';
34 responseData.page = 'sale'; 34 responseData.page = 'sale';
35 responseData.footerTop = true; 35 responseData.footerTop = true;
36 - responseData.devEnv = true;  
37 36
38 // 假数据输出 37 // 假数据输出
39 // res.render('sale/index', Object.assign(responseData, simulation.saleIndex())); 38 // res.render('sale/index', Object.assign(responseData, simulation.saleIndex()));
@@ -74,7 +73,6 @@ exports.discount = (req, res) => { @@ -74,7 +73,6 @@ exports.discount = (req, res) => {
74 responseData.module = 'product'; 73 responseData.module = 'product';
75 responseData.page = 'sale'; 74 responseData.page = 'sale';
76 responseData.footerTop = true; 75 responseData.footerTop = true;
77 - responseData.devEnv = true;  
78 76
79 // 假数据输出 77 // 假数据输出
80 // res.render('sale/discount', Object.assign(responseData, simulation.discount())); 78 // res.render('sale/discount', Object.assign(responseData, simulation.discount()));
@@ -117,7 +115,6 @@ exports.vip = (req, res) => { @@ -117,7 +115,6 @@ exports.vip = (req, res) => {
117 responseData.module = 'product'; 115 responseData.module = 'product';
118 responseData.page = 'sale'; 116 responseData.page = 'sale';
119 responseData.footerTop = true; 117 responseData.footerTop = true;
120 - responseData.devEnv = true;  
121 118
122 // 假数据输出 119 // 假数据输出
123 // res.render('sale/other', Object.assign(responseData, simulation.other())); 120 // res.render('sale/other', Object.assign(responseData, simulation.other()));
@@ -155,7 +152,6 @@ exports.newSale = (req, res) => { @@ -155,7 +152,6 @@ exports.newSale = (req, res) => {
155 responseData.module = 'product'; 152 responseData.module = 'product';
156 responseData.page = 'sale'; 153 responseData.page = 'sale';
157 responseData.footerTop = true; 154 responseData.footerTop = true;
158 - responseData.devEnv = true;  
159 155
160 // 假数据输出 156 // 假数据输出
161 // res.render('sale/other', Object.assign(responseData, simulation.other())); 157 // res.render('sale/other', Object.assign(responseData, simulation.other()));
@@ -193,7 +189,6 @@ exports.breakingYards = (req, res) => { @@ -193,7 +189,6 @@ exports.breakingYards = (req, res) => {
193 responseData.module = 'product'; 189 responseData.module = 'product';
194 responseData.page = 'sale'; 190 responseData.page = 'sale';
195 responseData.footerTop = true; 191 responseData.footerTop = true;
196 - responseData.devEnv = true;  
197 192
198 // 假数据输出 193 // 假数据输出
199 // res.render('sale/other', Object.assign(responseData, simulation.other())); 194 // res.render('sale/other', Object.assign(responseData, simulation.other()));
@@ -224,7 +219,6 @@ exports.getGoodsList = (req, res) => { @@ -224,7 +219,6 @@ exports.getGoodsList = (req, res) => {
224 return sale.getSaleGoodsData(params).then(result => { 219 return sale.getSaleGoodsData(params).then(result => {
225 let responseData = {}; 220 let responseData = {};
226 221
227 - responseData.devEnv = true;  
228 responseData.footerTop = false; 222 responseData.footerTop = false;
229 responseData.layout = false; 223 responseData.layout = false;
230 224
@@ -13,6 +13,11 @@ var app = express(); @@ -13,6 +13,11 @@ var app = express();
13 // set view engin 13 // set view engin
14 var doraemon = path.join(__dirname, '../../doraemon/views'); // parent view root 14 var doraemon = path.join(__dirname, '../../doraemon/views'); // parent view root
15 15
  16 +app.on('mount', function(parent) {
  17 + delete parent.locals.settings; // 不继承父 App 的设置
  18 + Object.assign(app.locals, parent.locals);
  19 +});
  20 +
16 app.set('views', path.join(__dirname, 'views/action')); 21 app.set('views', path.join(__dirname, 'views/action'));
17 app.engine('.hbs', hbs({ 22 app.engine('.hbs', hbs({
18 extname: '.hbs', 23 extname: '.hbs',
@@ -13,9 +13,9 @@ module.exports = { @@ -13,9 +13,9 @@ module.exports = {
13 port: 6002, 13 port: 6002,
14 siteUrl: 'http://localhost:6002/', 14 siteUrl: 'http://localhost:6002/',
15 domains: { 15 domains: {
16 - api: 'http://devapi.yoho.cn:58078/', // testapi.yoho.cn:28078  
17 - service: 'http://devservice.yoho.cn:58077/', // devservice.yoho.cn:58077 testservice.yoho.cn:28077  
18 - search: 'http://192.168.10.64:8080/yohosearch/' 16 + api: 'http://testapi.yoho.cn:28078/',
  17 + service: 'http://testservice.yoho.cn:28077/',
  18 + search: 'http://192.168.102.216:8080/yohosearch/'
19 }, 19 },
20 useOneapm: false, 20 useOneapm: false,
21 useCache: false, 21 useCache: false,
@@ -41,7 +41,7 @@ module.exports = { @@ -41,7 +41,7 @@ module.exports = {
41 udp: { // send by udp 41 udp: { // send by udp
42 level: 'debug', // logger level 42 level: 'debug', // logger level
43 host: '192.168.102.162', // influxdb host 43 host: '192.168.102.162', // influxdb host
44 - port: '4444'// influxdb port 44 + port: '4444' // influxdb port
45 }, 45 },
46 console: { 46 console: {
47 level: 'debug', 47 level: 'debug',
@@ -71,6 +71,13 @@ if (isProduction) { @@ -71,6 +71,13 @@ if (isProduction) {
71 Object.assign(module.exports, { 71 Object.assign(module.exports, {
72 appName: 'www.yohobuy.com for test', 72 appName: 'www.yohobuy.com for test',
73 useOneapm: true, 73 useOneapm: true,
74 - useCache: true 74 + useCache: true,
  75 + memcache: {
  76 + master: ['127.0.0.1:12111'],
  77 + slave: ['127.0.0.1:12112'],
  78 + session: ['127.0.0.1:12111'],
  79 + timeout: 1000,
  80 + retries: 0
  81 + }
75 }); 82 });
76 } 83 }
  1 +'use strict';
  2 +
  3 +// 页面seo相关属性的配置文件
  4 +const seoMap = require('./seoConfig');
  5 +
  6 +/**
  7 + * 设置seo相关的数据,包括title, keywords, description
  8 + * @param {undefined}
  9 + * @return {Function} 中间件函数,用于给res.locals对象添加属性
  10 + */
  11 +module.exports = () => {
  12 + return (req, res, next) => {
  13 + if (!req.xhr) {
  14 + Object.assign(res.locals, seoMap[req.path] || seoMap['/']);
  15 + }
  16 + next();
  17 + };
  18 +};
  1 +const seoMap = {
  2 +/* eslint-disable */
  3 + '/': {
  4 + title: 'YOHO!有货 | 年轻人潮流购物中心,中国潮流购物风向标,官方授权正品保证',
  5 + keywords: 'Yoho! 有货官网,潮流志,潮流男装,潮牌,美国潮牌,日本潮牌,香港潮牌,潮牌店,新品首发,欧美潮流,全球购,代购,时尚,流行,特卖,B2C,正品,购物网站,网上购物,货到付款',
  6 + description: 'YOHO! 有货,年轻人潮流购物中心,中国最大的潮流商品购物网站。100%品牌正品保证,支持货到付款。作为YOHO!旗下的购物平台,汇集了全球潮流时尚商品和中国最流行的商品,也是国内最大的原创文化商品平台,也是香港,台湾地区流行商品的集中地。同时包含日本、韩国等众多国外潮流品牌,带给您全新潮流购物体验。'
  7 + },
  8 + '/woman': {
  9 + title: '女生|时尚潮流女装,日韩女装,潮牌女装全球购|YOHO!BUY有货 100%正品保证',
  10 + keywords: '女生服饰,时尚潮流女装,日韩女装,女装正品购物网站,女装全球购',
  11 + description: 'YOHO!BUY有货官网女生频道汇集了全球女装潮流时尚,提供时尚潮流女装,日版女装,韩版女装,潮牌女装正品全球购。YOHO!BUY有货购物100%正品保证,支持货到付款。'
  12 + },
  13 + '/kids': {
  14 + title: '潮童|男童装,女童装,韩版童装,儿童服装服饰|YOHO!BUY有货 100%正品保证',
  15 + keywords: '潮童,男童装,女童装,韩版童装,儿童服装服饰',
  16 + description: 'YOHO!BUY有货官网潮童频道汇集了全球潮童潮流时尚,提供新款男童装,女童装,韩版童装,儿童服装服饰正品全球购。YOHO!BUY有货购物100%正品保证,支持货到付款。'
  17 + },
  18 + '/lifestyle': {
  19 + title: '创意生活|创意生活馆,潮流创意家居,家居生活用品|YOHO!BUY有货 100%正品保证',
  20 + keywords: '创意生活,创意生活馆,潮流家居,潮流创意家居,家居生活用品,YOHO!有货',
  21 + description: 'YOHO!BUY有货官网创意生活频道汇集了创意生活馆,潮流创意家居,家居生活用品等正品网购,给您的生活带来更多创意。YOHO!BUY有货购物100%正品保证,支持货到付款。'
  22 + }
  23 +/* eslint-enable */
  24 +};
  25 +
  26 +
  27 +module.exports = seoMap;
@@ -13,27 +13,7 @@ const sign = require(`${global.library}/sign`); @@ -13,27 +13,7 @@ const sign = require(`${global.library}/sign`);
13 13
14 const serviceApi = new ServiceAPI(); 14 const serviceApi = new ServiceAPI();
15 15
16 -/**  
17 - * 获取公共配置  
18 - * @param undefined  
19 - * @return {Object} 配置对象  
20 - */  
21 -const commonConfig = () => ({  
22 - title: 'home'  
23 -});  
24 -  
25 -const getChannelIndex = (type) => {  
26 - const channelMap = {  
27 - boys: 0,  
28 - girls: 1,  
29 - kids: 2,  
30 - lifestyle: 3  
31 - };  
32 -  
33 - const index = channelMap[type];  
34 -  
35 - return _.isNil(index) ? 0 : index;  
36 -}; 16 +const log = require(`${global.library}/logger`);
37 17
38 /** 18 /**
39 * 获取菜单 19 * 获取菜单
@@ -72,19 +52,24 @@ const getMenuData = () => ( @@ -72,19 +52,24 @@ const getMenuData = () => (
72 52
73 /** 53 /**
74 * 获取导航 54 * 获取导航
75 - * @param undefined 55 + * @param {Object} data 要处理的数据
  56 + * @param {String} type 频道类型
76 * @return {array} 导航数组 57 * @return {array} 导航数组
77 */ 58 */
78 -const getNavBar = (data) => { 59 +const getNavBar = (data, type) => {
79 let navBars = []; 60 let navBars = [];
80 61
81 - _.forEach(data, function(item) { 62 + _.forEach(data, item => {
82 let obj = {}; 63 let obj = {};
83 64
84 obj.link = item.sort_url; 65 obj.link = item.sort_url;
85 obj.cn = item.sort_name; 66 obj.cn = item.sort_name;
86 obj.en = item.sort_name_en; 67 obj.en = item.sort_name_en;
87 68
  69 + if (type === _.camelCase(item.sort_name_en).toLowerCase()) {
  70 + obj.active = true;
  71 + }
  72 +
88 navBars.push(obj); 73 navBars.push(obj);
89 }); 74 });
90 75
@@ -94,14 +79,18 @@ const getNavBar = (data) => { @@ -94,14 +79,18 @@ const getNavBar = (data) => {
94 79
95 /** 80 /**
96 * 获取品牌名字 81 * 获取品牌名字
97 - * @param undefined 82 + * @param {Object} data 要处理数据
98 * @return {array} 品牌数组 83 * @return {array} 品牌数组
99 */ 84 */
100 const getBrandItems = (data) => { 85 const getBrandItems = (data) => {
101 let brandItems = []; 86 let brandItems = [];
102 87
103 - _.forEach(data, function(item) {  
104 - let obj = {}; 88 + _.forEach(data, item => {
  89 + let obj = {
  90 + link: '',
  91 + hot: false,
  92 + brandName: ''
  93 + };
105 94
106 obj.link = item.sort_url; 95 obj.link = item.sort_url;
107 obj.hot = item.is_hot === 'Y' ? true : false; 96 obj.hot = item.is_hot === 'Y' ? true : false;
@@ -116,18 +105,22 @@ const getBrandItems = (data) => { @@ -116,18 +105,22 @@ const getBrandItems = (data) => {
116 105
117 /** 106 /**
118 * 获取三级菜单 107 * 获取三级菜单
119 - * @param undefined 108 + * @param {Object} data 要处理数据
120 * @return {array} 三级菜单数组 109 * @return {array} 三级菜单数组
121 */ 110 */
122 const getThirdNav = (data) => { 111 const getThirdNav = (data) => {
123 let thirdNav = []; 112 let thirdNav = [];
124 113
125 - _.forEach(data, function(item) {  
126 - let obj = {}; 114 + _.forEach(data, item => {
  115 + let obj = {
  116 + link: '',
  117 + title: '',
  118 + brandItems: false
  119 + };
127 120
128 obj.link = item.sort_url; 121 obj.link = item.sort_url;
129 obj.title = item.sort_name; 122 obj.title = item.sort_name;
130 - obj.imgCode = item.content_code; 123 +
131 124
132 if (item.sub) { 125 if (item.sub) {
133 obj.brandItems = getBrandItems(item.sub); 126 obj.brandItems = getBrandItems(item.sub);
@@ -137,18 +130,22 @@ const getThirdNav = (data) => { @@ -137,18 +130,22 @@ const getThirdNav = (data) => {
137 }); 130 });
138 131
139 132
  133 +
140 return thirdNav; 134 return thirdNav;
141 }; 135 };
142 136
143 /** 137 /**
144 * 获取子菜单 138 * 获取子菜单
145 - * @param undefined 139 + * @param {Object} data 要处理数据
  140 + * @param {String} type 频道类型
146 * @return {array} 子菜单数组 141 * @return {array} 子菜单数组
147 */ 142 */
148 const getSubNav = (data, type) => { 143 const getSubNav = (data, type) => {
149 let subNav = []; 144 let subNav = [];
150 145
151 - _.forEach(data[getChannelIndex(type)].sub, function(item) { 146 + _.forEach(data, it => {
  147 + if (type === _.camelCase(it.sort_name_en).toLowerCase()) {
  148 + _.forEach(it.sub, item => {
152 let obj = {}; 149 let obj = {};
153 150
154 obj.link = item.sort_url; 151 obj.link = item.sort_url;
@@ -158,11 +155,13 @@ const getSubNav = (data, type) => { @@ -158,11 +155,13 @@ const getSubNav = (data, type) => {
158 155
159 if (item.sub) { 156 if (item.sub) {
160 obj.thirdNav = getThirdNav(item.sub); 157 obj.thirdNav = getThirdNav(item.sub);
  158 + obj.imgCode = item.content_code;
161 } 159 }
162 160
163 subNav.push(obj); 161 subNav.push(obj);
164 }); 162 });
165 - 163 + }
  164 + });
166 165
167 return subNav; 166 return subNav;
168 }; 167 };
@@ -176,31 +175,28 @@ const getSubNav = (data, type) => { @@ -176,31 +175,28 @@ const getSubNav = (data, type) => {
176 * @param {String} 指定页面类型为boys,girls,kids,lifestyle 175 * @param {String} 指定页面类型为boys,girls,kids,lifestyle
177 * @return {object} 头部数据 176 * @return {object} 头部数据
178 */ 177 */
179 -exports.setHeaderData = (resData, type) => {  
180 - let config = commonConfig(); 178 +const setHeaderData = (resData, type) => {
181 let data = { 179 let data = {
182 headerData: { 180 headerData: {
183 header: true, 181 header: true,
184 - headType: type, 182 + headtype: type,
185 yohoGroup: getMenuData(), 183 yohoGroup: getMenuData(),
186 - navbars: resData ? getNavBar(resData) : [], 184 + navbars: resData ? getNavBar(resData, type) : [],
187 subNav: resData ? getSubNav(resData, type) : [] 185 subNav: resData ? getSubNav(resData, type) : []
188 } 186 }
189 }; 187 };
190 188
191 - if (data.headerData.navbars.length) {  
192 - data.headerData.navbars[getChannelIndex(type)].active = true;  
193 - }  
194 -  
195 - return _.merge(config, data); 189 + return data;
196 }; 190 };
197 191
  192 +
  193 +
198 /** 194 /**
199 * 请求头部数据 195 * 请求头部数据
200 - * @param undefined 196 + * @param {String} 频道类型
201 * @return {promise} 197 * @return {promise}
202 */ 198 */
203 -exports.requestHeaderData = () => { 199 +exports.requestHeaderData = type => {
204 let data = sign.apiSign({ 200 let data = sign.apiSign({
205 201
206 /* eslint-disable */ 202 /* eslint-disable */
@@ -208,5 +204,14 @@ exports.requestHeaderData = () => { @@ -208,5 +204,14 @@ exports.requestHeaderData = () => {
208 /* eslint-enable */ 204 /* eslint-enable */
209 }); 205 });
210 206
211 - return serviceApi.get('operations/api/v6/category/getCategory', data, true); 207 + type = type || 'boys';
  208 +
  209 + return serviceApi.get('operations/api/v6/category/getCategory', data, true).then(res => {
  210 + if (res && res.code === 200) {
  211 + return setHeaderData(res.data, type);
  212 + } else {
  213 + log.error('获取头部信息的接口返回状态码 不是 200');
  214 + return {};
  215 + }
  216 + });
212 }; 217 };
@@ -189,8 +189,10 @@ @@ -189,8 +189,10 @@
189 </div> 189 </div>
190 <div class="left"> 190 <div class="left">
191 <span class="iconfont rgbf">&#xe602;</span> 191 <span class="iconfont rgbf">&#xe602;</span>
  192 + <a href="http://chat8.live800.com/live800/chatClient/chatbox.jsp?companyID=620092&amp;configID=149091&amp;jid=8732423409" target="_blank">
192 <span class="red">便捷</span> 193 <span class="red">便捷</span>
193 <span class="rgbf">在线客服</span> 194 <span class="rgbf">在线客服</span>
  195 + </a>
194 </div> 196 </div>
195 <div class="right subscribe footer-right"> 197 <div class="right subscribe footer-right">
196 <input id="subscriber-box" class="rgb6 top" name="subscriberBox"value="订阅我们的邮件"> 198 <input id="subscriber-box" class="rgb6 top" name="subscriberBox"value="订阅我们的邮件">
@@ -15,6 +15,7 @@ const Timer = require('./timer'); @@ -15,6 +15,7 @@ const Timer = require('./timer');
15 const config = require('../config/common'); 15 const config = require('../config/common');
16 const api = config.domains.api; 16 const api = config.domains.api;
17 const serviceApi = config.domains.service; 17 const serviceApi = config.domains.service;
  18 +const searchApi = config.domains.search;
18 19
19 class Http { 20 class Http {
20 21
@@ -182,5 +183,12 @@ class ServiceAPI extends Http { @@ -182,5 +183,12 @@ class ServiceAPI extends Http {
182 } 183 }
183 } 184 }
184 185
  186 +class SearchAPI extends Http {
  187 + constructor() {
  188 + super(searchApi);
  189 + }
  190 +}
  191 +
185 exports.API = API; 192 exports.API = API;
186 exports.ServiceAPI = ServiceAPI; 193 exports.ServiceAPI = ServiceAPI;
  194 +exports.SearchAPI = SearchAPI;
@@ -13,7 +13,10 @@ let camelCase, @@ -13,7 +13,10 @@ let camelCase,
13 camelCaseObject = (obj) => { 13 camelCaseObject = (obj) => {
14 _.forEach(Object.keys(obj), (k) => { 14 _.forEach(Object.keys(obj), (k) => {
15 obj[k] = camelCase(obj[k]); 15 obj[k] = camelCase(obj[k]);
  16 + if (/[_-]/.test(k)) {
16 obj[_.camelCase(k)] = obj[k]; 17 obj[_.camelCase(k)] = obj[k];
  18 + delete obj[k];
  19 + }
17 }); 20 });
18 return obj; 21 return obj;
19 }; 22 };
  1 +{
  2 + "apps": [
  3 + {
  4 + "name": "yohobuy-node",
  5 + "script": "app.js",
  6 + "instances": "max",
  7 + "exec_mode": "cluster",
  8 + "env": {
  9 + "PORT": 6002
  10 + }
  11 + }
  12 + ]
  13 +}
1 -/** ****/ (function(modules) { // webpackBootstrap  
2 -/** ****/ // The module cache  
3 -/** ****/ var installedModules = {};  
4 -  
5 -/** ****/ // The require function  
6 -/** ****/ function __webpack_require__(moduleId) {  
7 -  
8 -/** ****/ // Check if module is in cache  
9 -/** ****/ if (installedModules[moduleId])  
10 -/** ****/ return installedModules[moduleId].exports;  
11 -  
12 -/** ****/ // Create a new module (and put it into the cache)  
13 -/** ****/ var module = installedModules[moduleId] = {  
14 -/** ****/ exports: {},  
15 -/** ****/ id: moduleId,  
16 -/** ****/ loaded: false  
17 -/** ****/ };  
18 -  
19 -/** ****/ // Execute the module function  
20 -/** ****/ modules[moduleId].call(module.exports, module, module.exports, __webpack_require__);  
21 -  
22 -/** ****/ // Flag the module as loaded  
23 -/** ****/ module.loaded = true;  
24 -  
25 -/** ****/ // Return the exports of the module  
26 -/** ****/ return module.exports;  
27 -/** ****/ }  
28 -  
29 -  
30 -/** ****/ // expose the modules object (__webpack_modules__)  
31 -/** ****/ __webpack_require__.m = modules;  
32 -  
33 -/** ****/ // expose the module cache  
34 -/** ****/ __webpack_require__.c = installedModules;  
35 -  
36 -/** ****/ // __webpack_public_path__  
37 -/** ****/ __webpack_require__.p = '';  
38 -  
39 -/** ****/ // Load entry module and return exports  
40 -/** ****/ return __webpack_require__(0);  
41 -/** ****/ })([  
42 -/* 0 */  
43 -/** */ function(module, exports) {  
44 -  
45 - console.log(1);  
46 -  
47 -  
48 -/** */ }  
49 -/** ****/ ]);  
This diff could not be displayed because it is too large.
This diff could not be displayed because it is too large.
This diff could not be displayed because it is too large.
This diff could not be displayed because it is too large.
This diff could not be displayed because it is too large.
This diff could not be displayed because it is too large.
@@ -2,7 +2,7 @@ @@ -2,7 +2,7 @@
2 <!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd" > 2 <!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd" >
3 <svg xmlns="http://www.w3.org/2000/svg"> 3 <svg xmlns="http://www.w3.org/2000/svg">
4 <metadata> 4 <metadata>
5 -Created by FontForge 20120731 at Mon May 23 22:22:36 2016 5 +Created by FontForge 20120731 at Tue May 31 15:22:26 2016
6 By admin 6 By admin
7 </metadata> 7 </metadata>
8 <defs> 8 <defs>
@@ -19,7 +19,7 @@ Created by FontForge 20120731 at Mon May 23 22:22:36 2016 @@ -19,7 +19,7 @@ Created by FontForge 20120731 at Mon May 23 22:22:36 2016
19 bbox="0 -212 1158 896" 19 bbox="0 -212 1158 896"
20 underline-thickness="50" 20 underline-thickness="50"
21 underline-position="-100" 21 underline-position="-100"
22 - unicode-range="U+0078-E607" 22 + unicode-range="U+0078-E617"
23 /> 23 />
24 <missing-glyph horiz-adv-x="374" 24 <missing-glyph horiz-adv-x="374"
25 d="M34 0v682h272v-682h-272zM68 34h204v614h-204v-614z" /> 25 d="M34 0v682h272v-682h-272zM68 34h204v614h-204v-614z" />
@@ -56,5 +56,41 @@ d="M903 577l-68 69l-388 -388l-231 230l-68 -68l299 -298l65 65z" /> @@ -56,5 +56,41 @@ d="M903 577l-68 69l-388 -388l-231 230l-68 -68l299 -298l65 65z" />
56 d="M512 599q47 0 88 -18t72 -49t49 -72t18 -89q0 -46 -18 -87t-49 -72t-72 -49t-88 -18t-88 18t-72 49t-49 72t-18 87q0 48 18 89t49 72t72 49t88 18v0zM512 599z" /> 56 d="M512 599q47 0 88 -18t72 -49t49 -72t18 -89q0 -46 -18 -87t-49 -72t-72 -49t-88 -18t-88 18t-72 49t-49 72t-18 87q0 48 18 89t49 72t72 49t88 18v0zM512 599z" />
57 <glyph glyph-name="uniE607" unicode="&#xe607;" 57 <glyph glyph-name="uniE607" unicode="&#xe607;"
58 d="M797 219.5q0 -7.5 -5 -13.5l-29 -28q-6 -6 -13.5 -6t-12.5 6l-225 224l-224 -224q-6 -6 -13.5 -6t-13.5 6l-28 28q-6 6 -6 13.5t6 13.5l266 266q6 6 13.5 6t12.5 -6l267 -266q5 -6 5 -13.5z" /> 58 d="M797 219.5q0 -7.5 -5 -13.5l-29 -28q-6 -6 -13.5 -6t-12.5 6l-225 224l-224 -224q-6 -6 -13.5 -6t-13.5 6l-28 28q-6 6 -6 13.5t6 13.5l266 266q6 6 13.5 6t12.5 -6l267 -266q5 -6 5 -13.5z" />
  59 + <glyph glyph-name="uniE608" unicode="&#xe608;"
  60 +d="M284 15q-14 -14 -14 -33t13.5 -32.5t32.5 -13.5t32 14l397 401q13 14 13 33t-13 33l-397 401q-13 14 -32 14t-32.5 -13.5t-13.5 -32.5t13 -33l351 -369l-350 -369v0zM284 15z" />
  61 + <glyph glyph-name="uniE609" unicode="&#xe609;"
  62 +d="M745 753q13 14 13 33t-13.5 32.5t-32.5 13.5t-32 -14l-396 -401q-14 -14 -14 -33t14 -33l396 -401q14 -14 32.5 -14t32 13.5t13.5 32.5t-13 33l-351 369l351 369v0zM745 753z" />
  63 + <glyph glyph-name="uniE60A" unicode="&#xe60a;"
  64 +d="M512.5 750q-12.5 0 -21.5 -9t-9 -22v-311h-249q-12 0 -21.5 -9t-9.5 -22t9.5 -22t21.5 -9h280q12 0 21.5 9t9.5 22v342q0 13 -9.5 22t-22 9zM513 874q-101 0 -193 -39.5t-158.5 -105.5t-106 -158t-39.5 -193t39.5 -193t106 -158.5t158.5 -105.5t193 -39t192.5 39
  65 +t158 105.5t106 158.5t39.5 193t-39.5 193t-106 158t-158 105.5t-192.5 39.5zM513 -56q-118 0 -218 58t-158.5 158t-58.5 218t58.5 218t158.5 158t218 58t218 -58t158 -158t58 -218t-58 -218t-158 -158t-218 -58z" />
  66 + <glyph glyph-name="uniE60B" unicode="&#xe60b;"
  67 +d="M286 509l-46 -45l272 -272l272 272l-46 45l-226 -226z" />
  68 + <glyph glyph-name="uniE60C" unicode="&#xe60c;"
  69 +d="M387 158l45 -46l272 272l-272 272l-45 -46l226 -226z" />
  70 + <glyph glyph-name="uniE60D" unicode="&#xe60d;"
  71 +d="M766 193l-196 192l196 192l-61 60l-196 -193l-196 193l-60 -60l196 -192l-196 -192l60 -59l196 192l196 -192z" />
  72 + <glyph glyph-name="uniE60E" unicode="&#xe60e;"
  73 +d="M704 665l-41 39l-343 -320l343 -320l41 39l-301 281z" />
  74 + <glyph glyph-name="uniE60F" unicode="&#xe60f;"
  75 +d="M892 125l-236 236q54 77 54 172q0 124 -87 211t-210.5 87t-211 -87t-87.5 -211t87.5 -211t210.5 -87q95 0 173 55l236 -236q16 -17 38 -18t37 14t14 37t-18 38zM213 533q0 82 58.5 140.5t140.5 58.5t140.5 -58.5t58.5 -140.5t-58.5 -140.5t-140.5 -58.5t-140.5 58.5
  76 +t-58.5 140.5z" />
  77 + <glyph glyph-name="uniE610" unicode="&#xe610;"
  78 +d="M512 77l-439 614h878z" />
  79 + <glyph glyph-name="uniE611" unicode="&#xe611;" horiz-adv-x="1173"
  80 +d="M569 607q-28 66 -74 108.5t-95 56.5t-100 2.5t-91.5 -45t-66 -94t-26.5 -137.5q0 -36 8.5 -67.5t26 -58t35.5 -47t46.5 -41t49 -34t52.5 -32.5t48 -30q71 -47 124.5 -106.5t63.5 -93.5q7 31 62.5 92t124.5 110q19 14 55.5 36.5t61 38.5t55 42.5t49 52t31.5 62.5t13 79
  81 +q0 76 -26.5 136t-67 92t-92 42.5t-101 -4t-94.5 -56t-72 -104.5z" />
  82 + <glyph glyph-name="uniE612" unicode="&#xe612;"
  83 +d="M0 896h1024v-1024h-1024v1024zM85 -43h854v854h-854v-854z" />
  84 + <glyph glyph-name="uniE613" unicode="&#xe613;"
  85 +d="M1024 -128h-1024v1024h1024v-1024zM947 674l-34 34q-13 13 -30 13t-30 -13l-486 -495l-196 205q-13 13 -30 13t-30 -13l-34 -34q-13 -13 -13 -30t13 -30l256 -256q23 -22 51 -8q9 0 9 8l546 546q18 13 20 30.5t-12 29.5z" />
  86 + <glyph glyph-name="uniE614" unicode="&#xe614;"
  87 +d="M160 996zM865 247q0 -18 -13 -31l-308 -308q-13 -13 -31 -13t-31 13l-309 308q-13 13 -13 31t13.5 31t30.5 13h617q18 0 31 -13t13 -31zM865 511q0 -18 -13 -31t-31 -13h-617q-18 0 -31 13t-13 31t13 31l309 309q13 13 31 13t31 -13l308 -309q13 -13 13 -31z" />
  88 + <glyph glyph-name="uniE615" unicode="&#xe615;"
  89 +d="M951 77h-878l439 614z" />
  90 + <glyph glyph-name="uniE616" unicode="&#xe616;"
  91 +d="M877 896h-730q-61 0 -104 -43t-43 -104v-730q0 -61 43 -104t104 -43h730q61 0 104 43t43 104v730q0 61 -43 104t-104 43zM939 19q0 -26 -18 -44t-44 -18h-730q-26 0 -44 18t-18 44v730q0 26 18 44t44 18h730q26 0 44 -18t18 -44v-730z" />
  92 + <glyph glyph-name="uniE617" unicode="&#xe617;"
  93 +d="M939 -128h-854q-35 0 -60 25t-25 60v854q0 35 25 60t60 25h854q35 0 60 -25t25 -60v-854q0 -35 -25 -60t-60 -25zM939 789q0 10 -6 16t-16 6h-810q-10 0 -16 -6t-6 -16v-810q0 -10 6 -16t16 -6h810q10 0 16 6t6 16v810zM457 183q-10 -12 -30.5 -12t-29.5 12l-171 171
  94 +q-13 10 -13 30q0 18 12.5 30.5t30.5 12.5q20 0 30 -13l141 -141l311 312q13 12 30 12q18 0 30.5 -12.5t12.5 -29.5q0 -21 -13 -30z" />
59 </font> 95 </font>
60 </defs></svg> 96 </defs></svg>

6.28 KB | W: | H:

4.98 KB | W: | H:

  • 2-up
  • Swipe
  • Onion skin
  1 +require('../common');
@@ -19,14 +19,12 @@ require('../plugins/logo-brand'); @@ -19,14 +19,12 @@ require('../plugins/logo-brand');
19 require('../plugins/accordion'); 19 require('../plugins/accordion');
20 20
21 $(document).on('mouseenter', '.imgopacity a img', function() { 21 $(document).on('mouseenter', '.imgopacity a img', function() {
22 - $(this).css('opacity', 0.8); 22 + $(this).css('opacity', 0.8); // eslint-disable-line
23 }); 23 });
24 $(document).on('mouseout', '.imgopacity a img', function() { 24 $(document).on('mouseout', '.imgopacity a img', function() {
25 - $(this).css('opacity', 1); 25 + $(this).css('opacity', 1); // eslint-disable-line
26 }); 26 });
27 27
28 -  
29 -  
30 if ($.inArray(homePage, ['boys', 'girls', 'kids', 'lifestyle']) > -1) { 28 if ($.inArray(homePage, ['boys', 'girls', 'kids', 'lifestyle']) > -1) {
31 require('../plugins/new-arrivls')({ 29 require('../plugins/new-arrivls')({
32 type: homePage, 30 type: homePage,
@@ -5,7 +5,7 @@ var $contain = $('.slide-accordion'); @@ -5,7 +5,7 @@ var $contain = $('.slide-accordion');
5 var $item = $contain.find('li'); 5 var $item = $contain.find('li');
6 6
7 var $width = $item.width(); 7 var $width = $item.width();
8 -var $spn = parseInt($('.home-page').width()) === 1150 ? (120 + 5) : (102 + 5); 8 +var $spn = parseInt($('.home-page').width(), 0) === 1150 ? (120 + 5) : (102 + 5);
9 var slide; 9 var slide;
10 10
11 function switchfun(to) { 11 function switchfun(to) {
@@ -86,7 +86,7 @@ function uriLoc(attr, val) { @@ -86,7 +86,7 @@ function uriLoc(attr, val) {
86 } 86 }
87 87
88 // 隐藏高级选项面板 88 // 隐藏高级选项面板
89 -function hideSeniorPanel(index) { 89 +function hideSeniorPanel() {
90 $seniorSubWrap.children('.senior-sub:eq(' + hoveredIndex + ')').addClass('hide'); 90 $seniorSubWrap.children('.senior-sub:eq(' + hoveredIndex + ')').addClass('hide');
91 $seniorAttrWrap.children('.attr:eq(' + hoveredIndex + ')').removeClass('hover'); 91 $seniorAttrWrap.children('.attr:eq(' + hoveredIndex + ')').removeClass('hover');
92 hoveredIndex = -1; 92 hoveredIndex = -1;
@@ -371,11 +371,11 @@ $seniorAttrWrap.on('mouseenter', '.attr', function() { @@ -371,11 +371,11 @@ $seniorAttrWrap.on('mouseenter', '.attr', function() {
371 $('.senior-sub').on('click', '.multi-select', function() { 371 $('.senior-sub').on('click', '.multi-select', function() {
372 $(this).closest('.senior-sub').addClass('multi'); 372 $(this).closest('.senior-sub').addClass('multi');
373 }).on('click', '.multi-select-ok', function() { 373 }).on('click', '.multi-select-ok', function() {
374 - var $btn = $(this),  
375 - $sub = $btn.closest('.senior-sub'), 374 + var $btn2 = $(this),
  375 + $sub = $btn2.closest('.senior-sub'),
376 val = []; 376 val = [];
377 377
378 - if ($btn.hasClass('dis')) { 378 + if ($btn2.hasClass('dis')) {
379 return; 379 return;
380 } 380 }
381 381
@@ -31,9 +31,9 @@ var logoAngle = 0, @@ -31,9 +31,9 @@ var logoAngle = 0,
31 loopTime = 500; 31 loopTime = 500;
32 32
33 // handlebars模板 33 // handlebars模板
34 -centerFn = handlebars.compile($('#simple-account-info-tpl').html());  
35 -loginFn = handlebars.compile($('#header-login-info-tpl').html());  
36 -cartFn = handlebars.compile($('#mini-cart-tpl').html()); 34 +centerFn = handlebars.compile($('#simple-account-info-tpl').html() || '');
  35 +loginFn = handlebars.compile($('#header-login-info-tpl').html() || '');
  36 +cartFn = handlebars.compile($('#mini-cart-tpl').html() || '');
37 37
38 // handlebars helper 38 // handlebars helper
39 handlebars.registerHelper('notzero', function(v1, options) { 39 handlebars.registerHelper('notzero', function(v1, options) {
@@ -60,6 +60,9 @@ function formatThirdMenu() { @@ -60,6 +60,9 @@ function formatThirdMenu() {
60 i++; 60 i++;
61 }); 61 });
62 for (i = 0; i < 3; i++) { 62 for (i = 0; i < 3; i++) {
  63 + if (!list[i]) {
  64 + return;
  65 + }
63 $thirdList.before('<dl class="category-list">' + list[i] + '</dl>'); 66 $thirdList.before('<dl class="category-list">' + list[i] + '</dl>');
64 } 67 }
65 $thirdList.remove(); 68 $thirdList.remove();
@@ -400,8 +403,8 @@ $subNav.on({ @@ -400,8 +403,8 @@ $subNav.on({
400 } 403 }
401 param.content_code = $show.data().code; 404 param.content_code = $show.data().code;
402 param.client_type = 'web'; 405 param.client_type = 'web';
403 - param.width = 174;  
404 - param.height = 155; 406 + param.width = 337;
  407 + param.height = 250;
405 param._ = new Date(); 408 param._ = new Date();
406 $.getJSON('http://new.yohobuy.com/common/getbanner?callback=?', param, function(JsonData) { 409 $.getJSON('http://new.yohobuy.com/common/getbanner?callback=?', param, function(JsonData) {
407 if (JsonData.code === 200) { 410 if (JsonData.code === 200) {
@@ -563,8 +563,8 @@ @@ -563,8 +563,8 @@
563 background-image: resolve('layout/new.png'); 563 background-image: resolve('layout/new.png');
564 background-repeat: no-repeat; 564 background-repeat: no-repeat;
565 position: absolute; 565 position: absolute;
566 - margin-top: -20px;  
567 - margin-left: 16px; 566 + right: -29px;
  567 + top: -6px;
568 } 568 }
569 569
570 a { 570 a {
@@ -572,6 +572,7 @@ @@ -572,6 +572,7 @@
572 font-size: 14px; 572 font-size: 14px;
573 line-height: 14px; 573 line-height: 14px;
574 display: inline-block; 574 display: inline-block;
  575 + position: relative;
575 } 576 }
576 577
577 li:hover a { 578 li:hover a {
@@ -775,4 +776,9 @@ @@ -775,4 +776,9 @@
775 .head-wrapper .main-logo { 776 .head-wrapper .main-logo {
776 left: 39%; 777 left: 39%;
777 } 778 }
  779 +
  780 + .show-detail img {
  781 + width: 174px;
  782 + height: 155px;
  783 + }
778 } 784 }
@@ -228,8 +228,9 @@ a { @@ -228,8 +228,9 @@ a {
228 @import "header"; 228 @import "header";
229 @import "footer"; 229 @import "footer";
230 @import "404"; 230 @import "404";
231 -@import "common/index";  
232 -@import "plugin/slider"; 231 +@import "index/index";
  232 +@import "product/index";
  233 +@import "plugins/slider";
233 234
234 /* 模块 */ 235 /* 模块 */
235 @import "index/index"; 236 @import "index/index";
  1 +.yoho-dialog {
  2 + position: fixed;
  3 + padding: 20px;
  4 + top: 50%;
  5 + left: 50%;
  6 + min-height: 130px;
  7 + min-width: 350px;
  8 + background: #f8f8f8;
  9 + z-index: 1001;
  10 + border: 5px solid rgba(0,0,0,.38);
  11 +
  12 + .close {
  13 + position: absolute;
  14 + top: 5px;
  15 + right: 5px;
  16 + cursor: pointer;
  17 + }
  18 +
  19 + .content {
  20 + text-align: center;
  21 + }
  22 +
  23 + .btns {
  24 + text-align: center;
  25 + }
  26 + .alert-sure{
  27 + background: #000;
  28 + color: #fff;
  29 + }
  30 + .confirm-sure{
  31 + background: #000;
  32 + color: #fff;
  33 + }
  34 + .btn {
  35 + display: inline-block;
  36 + width: 56px;
  37 + height: 26px;
  38 + line-height: 26px;
  39 + text-align: center;
  40 + border: 1px solid #000;
  41 + cursor: pointer;
  42 + margin-left: 10px;
  43 + &:first-child {
  44 + margin-left: 0;
  45 + }
  46 + }
  47 +
  48 + &.alert-dialog .content,
  49 + &.confirm-dialog .content {
  50 + width: 350px;
  51 + height: auto;
  52 + min-height: 90px;
  53 + overflow: hidden;
  54 + line-height: 20px;
  55 + position: relative;
  56 + padding-top: 40px;
  57 + padding-bottom: 20px;
  58 + p{
  59 + position: absolute;
  60 + left: 0;
  61 + bottom: 25px;
  62 + width: 100%;
  63 + color: #444;
  64 + line-height: 25px;
  65 + }
  66 + div{
  67 + position: absolute;
  68 + top: 0;
  69 + left: 100px;
  70 + padding-top: 30px;
  71 + font-size: 22px;
  72 + font-weight: bold;
  73 + width: 150px;
  74 + height: 30px;
  75 + line-height: 30px;
  76 + margin: 0 auto;
  77 + span{
  78 + background: url(/cart/del.png);
  79 + float: left;
  80 + width: 27px;
  81 + height: 30px;
  82 + }
  83 + }
  84 + }
  85 +
  86 + &.subcontent-dialog {
  87 + padding: 30px 0px 30px 0px;
  88 +
  89 + .content {
  90 + font-weight: bold;
  91 + margin: 0px auto 30px auto;
  92 + }
  93 +
  94 + .sub-content {
  95 + text-align: center;
  96 + font-size: 12px;
  97 + color: #555;
  98 + margin-left: 5px;
  99 + margin-bottom: 5px;
  100 + }
  101 +
  102 +
  103 + .btn {
  104 + margin-top: 25px;
  105 + width: 100px;
  106 + font-size: 13px;
  107 + margin-left: 0;
  108 + margin-right: 0;
  109 +
  110 + &.black {
  111 + background-color: #000;
  112 + color: #fff;
  113 + }
  114 + }
  115 + }
  116 +}
  1 +.slider {
  2 + position: relative;
  3 + height: 327px;
  4 + width: 100%;
  5 + overflow: hidden;
  6 +
  7 + img {
  8 + max-width: 100%;
  9 + max-height: 100%;
  10 + }
  11 +}
  12 +
  13 +.slide-pagination {
  14 + position: absolute;
  15 + left: 0;
  16 + right: 0;
  17 + bottom: 12px;
  18 + text-align: center;
  19 +}
  20 +
  21 +.slide-pagination-inner {
  22 + display: inline-block;
  23 + position: relative;
  24 + padding: 7px;
  25 + vertical-align: middle;
  26 +}
  27 +
  28 +.slide-shade {
  29 + position: absolute;
  30 + left: 0;
  31 + right: 0;
  32 + top: 0;
  33 + bottom: 0;
  34 + background: #000;
  35 + opacity: 0.3;
  36 + border-radius: 13px;
  37 +}
  38 +
  39 +.slide-pagination-last span {
  40 + display: block;
  41 + float: left;
  42 + position: relative;
  43 + margin: 0 7px;
  44 + width: 12px;
  45 + height: 12px;
  46 + background: #fff;
  47 + cursor: pointer;
  48 + opacity: 0.6;
  49 + border-radius: 6px;
  50 + z-index: 2;
  51 +
  52 + &.focus {
  53 + opacity: 1;
  54 + }
  55 +}
  56 +
  57 +.slide-switch {
  58 + display: none;
  59 +
  60 + &.show {
  61 + display: block;
  62 + }
  63 +
  64 + a {
  65 + display: block;
  66 + position: absolute;
  67 + top: 50%;
  68 + margin: -30px 0 0;
  69 + width: 60px;
  70 + height: 60px;
  71 + line-height: 56px;
  72 + text-align: center;
  73 + z-index: 2;
  74 + background: #fff;
  75 + opacity: 0.55;
  76 +
  77 + &:hover{
  78 + opacity: 0.9;
  79 + }
  80 +
  81 + .iconfont {
  82 + font-size: 32px;
  83 + color: #59585a;
  84 + }
  85 + }
  86 +
  87 + .prev {
  88 + left: 0;
  89 + }
  90 +
  91 + .next {
  92 + right: 0;
  93 + }
  94 +}
@@ -242,7 +242,6 @@ @@ -242,7 +242,6 @@
242 overflow: hidden; 242 overflow: hidden;
243 } 243 }
244 } 244 }
245 -  
246 } 245 }
247 246
248 .good-info-big { 247 .good-info-big {
@@ -63,6 +63,7 @@ @@ -63,6 +63,7 @@
63 } 63 }
64 64
65 /* 990px */ 65 /* 990px */
  66 +
66 .min-screen .product-list-page, 67 .min-screen .product-list-page,
67 .min-screen .new-sale-page { 68 .min-screen .new-sale-page {
68 69
  1 +/**
  2 + * 登录判断
  3 + * @author: xuqi<qi.xu@yoho.cn>
  4 + * @date: 2016/4/25
  5 + */
  6 +
  7 +'use strict';
  8 +
  9 +const _ = require('lodash');
  10 +
  11 +const // domain = '.static.yhbimg.com',
  12 + defaultImage = '/2015/08/25/02/01dd632a6e07bfef457ce4beda21dd6413.png',
  13 + qiniuDomain = 'yhfair.qiniudn.com',
  14 + domainList = {
  15 + '01': ['img10.static.yhbimg.com', 'img11.static.yhbimg.com'],
  16 + '02': ['img12.static.yhbimg.com', 'img13.static.yhbimg.com'],
  17 + 'yhb-head': 'head.static.yhbimg.com'
  18 + };
  19 +
  20 +const regexp = /(?:\{)([a-zA-z][^\s\}]+)(?:\})/g;
  21 +
  22 +const myReplace = (tem, data) => {
  23 + return tem.replace(regexp, function(fullMatch, capture) {
  24 + if (data[capture]) {
  25 + return data[capture];
  26 + } else {
  27 + return fullMatch;
  28 + }
  29 +
  30 + });
  31 +};
  32 +
  33 +const makeBaseUrl = (domain, key) =>{
  34 + encodeURIComponent(key).replace('%2F', '/');
  35 + return `http://${domain}/${key}`;
  36 +};
  37 +
  38 +const makeTemplateRequest = url => {
  39 + let ops = ['{mode}', 'w/{width}', 'h/{height}'];
  40 +
  41 + if (ops.length === 0) {
  42 + return url;
  43 + }
  44 +
  45 + return url + '?imageView/' + ops.join('/');
  46 +};
  47 +
  48 +const getImgTemplateUrl = (fileName, mode, domain) =>{
  49 + // 默认值
  50 + if (!mode) {
  51 + mode = 1;
  52 + }
  53 + if (!domain) {
  54 + domain = null;
  55 + }
  56 +
  57 + if (domain === null) {
  58 + domain = qiniuDomain;
  59 + }
  60 +
  61 + let baseUrl = makeBaseUrl(domain, fileName);
  62 +
  63 + return makeTemplateRequest(baseUrl);
  64 +};
  65 +
  66 +const getDomain = (bucket, fileName) => {
  67 + let domain = '';
  68 +
  69 + if (bucket in domainList) {
  70 + domain = domainList.bucket;
  71 + } else {
  72 + let node = fileName.substr(15, 2);
  73 +
  74 + if (node in domainList) {
  75 + let urlList = domainList[node];
  76 + let nodeNum = _.random(urlList.length - 1);
  77 +
  78 + domain = urlList[nodeNum];
  79 + }
  80 + }
  81 +
  82 + return domain;
  83 +};
  84 +
  85 +const url = (fileName, bucket, mode) =>{
  86 + // 默认值
  87 + if (!mode) {
  88 + mode = 1;
  89 + }
  90 + if (!bucket) {
  91 + bucket = 'yhfair';
  92 + }
  93 +
  94 + let domain = getDomain(bucket, fileName);
  95 +
  96 + return getImgTemplateUrl(bucket + fileName, mode, domain);
  97 +};
  98 +
  99 +const template = (fileName, bucket, mode) => {
  100 + // 默认值
  101 + if (!mode) {
  102 + mode = 1;
  103 + }
  104 + if (!bucket) {
  105 + bucket = 'yhfair';
  106 + }
  107 +
  108 + return url(fileName, bucket, mode);
  109 +};
  110 +
  111 +
  112 +exports.getImageUrl = (fileName, width, height, mode, bucket) => {
  113 + // 默认值
  114 + if (!mode) {
  115 + mode = 2;
  116 + }
  117 + if (!bucket) {
  118 + bucket = 'goodsimg';
  119 + }
  120 +
  121 + if (typeof(fileName) !== 'string') {
  122 + return template(defaultImage, bucket, mode);
  123 + }
  124 + if (fileName.indexOf('http://') !== 0) {
  125 + fileName = template(fileName, bucket, mode);
  126 + }
  127 + return myReplace(fileName, {width: width, height: height, mode: mode});
  128 +};
  1 +'use strict';
  2 +
  3 +const _ = require('lodash');
  4 +
  5 +module.exports = seoData => {
  6 + const defaultSeoData = {
  7 + /* eslint-disable */
  8 + title: 'YOHO!有货 | 年轻人潮流购物中心,中国潮流购物风向标,官方授权正品保证',
  9 + keywords: 'Yoho! 有货官网,潮流志,潮流男装,潮牌,美国潮牌,日本潮牌,香港潮牌,潮牌店,新品首发,欧美潮流,全球购,代购,时尚,流行,特卖,B2C,正品,购物网站,网上购物,货到付款',
  10 + description: 'YOHO! 有货,年轻人潮流购物中心,中国最大的潮流商品购物网站。100%品牌正品保证,支持货到付款。作为YOHO!旗下的购物平台,汇集了全球潮流时尚商品和中国最流行的商品,也是国内最大的原创文化商品平台,也是香港,台湾地区流行商品的集中地。同时包含日本、韩国等众多国外潮流品牌,带给您全新潮流购物体验。'
  11 + /* eslint-enable */
  12 + };
  13 +
  14 +
  15 + _.merge(defaultSeoData, seoData);
  16 +
  17 + return (req, res, next) => {
  18 + if (!req.xhr) {
  19 + res.locals.title = seoData.title;
  20 + res.locals.keywords = seoData.keywords;
  21 + res.locals.description = seoData.description;
  22 + }
  23 + next();
  24 + };
  25 +};