Authored by 周少峰

Merge branch 'feature/productProcess'

... ... @@ -650,7 +650,7 @@ module.exports = class extends global.yoho.BaseModel {
return;
}
if (it.product_id) {
if (it.product_skn) {
formatData.idx = getIndex(it.product_skn);
if (formatData.idx === 0 || formatData.idx) {
data.singlehot.imgHot.push(formatData);
... ...
... ... @@ -26,7 +26,7 @@ exports.index = (req, res, next) => {
let pathNav = req.ctx(guangModel).getPathNav(channel);
let uid = req.user.uid;
let udid = ghelper.getUdid(req, res);
let udid = req.yoho.udid;
let gender = ghelper.getGenderByCookie(req);
let isHotDegrade = _.get(req.app.locals.pc, 'guang.removeHotTag', false);
let isAdDegrade = _.get(req.app.locals.pc, 'guang.removeAd', false);
... ... @@ -87,7 +87,7 @@ exports.tags = (req, res, next) => {
let type = req.query.type || 0;
let uid = req.user.uid;
let udid = ghelper.getUdid(req, res);
let udid = req.yoho.udid;
let gender = ghelper.getGenderByCookie(req);
let channel = req.yoho.channel;
let pathNav = req.ctx(guangModel).getPathNav(channel, query);
... ... @@ -148,7 +148,7 @@ exports.editor = (req, res, next) => {
let isAdDegrade = _.get(req.app.locals.pc, 'guang.removeAd', false);
let uid = req.user.uid;
let udid = ghelper.getUdid(req, res);
let udid = req.yoho.udid;
let pathNav = req.ctx(guangModel).getPathNav(channel);
... ... @@ -205,7 +205,7 @@ exports.detail = (req, res, next) => {
let col = req.query.col || 0;
let pjax = req.query._pjax;
let uid = req.user.uid;
let udid = ghelper.getUdid(req, res);
let udid = req.yoho.udid;
let gender = ghelper.getGenderByCookie(req);
let channel = req.yoho.channel;
let isHotDegrade = _.get(req.app.locals.pc, 'guang.removeHotTag', false);
... ... @@ -354,7 +354,7 @@ exports.detail = (req, res, next) => {
exports.listDynamicData = (req, res) => {
let ids = req.query.ids;
let udid = ghelper.getUdid(req, res);
let udid = req.yoho.udid;
let other = {};
let query = req.query.query,
... ... @@ -385,7 +385,7 @@ exports.listDynamicData = (req, res) => {
exports.detailDynamicData = (req, res) => {
let id = req.query.id,
uid = req.user.uid,
udid = ghelper.getUdid(req, res);
udid = req.yoho.udid;
req.ctx(guangModel).getDynamicDataById(id, uid, udid).then((ret) => {
res.status(200).send(ret);
... ... @@ -401,7 +401,7 @@ exports.comment = (req, res) => {
let id = req.body.id || req.query.id;
let uid = req.user.uid;
let udid = ghelper.getUdid(req, res);
let udid = req.yoho.udid;
let comment = req.body.comment;
// let pageSize = req.query.pageSize || 20;
... ... @@ -456,7 +456,7 @@ exports.praise = (req, res) => {
let id = req.body.id || req.query.id;
// let uid = req.user.uid;
let udid = ghelper.getUdid(req, res);
let udid = req.yoho.udid;
req.ctx(guangModel).praise(id, udid).then(ret => {
res.send(ret);
... ... @@ -472,7 +472,7 @@ exports.praise = (req, res) => {
*/
exports.cancelPraise = (req, res) =>{
let id = req.body.id || req.query.id;
let udid = ghelper.getUdid(req, res);
let udid = req.yoho.udid;
req.ctx(guangModel).cancelPraise(id, udid).then(ret => {
res.send(ret);
... ...
... ... @@ -8,7 +8,7 @@ const utils = '../../../utils';
const SearchApiModel = require('./search-api');
const ShopApiModel = require('./shop-api');
const headerModel = require('../../../doraemon/models/header');
const productProcess = require(`${utils}/product-process`);
const productProcess = require(`${utils}/product-process-simple`);
const searchHandler = require('./search-handler');
const shopHandler = require('./shop-handler');
const helpers = global.yoho.helpers;
... ...
... ... @@ -16,7 +16,7 @@ const SaleApiModel = require('./sale-api');
const SearchApiModel = require('./search-api');
const headerModel = require('../../../doraemon/models/header');
const productProcess = require(`${utils}/product-process`);
const productProcess = require(`${utils}/product-process-simple`);
const searchHandler = require('./search-handler');
const _ = require('lodash');
const Fn = require('lodash/fp');
... ...
... ... @@ -13,7 +13,7 @@ const helpers = global.yoho.helpers;
const shopHandler = require('./shop-handler');
const searchHandler = require('./search-handler');
const headerModel = require('../../../doraemon/models/header');
const productProcess = require('../../../utils/product-process');
const productProcess = require('../../../utils/product-process-simple');
const DEFAULT_IMG = '01091c21f2317a64f123f1649fbbccf7ba';
... ...
... ... @@ -82,7 +82,7 @@
{{#if changedQuery}}
<div class="search-suggest-less">
没有找到&nbsp;<em>"{{name}}"</em>&nbsp;相关的商品,
为您推荐&nbsp;"<a href="/?query={{suggestFirst}}&is_rec=Y">{{suggestFirst}}</a>"&nbsp;的搜索结果。{{#if suggestSecond}}或者试试{{#suggestSecond}}&nbsp;"<a href="/?query={{.}}&is_rec=Y">{{.}}</a>"&nbsp;{{/suggestSecond}}{{/if}}
为您推荐&nbsp;"<a href="/?query={{suggestFirst}}&is_rec=Y" id="rec-query-key">{{suggestFirst}}</a>"&nbsp;的搜索结果。{{#if suggestSecond}}或者试试{{#suggestSecond}}&nbsp;"<a href="/?query={{.}}&is_rec=Y">{{.}}</a>"&nbsp;{{/suggestSecond}}{{/if}}
</div>
{{/if}}
... ...
... ... @@ -110,7 +110,7 @@ module.exports = {
port: '4444' // influxdb port
},
console: {
level: 'error',
level: 'info',
colorize: 'all',
prettyPrint: true
}
... ...
... ... @@ -6,7 +6,7 @@
'use strict';
const md5 = require('md5');
const uuid = require('uuid');
const _ = require('lodash');
const config = global.yoho.config;
... ... @@ -76,14 +76,15 @@ module.exports = () => {
// uuid
yoho.udid = (function() {
let udid = req.cookies._yasvd || req.cookies.udid;
let udid = req.cookies.udid;
if (!udid) {
udid = md5(yoho.clientIp);
udid = uuid.v4();
if (res && res.cookie) {
res.cookie('udid', udid, {
domain: config.cookieDomain
domain: config.cookieDomain,
expires: new Date(Date.now() + 365 * 24 * 60 * 60 * 1000)
});
}
}
... ...
... ... @@ -26,7 +26,7 @@
window._timeStart = Date.now();
{{#ifand isProduction pc.open.bughd}}
window._yohoAppName = 'yohobuy-node';
!function(e){function t(n){if(r[n])return r[n].exports;var o=r[n]={exports:{},id:n,loaded:!1};return e[n].call(o.exports,o,o.exports,t),o.loaded=!0,o.exports}var r={};return t.m=e,t.c=r,t.p="",t(0)}([function(e,t,r){String.prototype.trim||(String.prototype.trim=function(){return this.replace(/^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g,"")});var n=r(13),o=r(14);n.init(),o.init()},function(e,t){e.exports=function(e,t,r){if("undefined"==typeof t){var n=null;if(document.cookie)for(var o=document.cookie.split(";"),i=0;i<o.length;i++){var a=(o[i]||"").trim();if(a.substring(0,e.length+1)==e+"="){n=decodeURIComponent(a.substring(e.length+1));break}}return n}r=r||{},null===t&&(t="",r.expires=-1);var d="";if(r.expires&&("number"==typeof r.expires||r.expires.toUTCString)){var u;"number"==typeof r.expires?(u=new Date,u.setTime(u.getTime()+24*r.expires*60*60*1e3)):u=r.expires,d="; expires="+u.toUTCString()}var s=r.path?"; path="+r.path:"",p=r.domain?"; domain="+r.domain:"",c=r.secure?"; secure":"";document.cookie=[e,"=",encodeURIComponent(t),d,s,p,c].join("")}},,function(e,t,r){var n=r(1),o=window._yohoAppName||"unknown",i={config:{reportUrl:"//badjs.yoho.cn/apm/yas.gif"},stringify:function(e){for(var t=[],r=0;r<e.length;r++){var n=e[r],o=[];for(var i in n)n.hasOwnProperty(i)&&o.push(i+"::"+n[i]);t.push(o.join("$$"))}return t.join("**")},report:function(e,t){if(e){var r=new Image;r.src=this.config.reportUrl+"?s="+o+"&l="+e+"&t="+(new Date).getTime(),t&&t()}},getUdid:function(){var e=(n("yohobuy_session")||"").slice(2).split(".")[0];return e||0},getUid:function(){var e=(n("_UID")||"").split("::")[1];return e||0},getReqId:function(){return n("docreqid")||0}};e.exports=i},,,,,,,,,,function(e,t,r){var n=r(1),o=r(3),i="_errLog",a={writeError:function(e,t,r,a,d){var u=JSON.parse(n(i)||"[]");u.push({tp:"err",msg:e,sc:t,ln:r,cn:a,pt:encodeURIComponent(location.href),u:o.getUid(),ud:o.getUdid(),rid:o.getReqId(),st:JSON.stringify(d&&d.stack)}),n(i,JSON.stringify(u)),u.length>=5&&this.reportError()},clearError:function(){n(i,"[]")},reportError:function(){var e=this,t=JSON.parse(n(i)||"[]"),r=o.stringify(t);o.report(r,function(){e.clearError()})},init:function(){var e=this;window.onerror=function(t,r,n,o,i){e.writeError(t,r,n,o,i)},this.reportError()}};e.exports=a},function(e,t,r){function n(e){var t=e.offsetTop;return null!==e.offsetParent&&(t+=n(e.offsetParent)),t}var o=r(3),i=window.screen.height,a=[],d=!1,u=!1,s=0,p=setInterval(function(){var e,t;if(d){if(a.length)for(e=0;e<a.length;e++){if(t=a[e],!t.complete){u=!1;break}u=!0}else u=!0;u&&(s=(new Date).getTime()-_timeStart,clearInterval(p))}else{var r=document.body&&document.body.querySelectorAll("img")||[];for(e=0;e<r.length;e++){t=r[e];var o=n(t);if(o>i){d=!0;break}o<=i&&!t.hasPushed&&(t.hasPushed=1,a.push(t))}}},0),c={reportTime:function(e){var t=o.stringify(e);o.report(t)},addEvent:function(){var e=this,t=[],r=encodeURIComponent(location.href),n=o.getUid(),i=o.getUdid(),a=o.getReqId(),c=window.performance&&window.performance.timing.navigationStart||0;_timeStart=window._timeStart||0,document.addEventListener&&document.addEventListener("DOMContentLoaded",function(e){t.push({tp:"dcl",t:(new Date).getTime()-_timeStart,pt:r,u:n,ud:i,rid:a});var o=document.body&&document.body.querySelectorAll("img")||[];o.length||(d=!0)},!1),window.addEventListener&&window.addEventListener("load",function(o){t.push({tp:"ld",t:(new Date).getTime()-_timeStart,pt:r,u:n,ud:i,rid:a}),u=!0,d=!0,p&&clearInterval(p),s&&t.push({tp:"fs",t:s,pt:r,u:n,ud:i,rid:a}),t.push({tp:"pf",dcl:(window.performance&&window.performance.timing.domComplete||0)-c,ld:(window.performance&&window.performance.timing.loadEventStart||0)-c,pt:r,u:n,ud:i,rid:a}),e.reportTime(t)},!1)},init:function(){this.addEvent()}};e.exports=c}]);
{{/ifand}}
... ... @@ -52,6 +52,8 @@
{{/if}}
{{> footer}}
<script>window._yasVersion='2.4.8';</script>
{{#if devEnv}}
<script src="//{{devHost}}:5002/libs.js"></script>
<script src="//{{devHost}}:5002/{{module}}.{{page}}.js"></script>
... ...
<div class="good-info" data-skn="{{skn}}" data-from="{{from}}">
{{#if product_id}}
<span class="hide product-id">{{product_id}}</span>
{{/if}}
<span class="hide shelve-time">{{shelve_time}}</span>
<div class="tag-container clearfix">
{{# tags}}
{{#if is_global}}
... ... @@ -45,10 +41,6 @@
{{# is_solded}}
<p class="sale-out">已售罄</p>
{{/ is_solded}}
{{#if show_col_btn}}
<span class="col-btn iconfont{{#if coled}} coled{{/if}}">&#xe616;</span>
{{/if}}
</div>
<div class="good-detail-text {{#for_stu}} stu-good-detail {{/for_stu}}">
<a href="{{url}}" target="_blank">{{{product_name}}}</a>
... ...
{
"name": "yohobuy-node",
"version": "6.1.9",
"version": "6.1.11",
"private": true,
"description": "A New Yohobuy Project With Express",
"repository": {
... ... @@ -57,7 +57,7 @@
"urlencode": "^1.1.0",
"uuid": "^2.0.2",
"yoho-express-session": "^2.0.0",
"yoho-node-lib": "=0.5.19",
"yoho-node-lib": "=0.5.21",
"yoho-zookeeper": "^1.0.8"
},
"devDependencies": {
... ...
... ... @@ -114,7 +114,7 @@ function getShoppingKey() {
a.src = j;
m.parentNode.insertBefore(a, m);
}(window, document, 'script', (document.location.protocol === 'https:' ? 'https:' : 'http:') + '//' + // eslint-disable-line
'cdn.yoho.cn/yas-jssdk/2.4.7/yas.js', '_yas')); // eslint-disable-line
'cdn.yoho.cn/yas-jssdk/' + window._yasVersion + '/yas.js', '_yas')); // eslint-disable-line
(function() {
var uid = getUid();
... ... @@ -124,7 +124,7 @@ function getShoppingKey() {
window._ozuid = uid; // 暴露ozuid
if (window._yas) {
window._yas(1 * new Date(), '2.4.7', 'yohobuy_web', uid, '', '');
window._yas(1 * new Date(), window._yasVersion, 'yohobuy_web', uid, '', '');
}
}());
... ...
... ... @@ -167,12 +167,12 @@ if ($brandMore.length > 0) {
// 【品牌】加载更多品牌数据
function checkMoreBrands(callback) {
var squery = window.location.search;
// /product/search/filter/brands?callback=?
var url = '//search.yohobuy.com/product/search/filter/brands';
var url = '//search.yohobuy.com/product/search/filter/brands?callback=?';
var brandsHtml;
var params = (location.search || '').substr(1);
var params = window.queryString();
var $changeKey = $('#rec-query-key');
// 直出brands list取消异步加载,目前只用于5.6全球购商品列表
if (!moreBrandLoaded && $filterBrands.find('.brand-panel').length) {
... ... @@ -185,10 +185,8 @@ function checkMoreBrands(callback) {
$brandsIndex = $('.brands-index');
}
if (squery && squery.length > 0) {
url += squery + '&callback=?';
} else {
url += '?callback=?';
if (params.query && $changeKey.length) {
params.query = $changeKey.text();
}
if (hideInfo) {
... ...
'use strict';
const _ = require('lodash');
const helpers = global.yoho.helpers;
const logger = global.yoho.logger;
/**
* 商品搜索商品数据处理
*/
exports.processProductList = (list, options) => {
const pruductList = [];
options = Object.assign({
showTags: true,
showNew: true,
showSale: true,
showFew: true,
showLimit: true,
showDiscount: true, // 显示折扣
newCoverSort: false, // 新封面排序
width: 290,
height: 388,
isApp: false,
showPoint: true,
gender: '2,3',
from: {} // 来源
}, options);
_.forEach(list, (product) => {
// 全球购接口与普通接口返回商品差异属性预处理
if (options.isGlobal && product) {
Object.assign(product, {
goods_list: [{
images_url: product.default_images,
status: 1
}],
sales_price: product.final_price || product.orign_price,
market_price: null,
tbl_country_name: product.country_name,
tbl_brand_id: product.brand_id
});
}
// 商品信息有问题,则不显示
if (!product || !product.product_skn || !_.get(product, 'goods_list.length', 0)) {
return;
}
let proInfo = {
skn: product.product_skn,
product_name: product.product_name,
market_price: product.market_price,
sales_price: product.sales_price,
is_few: product.is_soon_sold_out === 'Y'
};
// 市场价和售价一样,则不显示市场价, 不显示折扣信息
if (proInfo.market_price <= proInfo.sales_price) {
delete proInfo.market_price;
} else if (options.showDiscount) {
proInfo.discount = (proInfo.sales_price / proInfo.market_price * 10).toFixed(1);
}
// 商品链接
if (product.is_global === 'Y') {
proInfo.url = helpers.urlFormat(`/product/global/${product.product_skn}.html`, null);
} else if (product.product_skn) {
proInfo.url = helpers.getUrlBySkc(product.product_skn);
}
// 店铺链接
if (product.is_global === 'Y' && product.tbl_brand_id) {
proInfo.brandUrl = helpers.urlFormat('/product/global/list', {brand: product.tbl_brand_id});
} else if (product.shop_id * 1) {
Object.assign(proInfo, {
brand_name: product.shop_name,
brandUrl: helpers.urlFormat('', {shopId: product.shop_id},
product.shop_domain || 'default-domain')
});
}
let defaultColorImg,
goodsList = [];
// 处理商品颜色封面
_.forEach(_.orderBy(product.goods_list, ['is_default'], ['desc']), goods => {
if (goods.is_default === 'Y' && !defaultColorImg) {
defaultColorImg = goods.images_url; // 颜色默认封面
}
if (+goods.status) {
goodsList.push({
images_url: goods.images_url,
color_name: goods.color_name,
url: proInfo.url,
status: 1
});
}
});
Object.assign(proInfo, {
goods_list: goodsList,
thumb: product.default_images || defaultColorImg
});
// 处理标签
if (options.showTags) {
let tags = [],
isfew = false;
if (product.is_global === 'Y') {
tags.push({
is_global: true,
plane: product.tbl_plane === 'Y',
name: product.tbl_country_name
});
}
_.get(product, 'tags', []).forEach((value) => {
let tag = {};
switch (value) {
case 'is_soon_sold_out': // 即将售磬
options.showFew && (tag.is_few = true, isfew = true);
break;
case 'is_solded': // 已售磬
product.is_solded = true;
break;
case 'is_new': // 新品NEW
options.showNew && (tag.is_new = true);
break;
case 'is_discount': // SALE
options.showSale && (tag.is_sale = true);
break;
case 'is_limited': // 限量
options.showLimit && (tag.is_limit = true);
break;
case 'is_yohood': // YOHOOD
tag.is_new_festival = true;
break;
case 'is_advance': // 再到着
tag.is_re_new = true;
break;
case 'midYear':// 年中热促
tag.is_year_mid_promotion = true;
break;
case 'yearEnd':// 年终大促
tag.is_year_end_promotion = true;
break;
case 'is_presell':// 预售
tag.is_presell = true;
break;
default:
break;
}
tags.push(tag);
});
proInfo.tags = tags;
isfew ? proInfo.is_few = isfew : delete proInfo.is_few;
}
if (options.query && _.isString(proInfo.product_name)) {
try {
let qreg = new RegExp(options.query.replace('\\', '\\\\'), 'ig');
proInfo.product_name = proInfo.product_name.replace(qreg, '<span style="color:#c00;">$&</span>');
} catch (e) {
logger.debug(`product_name replace query fail:${e.toString()}`);
}
}
pruductList.push(proInfo);
});
return pruductList;
};
... ...