Authored by zzzzzzz

合并master

  1 +/**
  2 + * 分类页面
  3 + */
  4 +'use strict';
  5 +const cateModel = require('../models/cate');
  6 +const headerModel = require('../../../doraemon/models/header');
  7 +const helpers = global.yoho.helpers;
  8 +
  9 +let index = (req, res, next) => {
  10 + cateModel.getCateData(req.yoho.channel).then((result) => {
  11 + res.render('cate', {
  12 + module: 'channel',
  13 + page: 'cate',
  14 + title: '商品分类',
  15 + pageHeader: headerModel.setNav({
  16 + navTitle: '商品分类'
  17 + }),
  18 + pageFooter: false,
  19 + category: {
  20 + nav: result.nav,
  21 + list: result.list,
  22 + searchUrl: helpers.urlFormat('/search', null, 'search')
  23 + }
  24 + });
  25 + }).catch(next);
  26 +};
  27 +
  28 +module.exports = {
  29 + index
  30 +};
  1 +/**
  2 + * 分类页面 model
  3 + * @author: Bi Kai<kai.bi@yoho.cn>
  4 + * @date: 2016/07/06
  5 + */
  6 +'use strict';
  7 +const _ = require('lodash');
  8 +const api = global.yoho.API;
  9 +const helpers = global.yoho.helpers;
  10 +const camelCase = global.yoho.camelCase;
  11 +
  12 +const genderMap = {
  13 + boys: '1,3',
  14 + girls: '2,3',
  15 + kids: '1,2,3',
  16 + lifestyle: '1,2,3'
  17 +};
  18 +
  19 +let _processCateData = (list, channel) => {
  20 + let nav = ['boys', 'girls', 'kids', 'lifestyle'];
  21 +
  22 + nav = _.map(nav, function(item) {
  23 + return {
  24 + name: _.capitalize(item),
  25 + channel: item,
  26 + focus: item === channel
  27 + };
  28 + });
  29 +
  30 + list = camelCase(list);
  31 + _.map(list, function(item, key) {
  32 + item.focus = key === channel;
  33 +
  34 + _.map(item, function(firstItem) {
  35 + // 如果有二级菜单,二级菜单跳转,否则一级菜单跳转
  36 + if (firstItem.sub && firstItem.sub.length) {
  37 + _.map(firstItem.sub, function(secondItem) {
  38 + secondItem.url = helpers.urlFormat('/', {
  39 + sort: _.get(secondItem, 'relationParameter.sort'),
  40 + sort_name: secondItem.categoryName,
  41 + gender: genderMap[key] || ''
  42 + }, 'list');
  43 + });
  44 +
  45 + firstItem.sub.unshift({
  46 + categoryName: `全部${firstItem.categoryName}`,
  47 + url: helpers.urlFormat('/', {
  48 + sort: _.get(firstItem, 'relationParameter.sort'),
  49 + sort_name: firstItem.categoryName,
  50 + gender: genderMap[key] || ''
  51 + }, 'list')
  52 + });
  53 + } else {
  54 + firstItem.url = helpers.urlFormat('/', {
  55 + sort: _.get(firstItem, 'relationParameter.sort'),
  56 + sort_name: firstItem.categoryName,
  57 + gender: genderMap[key] || ''
  58 + }, 'list');
  59 + }
  60 + });
  61 + });
  62 +
  63 + return {
  64 + nav,
  65 + list
  66 + };
  67 +};
  68 +
  69 +let getCateData = (channel) => {
  70 + return api.get('', {
  71 + method: 'app.sort.get'
  72 + }, {
  73 + cache: true
  74 + }).then((result) => {
  75 + if (!result.code || result.code !== 200 || !result.data) {
  76 + return [];
  77 + }
  78 +
  79 + // 统一频道名称
  80 + result.data.boys = result.data.boy;
  81 + result.data.girls = result.data.girl;
  82 + _.unset(result.data, 'boy');
  83 + _.unset(result.data, 'girl');
  84 +
  85 + return result.data;
  86 + }).then((list) => {
  87 + return _processCateData(list, channel);
  88 + });
  89 +};
  90 +
  91 +module.exports = {
  92 + getCateData
  93 +};
@@ -9,6 +9,7 @@ @@ -9,6 +9,7 @@
9 const express = require('express'); 9 const express = require('express');
10 const cRoot = './controllers'; 10 const cRoot = './controllers';
11 const channel = require(cRoot); 11 const channel = require(cRoot);
  12 +const cate = require(cRoot + '/cate');
12 13
13 const router = express.Router(); // eslint-disable-line 14 const router = express.Router(); // eslint-disable-line
14 15
@@ -20,4 +21,6 @@ router.get('/lifestyle', channel.switchChannel, channel.lifestyle); @@ -20,4 +21,6 @@ router.get('/lifestyle', channel.switchChannel, channel.lifestyle);
20 21
21 router.get('/channel/bottomBanner', channel.bottomBanner); 22 router.get('/channel/bottomBanner', channel.bottomBanner);
22 23
  24 +router.get('/cate', cate.index);
  25 +
