Authored by yyq

Merge branch 'feature/newGolbal' into release/5.6

@@ -71,8 +71,6 @@ app.use(global.yoho.hbs({ @@ -71,8 +71,6 @@ app.use(global.yoho.hbs({
71 helpers: Object.assign(global.yoho.helpers, require('./utils/helpers')) 71 helpers: Object.assign(global.yoho.helpers, require('./utils/helpers'))
72 })); 72 }));
73 73
74 -app.use(global.yoho.middleware());  
75 -  
76 app.use(favicon(path.join(__dirname, '/favicon.ico'))); 74 app.use(favicon(path.join(__dirname, '/favicon.ico')));
77 app.use(express.static(path.join(__dirname, 'public'))); 75 app.use(express.static(path.join(__dirname, 'public')));
78 app.use(bodyParser.json()); 76 app.use(bodyParser.json());
@@ -24,7 +24,7 @@ const getBrandTopData = (contentCode) => { @@ -24,7 +24,7 @@ const getBrandTopData = (contentCode) => {
24 * @param int $channel 频道标识 1:男,2:女,3:潮童,4:创意生活 24 * @param int $channel 频道标识 1:男,2:女,3:潮童,4:创意生活
25 */ 25 */
26 const getBrandListData = channel => { 26 const getBrandListData = channel => {
27 - let params = {method: 'app.brand.brandlist'}; 27 + let params = {method: 'app.brand.allBrandList'};
28 28
29 if (!isNaN(channel)) { 29 if (!isNaN(channel)) {
30 params.yh_channel = channel; 30 params.yh_channel = channel;
@@ -31,6 +31,8 @@ const GIRLS = 'girls'; @@ -31,6 +31,8 @@ const GIRLS = 'girls';
31 const KIDS = 'kids'; 31 const KIDS = 'kids';
32 const LIFESTYLE = 'lifestyle'; 32 const LIFESTYLE = 'lifestyle';
33 33
  34 +const GLOBAL_BASE_URI = '/product/global/list';
  35 +
34 /** 36 /**
35 * 获取品牌一览资源位&channelType 37 * 获取品牌一览资源位&channelType
36 * 38 *
@@ -167,13 +169,14 @@ const getBrandViewList = (channel, start, length) => { @@ -167,13 +169,14 @@ const getBrandViewList = (channel, start, length) => {
167 } 169 }
168 170
169 // 品牌list A-Z 0-9 171 // 品牌list A-Z 0-9
170 - if (res.data && res.data.brands) { 172 + if (res.data && res.data.all_list) {
171 173
172 - _.forEach(res.data.brands, (subValue, key) => { 174 + _.forEach(res.data.all_list, (subValue, key) => {
173 let listTmp = []; 175 let listTmp = [];
174 176
175 _.forEach(subValue, ssubValue => { 177 _.forEach(subValue, ssubValue => {
176 let extQs = {}; 178 let extQs = {};
  179 + let baseUri = '';
177 180
178 // 为品牌名称 181 // 为品牌名称
179 let href; 182 let href;
@@ -183,22 +186,35 @@ const getBrandViewList = (channel, start, length) => { @@ -183,22 +186,35 @@ const getBrandViewList = (channel, start, length) => {
183 } else if (switchParams.channelType === 2) { 186 } else if (switchParams.channelType === 2) {
184 Object.assign(extQs, {gender: '2,3'}); 187 Object.assign(extQs, {gender: '2,3'});
185 } 188 }
  189 + let shopInfo, shopId;
186 190
187 switch (ssubValue.type * 1) { 191 switch (ssubValue.type * 1) {
188 case 1: 192 case 1:
189 - extQs = {query: ssubValue.brand_domain}; 193 + extQs = {
  194 + query: ssubValue.brand_domain,
  195 + brand: ssubValue.id
  196 + };
190 ssubValue.brand_domain = 'search'; 197 ssubValue.brand_domain = 'search';
191 break; 198 break;
192 case 2: 199 case 2:
193 - if (ssubValue.shop_id) {  
194 - Object.assign(extQs, {shopId: ssubValue.shop_id}); 200 + shopInfo = _.get(ssubValue, 'shop_info.yoho_shop_list[0]', {});
  201 + shopId = shopInfo.shop_id || ssubValue.shop_id;
  202 +
  203 + ssubValue.brand_domain = shopInfo.shop_domain || ssubValue.brand_domain;
  204 + if (shopId) {
  205 + Object.assign(extQs, {shopId: shopId});
195 } 206 }
196 break; 207 break;
  208 + case 3:
  209 + Object.assign(extQs, {brand: ssubValue.global_brand_id});
  210 + ssubValue.brand_domain = '';
  211 + baseUri = GLOBAL_BASE_URI;
  212 + break;
197 default: 213 default:
198 break; 214 break;
199 } 215 }
200 216
201 - href = helpers.urlFormat('', extQs, ssubValue.brand_domain); 217 + href = helpers.urlFormat(baseUri, extQs, ssubValue.brand_domain);
202 218
203 let brandItem = { 219 let brandItem = {
204 name: ssubValue.brand_name, 220 name: ssubValue.brand_name,
  1 +/**
  2 + * 商品促销controller
  3 + * @author: yyq<yanqing.yang@yoho.cn>
  4 + * @date: 2017/4/6
  5 + */
  6 +
  7 +'use strict';
  8 +
  9 +const mRoot = '../models';
  10 +const globalModel = require(`${mRoot}/global`); // global model
  11 +
  12 +/**
  13 + * 全球购列表页
  14 + * @param {[type]} req [description]
  15 + * @param {[type]} res [description]
  16 + * @return {[type]} [description]
  17 + */
  18 +exports.list = (req, res, next) => {
  19 + globalModel.getGlobalProductListData(req.query, req.yoho).then(result => {
  20 + res.render('list/index', Object.assign({
  21 + page: 'list',
  22 + pageClass: 'global-list-page'
  23 + }, result));
  24 + }).catch(next);
  25 +};
  26 +
  27 +/**
  28 + * 全球购商品详情页
  29 + * @param {[type]} req [description]
  30 + * @param {[type]} res [description]
  31 + * @return {[type]} [description]
  32 + */
  33 +exports.detail = (req, res, next) => {
  34 + globalModel.getGlobalProductDetailData(req.params[0], req.yoho.channelNum,
  35 + req.yoho.channel).then(result => {
  36 + res.render('global/detail', Object.assign({
  37 + page: 'detail'
  38 + }, result));
  39 + }).catch(next);
  40 +};
@@ -174,7 +174,6 @@ exports.newWithChannel = (req, res, next) => { @@ -174,7 +174,6 @@ exports.newWithChannel = (req, res, next) => {
174 exports.brand = (req, res, next) => { 174 exports.brand = (req, res, next) => {
175 let brandDomain = req.query.domain; 175 let brandDomain = req.query.domain;
176 let shopId = req.query.shopId; 176 let shopId = req.query.shopId;
177 - let resData = {};  
178 177
179 // shopId存在,直接走店铺 178 // shopId存在,直接走店铺
180 if (shopId) { 179 if (shopId) {
@@ -198,13 +197,11 @@ exports.brand = (req, res, next) => { @@ -198,13 +197,11 @@ exports.brand = (req, res, next) => {
198 case 2: // 店铺 197 case 2: // 店铺
199 return shop(brandInfo.shopId, req, res, next, brandInfo); 198 return shop(brandInfo.shopId, req, res, next, brandInfo);
200 default: // 品牌 199 default: // 品牌
201 - return list.getBrandData(req.query, Object.assign({uid: req.user.uid}, brandInfo),  
202 - req.yoho.channel).then(result => {  
203 - Object.assign(resData, result, {  
204 - page: 'list'  
205 - });  
206 - res.render('list/brand', resData);  
207 - }); 200 + res.redirect(helpers.urlFormat('', {
  201 + query: brandInfo.brandDomain,
  202 + brand: brandInfo.brandId
  203 + }, 'search'));
  204 + break;
208 } 205 }
209 }).catch(next); 206 }).catch(next);
210 }; 207 };
  1 +/**
  2 + * 全球购API
  3 + * @author: yyq<yanqing.yang@yoho.cn>
  4 + * @date: 2017/4/6
  5 + */
  6 +
  7 +'use strict';
  8 +
  9 +const globalApi = global.yoho.GlobalAPI;
  10 +const config = global.yoho.config;
  11 +
  12 +const getGlobalProductListAsync = (params, from) => {
  13 + let finalParams = {
  14 + limit: 60
  15 + };
  16 +
  17 + Object.assign(finalParams, params);
  18 +
  19 + if (from) {
  20 + finalParams.fromPage = from;
  21 + }
  22 +
  23 + return globalApi.get('product/api/v2/detail/getlist', finalParams, config.apiCache);
  24 +};
  25 +
  26 +const getGlobalProductDetailAsync = (skn, channelNum) => {
  27 + return globalApi.get('product/api/v2/detail/get', {
  28 + physical_channel: channelNum,
  29 + product_skn: skn,
  30 + client_type: 'iphone'
  31 + }, config.apiCache);
  32 +};
  33 +
  34 +const getGlobalProductHtmlAsync = (skn, channelNum) => {
  35 + return globalApi.get('product/api/v1/detail/gethtml', {
  36 + physical_channel: channelNum,
  37 + product_skn: skn,
  38 + return_type: 'html',
  39 + client_type: 'iphone'
  40 + }, config.apiCache);
  41 +};
  42 +
  43 +module.exports = {
  44 + getGlobalProductListAsync,
  45 + getGlobalProductDetailAsync,
  46 + getGlobalProductHtmlAsync
  47 +};
  1 +/**
  2 + * 商品促销 model
  3 + * @author: yyq<yanqing.yang@yoho.cn>
  4 + * @date: 2017/4/6
  5 + */
  6 +
  7 +'use strict';
  8 +
  9 +const _ = require('lodash');
  10 +
  11 +const helpers = global.yoho.helpers;
  12 +
  13 +const homeService = require('./home-service');
  14 +const globalApi = require('./global-api');
  15 +const headerModel = require('../../../doraemon/models/header');
  16 +const searchHandler = require('./search-handler');
  17 +const pager = require(`${global.utils}/pager`).setPager;
  18 +const productProcess = require(`${global.utils}/product-process`);
  19 +
  20 +const GLOBAL_LIST_URI = '/product/global/list';
  21 +
  22 +const _handelGlobalPathNav = (data, channel, page) => {
  23 + let rootName = '首页';
  24 +
  25 + if (channel && _.isString(channel)) {
  26 + rootName = `${channel.toUpperCase()}首页`;
  27 + }
  28 +
  29 + let pathNav = [{
  30 + href: channel === 'boys' ? '/' : helpers.urlFormat(`/${channel}/`),
  31 + name: rootName,
  32 + pathTitle: rootName
  33 + }, {
  34 + href: helpers.urlFormat(GLOBAL_LIST_URI),
  35 + name: '全球购',
  36 + pathTitle: '全球购'
  37 + }];
  38 +
  39 + if (data.sort) {
  40 + pathNav.push({
  41 + href: helpers.urlFormat(GLOBAL_LIST_URI, data.sort.params),
  42 + name: data.sort.name,
  43 + pathTitle: data.sort.name
  44 + });
  45 + }
  46 +
  47 + if (data.brand) {
  48 + pathNav.push({
  49 + name: data.brand.name,
  50 + pathTitle: data.brand.name
  51 + });
  52 + page = 'global-brand';
  53 + }
  54 +
  55 + return {
  56 + pathNav: pathNav,
  57 + listType: page
  58 + };
  59 +};
  60 +
  61 +const _checkSortEqual = (rp, params) => {
  62 + let status = true;
  63 +
  64 + _.forEach(rp, (value, key) => {
  65 + if (status && params[key] !== value) {
  66 + status = false;
  67 + }
  68 + });
  69 +
  70 + return status;
  71 +};
  72 +
  73 +const _handelGlobalSort = (origin, params, originParams) => {
  74 + let all = [{
  75 + name: '全部品类',
  76 + href: `${searchHandler.handleFilterUrl(params, {}, {msort: true, misort: true, sort: true})}`
  77 + }];
  78 + let list = [];
  79 + let selectSort = {};
  80 +
  81 + _.forEach(origin, value => {
  82 + let equalCategory = _checkSortEqual(value.relation_parameter, originParams);
  83 + let category = {
  84 + name: value.category_name,
  85 + num: value.node_count,
  86 + childList: [
  87 + {
  88 + name: `全部${value.category_name}`,
  89 + num: value.node_count,
  90 + href: `${searchHandler.handleFilterUrl(params, value.relation_parameter)}`,
  91 + childActive: _checkSortEqual(value.relation_parameter, originParams)
  92 + }
  93 + ]
  94 + };
  95 +
  96 + if (equalCategory) {
  97 + Object.assign(selectSort, {
  98 + name: value.category_name,
  99 + params: value.relation_parameter
  100 + });
  101 + }
  102 +
  103 + _.forEach(value.sub, subValue => {
  104 + let child = {
  105 + name: subValue.category_name,
  106 + num: subValue.node_count,
  107 + href: `${searchHandler.handleFilterUrl(params, subValue.relation_parameter)}`,
  108 + childActive: _checkSortEqual(subValue.relation_parameter, originParams)
  109 + };
  110 +
  111 + category.childList.push(child);
  112 +
  113 + if (child.childActive) {
  114 + category.active = true;
  115 + Object.assign(selectSort, {
  116 + name: subValue.category_name,
  117 + params: subValue.relation_parameter
  118 + });
  119 + }
  120 + });
  121 +
  122 + list.push(category);
  123 + });
  124 +
  125 + return {
  126 + allSort: {
  127 + all: all,
  128 + list: list
  129 + },
  130 + selectSort: selectSort
  131 + };
  132 +};
  133 +
  134 +const getGlobalProductListData = (params, yoho) => {
  135 + let dps = {};
  136 +
  137 + if (params.brand) {
  138 + dps.brand = params.brand;
  139 + }
  140 +
  141 + return Promise.props({
  142 + header: headerModel.requestHeaderData(yoho.channel),
  143 + fullList: globalApi.getGlobalProductListAsync({
  144 + physical_channel: yoho.channelNum,
  145 + limit: 1
  146 + }),
  147 + list: globalApi.getGlobalProductListAsync(Object.assign({
  148 + physical_channel: yoho.channelNum
  149 + }, params, {limit: params.limit ? params.limit - 1 : 59}))
  150 + }).then(result => {
  151 + let resData = {};
  152 +
  153 + Object.assign(resData, result.header);
  154 +
  155 + if (result.list.code === 200) {
  156 + let listData = _.get(result.list, 'data', {});
  157 + let totalNum = _.get(listData, 'total', 0);
  158 +
  159 + // opts 显示新品、折扣
  160 + listData.filter = listData.filter || {};
  161 + Object.assign(listData.filter, {
  162 + new: 'Y',
  163 + specialoffer: 'Y'
  164 + });
  165 +
  166 + resData.list = {
  167 + leftContent: _handelGlobalSort(_.get(result.fullList, 'data.filter.group_sort', []), dps, params),
  168 + filters: searchHandler.handleFilterDataAll(listData, params),
  169 + opts: searchHandler.handleOptsData(params, totalNum, listData.filter),
  170 + totalCount: totalNum,
  171 + footPager: pager(_.get(listData, 'page_total', 0), params),
  172 + goods: productProcess.processProductList(_.get(listData, 'product_list', []),
  173 + Object.assign({showDiscount: false, isGlobal: true}, params)),
  174 + hasNextPage: searchHandler.handleNextPage(params, totalNum),
  175 + latestWalk: 6 // 最近浏览记录
  176 + };
  177 +
  178 + if (resData.list.filters && resData.list.filters.brand) {
  179 + _.set(resData.list, 'filters.brand.showAllBrands', true); // 设置首次展示品牌筛选所有品牌
  180 + }
  181 +
  182 + // pathNav brand
  183 + let pathInfo = {};
  184 +
  185 + if (dps.brand) {
  186 + let bandInfo = _.find(_.get(result.fullList, 'data.filter.brand', []), o => {
  187 + return o.id * 1 === dps.brand * 1;
  188 + });
  189 +
  190 + if (bandInfo) {
  191 + pathInfo.brand = {
  192 + name: bandInfo.brand_name
  193 + };
  194 + }
  195 + }
  196 +
  197 + // psthNav sort
  198 + let selectedSort = _.get(resData.list, 'leftContent.selectSort', {});
  199 +
  200 + if (!_.isEmpty(selectedSort)) {
  201 + pathInfo.sort = selectedSort;
  202 + }
  203 +
  204 + Object.assign(resData.list, _handelGlobalPathNav(pathInfo, yoho.channel, 'global-list'));
  205 + }
  206 +
  207 + return resData;
  208 + });
  209 +};
  210 +
  211 +const getGlobalProductDetailData = (skn, channelNum, channel) => {
  212 + return Promise.props({
  213 + header: headerModel.requestHeaderData(channel),
  214 + detail: globalApi.getGlobalProductDetailAsync(skn, channelNum),
  215 + html: globalApi.getGlobalProductHtmlAsync(skn, channelNum)
  216 + }).then(result => {
  217 + let resData = {};
  218 + let detailInfo, html = '';
  219 +
  220 + if (+result.detail.code === 200) {
  221 + detailInfo = _.get(result, 'detail.data', {});
  222 +
  223 + let brandInfo = detailInfo.brand_info || {};
  224 +
  225 + resData.banner = {
  226 + bgColor: '#000',
  227 + homeUrl: helpers.urlFormat(GLOBAL_LIST_URI, {brand: brandInfo.brand_id}),
  228 + brandName: brandInfo.brand_name,
  229 + logo: brandInfo.brand_ico
  230 + };
  231 +
  232 + resData.pathNav = _.concat(
  233 + homeService.getHomeChannelNav(channel),
  234 + [
  235 + {name: '全球购', href: helpers.urlFormat(GLOBAL_LIST_URI)},
  236 + {name: detailInfo.product_name || ''}
  237 + ]
  238 + );
  239 +
  240 + if (detailInfo.orign_price - detailInfo.final_price === 0) {
  241 + _.unset(detailInfo, 'formart_orign_price');
  242 + } else {
  243 + detailInfo.promotion = ((detailInfo.final_price / detailInfo.orign_price) * 10).toFixed(1);
  244 +
  245 + // 只显示大于1折小于9折的折扣
  246 + if (detailInfo.promotion <= 1.0 || detailInfo.promotion >= 9.0) {
  247 + detailInfo.promotion = false;
  248 + }
  249 + }
  250 +
  251 + if (detailInfo.market_price - detailInfo.sales_price === 0) {
  252 + _.unset(detailInfo, 'format_market_price');
  253 + }
  254 +
  255 + if (!_.isEmpty(detailInfo.goods_list)) {
  256 + let colors = [];
  257 +
  258 + _.forEach(detailInfo.goods_list, (value, index) => {
  259 + let size = [];
  260 +
  261 +
  262 + _.forEach(value.size_list || [], subVal => {
  263 + size.push({
  264 + sku: subVal.product_sku,
  265 + name: subVal.size_name,
  266 + soldOut: subVal.storage_number * 1 <= 0
  267 + });
  268 + });
  269 +
  270 +
  271 + if (_.isEmpty(value.images_list)) {
  272 + value.images_list = [{
  273 + image_url: value.color_image
  274 + }];
  275 + }
  276 +
  277 + if (index === 0 && !detailInfo.mainThumb) {
  278 + value.focus = true;
  279 + detailInfo.mainThumb = _.get(value, 'images_list[0].image_url', value.color_image);
  280 + }
  281 +
  282 + colors.push({
  283 + src: value.color_image,
  284 + name: value.color_name,
  285 + title: value.color_name,
  286 + imgList: value.images_list,
  287 + focus: value.focus,
  288 + size: size
  289 + });
  290 + });
  291 +
  292 + detailInfo.colors = colors;
  293 + }
  294 + }
  295 +
  296 + if (result.html && !_.get(result.html, 'code', '')) {
  297 + let regContent = /<body[^>]*>([\s\S]*)<\/body>/.exec(result.html);
  298 +
  299 + html = regContent[1] || '';
  300 + html = html.replace(/<script.*?>.*?<\/script>/ig, '');
  301 + }
  302 +
  303 + Object.assign(resData, result.header, {
  304 + goodsInfo: detailInfo,
  305 + detailHtml: html || ''
  306 + });
  307 +
  308 + return resData;
  309 + });
  310 +};
  311 +
  312 +module.exports = {
  313 + getGlobalProductListData,
  314 + getGlobalProductDetailData
  315 +};
@@ -26,6 +26,8 @@ const isFavoriteBrandUrl = '/shops/service/v1/favorite/getUidBrandFav'; @@ -26,6 +26,8 @@ const isFavoriteBrandUrl = '/shops/service/v1/favorite/getUidBrandFav';
26 // 根据品牌查询相关文章 26 // 根据品牌查询相关文章
27 const relateArticleUrl = 'guang/service/v2/article/getArticleByBrand'; 27 const relateArticleUrl = 'guang/service/v2/article/getArticleByBrand';
28 28
  29 +const GLOBAL_BASE_URI = '/product/global/list';
  30 +
29 // 缓存生效时间 31 // 缓存生效时间
30 const CACHE_TIME_S = 60; 32 const CACHE_TIME_S = 60;
31 33
@@ -287,7 +289,7 @@ const getBrandCouponAsync = (brandId, uid) => { @@ -287,7 +289,7 @@ const getBrandCouponAsync = (brandId, uid) => {
287 */ 289 */
288 const getBrandShop = (query) => { 290 const getBrandShop = (query) => {
289 let finalParams = { 291 let finalParams = {
290 - method: 'web.search.shopNewInfo' 292 + method: 'web.search.shopListInfo'
291 }; 293 };
292 294
293 return api.get('', Object.assign(finalParams, {keyword: query}), config.apiCache); 295 return api.get('', Object.assign(finalParams, {keyword: query}), config.apiCache);
@@ -302,32 +304,42 @@ const getShopList = params => { @@ -302,32 +304,42 @@ const getShopList = params => {
302 } 304 }
303 305
304 return getBrandShop(params.query).then(shops => { 306 return getBrandShop(params.query).then(shops => {
305 - let shopEntry = {},  
306 - sort = _.get(shops, 'data.sortInfo.sort', {}),  
307 - shopInfo = _.get(shops, 'data.shopBrandInfo.shopInfo', {}) ||  
308 - _.get(shops, 'data.shopBrandInfo.brandInfo', {});  
309 -  
310 - if (_.isEmpty(shopInfo)) {  
311 - return;  
312 - }  
313 -  
314 - shopEntry = {  
315 - home: helpers.urlFormat('', '', shopInfo.shop_domain || shopInfo.brand_domain),  
316 - logo: shopInfo.shop_logo || shopInfo.brand_ico,  
317 - shopName: shopInfo.shop_name || shopInfo.brand_name,  
318 - sort: []  
319 - };  
320 -  
321 - // 店铺/品牌的小分类  
322 - _.forEach(sort, (sortInfo) => {  
323 - _.forEach(_.get(sortInfo, 'sub', []), (subSort) => {  
324 - shopEntry.sort.push({  
325 - href: helpers.urlFormat('', {misort: subSort.sort_id},  
326 - shopInfo.shop_domain || shopInfo.brand_domain),  
327 - name: subSort.sort_name 307 + let shopEntry = [];
  308 +
  309 + _.forEach(_.get(shops, 'data.shopList', []), value => {
  310 + let shopInfo = {
  311 + home: helpers.urlFormat('', null, value.shop_domain || value.brand_domain),
  312 + logo: value.shop_logo || value.brand_ico,
  313 + shopName: value.shop_name || value.brand_name,
  314 + sort: []
  315 + };
  316 +
  317 + if (value.is_global === 'Y') {
  318 + shopInfo.home = helpers.urlFormat(GLOBAL_BASE_URI, {brand: value.global_brand_id});
  319 + }
  320 +
  321 + // 店铺/品牌的小分类
  322 + _.forEach(value.sort, sortInfo => {
  323 + _.forEach(_.get(sortInfo, 'sub', []), subSort => {
  324 + let sortHref;
  325 +
  326 + if (value.is_global === 'Y') {
  327 + sortHref = helpers.urlFormat('', {misort: subSort.sort_id},
  328 + value.shop_domain || value.brand_domain);
  329 + } else {
  330 + sortHref = helpers.urlFormat(GLOBAL_BASE_URI, {
  331 + misort: subSort.sort_id,
  332 + brand: value.global_brand_id
  333 + });
  334 + }
  335 + shopInfo.sort.push({
  336 + href: sortHref,
  337 + name: subSort.sort_name
  338 + });
328 }); 339 });
329 }); 340 });
330 341
  342 + shopEntry.push(shopInfo);
331 }); 343 });
332 344
333 return shopEntry; 345 return shopEntry;
@@ -647,7 +647,9 @@ exports.handleFilterData = (origin, params, total) => { @@ -647,7 +647,9 @@ exports.handleFilterData = (origin, params, total) => {
647 } 647 }
648 }; 648 };
649 649
650 - dest.brand = formatterFilterBrands(origin.brand, origin.paramBrand, params); 650 + if (origin.brand) {
  651 + dest.brand = formatterFilterBrands(origin.brand, origin.paramBrand, params);
  652 + }
651 653
652 // 处理价格筛选数据 654 // 处理价格筛选数据
653 let priceRangechecked = false; 655 let priceRangechecked = false;
@@ -751,6 +753,8 @@ exports.handleFilterData = (origin, params, total) => { @@ -751,6 +753,8 @@ exports.handleFilterData = (origin, params, total) => {
751 // 处理颜色筛选数据 753 // 处理颜色筛选数据
752 if (!_.isEmpty(origin.color)) { 754 if (!_.isEmpty(origin.color)) {
753 _.forEach(origin.color, (value) => { 755 _.forEach(origin.color, (value) => {
  756 + value.color_code = value.color_code.replace(/#/ig, '');
  757 +
754 let color = { 758 let color = {
755 checked: parseInt(params.color, 10) === parseInt(value.color_id, 10), 759 checked: parseInt(params.color, 10) === parseInt(value.color_id, 10),
756 href: handleFilterUrl(params, {color: value.color_id}), 760 href: handleFilterUrl(params, {color: value.color_id}),
@@ -817,7 +821,7 @@ exports.handleFilterData = (origin, params, total) => { @@ -817,7 +821,7 @@ exports.handleFilterData = (origin, params, total) => {
817 handleCheckedData(params, dest.gender, 'gender')); 821 handleCheckedData(params, dest.gender, 'gender'));
818 822
819 // 处理品牌筛选数据 823 // 处理品牌筛选数据
820 - if (dest.brand.brandsShow) { 824 + if (dest.brand && dest.brand.brandsShow) {
821 825
822 dest.checkedConditions.conditions = _.union(dest.checkedConditions.conditions, 826 dest.checkedConditions.conditions = _.union(dest.checkedConditions.conditions,
823 handleBrandCheckedData(params, dest.brand.selectedBrands)); 827 handleBrandCheckedData(params, dest.brand.selectedBrands));
@@ -1364,10 +1368,9 @@ exports.handleFilterUrl = handleFilterUrl; @@ -1364,10 +1368,9 @@ exports.handleFilterUrl = handleFilterUrl;
1364 exports.handleCheckedData = handleCheckedData; 1368 exports.handleCheckedData = handleCheckedData;
1365 1369
1366 exports.handleNextPage = (params, total) => { 1370 exports.handleNextPage = (params, total) => {
1367 -  
1368 let href; 1371 let href;
1369 - let currentPage = parseInt((_.isEmpty(params.page) ? 1 : params.page), 10); // 当前页  
1370 - let perPageCount = parseInt((_.isEmpty(params.limit) ? 60 : params.limit) - 1, 10); // 每页商品数 1372 + let currentPage = parseInt((params.page ? params.page : 1), 10); // 当前页
  1373 + let perPageCount = parseInt((params.limit ? params.limit : 60) - 1, 10); // 每页商品数
1371 let totalPage = _.ceil(total / perPageCount); // 总页数 1374 let totalPage = _.ceil(total / perPageCount); // 总页数
1372 1375
1373 if (currentPage >= totalPage) { 1376 if (currentPage >= totalPage) {
@@ -44,6 +44,9 @@ const students = require(`${cRoot}/students`); @@ -44,6 +44,9 @@ const students = require(`${cRoot}/students`);
44 // 新品到着controller 44 // 新品到着controller
45 const newArrive = require(`${cRoot}/newArrive`); 45 const newArrive = require(`${cRoot}/newArrive`);
46 46
  47 +// 全球购controller
  48 +const globalCtrl = require(`${cRoot}/global`);
  49 +
47 // 商品促销routers 50 // 商品促销routers
48 router.get('/sale', sale.index); // sale 首页 51 router.get('/sale', sale.index); // sale 首页
49 router.get(/\/(.*)-sale/, sale.index); // sale 首页(SEO改造) 52 router.get(/\/(.*)-sale/, sale.index); // sale 首页(SEO改造)
@@ -83,6 +86,13 @@ router.get('/detail/notify/status', auth, notify.show); // åˆ°è´ @@ -83,6 +86,13 @@ router.get('/detail/notify/status', auth, notify.show); // 到è´
83 router.post('/detail/notify/add', auth, notify.add); // 增加到货通知 86 router.post('/detail/notify/add', auth, notify.add); // 增加到货通知
84 router.post('/detail/notify/cancel', auth, notify.cancel); // 删除到货通知 87 router.post('/detail/notify/cancel', auth, notify.cancel); // 删除到货通知
85 88
  89 +// 全球购routers
  90 +router.get('/global/list', globalCtrl.list); // 全球购列表页
  91 +router.get('/global/detail', globalCtrl.detail);
  92 +router.get(/\/global\/([\d]+)(.*)/, globalCtrl.detail);
  93 +
  94 +// router.get(/\/global\/([\d]+)(.*)/, globalCtrl.detail); // 全球购商品详情页
  95 +
86 // 搜索 96 // 搜索
87 router.get('/search/index', gbk2utf, search.index); 97 router.get('/search/index', gbk2utf, search.index);
88 router.get('/search/filter/brands', search.searchFilterBrands); 98 router.get('/search/filter/brands', search.searchFilterBrands);
  1 +<div class="global-detail-page product-detail-page yoho-page">
  2 + {{>product/brand-banner}}
  3 +
  4 + <div class="center-content">
  5 + {{> common/path-nav}}
  6 +
  7 + <div class="main clearfix">
  8 + {{# goodsInfo}}
  9 + <div class="pull-left imgs clearfix">
  10 + <div class="pull-left img">
  11 + <div class="tags clearfix">
  12 + <span class="good-tag global-tag">{{country_name}}</span>
  13 + </div>
  14 +
  15 + <div id="min-img">
  16 + <img id="img-show" class="img-show" src="{{image2 mainThumb w=420 h=560}}">
  17 + <div class="magnifier move-object hide"></div>
  18 + <div class="magnifier move-over"></div>
  19 + <div id="max" class="magnifier max hide">
  20 + <img id='big' src="{{image2 mainThumb w=750 h=1000}}">
  21 + </div>
  22 + </div>
  23 +
  24 + <div class="share-row">
  25 + <span class="title pull-left">分享:</span> {{> common/share }}
  26 + </div>
  27 + </div>
  28 + <div id="thumbs" class="pull-right thumbs">
  29 + {{# goods_list}}
  30 + <div class="thumb-wrap{{#unless focus}} hide{{/unless}}">
  31 + {{#if focus}}
  32 + {{# images_list}}
  33 + <img class="thumb {{#if @first}}active{{/if}}" src="{{image2 image_url w=75 h=100}}"
  34 + data-shower="{{image2 image_url w=420 h=560}}"
  35 + data-origin="{{image2 image_url w=750 h=1000}}">
  36 + {{/ images_list}}
  37 + {{^}}
  38 + {{# images_list}}
  39 + <img class="thumb lazy"
  40 + data-original="{{image2 image_url w=75 h=100}}"
  41 + data-shower="{{image2 image_url w=420 h=560}}"
  42 + data-origin="{{image2 image_url w=750 h=1000}}">
  43 + {{/ images_list}}
  44 + {{/if}}
  45 + </div>
  46 + {{/ goods_list}}
  47 + </div>
  48 + </div>
  49 + <div class="pull-right infos">
  50 + <h1 class="name">{{product_name}}</h1>
  51 +
  52 + <div class="line"></div>
  53 +
  54 + <p class="market-price">
  55 + {{# formart_orign_price}}
  56 + <span class="price-row">
  57 + <span class="title"><s></s>价:</span>
  58 + <span class="price has-other-price">{{.}}</span>
  59 + </span><br>
  60 + {{/ formart_orign_price}}
  61 + {{# formart_final_price}}
  62 + <span class="price-row">
  63 + <span class="title">当前价:</span>
  64 + <span class="price">{{.}}</span>
  65 + </span>
  66 + {{/ formart_final_price}}
  67 + {{#if promotion}}
  68 + <span class="desc">
  69 + <span class="promotion">{{promotion}}</span>
  70 + </span>
  71 + {{/if}}
  72 +
  73 + </p>
  74 + <p class="foreign-price">
  75 + {{# format_market_price}}
  76 + <span class="title">原 价:</span>
  77 + <span class="price">{{.}}</span>
  78 + {{/ format_market_price}}
  79 + {{# format_sales_price}}
  80 + <span class="title">当前价:</span>
  81 + <span class="price">{{.}}</span>
  82 + {{/ format_sales_price}}
  83 + </p>
  84 +
  85 +
  86 + <div class="line"></div>
  87 +
  88 + <div class="trade-content">
  89 + <div id="type-chose" class="type-chose">
  90 + {{> product/color-list}}
  91 + {{> product/size-list}}
  92 +
  93 + <div class="chose-count row clearfix">
  94 + <span class="title pull-left">&nbsp;&nbsp;量:</span>
  95 + <div class="num-wraper pull-left clearfix">
  96 + {{> product/num}}
  97 + </div>
  98 + </div>
  99 +
  100 + <div class="line"></div>
  101 +
  102 + <span id="code-buy" class="code-buy" skn="{{product_skn}}">
  103 + <i class="iconfont">&#xe703;</i>
  104 + <em>扫一扫购买</em>
  105 + <div class="code-box">
  106 + <div id="qrcode-img" class="code-img" data-url='http://union.yoho.cn/union/app-downloads.html?openby:yohobuy={"action":"go.globalpurchase","params":{"skn":"{{product_skn}}"}}'></div>
  107 + </div>
  108 + </span>
  109 +
  110 + </div>
  111 + </div>
  112 +
  113 + <div class="extra-tip">
  114 + <a href="#">全球购物须知</a>
  115 +
  116 + <ul class="global-buy-tips">
  117 + {{# illustrate_contents}}
  118 + <li>
  119 + {{title}} >
  120 + <div class="hover-tip">{{content}}</div>
  121 + </li>
  122 + {{/ illustrate_contents}}
  123 + </ul>
  124 + </div>
  125 + </div>
  126 + {{/ goodsInfo}}
  127 + </div>
  128 + <div class="global-detail-wrap">{{{detailHtml}}}</div>
  129 + </div>
  130 +</div>
1 -<div class="product-page yoho-page product-list-page"> 1 +<div class="product-page yoho-page product-list-page {{pageClass}}">
2 {{#if hideInfo}} 2 {{#if hideInfo}}
3 <div id="page-hide-info"{{#each hideInfo}} data-{{@key}}="{{.}}"{{/each}}></div> 3 <div id="page-hide-info"{{#each hideInfo}} data-{{@key}}="{{.}}"{{/each}}></div>
4 {{/if}} 4 {{/if}}
@@ -10,10 +10,12 @@ @@ -10,10 +10,12 @@
10 <a class="home" href="{{homeUrl}}" title="{{brandName}}"> 10 <a class="home" href="{{homeUrl}}" title="{{brandName}}">
11 <span class="iconfont">&#xe61a;</span> 11 <span class="iconfont">&#xe61a;</span>
12 </a> 12 </a>
13 - <span id="brand-favour" class="brand-fav{{#if isCollect}} coled{{/if}}" data-id="{{brandId}}">  
14 - <i class="iconfont">&#xe641;</i>  
15 - <span class="fav-num"></span>  
16 - </span> 13 + {{#if brandId}}
  14 + <span id="brand-favour" class="brand-fav{{#if isCollect}} coled{{/if}}" data-id="{{brandId}}">
  15 + <i class="iconfont">&#xe641;</i>
  16 + <span class="fav-num"></span>
  17 + </span>
  18 + {{/if}}
17 </div> 19 </div>
18 </div> 20 </div>
19 {{/if}} 21 {{/if}}
@@ -74,3 +74,4 @@ @@ -74,3 +74,4 @@
74 <span class="date">{{arrivalDate}}</span> 74 <span class="date">{{arrivalDate}}</span>
75 </div> 75 </div>
76 {{/if}} 76 {{/if}}
  77 +</p>
@@ -21,12 +21,14 @@ module.exports = { @@ -21,12 +21,14 @@ module.exports = {
21 api: 'http://api-test3.yohops.com:9999/', 21 api: 'http://api-test3.yohops.com:9999/',
22 service: 'http://service-test3.yohops.com:9999/', 22 service: 'http://service-test3.yohops.com:9999/',
23 serviceNotify: 'http://service-test3.yohops.com:9999/', 23 serviceNotify: 'http://service-test3.yohops.com:9999/',
  24 + global: 'http://global-test-soa.yohops.com:9999/',
24 25
25 // prod 26 // prod
26 // singleApi: 'http://single.yoho.cn/', 27 // singleApi: 'http://single.yoho.cn/',
27 // api: 'http://api.yoho.cn/', 28 // api: 'http://api.yoho.cn/',
28 // service: 'http://service.yoho.cn/', 29 // service: 'http://service.yoho.cn/',
29 // serviceNotify: 'http://service.yoho.cn/', 30 // serviceNotify: 'http://service.yoho.cn/',
  31 + // global: 'http://api-global.yohobuy.com/',
30 32
31 // gray 33 // gray
32 // singleApi: 'http://single.gray.yohops.com/', 34 // singleApi: 'http://single.gray.yohops.com/',
@@ -139,6 +141,7 @@ if (isProduction) { @@ -139,6 +141,7 @@ if (isProduction) {
139 api: 'http://api.yoho.yohoops.org/', 141 api: 'http://api.yoho.yohoops.org/',
140 service: 'http://service.yoho.yohoops.org/', 142 service: 'http://service.yoho.yohoops.org/',
141 search: 'http://search.yohoops.org/yohosearch/', 143 search: 'http://search.yohoops.org/yohosearch/',
  144 + global: 'http://api-global.yohobuy.com/product/',
142 serviceNotify: 'http://service.yoho.cn/', 145 serviceNotify: 'http://service.yoho.cn/',
143 imSocket: 'ws://imsocket.yohobuy.com:10000', 146 imSocket: 'ws://imsocket.yohobuy.com:10000',
144 imCs: 'https://imhttp.yohobuy.com/api', 147 imCs: 'https://imhttp.yohobuy.com/api',
@@ -170,6 +173,7 @@ if (isProduction) { @@ -170,6 +173,7 @@ if (isProduction) {
170 singleApi: process.env.TEST_API || 'http://192.168.102.31:8092/brower', 173 singleApi: process.env.TEST_API || 'http://192.168.102.31:8092/brower',
171 api: process.env.TEST_API || 'http://testapi.yoho.cn:28078/', 174 api: process.env.TEST_API || 'http://testapi.yoho.cn:28078/',
172 service: process.env.TEST_SERVICE || 'http://testservice.yoho.cn:28077/', 175 service: process.env.TEST_SERVICE || 'http://testservice.yoho.cn:28077/',
  176 + global: process.env.TEST_GOLBAL || 'http://global-test-soa.yohops.com:9999/',
173 search: process.env.TEST_SEARCH || 'http://192.168.102.216:8080/yohosearch/', 177 search: process.env.TEST_SEARCH || 'http://192.168.102.216:8080/yohosearch/',
174 serviceNotify: process.env.TEST_SERVICE || 'http://testservice.yoho.cn:28077/', 178 serviceNotify: process.env.TEST_SERVICE || 'http://testservice.yoho.cn:28077/',
175 imSocket: 'ws://socket.yohobuy.com:10240', 179 imSocket: 'ws://socket.yohobuy.com:10240',
@@ -6,7 +6,11 @@ @@ -6,7 +6,11 @@
6 {{#each pathNav}} 6 {{#each pathNav}}
7 {{#if name}} 7 {{#if name}}
8 {{#if href}} 8 {{#if href}}
9 - <a {{#if @last}}class="last"{{/if}} href="{{href}}" title="{{pathTitle}}">{{{name}}}</a> 9 + {{#if @last}}
  10 + <span class="last" title="{{pathTitle}}">{{{name}}}</span>
  11 + {{^}}
  12 + <a href="{{href}}" title="{{pathTitle}}">{{{name}}}</a>
  13 + {{/if}}
10 {{^}} 14 {{^}}
11 <span {{#if @last}}class="last"{{/if}} title="{{pathTitle}}">{{{name}}}</span> 15 <span {{#if @last}}class="last"{{/if}} title="{{pathTitle}}">{{{name}}}</span>
12 {{/if}} 16 {{/if}}
@@ -122,7 +122,11 @@ @@ -122,7 +122,11 @@
122 <span id="brand-multi" class="multi-select">多选 +</span> 122 <span id="brand-multi" class="multi-select">多选 +</span>
123 {{/if}} 123 {{/if}}
124 </div> 124 </div>
125 - <div data-role="all-brand"></div> 125 + <div data-role="all-brand">
  126 + {{#if showAllBrands}}
  127 + {{> product/filter-brands-sync}}
  128 + {{/if}}
  129 + </div>
126 </div> 130 </div>
127 </div> 131 </div>
128 {{/ brand}} 132 {{/ brand}}
  1 +<div class="brand-panel hide">
  2 + <div class="panel-head clearfix">
  3 + <p class="brands-index">
  4 + {{#each brandIndex}}
  5 + <span data-index="{{index}}">{{name}}</span>
  6 + {{/each}}
  7 + </p>
  8 +
  9 + <div class="brand-search">
  10 + <input id="brand-search-input" type="text">
  11 + <span class="btn">
  12 + <i class="iconfont">&#xe60f;</i>
  13 + </span>
  14 + </div>
  15 + </div>
  16 +
  17 + <div class="panel-body">
  18 + <div class="ul-scroll">
  19 + <ul class="check-container clearfix">
  20 + {{# brandsShow}}
  21 + <li class="attr {{#if checked}}checked{{/if}}" data-index="{{index}}" data-key="{{key}}">
  22 + <a href="{{href}}">
  23 + <span class="iconfont checkbox {{#if checked}}checked{{/if}}" data-id="{{id}}">
  24 + {{#if checked}}
  25 + &#xe613;
  26 + {{else}}
  27 + &#xe612;
  28 + {{/if}}
  29 + </span>
  30 + <span title="{{name}}">{{name}}</span>
  31 + </a>
  32 + </li>
  33 + {{/ brandsShow}}
  34 + </ul>
  35 + </div>
  36 + </div>
  37 +
  38 + <div class="btns">
  39 + <button id="brand-multi-ok" class="multi-select-ok dis">确定</button>
  40 + <button class="multi-select-cancel">取消</button>
  41 + </div>
  42 +</div>
@@ -5,6 +5,9 @@ @@ -5,6 +5,9 @@
5 <span class="hide shelve-time">{{shelve_time}}</span> 5 <span class="hide shelve-time">{{shelve_time}}</span>
6 <div class="tag-container clearfix"> 6 <div class="tag-container clearfix">
7 {{# tags}} 7 {{# tags}}
  8 + {{#if is_global}}
  9 + <span class="good-tag global-tag">{{name}}</span>
  10 + {{/if}}
8 {{# is_new_festival}} 11 {{# is_new_festival}}
9 <span class="good-tag new-festival-tag">新品节</span> 12 <span class="good-tag new-festival-tag">新品节</span>
10 {{/ is_new_festival}} 13 {{/ is_new_festival}}
@@ -49,7 +49,7 @@ @@ -49,7 +49,7 @@
49 "urlencode": "^1.1.0", 49 "urlencode": "^1.1.0",
50 "uuid": "^2.0.2", 50 "uuid": "^2.0.2",
51 "yoho-express-session": "^2.0.0", 51 "yoho-express-session": "^2.0.0",
52 - "yoho-node-lib": "0.2.11", 52 + "yoho-node-lib": "0.2.14",
53 "yoho-zookeeper": "^1.0.8" 53 "yoho-zookeeper": "^1.0.8"
54 }, 54 },
55 "devDependencies": { 55 "devDependencies": {

7.35 KB | W: | H:

7.66 KB | W: | H:

  • 2-up
  • Swipe
  • Onion skin

1.96 KB | W: | H:

3.76 KB | W: | H:

  • 2-up
  • Swipe
  • Onion skin
@@ -162,7 +162,6 @@ if ($brandMore.length > 0) { @@ -162,7 +162,6 @@ if ($brandMore.length > 0) {
162 162
163 // 【品牌】加载更多品牌数据 163 // 【品牌】加载更多品牌数据
164 function checkMoreBrands(callback) { 164 function checkMoreBrands(callback) {
165 -  
166 var squery = window.location.search; 165 var squery = window.location.search;
167 166
168 // /product/search/filter/brands?callback=? 167 // /product/search/filter/brands?callback=?
@@ -170,6 +169,17 @@ function checkMoreBrands(callback) { @@ -170,6 +169,17 @@ function checkMoreBrands(callback) {
170 var brandsHtml; 169 var brandsHtml;
171 var params = (location.search || '').substr(1); 170 var params = (location.search || '').substr(1);
172 171
  172 + // 直出brands list取消异步加载,目前只用于5.6全球购商品列表
  173 + if (!moreBrandLoaded && $filterBrands.find('.brand-panel').length) {
  174 + moreBrandLoaded = true;
  175 +
  176 + // init brand vars
  177 + $brandInput = $filterBrands.find('#brand-search-input');
  178 + $brandPanel = $filterBrands.find('.brand-panel');
  179 + $brandAttrs = $brandPanel.find('.attr');
  180 + $brandsIndex = $('.brands-index');
  181 + }
  182 +
173 if (squery && squery.length > 0) { 183 if (squery && squery.length > 0) {
174 url += squery + '&callback=?'; 184 url += squery + '&callback=?';
175 } else { 185 } else {
@@ -121,6 +121,21 @@ @@ -121,6 +121,21 @@
121 } 121 }
122 } 122 }
123 123
  124 + .global-tag {
  125 + background-color: #482d3d;
  126 + font-weight: 300;
  127 +
  128 + &:before {
  129 + content: "";
  130 + width: 16px;
  131 + height: 14px;
  132 + margin-right: 2px;
  133 + background-image: url("/product/airplane-tag.png");
  134 + display: inline-block;
  135 + vertical-align: sub;
  136 + }
  137 + }
  138 +
124 .new-tag { 139 .new-tag {
125 background: #78dc7d; 140 background: #78dc7d;
126 } 141 }
@@ -11,6 +11,7 @@ @@ -11,6 +11,7 @@
11 @import "outlets/index"; 11 @import "outlets/index";
12 @import "shop-index"; 12 @import "shop-index";
13 @import "students/index"; 13 @import "students/index";
  14 +@import "global/index";
14 @import "top-coupon"; 15 @import "top-coupon";
15 @import "new-arrive"; 16 @import "new-arrive";
16 @import "good-slide"; 17 @import "good-slide";
  1 +.global-detail-page {
  2 + .tags > .global-tag {
  3 + background-color: #482d3d;
  4 + font-weight: 300;
  5 +
  6 + &:before {
  7 + content: "";
  8 + width: 16px;
  9 + height: 14px;
  10 + margin-right: 4px;
  11 + background-image: url("/product/airplane-tag.png");
  12 + display: inline-block;
  13 + vertical-align: sub;
  14 + }
  15 + }
  16 +
  17 + .main .foreign-price {
  18 + > * {
  19 + color: #b0b0b0;
  20 + font-weight: 300;
  21 + }
  22 +
  23 + .price {
  24 + font-size: 13px;
  25 + margin-right: 20px;
  26 + }
  27 + }
  28 +
  29 + .extra-tip {
  30 + font-size: 13px;
  31 +
  32 + > a {
  33 + color: #f00;
  34 + text-decoration: underline;
  35 + }
  36 +
  37 + .global-buy-tips {
  38 + padding-top: 20px;
  39 +
  40 + > li {
  41 + float: left;
  42 + margin-right: 60px;
  43 + cursor: default;
  44 +
  45 + &:hover > .hover-tip {
  46 + display: block;
  47 + }
  48 + }
  49 +
  50 + .hover-tip {
  51 + width: 220px;
  52 + line-height: 1.5;
  53 + padding: 10px;
  54 + color: #666;
  55 + font-size: 12px;
  56 + background-color: #fff;
  57 + border: 1px solid #ddd;
  58 + margin-top: 6px;
  59 + display: none;
  60 + position: absolute;
  61 + }
  62 + }
  63 + }
  64 +
  65 + .global-detail-wrap {
  66 + padding: 30px 0;
  67 + }
  68 +
  69 + .good-detail-page {
  70 + background-color: transparent;
  71 + position: relative;
  72 + width: 100%;
  73 + overflow: hidden;
  74 + border: 1px solid #e0e0e0;
  75 + box-sizing: border-box;
  76 +
  77 + .good-sure {
  78 + text-align: center;
  79 + margin-top: 30px;
  80 + margin-bottom: 20px;
  81 + padding-top: 10px;
  82 + padding-bottom: 10px;
  83 + border: 1px #e0e0e0 solid;
  84 +
  85 + img {
  86 + width: 517px;
  87 + max-width: 100%;
  88 + display: block;
  89 + border: 0;
  90 + margin: 0 auto;
  91 + }
  92 + }
  93 +
  94 + .info {
  95 + margin-top: 39px;
  96 + margin-left: 175px;
  97 + margin-right: 175px;
  98 + color: #999;
  99 + border-top: 1px solid #e0e0e0;
  100 + font-size: 12px;
  101 + text-align: center;
  102 +
  103 + h2 {
  104 + color: #444;
  105 + border: 1px solid #444;
  106 + padding: 7px 28px 6px;
  107 + text-align: center;
  108 + background-color: #fff;
  109 + display: inline-block;
  110 + font-size: 16px;
  111 + margin: 30px auto;
  112 +
  113 + span {
  114 + display: none;
  115 + }
  116 + }
  117 + }
  118 +
  119 + .description {
  120 + table {
  121 + background: #fff;
  122 + width: 100%;
  123 + border-collapse: collapse;
  124 + border-spacing: 0;
  125 + text-align: center;
  126 + margin: 0 auto 20px;
  127 + font-size: 14px;
  128 + color: #666;
  129 + }
  130 +
  131 + td {
  132 + float: left;
  133 + width: 25%;
  134 + font-size: 14px;
  135 + line-height: 22px;
  136 + color: #444;
  137 + }
  138 + }
  139 +
  140 + .table-wrap {
  141 + text-align: center;
  142 + margin: 0 auto 20px;
  143 + width: 100%;
  144 + font-size: 14px;
  145 + color: #666;
  146 + border: 1px solid #e0e0e0;
  147 +
  148 + table {
  149 + width: 100%;
  150 + }
  151 +
  152 + thead {
  153 + background-color: #f5f5f5;
  154 + color: #666;
  155 + font-size: 14px;
  156 + border-bottom: 1px solid #e0e0e0;
  157 + }
  158 +
  159 + tr {
  160 + text-align: center;
  161 + height: 30px;
  162 + }
  163 +
  164 + th,
  165 + td {
  166 + text-align: center;
  167 + }
  168 +
  169 + tbody {
  170 + color: #222;
  171 +
  172 + tr:nth-child(2n) {
  173 + background-color: rgb(249, 249, 249);
  174 + }
  175 + }
  176 + }
  177 +
  178 + .details {
  179 + font-size: 14px;
  180 + line-height: 1.5;
  181 +
  182 + table {
  183 + text-align: center;
  184 + margin: 0 auto 20px;
  185 + width: 100%;
  186 + font-size: 14px;
  187 + color: #666;
  188 + border: 1px solid #e0e0e0;
  189 +
  190 + thead {
  191 + background-color: #f5f5f5;
  192 + color: #666;
  193 + font-size: 14px;
  194 + border-bottom: 1px solid #e0e0e0;
  195 + }
  196 +
  197 + tbody {
  198 + color: #222;
  199 + }
  200 +
  201 + tr {
  202 + text-align: center;
  203 + height: 30px;
  204 + }
  205 +
  206 + th,
  207 + td {
  208 + text-align: center;
  209 + height: 30px;
  210 + }
  211 +
  212 + tr:nth-child(2n) {
  213 + background-color: rgb(249, 249, 249);
  214 + }
  215 +
  216 + & + p {
  217 + color: #999;
  218 + font-size: 14px;
  219 + line-height: 20px;
  220 + text-align: center;
  221 + margin-top: 20px;
  222 + margin-bottom: 30px;
  223 + }
  224 + }
  225 +
  226 + img {
  227 + width: 100%;
  228 + }
  229 + }
  230 +
  231 + .brand-intro {
  232 + p {
  233 + font-size: 14px;
  234 + color: #444;
  235 + display: inline-block;
  236 + margin-bottom: 0;
  237 + line-height: 25px;
  238 + }
  239 +
  240 + img {
  241 + display: block;
  242 + width: 100%;
  243 + margin-bottom: 20px;
  244 + }
  245 + }
  246 +
  247 + .service-info {
  248 + img {
  249 + width: 517px;
  250 + display: block;
  251 + margin: 0 auto 20px;
  252 + }
  253 +
  254 + .service-prob {
  255 + display: block;
  256 + width: 100%;
  257 + margin-bottom: 10px;
  258 + line-height: 20px;
  259 + color: #000;
  260 + font-size: 14px;
  261 + text-align: left;
  262 +
  263 + &:before {
  264 + display: inline-block;
  265 + content: "\e695";
  266 + line-height: 18px;
  267 + margin-right: 10px;
  268 + font-style: normal;
  269 + font-family: "iconfont";
  270 + font-size: 18px;
  271 + text-decoration: none;
  272 + -webkit-font-smoothing: antialiased;
  273 + -webkit-text-stroke-width: 0.2px;
  274 + }
  275 + }
  276 +
  277 + .service-answer {
  278 + display: block;
  279 + float: left;
  280 + margin-top: 0;
  281 + margin-bottom: 30px;
  282 + line-height: 20px;
  283 + font-size: 14px;
  284 + font-family: initial;
  285 + text-align: justify;
  286 +
  287 + &:before {
  288 + display: inline-block;
  289 + content: "\e696";
  290 + line-height: 18px;
  291 + margin-right: 10px;
  292 + font-style: normal;
  293 + font-family: "iconfont";
  294 + font-size: 18px;
  295 + text-decoration: none;
  296 + -webkit-font-smoothing: antialiased;
  297 + -webkit-text-stroke-width: 0.2px;
  298 + }
  299 + }
  300 + }
  301 +
  302 + .service-operation,
  303 + .recommend-for-you {
  304 + display: none;
  305 + }
  306 + }
  307 +}
  1 +@import "detail";
  2 +
  3 +.global-list-page {
  4 + .path-nav:after {
  5 + content: "";
  6 + width: 54px;
  7 + height: 20px;
  8 + margin-left: 6px;
  9 + display: inline-block;
  10 + background-image: url("/product/global-path-icon.png");
  11 + vertical-align: bottom;
  12 + }
  13 +}
@@ -33,10 +33,11 @@ const joinUrl = (params) => { @@ -33,10 +33,11 @@ const joinUrl = (params) => {
33 */ 33 */
34 exports.setPager = (total, params)=>{ 34 exports.setPager = (total, params)=>{
35 let resData = {}; 35 let resData = {};
  36 + let defParams = _.cloneDeep(params);
36 let cutStatus, // 切割状态 1:去头 2:去尾 3:双切 37 let cutStatus, // 切割状态 1:去头 2:去尾 3:双切
37 i; 38 i;
38 let pages = []; 39 let pages = [];
39 - let currentPage = parseInt(params.page || 1, 10); // 当前页 40 + let currentPage = parseInt(defParams.page || 1, 10); // 当前页
40 41
41 // 小于两页直接退出 42 // 小于两页直接退出
42 if (total < 2) { 43 if (total < 2) {
@@ -55,7 +56,7 @@ exports.setPager = (total, params)=>{ @@ -55,7 +56,7 @@ exports.setPager = (total, params)=>{
55 } 56 }
56 57
57 pages.push({ 58 pages.push({
58 - url: joinUrl(Object.assign(params, {page: i})), 59 + url: joinUrl(Object.assign(defParams, {page: i})),
59 num: i, 60 num: i,
60 cur: currentPage === i 61 cur: currentPage === i
61 }); 62 });
@@ -74,7 +75,7 @@ exports.setPager = (total, params)=>{ @@ -74,7 +75,7 @@ exports.setPager = (total, params)=>{
74 } 75 }
75 76
76 list.push({ 77 list.push({
77 - url: joinUrl(Object.assign(params, {page: p})), 78 + url: joinUrl(Object.assign(defParams, {page: p})),
78 num: p 79 num: p
79 }); 80 });
80 } 81 }
@@ -88,7 +89,7 @@ exports.setPager = (total, params)=>{ @@ -88,7 +89,7 @@ exports.setPager = (total, params)=>{
88 } 89 }
89 90
90 list.push({ 91 list.push({
91 - url: joinUrl(Object.assign(params, {page: p})), 92 + url: joinUrl(Object.assign(defParams, {page: p})),
92 num: p 93 num: p
93 }); 94 });
94 } 95 }
@@ -102,12 +103,12 @@ exports.setPager = (total, params)=>{ @@ -102,12 +103,12 @@ exports.setPager = (total, params)=>{
102 if (fnum > 1) { 103 if (fnum > 1) {
103 if (fnum > 2) { 104 if (fnum > 2) {
104 pages = _.concat({ 105 pages = _.concat({
105 - url: joinUrl(Object.assign(params, {page: 1})), 106 + url: joinUrl(Object.assign(defParams, {page: 1})),
106 num: 1 107 num: 1
107 }, {num: '...'}, pages); 108 }, {num: '...'}, pages);
108 } else { 109 } else {
109 pages = _.concat({ 110 pages = _.concat({
110 - url: joinUrl(Object.assign(params, {page: 1})), 111 + url: joinUrl(Object.assign(defParams, {page: 1})),
111 num: 1 112 num: 1
112 }, pages); 113 }, pages);
113 } 114 }
@@ -116,12 +117,12 @@ exports.setPager = (total, params)=>{ @@ -116,12 +117,12 @@ exports.setPager = (total, params)=>{
116 if (lnum < total) { 117 if (lnum < total) {
117 if (lnum < total - 1) { 118 if (lnum < total - 1) {
118 pages = _.concat(pages, {num: '...'}, { 119 pages = _.concat(pages, {num: '...'}, {
119 - url: joinUrl(Object.assign(params, {page: total})), 120 + url: joinUrl(Object.assign(defParams, {page: total})),
120 num: total 121 num: total
121 }); 122 });
122 } else { 123 } else {
123 pages = _.concat(pages, { 124 pages = _.concat(pages, {
124 - url: joinUrl(Object.assign(params, {page: total})), 125 + url: joinUrl(Object.assign(defParams, {page: total})),
125 num: total 126 num: total
126 }); 127 });
127 } 128 }
@@ -131,12 +132,12 @@ exports.setPager = (total, params)=>{ @@ -131,12 +132,12 @@ exports.setPager = (total, params)=>{
131 132
132 // 上一页 133 // 上一页
133 if (currentPage > 1) { 134 if (currentPage > 1) {
134 - resData.prePage = {url: joinUrl(Object.assign(params, {page: currentPage - 1}))}; 135 + resData.prePage = {url: joinUrl(Object.assign(defParams, {page: currentPage - 1}))};
135 } 136 }
136 137
137 // 下一页 138 // 下一页
138 if (currentPage < total) { 139 if (currentPage < total) {
139 - resData.nextPage = {url: joinUrl(Object.assign(params, {page: currentPage + 1}))}; 140 + resData.nextPage = {url: joinUrl(Object.assign(defParams, {page: currentPage + 1}))};
140 } 141 }
141 142
142 return resData; 143 return resData;
@@ -102,10 +102,6 @@ const procProductImgs = (item, gender) => { @@ -102,10 +102,6 @@ const procProductImgs = (item, gender) => {
102 } 102 }
103 }; 103 };
104 104
105 -const procCnAlphabetName = (nameStr) => {  
106 - return nameStr.match(/\w/ig).join('');  
107 -};  
108 -  
109 /** 105 /**
110 * 商品搜索商品数据处理 106 * 商品搜索商品数据处理
111 */ 107 */
@@ -153,6 +149,18 @@ exports.processProductList = (list, options) => { @@ -153,6 +149,18 @@ exports.processProductList = (list, options) => {
153 // } 149 // }
154 150
155 _.forEach(list, (product) => { 151 _.forEach(list, (product) => {
  152 + // 全球购接口与普通接口返回商品差异属性预处理
  153 + if (options.isGlobal && product) {
  154 + Object.assign(product, {
  155 + goods_list: [{
  156 + images_url: product.default_images,
  157 + status: 1
  158 + }],
  159 + sales_price: product.orign_price,
  160 + market_price: null,
  161 + tbl_country_name: product.country_name
  162 + });
  163 + }
156 164
157 // 商品信息有问题,则不显示 165 // 商品信息有问题,则不显示
158 if (!product || !product.product_skn || !_.get(product, 'goods_list.length', 0)) { 166 if (!product || !product.product_skn || !_.get(product, 'goods_list.length', 0)) {
@@ -198,20 +206,32 @@ exports.processProductList = (list, options) => { @@ -198,20 +206,32 @@ exports.processProductList = (list, options) => {
198 thumb: product.default_images 206 thumb: product.default_images
199 }); 207 });
200 208
201 - product.cn_alphabet = procCnAlphabetName(product.cn_alphabet);  
202 -  
203 product.is_few = product.is_soon_sold_out === 'Y'; 209 product.is_few = product.is_soon_sold_out === 'Y';
204 - product.url = helpers.getUrlBySkc(product.product_id, _.get(product, 'goods_list[0].goods_id'), product.cn_alphabet);// eslint-disable-line 210 +
  211 + if (product.is_global === 'Y') {
  212 + product.url = helpers.urlFormat(`/product/global/${product.product_skn}.html`, null);
  213 + } else {
  214 + if (product.product_id) {
  215 + product.url = helpers.getUrlBySkc(product.product_id);
  216 + } else if (product.product_skn) {
  217 + product.url = helpers.urlFormat('/common/erp2goods', {skn: product.product_skn});
  218 + }
  219 + }
205 220
206 // 4.6需求 商品列表显示店铺名 221 // 4.6需求 商品列表显示店铺名
207 - if (product.shop_id * 1) { 222 + // is_global = Y & tbl_brand_id!= 0 则跳全球购品牌否则走品牌,因为全球购的商品有可能融进了有货的牌子
  223 + if (product.is_global === 'Y' && product.tbl_brand_id) {
  224 + product.brandUrl = helpers.urlFormat('/product/global/list', {brand: product.tbl_brand_id});
  225 + } else if (product.shop_id * 1) {
208 product.brand_name = product.shop_name; 226 product.brand_name = product.shop_name;
209 product.brandUrl = helpers.urlFormat('', { 227 product.brandUrl = helpers.urlFormat('', {
210 shopId: product.shop_id 228 shopId: product.shop_id
211 }, product.shop_domain || 'default-domain'); 229 }, product.shop_domain || 'default-domain');
212 } else { 230 } else {
213 - // tar add 1606071146 品牌链接处理  
214 - product.brandUrl = helpers.urlFormat('', '', product.brand_domain); 231 + // 5.6商品列表未关联店铺不显示品牌
  232 + _.unset(product, 'brand_name');
  233 +
  234 + // product.brandUrl = helpers.urlFormat('', '', product.brand_domain);
215 } 235 }
216 236
217 // TODO 删除from参数,暂时保留注释 237 // TODO 删除from参数,暂时保留注释
@@ -225,6 +245,13 @@ exports.processProductList = (list, options) => { @@ -225,6 +245,13 @@ exports.processProductList = (list, options) => {
225 let tags = [], 245 let tags = [],
226 isfew = false; 246 isfew = false;
227 247
  248 + if (product.is_global === 'Y') {
  249 + tags.push({
  250 + is_global: true,
  251 + name: product.tbl_country_name
  252 + });
  253 + }
  254 +
228 _.get(product, 'tags', []).forEach((value) => { 255 _.get(product, 'tags', []).forEach((value) => {
229 let tag = {}; 256 let tag = {};
230 257