23 module.exports = router; 26 module.exports = router;
  1 +<div class="category-page yoho-page">
  2 + {{# category}}
  3 + <div id="search-input" class="search-input">
  4 + <a href={{searchUrl}}>
  5 + <i class="search-icon iconfont">&#xe60f;</i>
  6 + <p>搜索商品</p>
  7 + </a>
  8 + </div>
  9 + <ul class="category-nav clearfix">
  10 + {{# nav}}
  11 + <li class="{{#if focus}}focus{{/if}}" data-channel="{{channel}}">
  12 + <span>{{name}}</span>
  13 + </li>
  14 + {{/ nav}}
  15 + </ul>
  16 + <div class="category-container clearfix">
  17 + {{#each list}}
  18 + <div class="content {{@key}} {{#unless focus}}hide{{/unless}}">
  19 + <ul class="primary-level">
  20 + {{# this}}
  21 + <li class="p-level-item{{#if @first}} focus{{/if}}">
  22 + {{#if url}}
  23 + <a href={{url}}> {{categoryName}}</a>
  24 + {{^}}
  25 + {{categoryName}}
  26 + {{/if}}
  27 + </li>
  28 + {{/ this}}
  29 + </ul>
  30 + <div class="sub-level-container">
  31 + {{# this}}
  32 + <ul class="sub-level {{#unless @first}}hide{{/unless}}">
  33 + {{# sub}}
  34 + <li>
  35 + <a href={{url}}>
  36 + {{categoryName}}
  37 + </a>
  38 + </li>
  39 + {{/ sub}}
  40 + </ul>
  41 + {{/ this}}
  42 + </div>
  43 + </div>
  44 + {{/each}}
  45 + </div>
  46 + {{/ category}}
  47 +</div>
@@ -112,14 +112,20 @@ exports.intro = (req, res, next) => { @@ -112,14 +112,20 @@ exports.intro = (req, res, next) => {
112 return next(); 112 return next();
113 } 113 }
114 114
115 - introModel.getintroData({ 115 + introModel.getintroIntro({
116 productskn: req.params.productskn 116 productskn: req.params.productskn
117 - }, req).then((result) => {  
118 - res.render('detail/intro', {  
119 - result: result,  
120 - layout: false  
121 - });  
122 - }).catch(next); 117 + }, req).then(html => {
  118 + res.send(html);
  119 + });
  120 +
  121 + // introModel.getintroData({
  122 + // productskn: req.params.productskn
  123 + // }, req).then((result) => {
  124 + // res.render('detail/intro', {
  125 + // result: result,
  126 + // layout: false
  127 + // });
  128 + // }).catch(next);
123 }; 129 };
124 130
125 /** 131 /**
@@ -94,7 +94,7 @@ const getConsults = (id, page, limit) => { @@ -94,7 +94,7 @@ const getConsults = (id, page, limit) => {
94 */ 94 */
95 let _processComment = (data) => { 95 let _processComment = (data) => {
96 let result = { 96 let result = {
97 - commentsNum: data.pageResponse.totalCount, 97 + commentsNum: (data.pageResponse && data.pageResponse.totalCount) || 0,
98 comments: [] 98 comments: []
99 }; 99 };
100 100
@@ -138,6 +138,426 @@ const _getLimitCodeUrl = (productCode, skn, ua) => { @@ -138,6 +138,426 @@ const _getLimitCodeUrl = (productCode, skn, ua) => {
138 * @param origin Object 原始数据 138 * @param origin Object 原始数据
139 * @return dest Object 格式化数据 139 * @return dest Object 格式化数据
140 */ 140 */
  141 +// 老接口h5的代码
  142 +// const _detailDataPkg = (origin, uid, vipLevel, ua) => {
  143 +// let dest = {}, // 结果输出
  144 +// thumbImageList = [],
  145 +// colorGroup = {},
  146 +// sizeGroup = [],
  147 +// totalStorageNum = 0;
  148 +
  149 +// // 商品名称
  150 +// if (origin.productName === null || typeof origin.productName === 'undefined') {
  151 +// return dest;
  152 +// }
  153 +
  154 +// dest.goodsName = origin.productName;
  155 +
  156 +// // 是否是虚拟商品
  157 +// dest.virtualGoods = origin.attribute * 1 === 3 ? true : false;
  158 +
  159 +// // 用户未登录时
  160 +// if (!uid) {
  161 +// let params = {};
  162 +
  163 +// params.refer = helpers.urlFormat('/product/show_' + origin.erpProductId + '.html');
  164 +// dest.loginUrl = helpers.urlFormat('/signin.html', params);
  165 +// }
  166 +
  167 +// // 商品促销短语
  168 +// if (origin.salesPhrase) {
  169 +// dest.goodsSubtitle = origin.salesPhrase;
  170 +// }
  171 +
  172 +// // 促销信息 TODO: 换新接口
  173 +// if (origin.promotionBoList) {
  174 +// let discountList = [];
  175 +
  176 +// _.forEach(origin.promotionBoList, function(value) {
  177 +// discountList.push({
  178 +// text: `【${value.promotionType}】${value.promotionTitle}`
  179 +// });
  180 +// });
  181 +
  182 +// if (discountList.length) {
  183 +// dest.goodsDiscount = {
  184 +// list: discountList
  185 +// };
  186 +// }
  187 +// }
  188 +
  189 +// // 商品标签
  190 +// if (origin.productTagBoList) {
  191 +// let productTags = {};
  192 +
  193 +// _.forEach(origin.productTagBoList, function(value) {
  194 +// switch (value.tagLabel) {
  195 +// case 'is_soon_sold_out':
  196 +// productTags.is_soon_sold_out = true;
  197 +// break;
  198 +// case 'is_new':
  199 +// productTags.is_new = true;
  200 +// break;
  201 +// case 'is_discount':
  202 +// productTags.is_discount = true;
  203 +// break;
  204 +// case 'is_limited':
  205 +// productTags.is_limited = true;
  206 +// break;
  207 +// case 'is_yohood':
  208 +// productTags.is_yohood = true;
  209 +// break;
  210 +// case 'is_advance':
  211 +// productTags.is_advance = true;
  212 +// break;
  213 +// default:
  214 +// break;
  215 +// }
  216 +// });
  217 +
  218 +// dest.tags = productTags;
  219 +// }
  220 +
  221 +// // 商品价格
  222 +// if (origin.productPriceBo) {
  223 +// let originPrice = origin.productPriceBo;
  224 +// let goodsPrice = {
  225 +// currentPrice: originPrice.formatSalesPrice
  226 +// };
  227 +
  228 +// if (originPrice.formatMarketPrice !== originPrice.formatSalesPrice) {
  229 +// goodsPrice.previousPrice = originPrice.formatMarketPrice;
  230 +// }
  231 +
  232 +// dest.goodsPrice = goodsPrice;
  233 +
  234 +// // 商品返回 有货币
  235 +// if (originPrice.yohoCoinNum) {
  236 +// dest.commodityReturn = originPrice.yohoCoinNum;
  237 +// }
  238 +// }
  239 +
  240 +// // VIP 商品价格
  241 +// if (origin.productPriceBo.vipPrices) {
  242 +// let vipList = [];
  243 +
  244 +// _.forEach(origin.productPriceBo.vipPrices, function(value) {
  245 +// vipList.push({
  246 +// level: value.vipLevel,
  247 +// text: value.vipPrice,
  248 +// currentLevel: (value.vipLevel === vipLevel)
  249 +// });
  250 +// });
  251 +
  252 +// if (vipList.length) {
  253 +// dest.vipLevel = {
  254 +// list: vipList
  255 +// };
  256 +// }
  257 +
  258 +// }
  259 +
  260 +// // 上市期
  261 +// if (origin.expectArrivalTime) {
  262 +// dest.periodOfMarket = `${origin.expectArrivalTime}月`;
  263 +// }
  264 +
  265 +// // 商品咨询
  266 +// dest.feedbacks = {
  267 +// consults: [],
  268 +// consultsNum: 0
  269 +// };
  270 +
  271 +// let consultParams = {
  272 +// product_id: origin.id
  273 +// };
  274 +
  275 +// if (_.has(dest, 'feedbacks.consultsNum')) {
  276 +// consultParams.total = dest.feedbacks.consultsNum;
  277 +// dest.feedbacks.consultsUrl = helpers.urlFormat('/product/detail/consults', consultParams);
  278 +// } else {
  279 +// dest.feedbacks.consultsUrl = helpers.urlFormat('/product/detail/consultform', consultParams);
  280 +// }
  281 +
  282 +
  283 +// // 商品评价
  284 +// dest.feedbacks.commentsNum = 0;
  285 +// if (origin.commentBoWrapper) {
  286 +// dest.feedbacks.commentsNum = origin.commentBoWrapper.commentTotal;
  287 +
  288 +// let commentList = [];
  289 +
  290 +// _.forEach(origin.commentBoWrapper.commentBoList, function(value) {
  291 +// commentList.push({
  292 +// userName: value.nickName,
  293 +// desc: `${value.colorName}/${value.sizeName}`,
  294 +// content: value.content ? value.content : '',
  295 +// time: value.createTime
  296 +// });
  297 +// });
  298 +
  299 +// dest.feedbacks.comments = commentList;
  300 +
  301 +// dest.feedbacks.commentsUrl = helpers.urlFormat('/product/detail/comments', {
  302 +// product_id: origin.id,
  303 +// total: dest.feedbacks.commentsNum
  304 +// });
  305 +// }
  306 +
  307 +// // 品牌信息
  308 +// if (origin.brand) {
  309 +// let extra = `?productSkn=${origin.erpProductId}&brandId=${origin.brand.id}`;
  310 +
  311 +// dest.preferenceUrl = `/product/detail/preference${extra}`;
  312 +// }
  313 +
  314 +// dest.productSkn = origin.erpProductId;
  315 +
  316 +// // 商品信息
  317 +// if (origin.goodsList) {
  318 +// let goodsGroup = [],
  319 +// sizeName = '',
  320 +// colorList = [],
  321 +// sizeList = {},
  322 +// allSizeList = {},
  323 +// colorStorageGroup = {},
  324 +// colorStorageNum = 0;
  325 +
  326 +// _.forEach(origin.goodsList, function(value) {
  327 +// if (value.status === 0) {
  328 +// return;
  329 +// }
  330 +
  331 +// colorStorageNum = 0;
  332 +
  333 +// // 商品分组
  334 +// if (value.goodsImagesList) {
  335 +// _.forEach(value.goodsImagesList, function(good) {
  336 +// goodsGroup.push({
  337 +// goodsId: good.goodsId,
  338 +// img: good.imageUrl
  339 +// });
  340 +// });
  341 +// }
  342 +
  343 +// // 商品的尺码列表
  344 +// colorStorageGroup[value.productSkc] = {};
  345 +// if (value.goodsSizeBoList) {
  346 +// sizeList[value.productSkc] = [];
  347 +// _.forEach(value.goodsSizeBoList, function(size) {
  348 +// sizeList[value.productSkc].push({
  349 +// id: size.id,
  350 +// skuId: size.goodsSizeSkuId,
  351 +// goodsId: size.goodsId,
  352 +// colorId: size.colorId,
  353 +// name: size.sizeName,
  354 +// sizeNum: size.goodsSizeStorageNum
  355 +// });
  356 +
  357 +// sizeName = size.sizeName;
  358 +
  359 +// // 所有尺码列表,赋值用于前端展示默认尺码的时候
  360 +// // 判断出没有库存则显示灰色
  361 +// let build = {
  362 +// id: size.id,
  363 +// storage: size.goodsSizeStorageNum
  364 +// };
  365 +
  366 +// allSizeList[sizeName] = (allSizeList[sizeName] === null ||
  367 +// typeof allSizeList[sizeName] === 'undefined') ? build :
  368 +// allSizeList[sizeName];
  369 +
  370 +// colorStorageNum += parseInt(size.goodsSizeStorageNum, 10);
  371 +// colorStorageGroup[value.productSkc][sizeName] = parseInt(size.goodsSizeStorageNum, 10);
  372 +// });
  373 +
  374 +// // 颜色分组
  375 +// colorList.push({
  376 +// id: value.colorId,
  377 +// skcId: value.productSkc,
  378 +// name: value.colorName,
  379 +// goodsName: value.goodsName,
  380 +// colorNum: colorStorageNum
  381 +// });
  382 +// }
  383 +
  384 +// // 缩略图
  385 +// thumbImageList.push({
  386 +// img: value.colorImage
  387 +// });
  388 +
  389 +// // 商品库存总数
  390 +// totalStorageNum += _.toNumber(colorStorageNum);
  391 +// });
  392 +
  393 +// // 遍历所有尺码,构建颜色显示数据
  394 +// let i = 1;
  395 +
  396 +// sizeGroup[0] = {
  397 +// size: []
  398 +// };
  399 +
  400 +// _.forEach(allSizeList, (value, key) => {
  401 +
  402 +// // 默认尺码
  403 +// sizeGroup[0].size.push({
  404 +// name: key,
  405 +// sizeNum: _.toNumber(value.storage) > 0 ? true : false,
  406 +// id: value.id
  407 +// });
  408 +
  409 +// colorGroup[i] = {
  410 +// color: []
  411 +// };
  412 +
  413 +// // 各个颜色的尺码, 每行显示一个尺码对应的颜色
  414 +// _.forEach(colorList, (colorArr) => {
  415 +// let tempColorArr = _.cloneDeep(colorArr);
  416 +
  417 +// if (colorStorageGroup[tempColorArr.skcId] &&
  418 +// colorStorageGroup[tempColorArr.skcId][key]) {
  419 +// tempColorArr.colorNum = colorStorageGroup[tempColorArr.skcId][key];
  420 +// } else {
  421 +// tempColorArr.colorNum = 0;
  422 +// }
  423 +// colorGroup[i].color.push(Object.assign({}, tempColorArr));
  424 +// });
  425 +// colorGroup[i].id = value.id;
  426 +
  427 +// ++i;
  428 +// });
  429 +
  430 +// colorGroup[0] = {
  431 +// color: []
  432 +// };
  433 +
  434 +// // 遍历所有颜色, 构建尺码显示数据
  435 +// i = 1;
  436 +// _.forEach(colorList, function(value) {
  437 +// // 各个尺码的颜色, 每行显示一个颜色的对应尺码
  438 +// sizeGroup[i] = {
  439 +// size: sizeList[value.skcId],
  440 +// colorId: value.skcId
  441 +// };
  442 +
  443 +// // 默认颜色
  444 +// colorGroup[0].color.push(value);
  445 +// ++i;
  446 +// });
  447 +
  448 +
  449 +// // 商品图:多个
  450 +// if (goodsGroup.length > 1) {
  451 +// let bannerList = [];
  452 +
  453 +// _.forEach(goodsGroup, function(value) {
  454 +// bannerList.push({
  455 +// img: value.img
  456 +// });
  457 +// });
  458 +
  459 +// dest.bannerTop = {
  460 +// list: bannerList
  461 +// };
  462 +// } else if (goodsGroup[0] !== null && typeof goodsGroup[0] !== 'undefined') {
  463 +// dest.bannerTop = {
  464 +// img: goodsGroup[0].img
  465 +// };
  466 +// }
  467 +// }
  468 +
  469 +// // 悬浮的购物车信息
  470 +// dest.cartInfo = {
  471 +// cartUrl: helpers.urlFormat('/cart/index/index'),
  472 +// numInCart: 0,
  473 +// goodsInstore: origin.storage
  474 +// };
  475 +
  476 +// let soldOut = (origin.storage === 0) || (origin.status === 0 || totalStorageNum === 0);
  477 +// let notForSale = origin.attribute === 2;
  478 +
  479 +// // 显示加入购物车链接
  480 +// if (!soldOut && !notForSale) {
  481 +// _.orderBy(colorGroup);
  482 +
  483 +// Object.assign(dest.cartInfo, {
  484 +// productId: origin.id,
  485 +// thumbs: thumbImageList,
  486 +// name: dest.goodsName ? dest.goodsName : '',
  487 +// price: dest.goodsPrice.previousPrice ? dest.goodsPrice.previousPrice : '',
  488 +// salePrice: dest.goodsPrice.currentPrice ? dest.goodsPrice.currentPrice : '',
  489 +// totalNum: totalStorageNum,
  490 +// colors: _.toArray(colorGroup),
  491 +// sizes: sizeGroup
  492 +// });
  493 +
  494 +// // 限购商品
  495 +// if (origin.isLimitBuy === 'Y') {
  496 +// // 是否开售
  497 +// let isBeginSale = (origin.saleStatus !== null && typeof origin.saleStatus !== 'undefined' &&
  498 +// origin.saleStatus === 1);
  499 +
  500 +// // 限购商品有关的展示状态
  501 +// let showStatus = 1;
  502 +
  503 +// if (origin.showStatus !== null && typeof origin.showStatus !== 'undefined') {
  504 +// showStatus = parseInt(origin.showStatus, 10);
  505 +// }
  506 +
  507 +// // 处理限购商品有关的按钮状态
  508 +// dest = _procShowStatus(dest, showStatus, isBeginSale);
  509 +
  510 +// dest.cartInfo.limitProductCode = origin.limitProductCode;
  511 +// dest.cartInfo.limitCodeUrl = _getLimitCodeUrl(origin.limitProductCode, origin.erpProductId, ua);
  512 +// dest.cartInfo.limitProductPay = helpers.urlFormat('/cart/index/orderEnsure');
  513 +// } else {
  514 +// dest.cartInfo.addToCartUrl = helpers.urlFormat('/product/buy_' + origin.id + '_' +
  515 +// origin.goodsList.id + '.html');
  516 +// }
  517 +// } else if (notForSale) {
  518 +// dest.cartInfo.notForSale = true;
  519 +// } else if (soldOut) {
  520 +// dest.cartInfo.soldOut = true;
  521 +// }
  522 +
  523 +// // 是否收藏
  524 +// dest.isCollect = false;
  525 +// if (origin.isCollect !== null && typeof origin.isCollect !== 'undefined' && origin.isCollect === 'Y') {
  526 +// dest.isCollect = true;
  527 +// dest.cartInfo.isCollect = true;
  528 +// }
  529 +
  530 +// // 底部简介URL链接
  531 +// dest.introUrl = '/product/detail/intro/' + origin.erpProductId;
  532 +// dest.id = origin.id;
  533 +
  534 +// // 虚拟商品(门票)
  535 +// if (origin.attribute * 1 === 3) {
  536 +// dest.tickets = true;
  537 +// dest.ticketsConfirm = helpers.urlFormat('/cart/index/ticketsConfirm');
  538 +
  539 +// // 展览票
  540 +// if (origin.erpProductId * 1 === SINGLE_TICKETS_SKN) {
  541 +// dest.single = true;
  542 +// } else {
  543 +// // 套票
  544 +// dest.package = true;
  545 +// }
  546 +
  547 +// // 购票限制
  548 +// dest.cartInfo.limit = 4;
  549 +
  550 +// // 清空活动
  551 +// dest.goodsDiscount = [];
  552 +
  553 +// // 来自登录页,自动弹出选择框
  554 +// // if (isset($_GET['product_type']) && $_GET['product_type'] == 'ticket') {
  555 +// // $result['showPannel'] = true;
  556 +// // }
  557 +// }
  558 +
  559 +// return dest;
  560 +// };
141 const _detailDataPkg = (origin, uid, vipLevel, ua) => { 561 const _detailDataPkg = (origin, uid, vipLevel, ua) => {
142 let dest = {}, // 结果输出 562 let dest = {}, // 结果输出
143 thumbImageList = [], 563 thumbImageList = [],
@@ -145,28 +565,26 @@ const _detailDataPkg = (origin, uid, vipLevel, ua) => { @@ -145,28 +565,26 @@ const _detailDataPkg = (origin, uid, vipLevel, ua) => {
145 sizeGroup = [], 565 sizeGroup = [],
146 totalStorageNum = 0; 566 totalStorageNum = 0;
147 567
148 - // 商品名称  
149 - if (origin.productName === null || typeof origin.productName === 'undefined') { 568 + // 商品名称
  569 + if (!origin.productName) {
  570 + dest.feedbacks = {};
150 return dest; 571 return dest;
151 } 572 }
152 573
153 dest.goodsName = origin.productName; 574 dest.goodsName = origin.productName;
154 575
155 - // 是否是虚拟商品  
156 - dest.virtualGoods = origin.attribute * 1 === 3 ? true : false; 576 + // 是否是虚拟商品
  577 + dest.virtualGoods = (origin.attribute * 1 === 3);
157 578
158 // 用户未登录时 579 // 用户未登录时
159 if (!uid) { 580 if (!uid) {
160 - let params = {};  
161 -  
162 - params.refer = helpers.urlFormat('/product/show_' + origin.erpProductId + '.html');  
163 - dest.loginUrl = helpers.urlFormat('/signin.html', params); 581 + dest.loginUrl = helpers.urlFormat('/signin.html', {
  582 + refer: helpers.urlFormat('/product/show_' + origin.productSkn + '.html')
  583 + });
164 } 584 }
165 585
166 - // 商品促销短语  
167 - if (origin.salesPhrase) {  
168 - dest.goodsSubtitle = origin.salesPhrase;  
169 - } 586 + // 商品促销短语
  587 + origin.salesPhrase && (dest.goodsSubtitle = origin.salesPhrase);
170 588
171 // 促销信息 TODO: 换新接口 589 // 促销信息 TODO: 换新接口
172 if (origin.promotionBoList) { 590 if (origin.promotionBoList) {
@@ -178,94 +596,61 @@ const _detailDataPkg = (origin, uid, vipLevel, ua) => { @@ -178,94 +596,61 @@ const _detailDataPkg = (origin, uid, vipLevel, ua) => {
178 }); 596 });
179 }); 597 });
180 598
181 - if (discountList.length) {  
182 - dest.goodsDiscount = {  
183 - list: discountList  
184 - };  
185 - } 599 + discountList.length && (dest.goodsDiscount = {
  600 + list: discountList
  601 + });
186 } 602 }
187 603
188 - // 商品标签  
189 - if (origin.productTagBoList) { 604 + // 商品标签
  605 + if (origin.tags) {
190 let productTags = {}; 606 let productTags = {};
191 607
192 - _.forEach(origin.productTagBoList, function(value) {  
193 - switch (value.tagLabel) {  
194 - case 'is_soon_sold_out':  
195 - productTags.is_soon_sold_out = true;  
196 - break;  
197 - case 'is_new':  
198 - productTags.is_new = true;  
199 - break;  
200 - case 'is_discount':  
201 - productTags.is_discount = true;  
202 - break;  
203 - case 'is_limited':  
204 - productTags.is_limited = true;  
205 - break;  
206 - case 'is_yohood':  
207 - productTags.is_yohood = true;  
208 - break;  
209 - case 'is_advance':  
210 - productTags.is_advance = true;  
211 - break;  
212 - default:  
213 - break;  
214 - } 608 + _.forEach(origin.tags, function(value) {
  609 + productTags[value] = true;
215 }); 610 });
216 611
217 dest.tags = productTags; 612 dest.tags = productTags;
218 } 613 }
219 614
220 - // 商品价格  
221 - if (origin.productPriceBo) {  
222 - let originPrice = origin.productPriceBo;  
223 - let goodsPrice = {  
224 - currentPrice: originPrice.formatSalesPrice,  
225 - studentPrice: originPrice.studentPrice  
226 - };  
227 -  
228 - if (originPrice.formatMarketPrice !== originPrice.formatSalesPrice) {  
229 - goodsPrice.previousPrice = originPrice.formatMarketPrice;  
230 - }  
231 - dest.goodsPrice = goodsPrice; 615 + // 商品价格
  616 + let goodsPrice = {
  617 + currentPrice: origin.formatSalesPrice === '0' ? origin.formatMarketPrice : origin.formatSalesPrice
  618 + };
232 619
233 - // 商品返回 有货币 620 + if (origin.formatSalesPrice !== '0' && origin.formatMarketPrice !== origin.formatSalesPrice) {
  621 + goodsPrice.previousPrice = origin.formatMarketPrice;
  622 + }
234 623
235 - if (originPrice.yohoCoinNum) {  
236 - dest.commodityReturn = originPrice.yohoCoinNum;  
237 - } 624 + dest.goodsPrice = goodsPrice;
238 625
239 - // 学生有货币  
240 - if (originPrice.studentCoinNum) {  
241 - dest.studentCoinNum = originPrice.studentCoinNum;  
242 - }  
243 - } 626 + // 商品返回 YOHO 币
  627 + origin.yohoCoinNum && (dest.commodityReturn = origin.yohoCoinNum);
244 628
245 - // VIP 商品价格  
246 - if (origin.productPriceBo.vipPrices) { 629 + // VIP 商品价格
  630 + if (origin.vip) {
247 let vipList = []; 631 let vipList = [];
  632 + let levelList = {
  633 + 银卡: 1,
  634 + 金卡: 2,
  635 + 白金: 3
  636 + };
248 637
249 - _.forEach(origin.productPriceBo.vipPrices, function(value) { 638 + _.forEach(origin.vip, function(value) {
250 vipList.push({ 639 vipList.push({
251 - level: value.vipLevel,  
252 - text: value.vipPrice, 640 + level: levelList[value.caption],
  641 + text: value.price,
253 currentLevel: (value.vipLevel === vipLevel) 642 currentLevel: (value.vipLevel === vipLevel)
254 }); 643 });
255 }); 644 });
256 645
257 - if (vipList.length) {  
258 - dest.vipLevel = {  
259 - list: vipList  
260 - };  
261 - } 646 + vipList.length && (dest.vipLevel = {
  647 + list: vipList
  648 + });
262 649
263 } 650 }
264 651
265 - // 上市期  
266 - if (origin.expectArrivalTime) {  
267 - dest.periodOfMarket = `${origin.expectArrivalTime}月`;  
268 - } 652 + // 上市期
  653 + origin.expectArrivalTime && (dest.periodOfMarket = `${origin.expectArrivalTime}月`);
269 654
270 // 商品咨询 655 // 商品咨询
271 dest.feedbacks = { 656 dest.feedbacks = {
@@ -274,7 +659,7 @@ const _detailDataPkg = (origin, uid, vipLevel, ua) => { @@ -274,7 +659,7 @@ const _detailDataPkg = (origin, uid, vipLevel, ua) => {
274 }; 659 };
275 660
276 let consultParams = { 661 let consultParams = {
277 - product_id: origin.id 662 + product_id: origin.productId
278 }; 663 };
279 664
280 if (_.has(dest, 'feedbacks.consultsNum')) { 665 if (_.has(dest, 'feedbacks.consultsNum')) {
@@ -284,39 +669,19 @@ const _detailDataPkg = (origin, uid, vipLevel, ua) => { @@ -284,39 +669,19 @@ const _detailDataPkg = (origin, uid, vipLevel, ua) => {
284 dest.feedbacks.consultsUrl = helpers.urlFormat('/product/detail/consultform', consultParams); 669 dest.feedbacks.consultsUrl = helpers.urlFormat('/product/detail/consultform', consultParams);
285 } 670 }
286 671
287 -  
288 - // 商品评价  
289 - dest.feedbacks.commentsNum = 0;  
290 - if (origin.commentBoWrapper) {  
291 - dest.feedbacks.commentsNum = origin.commentBoWrapper.commentTotal;  
292 -  
293 - let commentList = [];  
294 -  
295 - _.forEach(origin.commentBoWrapper.commentBoList, function(value) {  
296 - commentList.push({  
297 - userName: value.nickName,  
298 - desc: `${value.colorName}/${value.sizeName}`,  
299 - content: value.content ? value.content : '',  
300 - time: value.createTime  
301 - });  
302 - });  
303 -  
304 - dest.feedbacks.comments = commentList;  
305 -  
306 - dest.feedbacks.commentsUrl = helpers.urlFormat('/product/detail/comments', {  
307 - product_id: origin.id,  
308 - total: dest.feedbacks.commentsNum  
309 - });  
310 - } 672 + // 商品评价
  673 + dest.feedbacks.commentsUrl = helpers.urlFormat('/product/detail/comments', {
  674 + product_id: origin.productId,
  675 + });
311 676
312 // 品牌信息 677 // 品牌信息
313 if (origin.brand) { 678 if (origin.brand) {
314 - let extra = `?productSkn=${origin.erpProductId}&brandId=${origin.brand.id}`; 679 + let extra = `?productSkn=${origin.productSkn}&brandId=${origin.brandInfo.brandId}`;
315 680
316 dest.preferenceUrl = `/product/detail/preference${extra}`; 681 dest.preferenceUrl = `/product/detail/preference${extra}`;
317 } 682 }
318 683
319 - dest.productSkn = origin.erpProductId; 684 + dest.productSkn = origin.productSkn;
320 685
321 // 商品信息 686 // 商品信息
322 if (origin.goodsList) { 687 if (origin.goodsList) {
@@ -335,11 +700,11 @@ const _detailDataPkg = (origin, uid, vipLevel, ua) => { @@ -335,11 +700,11 @@ const _detailDataPkg = (origin, uid, vipLevel, ua) => {
335 700
336 colorStorageNum = 0; 701 colorStorageNum = 0;
337 702
338 - // 商品分组  
339 - if (value.goodsImagesList) {  
340 - _.forEach(value.goodsImagesList, function(good) { 703 + // 商品分组
  704 + if (value.imagesList) {
  705 + _.forEach(value.imagesList, function(good) {
341 goodsGroup.push({ 706 goodsGroup.push({
342 - goodsId: good.goodsId, 707 + goodsId: value.goodsId,
343 img: good.imageUrl 708 img: good.imageUrl
344 }); 709 });
345 }); 710 });
@@ -347,16 +712,16 @@ const _detailDataPkg = (origin, uid, vipLevel, ua) => { @@ -347,16 +712,16 @@ const _detailDataPkg = (origin, uid, vipLevel, ua) => {
347 712
348 // 商品的尺码列表 713 // 商品的尺码列表
349 colorStorageGroup[value.productSkc] = {}; 714 colorStorageGroup[value.productSkc] = {};
350 - if (value.goodsSizeBoList) { 715 + if (value.sizeList) {
351 sizeList[value.productSkc] = []; 716 sizeList[value.productSkc] = [];
352 - _.forEach(value.goodsSizeBoList, function(size) { 717 + _.forEach(value.sizeList, function(size) {
353 sizeList[value.productSkc].push({ 718 sizeList[value.productSkc].push({
354 - id: size.id,  
355 - skuId: size.goodsSizeSkuId,  
356 - goodsId: size.goodsId,  
357 - colorId: size.colorId, 719 + id: size.sizeId,
  720 + skuId: size.productSku,
  721 + goodsId: value.goodsId,
  722 + colorId: value.colorId,
358 name: size.sizeName, 723 name: size.sizeName,
359 - sizeNum: size.goodsSizeStorageNum 724 + sizeNum: size.storageNumber
360 }); 725 });
361 726
362 sizeName = size.sizeName; 727 sizeName = size.sizeName;
@@ -364,16 +729,14 @@ const _detailDataPkg = (origin, uid, vipLevel, ua) => { @@ -364,16 +729,14 @@ const _detailDataPkg = (origin, uid, vipLevel, ua) => {
364 // 所有尺码列表,赋值用于前端展示默认尺码的时候 729 // 所有尺码列表,赋值用于前端展示默认尺码的时候
365 // 判断出没有库存则显示灰色 730 // 判断出没有库存则显示灰色
366 let build = { 731 let build = {
367 - id: size.id,  
368 - storage: size.goodsSizeStorageNum 732 + id: size.sizeId,
  733 + storage: size.storageNumber
369 }; 734 };
370 735
371 allSizeList[sizeName] = (allSizeList[sizeName] === null || 736 allSizeList[sizeName] = (allSizeList[sizeName] === null ||
372 - typeof allSizeList[sizeName] === 'undefined') ? build :  
373 - allSizeList[sizeName];  
374 -  
375 - colorStorageNum += parseInt(size.goodsSizeStorageNum, 10);  
376 - colorStorageGroup[value.productSkc][sizeName] = parseInt(size.goodsSizeStorageNum, 10); 737 + typeof allSizeList[sizeName] === 'undefined') ? build : allSizeList[sizeName];
  738 + colorStorageNum += parseInt(size.storageNumber, 10);
  739 + colorStorageGroup[value.productSkc][sizeName] = parseInt(size.storageNumber, 10);
377 }); 740 });
378 741
379 // 颜色分组 742 // 颜色分组
@@ -381,7 +744,6 @@ const _detailDataPkg = (origin, uid, vipLevel, ua) => { @@ -381,7 +744,6 @@ const _detailDataPkg = (origin, uid, vipLevel, ua) => {
381 id: value.colorId, 744 id: value.colorId,
382 skcId: value.productSkc, 745 skcId: value.productSkc,
383 name: value.colorName, 746 name: value.colorName,
384 - goodsName: value.goodsName,  
385 colorNum: colorStorageNum 747 colorNum: colorStorageNum
386 }); 748 });
387 } 749 }
@@ -401,10 +763,8 @@ const _detailDataPkg = (origin, uid, vipLevel, ua) => { @@ -401,10 +763,8 @@ const _detailDataPkg = (origin, uid, vipLevel, ua) => {
401 sizeGroup[0] = { 763 sizeGroup[0] = {
402 size: [] 764 size: []
403 }; 765 };
404 -  
405 _.forEach(allSizeList, (value, key) => { 766 _.forEach(allSizeList, (value, key) => {
406 -  
407 - // 默认尺码 767 + // 默认尺码
408 sizeGroup[0].size.push({ 768 sizeGroup[0].size.push({
409 name: key, 769 name: key,
410 sizeNum: _.toNumber(value.storage) > 0 ? true : false, 770 sizeNum: _.toNumber(value.storage) > 0 ? true : false,
@@ -464,7 +824,7 @@ const _detailDataPkg = (origin, uid, vipLevel, ua) => { @@ -464,7 +824,7 @@ const _detailDataPkg = (origin, uid, vipLevel, ua) => {
464 dest.bannerTop = { 824 dest.bannerTop = {
465 list: bannerList 825 list: bannerList
466 }; 826 };
467 - } else if (goodsGroup[0] !== null && typeof goodsGroup[0] !== 'undefined') { 827 + } else if (goodsGroup[0]) {
468 dest.bannerTop = { 828 dest.bannerTop = {
469 img: goodsGroup[0].img 829 img: goodsGroup[0].img
470 }; 830 };
@@ -475,10 +835,9 @@ const _detailDataPkg = (origin, uid, vipLevel, ua) => { @@ -475,10 +835,9 @@ const _detailDataPkg = (origin, uid, vipLevel, ua) => {
475 dest.cartInfo = { 835 dest.cartInfo = {
476 cartUrl: helpers.urlFormat('/cart/index/index'), 836 cartUrl: helpers.urlFormat('/cart/index/index'),
477 numInCart: 0, 837 numInCart: 0,
478 - goodsInstore: origin.storage 838 + goodsInstore: origin.storageSum
479 }; 839 };
480 -  
481 - let soldOut = (origin.storage === 0) || (origin.status === 0 || totalStorageNum === 0); 840 + let soldOut = (origin.storageSum === 0) || (totalStorageNum === 0); // status
482 let notForSale = origin.attribute === 2; 841 let notForSale = origin.attribute === 2;
483 842
484 // 显示加入购物车链接 843 // 显示加入购物车链接
@@ -486,7 +845,7 @@ const _detailDataPkg = (origin, uid, vipLevel, ua) => { @@ -486,7 +845,7 @@ const _detailDataPkg = (origin, uid, vipLevel, ua) => {
486 _.orderBy(colorGroup); 845 _.orderBy(colorGroup);
487 846
488 Object.assign(dest.cartInfo, { 847 Object.assign(dest.cartInfo, {
489 - productId: origin.id, 848 + productId: origin.productId,
490 thumbs: thumbImageList, 849 thumbs: thumbImageList,
491 name: dest.goodsName ? dest.goodsName : '', 850 name: dest.goodsName ? dest.goodsName : '',
492 price: dest.goodsPrice.previousPrice ? dest.goodsPrice.previousPrice : '', 851 price: dest.goodsPrice.previousPrice ? dest.goodsPrice.previousPrice : '',
@@ -496,28 +855,25 @@ const _detailDataPkg = (origin, uid, vipLevel, ua) => { @@ -496,28 +855,25 @@ const _detailDataPkg = (origin, uid, vipLevel, ua) => {
496 sizes: sizeGroup 855 sizes: sizeGroup
497 }); 856 });
498 857
499 - // 限购商品  
500 - if (origin.isLimitBuy === 'Y') {  
501 - // 是否开售  
502 - let isBeginSale = (origin.saleStatus !== null && typeof origin.saleStatus !== 'undefined' &&  
503 - origin.saleStatus === 1); 858 + // 限购商品
  859 + if (origin.isLimitBuy) {
  860 + // 是否开售
  861 + let isBeginSale = (origin.saleStatus === 1);
504 862
505 // 限购商品有关的展示状态 863 // 限购商品有关的展示状态
506 let showStatus = 1; 864 let showStatus = 1;
507 865
508 - if (origin.showStatus !== null && typeof origin.showStatus !== 'undefined') {  
509 - showStatus = parseInt(origin.showStatus, 10);  
510 - } 866 + origin.showStatus && (showStatus = parseInt(origin.showStatus, 10));
511 867
512 // 处理限购商品有关的按钮状态 868 // 处理限购商品有关的按钮状态
513 dest = _procShowStatus(dest, showStatus, isBeginSale); 869 dest = _procShowStatus(dest, showStatus, isBeginSale);
514 870
515 dest.cartInfo.limitProductCode = origin.limitProductCode; 871 dest.cartInfo.limitProductCode = origin.limitProductCode;
516 - dest.cartInfo.limitCodeUrl = _getLimitCodeUrl(origin.limitProductCode, origin.erpProductId, ua); 872 + dest.cartInfo.limitCodeUrl = _getLimitCodeUrl(origin.limitProductCode, origin.productSkn, ua);
517 dest.cartInfo.limitProductPay = helpers.urlFormat('/cart/index/orderEnsure'); 873 dest.cartInfo.limitProductPay = helpers.urlFormat('/cart/index/orderEnsure');
518 } else { 874 } else {
519 - dest.cartInfo.addToCartUrl = helpers.urlFormat('/product/buy_' + origin.id + '_' +  
520 - origin.goodsList.id + '.html'); 875 + dest.cartInfo.addToCartUrl = helpers.urlFormat('/product/buy_' + origin.productId + '_' +
  876 + origin.goodsList.goodsId + '.html');
521 } 877 }
522 } else if (notForSale) { 878 } else if (notForSale) {
523 dest.cartInfo.notForSale = true; 879 dest.cartInfo.notForSale = true;
@@ -527,22 +883,22 @@ const _detailDataPkg = (origin, uid, vipLevel, ua) => { @@ -527,22 +883,22 @@ const _detailDataPkg = (origin, uid, vipLevel, ua) => {
527 883
528 // 是否收藏 884 // 是否收藏
529 dest.isCollect = false; 885 dest.isCollect = false;
530 - if (origin.isCollect !== null && typeof origin.isCollect !== 'undefined' && origin.isCollect === 'Y') { 886 + if (origin.isCollect === 'Y') {
531 dest.isCollect = true; 887 dest.isCollect = true;
532 dest.cartInfo.isCollect = true; 888 dest.cartInfo.isCollect = true;
533 } 889 }
534 890
535 - // 底部简介URL链接  
536 - dest.introUrl = '/product/detail/intro/' + origin.erpProductId;  
537 - dest.id = origin.id; 891 + // 底部简介URL链接
  892 + dest.introUrl = '/product/detail/intro/' + origin.productSkn;
  893 + dest.id = origin.productId;
538 894
539 // 虚拟商品(门票) 895 // 虚拟商品(门票)
540 if (origin.attribute * 1 === 3) { 896 if (origin.attribute * 1 === 3) {
541 dest.tickets = true; 897 dest.tickets = true;
542 dest.ticketsConfirm = helpers.urlFormat('/cart/index/ticketsConfirm'); 898 dest.ticketsConfirm = helpers.urlFormat('/cart/index/ticketsConfirm');
543 899
544 - // 展览票  
545 - if (origin.erpProductId * 1 === SINGLE_TICKETS_SKN) { 900 + // 展览票
  901 + if (origin.productSkn * 1 === SINGLE_TICKETS_SKN) {
546 dest.single = true; 902 dest.single = true;
547 } else { 903 } else {
548 // 套票 904 // 套票
@@ -619,12 +975,12 @@ const _getCommonConsult = () => { @@ -619,12 +975,12 @@ const _getCommonConsult = () => {
619 let getProductData = (data) => { 975 let getProductData = (data) => {
620 let finalResult; 976 let finalResult;
621 let params = { 977 let params = {
622 - method: 'h5.product.data' 978 + method: 'app.product.data'
623 }; 979 };
624 980
625 if (data.id) { // 通过 productId 获取商品详情 981 if (data.id) { // 通过 productId 获取商品详情
626 Object.assign(params, { 982 Object.assign(params, {
627 - productId: _.toString(data.id) 983 + product_id: _.toString(data.id)
628 }); 984 });
629 } else if (data.productSkn) { // 通过 productSkn 获取商品详情 985 } else if (data.productSkn) { // 通过 productSkn 获取商品详情
630 Object.assign(params, { 986 Object.assign(params, {
@@ -643,22 +999,22 @@ let getProductData = (data) => { @@ -643,22 +999,22 @@ let getProductData = (data) => {
643 params.current_vip_level = data.vipLevel; 999 params.current_vip_level = data.vipLevel;
644 1000
645 return api.get('', params, { 1001 return api.get('', params, {
646 - cache: false  
647 - }).then(result => {  
648 - if (result.code === 500) { 1002 + code: 200
  1003 + }).then(global.yoho.camelCase).then(result => {
  1004 + if (result.code === 500 || !result.data) {
649 return {}; 1005 return {};
650 } 1006 }
  1007 + result = result.data;
651 return Promise.all([ 1008 return Promise.all([
652 - _getShopsInfo(result.brandId),  
653 - _getPromotionInfo(result.erpProductId), 1009 + _getShopsInfo(result.brandInfo.brandId),
  1010 + _getPromotionInfo(result.productSkn),
654 comment.getCommentInfo({ 1011 comment.getCommentInfo({
655 - productId: result.id 1012 + productId: result.productId
656 }), 1013 }),
657 _getCommonConsult(), 1014 _getCommonConsult(),
658 - comment.getConsults(result.id, 1, 2) 1015 + comment.getConsults(result.productId, 1, 2)
659 ]).then((info) => { 1016 ]).then((info) => {
660 result.promotionBoList = info[1]; 1017 result.promotionBoList = info[1];
661 -  
662 finalResult = _detailDataPkg(result, data.uid, data.vipLevel, data.ua); 1018 finalResult = _detailDataPkg(result, data.uid, data.vipLevel, data.ua);
663 finalResult.enterStore = info[0]; 1019 finalResult.enterStore = info[0];
664 finalResult.isStudent = data.isStudent; 1020 finalResult.isStudent = data.isStudent;
@@ -681,7 +1037,6 @@ let getProductData = (data) => { @@ -681,7 +1037,6 @@ let getProductData = (data) => {
681 consults: _.take(info[3], 2) 1037 consults: _.take(info[3], 2)
682 }); 1038 });
683 } 1039 }
684 -  
685 return finalResult; 1040 return finalResult;
686 }); 1041 });
687 1042
@@ -6,7 +6,7 @@ @@ -6,7 +6,7 @@
6 */ 6 */
7 7
8 'use strict'; 8 'use strict';
9 - 9 +const $ = require('cheerio');
10 const _ = require('lodash'); 10 const _ = require('lodash');
11 11
12 // const log = require(`${library}/logger`); 12 // const log = require(`${library}/logger`);
@@ -339,6 +339,25 @@ let getintroData = (data, req) => { @@ -339,6 +339,25 @@ let getintroData = (data, req) => {
339 }); 339 });
340 }; 340 };
341 341
  342 +let getintroIntro = (data) => {
  343 + return api.get('', {
  344 + method: 'app.product.intro',
  345 + product_skn: data.productskn
  346 + }).then(result => {
  347 + result = $.load(result);
  348 +
  349 + result = result('#productDesc');
  350 +
  351 + return (result.html() || '').replace(/<img src=/g, '<img class="lazy" src="data:image/gif;' +
  352 + 'base64,R0lGODlhAQABAJEAAAAAAP///93d3f///yH5BAEAAAMALAAAAAABAAEAAAICVAEAOw=="' +
  353 + ' data-original=').replace(/<img border="0" src=/g, '<img border="0" class="lazy" ' +
  354 + 'src="data:image/gif;base64,' +
  355 + 'R0lGODlhAQABAJEAAAAAAP///93d3f///yH5BAEAAAMALAAAAAABAAEAAAICVAEAOw=="' +
  356 + ' data-original=');
  357 + });
  358 +};
  359 +
342 module.exports = { 360 module.exports = {
343 - getintroData 361 + getintroData,
  362 + getintroIntro
344 }; 363 };
@@ -73,7 +73,7 @@ @@ -73,7 +73,7 @@
73 </div> 73 </div>
74 {{/if}} 74 {{/if}}
75 75
76 - {{#if studentCoinNum}} 76 + {{!-- {{#if studentCoinNum}}
77 <div class="price-date"> 77 <div class="price-date">
78 <div class="student-price"> 78 <div class="student-price">
79 <i class="student-name">返</i> 学生返币{{ studentCoinNum}}个 79 <i class="student-name">返</i> 学生返币{{ studentCoinNum}}个
@@ -87,7 +87,7 @@ @@ -87,7 +87,7 @@
87 </div> 87 </div>
88 </div> 88 </div>
89 {{/commodityReturn}} 89 {{/commodityReturn}}
90 - {{/if}} 90 + {{/if}} --}}
91 91
92 {{#unless studentPrice}} 92 {{#unless studentPrice}}
93 {{# vipLevel}} 93 {{# vipLevel}}
1 { 1 {
2 "name": "m-yohobuy-node", 2 "name": "m-yohobuy-node",
3 - "version": "4.9.24", 3 + "version": "4.9.26",
4 "private": true, 4 "private": true,
5 "description": "A New Yohobuy Project With Express", 5 "description": "A New Yohobuy Project With Express",
6 "repository": { 6 "repository": {
@@ -31,8 +31,9 @@ @@ -31,8 +31,9 @@
31 }, 31 },
32 "license": "MIT", 32 "license": "MIT",
33 "dependencies": { 33 "dependencies": {
34 - "bluebird": "^3.4.1", 34 + "bluebird": "^3.4.3",
35 "body-parser": "^1.15.2", 35 "body-parser": "^1.15.2",
  36 + "cheerio": "^0.22.0",
36 "connect-memcached": "^0.2.0", 37 "connect-memcached": "^0.2.0",
37 "cookie-parser": "^1.4.3", 38 "cookie-parser": "^1.4.3",
38 "express": "^4.14.0", 39 "express": "^4.14.0",
@@ -53,15 +54,15 @@ @@ -53,15 +54,15 @@
53 "serve-favicon": "^2.3.0", 54 "serve-favicon": "^2.3.0",
54 "uuid": "^2.0.2", 55 "uuid": "^2.0.2",
55 "winston": "^2.2.0", 56 "winston": "^2.2.0",
56 - "winston-daily-rotate-file": "^1.2.0",  
57 "yoho-express-session": "^1.14.1", 57 "yoho-express-session": "^1.14.1",
  58 + "winston-daily-rotate-file": "^1.3.0",
58 "yoho-node-lib": "0.0.49" 59 "yoho-node-lib": "0.0.49"
59 }, 60 },
60 "devDependencies": { 61 "devDependencies": {
61 "autoprefixer": "^6.3.7", 62 "autoprefixer": "^6.3.7",
62 "ava": "^0.16.0", 63 "ava": "^0.16.0",
63 - "babel-preset-es2015": "^6.9.0",  
64 - "babel-register": "^6.9.0", 64 + "babel-preset-es2015": "^6.14.0",
  65 + "babel-register": "^6.14.0",
65 "eslint": "^3.0.1", 66 "eslint": "^3.0.1",
66 "eslint-config-yoho": "^1.0.1", 67 "eslint-config-yoho": "^1.0.1",
67 "gulp": "^3.9.1", 68 "gulp": "^3.9.1",
@@ -71,11 +72,11 @@ @@ -71,11 +72,11 @@
71 "gulp-sourcemaps": "^2.0.0-alpha", 72 "gulp-sourcemaps": "^2.0.0-alpha",
72 "gulp-util": "^3.0.7", 73 "gulp-util": "^3.0.7",
73 "husky": "^0.11.4", 74 "husky": "^0.11.4",
74 - "nodemon": "^1.10.0", 75 + "nodemon": "^1.10.2",
75 "nyc": "^8.1.0", 76 "nyc": "^8.1.0",
76 "postcss-assets": "^4.0.1", 77 "postcss-assets": "^4.0.1",
77 "postcss-cachebuster": "^0.1.3", 78 "postcss-cachebuster": "^0.1.3",
78 - "postcss-calc": "^5.2.1", 79 + "postcss-calc": "^5.3.1",
79 "postcss-center": "^1.0.0", 80 "postcss-center": "^1.0.0",
80 "postcss-clearfix": "^1.0.0", 81 "postcss-clearfix": "^1.0.0",
81 "postcss-crip": "^2.0.0", 82 "postcss-crip": "^2.0.0",
@@ -89,8 +90,8 @@ @@ -89,8 +90,8 @@
89 "shelljs": "^0.7.0", 90 "shelljs": "^0.7.0",
90 "stylelint": "^7.1.0", 91 "stylelint": "^7.1.0",
91 "stylelint-config-yoho": "^1.2.7", 92 "stylelint-config-yoho": "^1.2.7",
92 - "webpack": "^1.13.1",  
93 - "webpack-dev-server": "^1.14.1", 93 + "webpack": "^1.13.2",
  94 + "webpack-dev-server": "^1.15.0",
94 "webpack-stream": "^3.1.0", 95 "webpack-stream": "^3.1.0",
95 "yoho-fastclick": "^1.0.6", 96 "yoho-fastclick": "^1.0.6",
96 "yoho-hammer": "^2.0.7", 97 "yoho-hammer": "^2.0.7",
  1 +/**
  2 + * 分类
  3 + * @author: xuqi<qi.xu@yoho.cn>
  4 + * @date: 2015/10/14
  5 + */
  6 +
  7 +var $ = require('yoho-jquery');
  8 +
  9 +var $nav = $('.category-nav'),
  10 + $categoryContainer = $('.category-container'),
  11 + $contents = $categoryContainer.children('.content'),
  12 + $subLevelItem = $categoryContainer.find('.sub-level li'),
  13 + $primaryItem = $categoryContainer.find('.primary-level li');
  14 +
  15 +require('../common');
  16 +
  17 +function resetHeight() {
  18 + var $header = $('.yoho-header'),
  19 + $search = $('#search-input');
  20 +
  21 + var h = document.body.scrollHeight - $header.outerHeight() - $search.outerHeight() - $nav.outerHeight();
  22 +
  23 + $categoryContainer.css('min-height', h);
  24 +
  25 + $contents.height(h);
  26 +}
  27 +resetHeight();
  28 +
  29 +$('#search-input').focus(function() {
  30 + $(this).blur();
  31 +});
  32 +$nav.on('contextmenu', function() {
  33 + return false;
  34 +});
  35 +$('.category-container').on('contextmenu', function() {
  36 + return false;
  37 +});
  38 +
  39 +$nav.on('touchend touchcancel', function(e) {
  40 + var $this = $(e.target).closest('li'),
  41 + selector = '.' + $this.data('channel');
  42 +
  43 + resetHeight();
  44 + if ($this.hasClass('focus')) {
  45 + return;
  46 + }
  47 +
  48 + $nav.find('li.focus').removeClass('focus');
  49 + $this.addClass('focus');
  50 +
  51 + $contents.addClass('hide');
  52 + $contents.filter(selector).removeClass('hide');
  53 +});
  54 +
  55 +$categoryContainer.on('touchend', function(e) {
  56 + var $this = $(e.target),
  57 + $subLevel,
  58 + $cur, index;
  59 +
  60 + $cur = $this.closest('.p-level-item');
  61 + if ($cur.length > 0) {
  62 + index = $cur.index();
  63 + $subLevel = $this.closest('.content').find('.sub-level');
  64 +
  65 + if ($this.hasClass('focus')) {
  66 + return;
  67 + }
  68 +
  69 + $this.closest('.primary-level').children('.focus').removeClass('focus');
  70 + $this.addClass('focus');
  71 +
  72 + $subLevel.not('.hide').addClass('hide');
  73 + $subLevel.eq(index).removeClass('hide');
  74 + }
  75 +});
  76 +
  77 +$categoryContainer.find('.primary-level').on('touchstart touchend touchcancel', 'li', function() {
  78 + $primaryItem.removeClass('highlight');
  79 + $(this).addClass('highlight');
  80 +}).on('touchend touchcancel', 'li', function() {
  81 + $(this).removeClass('highlight');
  82 +});
  83 +
  84 +$categoryContainer.find('.sub-level').on('touchstart', 'li', function() {
  85 + $subLevelItem.removeClass('highlight');
  86 + $(this).addClass('highlight');
  87 +}).on('touchend touchcancel', 'li', function() {
  88 + $(this).removeClass('highlight');
  89 +});
  90 +
  91 +$nav.on('touchstart', 'li', function() {
  92 + $nav.find('li').removeClass('bytouch');
  93 + $(this).addClass('bytouch');
  94 +}).on('touchend touchcancel', 'li', function() {
  95 + $nav.find('li').removeClass('bytouch');
  96 +});
@@ -25,15 +25,6 @@ function setDetailText() { @@ -25,15 +25,6 @@ function setDetailText() {
25 }); 25 });
26 } 26 }
27 27
28 -function setDefaultHeight() {  
29 - var $detailImg = $('.good-detail-img');  
30 -  
31 - $detailImg.css({  
32 - height: $detailImg.find('img').height() - 1,  
33 - background: '#c3c3c3'  
34 - });  
35 -}  
36 -  
37 setDetailText(); 28 setDetailText();
38 29
39 $('.detail-tab span').on('click', function() { 30 $('.detail-tab span').on('click', function() {
@@ -43,18 +34,9 @@ $('.detail-tab span').on('click', function() { @@ -43,18 +34,9 @@ $('.detail-tab span').on('click', function() {
43 if ($(this).index() === 1) { 34 if ($(this).index() === 1) {
44 setDetailText(); 35 setDetailText();
45 lazyLoad($('img.lazy')); 36 lazyLoad($('img.lazy'));
46 -  
47 - setTimeout(function() {  
48 - setDefaultHeight();  
49 - }, 2000);  
50 } 37 }
51 }); 38 });
52 39
53 -setTimeout(function() {  
54 - setDefaultHeight();  
55 -}, 2500);  
56 -  
57 -  
58 window.setCookie('installmentUid', window.queryString.uid); 40 window.setCookie('installmentUid', window.queryString.uid);
59 window.setCookie('udid', window.queryString.udid); 41 window.setCookie('udid', window.queryString.udid);
60 window.setCookie('clientType', window.queryString.client_type); 42 window.setCookie('clientType', window.queryString.client_type);
  1 +.category-page {
  2 + font-size: 30px;
  3 +
  4 + .search-input {
  5 + position: relative;
  6 + background-color: #f8f8f8;
  7 + padding: 13px 20px;
  8 +
  9 + p {
  10 + box-sizing: border-box;
  11 + width: 100%;
  12 + height: 60px;
  13 + line-height: 60px;
  14 + border: none;
  15 + padding-left: 66px;
  16 + border-radius: 60px;
  17 + font-size: 26px;
  18 + background: #fff;
  19 + color: #999;
  20 + }
  21 + }
  22 +
  23 + .search-icon {
  24 + position: absolute;
  25 + top: 0;
  26 + bottom: 0;
  27 + left: 43px;
  28 + line-height: 86px;
  29 + color: #999;
  30 + }
  31 +
  32 + .category-nav {
  33 + height: 70px;
  34 + border-bottom: 1px solid #e6e6e6;
  35 +
  36 + li {
  37 + display: block;
  38 + box-sizing: border-box;
  39 + float: left;
  40 + height: 100%;
  41 + padding: 20px 0;
  42 + width: 25%;
  43 + text-align: center;
  44 + color: #999;
  45 +
  46 + &:last-child {
  47 + border-right: none;
  48 + }
  49 +
  50 + &.focus {
  51 + color: #000;
  52 + }
  53 +
  54 + &.bytouch{
  55 + background:#eee;
  56 + }
  57 + }
  58 +
  59 +
  60 +
  61 + span {
  62 + display: block;
  63 + width: 100%;
  64 + height: 30px;
  65 + line-height: 30px;
  66 + font-size: 30px;
  67 + border-right: 1px solid #e6e6e6;
  68 + }
  69 +
  70 + li:last-child span {
  71 + border-right: 0;
  72 + }
  73 + }
  74 +
  75 + .content {
  76 + background: #f8f8f8;
  77 +
  78 + &.hide {
  79 + display: none;
  80 + }
  81 + }
  82 +
  83 + .primary-level {
  84 + float: left;
  85 + box-sizing: border-box;
  86 + width: 45%;
  87 +
  88 + > li {
  89 + height: 89px;
  90 + line-height: 89px;
  91 + padding: 0 32px;
  92 + white-space: nowrap;
  93 + overflow: hidden;
  94 + text-overflow: ellipsis;
  95 +
  96 + &.focus {
  97 + background-color: #fff;
  98 + }
  99 +
  100 + &.highlight {
  101 + background-color: #eee;
  102 + }
  103 + }
  104 + }
  105 +
  106 + .sub-level-container {
  107 + float: left;
  108 + box-sizing: border-box;
  109 + background: #fff;
  110 + width: 55%;
  111 + height: 100%;
  112 + }
  113 +
  114 + .sub-level {
  115 + width: 100%;
  116 +
  117 + &.hide {
  118 + display: none;
  119 + }
  120 +
  121 + > li {
  122 + box-sizing: border-box;
  123 + height: 89px;
  124 + line-height: 89px;
  125 + border-bottom: 1px solid #e6e6e6;
  126 + padding-left: 20px;
  127 +
  128 + &.highlight {
  129 + background: #eee;
  130 + }
  131 +
  132 + &:last-child {
  133 + border-bottom: none;
  134 + }
  135 + }
  136 +
  137 + a {
  138 + display: block;
  139 + height: 100%;
  140 + width: 100%;
  141 + color: #000;
  142 + }
  143 + }
  144 +}
@@ -22,6 +22,7 @@ @@ -22,6 +22,7 @@
22 @import "fresh-only"; 22 @import "fresh-only";
23 @import "discount-list"; 23 @import "discount-list";
24 @import "left-right"; 24 @import "left-right";
  25 +@import "cate";
25 @import "three-picture"; 26 @import "three-picture";
26 27
27 .mobile-container { 28 .mobile-container {
@@ -103,13 +103,9 @@ @@ -103,13 +103,9 @@
103 height: auto; 103 height: auto;
104 } 104 }
105 105
106 - .good-thumb {  
107 - width: 100%;  
108 - height: 100%;  
109 - }  
110 -  
111 .good-detail-img { 106 .good-detail-img {
112 height: auto; 107 height: auto;
  108 + background: #c3c3c3;
113 109
114 img { 110 img {
115 height: 100%; 111 height: 100%;
@@ -82,7 +82,7 @@ @@ -82,7 +82,7 @@
82 82
83 .title-box { 83 .title-box {
84 margin-left: 22px; 84 margin-left: 22px;
85 - width: 240px; 85 + width: 210px;
86 86
87 .product-name { 87 .product-name {
88 overflow: hidden; 88 overflow: hidden;
@@ -6,7 +6,12 @@ @@ -6,7 +6,12 @@
6 .service { 6 .service {
7 height: 28px; 7 height: 28px;
8 background: resolve("product/service.png") no-repeat; 8 background: resolve("product/service.png") no-repeat;
9 - background-size: cover; 9 + background-size: 100%;
  10 +
  11 + &.not-support-exchange {
  12 + background: resolve("product/not-support-exchange.png") no-repeat;
  13 + background-size: 100%;
  14 + }
10 } 15 }
11 16
12 .detail { 17 .detail {