Authored by 郭成尧

'商品详情重开分支'

... ... @@ -100,7 +100,6 @@ try {
// YOHO 后置中间件
app.use(errorHanlder.serverError());
} catch (err) {
console.error(err);
logger.error(err);
}
... ...
... ... @@ -136,7 +136,7 @@ const _getChannelResource = (params) => {
if (result && result.code === 200) {
return resourcesProcess(result.data.list);
} else {
logger.error('首页资源位接口返回状态码 不是 200');
logger.error('api index content resource code no 200');
return result;
}
});
... ... @@ -156,7 +156,7 @@ const _getLeftNav = (choosed) => {
if (result && result.code === 200) {
return _processSideBar(result.data, choosed);
} else {
logger.error('侧边栏数据接口返回状态码 不是 200');
logger.error('api left nav code no 200');
return result;
}
});
... ... @@ -191,7 +191,7 @@ const _getChannelList = () => {
});
return Object.keys(list).length ? list : channelList;
} else {
logger.error('频道选择接口返回状态码 不是 200');
logger.error('api channel select data code no 200');
return channelList;
}
});
... ... @@ -210,7 +210,7 @@ const _getChannelBg = () => {
if (result && result.code === 200) {
return result.data.length && result.data[0] && result.data[0].data && result.data[0].data.list[0];
} else {
logger.error('频道选择页背景图接口返回状态码 不是 200');
logger.error('api background img of channel select page code no 200');
return {
src: ''
};
... ...
... ... @@ -29,7 +29,7 @@ const _getResources = (page) => {
if (result && result.code === 200) {
return resourcesProcess(result.data);
} else {
logger.error('星潮教室页面资源位返回 code 不是 200');
logger.error('star class content resource return code no 200');
return [];
}
});
... ... @@ -158,7 +158,7 @@ const getIndexData = () => {
if (result && result.code === 200) {
return _processIndexData(result);
} else {
logger.error('星潮教室首页数据返回 code 不是 200');
logger.error('star class content resource return code no 200');
return {};
}
});
... ... @@ -183,7 +183,7 @@ const getDetailData = (params, uid) => {
return _processGuangData(result.data.list, true);
}
} else {
logger.error('明星专题文章数据返回 code 不是 200');
logger.error('api app.starClass.lastTagArticle code no 200');
return [];
}
});
... ... @@ -227,7 +227,7 @@ const getCollocationListData = (params, uid) => {
if (result && result.code === 200) {
return _processGuangData(result.data.list.artList);
} else {
logger.error('获取星搭配文章列表返回 code 不是 200');
logger.error('getStarClassroomArticleList code no 200');
return [];
}
});
... ...
... ... @@ -10,8 +10,11 @@ const mRoot = '../models';
const headerModel = require('../../../doraemon/models/header'); // 头部model
const detailModel = require(`${mRoot}/detail`); // 商品详情 model
const introModel = require(`${mRoot}/intro`); // 商品尺码信息 model
const preference = require(`${mRoot}/preference`); // 商品偏好 model
const preferenceModel = require(`${mRoot}/preference`); // 商品偏好 model
const detailRelated = require(`${mRoot}/consult-comment`); // 商品评论咨询 model
const _ = require('lodash');
const helpers = global.yoho.helpers;
/**
* 商品基本信息
... ... @@ -34,6 +37,42 @@ exports.index = (req, res, next) => {
uid: uid,
ua: req.get('user-agent') || ''
}).then((result) => {
if (_.isEmpty(result)) {
return next();
}
res.render('detail/detail', {
pageHeader: headerData,
result: result,
page: 'detail',
title: result.goodsName,
pageFooter: true
});
}).catch(next);
};
/**
* 商品基本信息 SKN 进入
* @param {[type]} req [description]
* @param {[type]} res [description]
* @return {[type]} [description]
*/
exports.indexSkn = (req, res, next) => {
if (!req.params[0]) {
return next();
}
let uid = req.user.uid || 0;
let headerData = headerModel.setNav({
navTitle: '商品详情'
});
detailModel.getProductData({
productSkn: req.params[0],
uid: uid,
ua: req.get('user-agent') || ''
}).then((result) => {
if (_.isEmpty(result)) {
return next();
}
res.render('detail/detail', {
pageHeader: headerData,
result: result,
... ... @@ -71,8 +110,8 @@ exports.intro = (req, res, next) => {
* @param {[type]} res [description]
* @return {[type]} [description]
*/
exports.preference = (req, res) => {
preference({
exports.preference = (req, res, next) => {
preferenceModel({
productskn: req.query.productSkn,
yhchannel: req.yoho.channel,
brandId: req.query.brandId
... ... @@ -80,19 +119,24 @@ exports.preference = (req, res) => {
res.render('detail/preference', Object.assign({
layout: false
}, result));
});
}).catch(next);
};
/**
* 购买评价页
*/
exports.comments = (req, res, next) => {
if (!req.query.product_id) {
return next();
}
let headerData = headerModel.setNav({
navTitle: '购买评价'
});
detailRelated.comments(req.query).then((result) => {
res.render('detail/comments', Object.assign({
title: '购买评价',
pageHeader: headerData,
pageFooter: true
}, result));
... ... @@ -103,12 +147,17 @@ exports.comments = (req, res, next) => {
* 购买咨询
*/
exports.consults = (req, res, next) => {
if (!req.query.product_id) {
return next();
}
let headerData = headerModel.setNav({
navTitle: '购买咨询'
});
detailRelated.consults(req.query).then((result) => {
res.render('detail/consults', Object.assign({
title: '购买咨询',
pageHeader: headerData,
pageFooter: true
}, result));
... ... @@ -116,17 +165,46 @@ exports.consults = (req, res, next) => {
};
/**
* 咨询点赞
*/
exports.consultUpvoteOrUseful = (req, res, next) => {
let uid = req.user.uid || 0;
if (!uid) {
return res.json({
code: 401,
message: '用户id为空',
data: helpers.urlFormat('/signin.html', {
refer: helpers.urlFormat('/product/detail/consults', {
product_id: req.body.product_id,
total: req.body.total
})
})
});
}
req.body.isUpvote = /upvote/.test(req.path);
req.body.uid = uid;
detailRelated.upvoteConsult(req.body).then((result) => {
res.json(result);
}).catch(next);
};
/**
* 咨询表单页
*/
exports.consultform = (req, res, next) => {
if (!req.query.product_id) {
return next();
}
let headerData = headerModel.setNav({
navTitle: '我要咨询'
});
if (!req.query.product_id) {
return next();
}
res.render('detail/consult-form', {
title: '我要咨询',
pageHeader: headerData,
productId: req.query.product_id,
formUrl: '/product/detail/consultsubmit',
... ...
... ... @@ -6,8 +6,9 @@
'use strict';
const api = global.yoho.API;
const _ = require('lodash');
const api = global.yoho.API;
const helpers = global.yoho.helpers;
/**
* 获取默认咨询列表
... ... @@ -31,33 +32,6 @@ const _getCommonConsult = () => {
};
/**
* 处理评价列表数据
* @data {[object]} 评价列表原始数据
* @return {[object]}
*/
const _formatCommentsList = (data) => {
let comment = {
list: [],
total: 0
};
if (data.length) {
_.forEach(data, (value) => {
comment.list.push({
userName: value.nickname,
desc: `${value.color_name}/${value.size_name}`,
content: value.content,
time: value.create_time
});
comment.total = value.total;
});
}
return comment;
};
/**
* 处理咨询列表数据
* @data {[object]} 咨询列表原始数据
* @return {[object]}
... ... @@ -84,15 +58,15 @@ const _formatConsultsList = (data) => {
};
/**
* 获取评价数据
* 获取咨询数据
* @id {[number]} 商品id
* @page {[number]} 页码
* @limit {[number]} 每页评价数量
* @limit {[number]} 每页咨询数量
* @return {[object]}
*/
const _getComments = (id, page, limit) => {
const getConsults = (id, page, limit) => {
let params = {
method: 'app.comment.li',
method: 'app.consult.li',
product_id: id,
page: page ? page : 1,
limit: limit ? limit : 300
... ... @@ -103,8 +77,12 @@ const _getComments = (id, page, limit) => {
}).then(result => {
let data = {};
if (result.data) {
Object.assign(data, _formatCommentsList(result.data));
if (result.data && result.data.list) {
Object.assign(data, {
list: _formatConsultsList(result.data.list),
pageTotal: result.data.page_total,
total: result.data.total
});
}
return data;
... ... @@ -112,34 +90,42 @@ const _getComments = (id, page, limit) => {
};
/**
* 获取咨询数据
* @id {[number]} 商品id
* @page {[number]} 页码
* @limit {[number]} 每页咨询数量
* @return {[object]}
* 处理评论数据
*/
const _getConsults = (id, page, limit) => {
let params = {
method: 'app.consult.li',
product_id: id,
page: page ? page : 1,
limit: limit ? limit : 300
let _processComment = (data) => {
let result = {
commentsNum: data.pageResponse.totalCount,
comments: []
};
return api.get('', params, {
code: 200
}).then(result => {
let data = {};
_.forEach(data.pageResponse.list, (item) => {
result.comments.push({
userName: item.userInfo.nickName,
desc: `${item.goods.color_name}/${item.goods.size_name}`,
content: item.content,
time: helpers.dateFormat('YYYY-MM-DD HH:mm:ss', new Date(item.createTime * 1000))
});
});
return result;
};
if (result.data && result.data.list) {
Object.assign(data, {
list: _formatConsultsList(result.data.list),
pageTotal: result.data.page_total,
total: result.data.total
});
/**
* 获取评论信息
*/
let getCommentInfo = (params) => {
return api.get('', Object.assign({
method: 'show.productShareOrderList',
limit: '1',
page: '1',
filterId: '7'
}, params), {
cache: true
}).then((result) => {
if (result.code === 200) {
return _processComment(result.data);
}
return data;
return {};
});
};
... ... @@ -149,14 +135,17 @@ const _getConsults = (id, page, limit) => {
* @return {[object]}
*/
let comments = (params) => {
return _getComments(params.product_id, 1, 60).then(result => {
return getCommentInfo({
productId: params.product_id,
limit: '60'
}).then(result => {
let data = {};
if (result.list && result.list.length) {
if (result.total) {
_.set(data, 'pageHeader.navTitle', `购买评价(${result.total})`);
if (result.comments && result.comments.length) {
if (result.commentsNum) {
_.set(data, 'pageHeader.navTitle', `购买评价(${result.commentsNum})`);
}
data.comments = result.list;
data.comments = result.comments;
}
return data;
... ... @@ -171,7 +160,7 @@ let comments = (params) => {
let consults = (params) => {
return api.all([
_getCommonConsult(),
_getConsults(params.product_id, 1, 60)
getConsults(params.product_id, 1, 60)
]).then(result => {
let data = {
link: `/product/detail/consultform?product_id=${params.product_id}`
... ... @@ -186,10 +175,20 @@ let consults = (params) => {
data.consults = result[1].list;
}
data.showReadMore = result[1].list.length > 2;
return data;
});
};
let upvoteConsult = (params) => {
return api.get('', {
method: params.isUpvote ? 'app.consult.like' : 'app.consult.useful',
id: params.id,
uid: params.uid
});
};
/**
* 购买咨询列表
* @uid {[number]} 用户id
... ... @@ -214,7 +213,10 @@ let addConsult = (uid, productId, content) => {
};
module.exports = {
getCommentInfo, // 商品详情相关,获取评价,来自晒单
comments, // 商品详情相关-购买评价
consults, // 商品详情相关-购买咨询
addConsult // 商品详情相关-添加咨询
addConsult, // 商品详情相关-添加咨询
upvoteConsult, // 咨询点赞
getConsults // 获取咨询
};
... ...
... ... @@ -6,8 +6,10 @@
'use strict';
const api = global.yoho.API;
const _ = require('lodash');
const comment = require('./consult-comment');
const api = global.yoho.API;
const helpers = global.yoho.helpers;
/**
... ... @@ -237,47 +239,19 @@ const _detailDataPkg = (origin, uid, vipLevel, ua) => {
dest.periodOfMarket = `${origin.expectArrivalTime}月`;
}
// 促销信息 TODO: 换新接口
if (origin.promotionBoList) {
let discountList = [];
_.forEach(origin.promotionBoList, function(value) {
discountList.push({
text: `【${value.promotionType}${value.promotionTitle}`
});
});
if (discountList.length) {
dest.goodsDiscount = {
list: discountList
};
}
}
// 商品咨询
dest.feedbacks = {
consults: [],
consultsNum: 0
};
if (origin.consultBoWrapper) {
dest.feedbacks.consultsNum = origin.consultBoWrapper.consultTotal;
_.forEach(origin.consultBoWrapper.consultBoList, function(value) {
dest.feedbacks.consults.push({
question: value.ask,
time: value.askTime,
answer: value.answer
});
});
}
let consultParams = {
product_id: origin.id
};
if (_.has(dest, 'feedbacks.consultsNum')) {
consultParams.total = dest.feedbacks.consultsNum;
dest.feedbacks.consultsUrl = helpers.urlFormat('/product/detail/consult', consultParams);
dest.feedbacks.consultsUrl = helpers.urlFormat('/product/detail/consults', consultParams);
} else {
dest.feedbacks.consultsUrl = helpers.urlFormat('/product/detail/consultform', consultParams);
}
... ... @@ -320,13 +294,13 @@ const _detailDataPkg = (origin, uid, vipLevel, ua) => {
if (origin.goodsList) {
let goodsGroup = [],
sizeName = '',
colorList = {},
colorList = [],
sizeList = {},
allSizeList = {},
colorStorageGroup = {},
colorStorageNum = 0;
_.forEach(origin.goodsList, function(value, key) {
_.forEach(origin.goodsList, function(value) {
if (value.status === 0) {
return;
}
... ... @@ -367,7 +341,7 @@ const _detailDataPkg = (origin, uid, vipLevel, ua) => {
};
allSizeList[sizeName] = (allSizeList[sizeName] === null ||
typeof allSizeList[sizeName] === 'undefined') ? build :
typeof allSizeList[sizeName] === 'undefined') ? build :
allSizeList[sizeName];
colorStorageNum += parseInt(size.goodsSizeStorageNum, 10);
... ... @@ -375,13 +349,13 @@ const _detailDataPkg = (origin, uid, vipLevel, ua) => {
});
// 颜色分组
colorList[key] = {
colorList.push({
id: value.colorId,
skcId: value.productSkc,
name: value.colorName,
goodsName: value.goodsName,
colorNum: colorStorageNum
};
});
}
// 缩略图
... ... @@ -399,10 +373,12 @@ const _detailDataPkg = (origin, uid, vipLevel, ua) => {
sizeGroup[0] = {
size: []
};
_.forEach(allSizeList, function(value) {
_.forEach(allSizeList, (value, key) => {
// 默认尺码
sizeGroup[0].size.push({
name: sizeName,
name: key,
sizeNum: _.toNumber(value.storage) > 0 ? true : false,
id: value.id
});
... ... @@ -412,13 +388,16 @@ const _detailDataPkg = (origin, uid, vipLevel, ua) => {
};
// 各个颜色的尺码, 每行显示一个尺码对应的颜色
_.forEach(colorList, function(colorArr) {
colorArr.colorNum = 0;
if (colorStorageGroup[colorArr.skcId] &&
colorStorageGroup[colorArr.skcId][sizeName]) {
colorArr.colorNum = colorStorageGroup[colorArr.skcId][sizeName];
_.forEach(colorList, (colorArr) => {
let tempColorArr = _.cloneDeep(colorArr);
if (colorStorageGroup[tempColorArr.skcId] &&
colorStorageGroup[tempColorArr.skcId][key]) {
tempColorArr.colorNum = colorStorageGroup[tempColorArr.skcId][key];
} else {
tempColorArr.colorNum = 0;
}
colorGroup[i].color.push(colorArr);
colorGroup[i].color.push(Object.assign({}, tempColorArr));
});
colorGroup[i].id = value.id;
... ... @@ -443,6 +422,7 @@ const _detailDataPkg = (origin, uid, vipLevel, ua) => {
++i;
});
// 商品图:多个
if (goodsGroup.length > 1) {
let bannerList = [];
... ... @@ -492,7 +472,7 @@ const _detailDataPkg = (origin, uid, vipLevel, ua) => {
if (origin.isLimitBuy === 'Y') {
// 是否开售
let isBeginSale = (origin.saleStatus !== null && typeof origin.saleStatus !== 'undefined' &&
origin.saleStatus === 1);
origin.saleStatus === 1);
// 限购商品有关的展示状态
let showStatus = 1;
... ... @@ -560,13 +540,44 @@ let _getPromotionInfo = (skn) => {
});
};
/**
* 获取默认咨询列表
*/
const _getCommonConsult = () => {
let params = {
method: 'app.consult.common'
};
return api.get('', params, {
code: 200
}).then(result => {
let data = {};
if (result.data) {
data = result.data;
}
return data;
});
};
let getProductData = (data) => {
let finalResult;
let params = {
productId: _.toString(data.id),
method: 'h5.product.data'
};
if (data.id) { // 通过 productId 获取商品详情
Object.assign(params, {
productId: _.toString(data.id)
});
} else if (data.productSkn) { // 通过 productSkn 获取商品详情
Object.assign(params, {
product_skn: _.toString(data.productSkn)
});
}
if (!_.isEmpty(data.uid)) {
params.uid = data.uid;
}
... ... @@ -577,12 +588,43 @@ let getProductData = (data) => {
return api.get('', params, {
cache: true
}).then(result => {
return Promise.all([_getShopsInfo(result.brandId), _getPromotionInfo(result.erpProductId)]).then((info) => {
if (result.code === 500) {
return {};
}
return Promise.all([
_getShopsInfo(result.brandId),
_getPromotionInfo(result.erpProductId),
comment.getCommentInfo({
productId: result.id
}),
_getCommonConsult(),
comment.getConsults(result.id, 1, 2)
]).then((info) => {
result.promotionBoList = info[1];
finalResult = _detailDataPkg(result, data.uid, data.vipLevel, data.ua);
finalResult.enterStore = info[0];
Object.assign(finalResult.feedbacks, info[2]);
if (!info[4].total && !_.isEmpty(info[3]) && !_.get(info[2], 'feedbacks.consultsNum', 0)) {
Object.assign(finalResult.feedbacks, {
commonConsults: true,
consultsNum: true,
consults: _.take(info[3], 2)
});
}
if (info[4]) {
finalResult.feedbacks.consultsNum = parseInt(info[4].total, 10);
Object.assign(finalResult.feedbacks, {
commonConsults: false,
consultsNum: parseInt(info[4].total, 10),
consults: _.take(info[4].list, 2)
});
}
return finalResult;
});
... ...
... ... @@ -75,9 +75,9 @@ const getSizeInfo = (sizeInfo) => {
dest.sizeInfo.detail.list = [];
// 参考尺码
let boyReference = !_.isEmpty(sizeInfo.productExtra.boyReference);
let girlReference = !_.isEmpty(sizeInfo.productExtra.girlReference);
let gender = !_.isEmpty(sizeInfo.productDescBo.gender) ? sizeInfo.productDescBo.gender : 3;
let boyReference = sizeInfo.productExtra.boyReference;
let girlReference = sizeInfo.productExtra.girlReference;
let gender = sizeInfo.productDescBo.gender ? sizeInfo.productDescBo.gender : 3;
let referenceName = '参考尺码';
if ((gender === 1 && boyReference) || (gender === 2 && girlReference)) {
... ... @@ -102,12 +102,14 @@ const getSizeInfo = (sizeInfo) => {
if (!_.isEmpty(sizeInfo.sizeInfoBo.sizeAttributeBos)) {
// [{param: attrName}] th
let sizeNameList = [];
temp = {};
temp.param = '吊牌尺码';
sizeNameList.push(temp);
// {id: [{param: str},......]} sizeBoGroup[id][0] 属性名, sizeBoGroup[id][index] 属性值
let sizeBoGroup = {};
_.forEach(sizeInfo.sizeInfoBo.sizeAttributeBos, function(attr) {
... ... @@ -126,13 +128,11 @@ const getSizeInfo = (sizeInfo) => {
if (boyReference && (gender === 1 || gender === 3)) {
temp = {};
temp.param = _.isEmpty(value.boyReferSize.referenceName) ?
' ' : value.boyReferSize.referenceName;
temp.param = value.boyReferSize.referenceName || '';
referenceList.push(temp);
} else if (girlReference && (gender === 2 || gender === 3)) {
temp = {};
temp.param = _.isEmpty(value.girlReferSize.referenceName) ?
' ' : value.girlReferSize.referenceName;
temp.param = value.girlReferSize.referenceName || '';
referenceList.push(temp);
} else {
showReference = false;
... ... @@ -140,7 +140,7 @@ const getSizeInfo = (sizeInfo) => {
_.forEach(value.sortAttributes, function(attr) {
temp = {};
temp.param = _.isEmpty(attr.sizeValue) ? ' ' : attr.sizeValue;
temp.param = attr.sizeValue || ' ';
sizeBoGroup[attr.id].push(temp);
});
});
... ... @@ -149,6 +149,7 @@ const getSizeInfo = (sizeInfo) => {
dest.sizeInfo.detail.list[0] = {};
dest.sizeInfo.detail.list[0].params = sizeNameList;
if (showReference) {
dest.sizeInfo.detail.list[1] = {};
dest.sizeInfo.detail.list[1].params = referenceList;
}
_.forEach(sizeBoGroup, function(value) {
... ... @@ -302,15 +303,15 @@ const getSizeInfo = (sizeInfo) => {
dest.productDetail.enTitle = 'DETAILS';
dest.productDetail.desc = productIntro.replace(/\r\n\t/g, '').
replace(/<\/p>/g, '').
replace(/<img src=/g, '<img class="lazy" src="data:image/gif;' +
'base64,R0lGODlhAQABAJEAAAAAAP///93d3f///yH5BAEAAAMALAAAAAABAAEAAAICVAEAOw=="' +
' data-original=').
replace(/<img border="0" src=/g, '<img border="0" class="lazy" ' +
'src="data:image/gif;base64,' +
'R0lGODlhAQABAJEAAAAAAP///93d3f///yH5BAEAAAMALAAAAAABAAEAAAICVAEAOw=="' +
' data-original=').
replace(/.jpg/g, '.jpg?imageMogr2/thumbnail/750x/quality/90');
replace(/<\/p>/g, '').
replace(/<img src=/g, '<img class="lazy" src="data:image/gif;' +
'base64,R0lGODlhAQABAJEAAAAAAP///93d3f///yH5BAEAAAMALAAAAAABAAEAAAICVAEAOw=="' +
' data-original=').
replace(/<img border="0" src=/g, '<img border="0" class="lazy" ' +
'src="data:image/gif;base64,' +
'R0lGODlhAQABAJEAAAAAAP///93d3f///yH5BAEAAAMALAAAAAABAAEAAAICVAEAOw=="' +
' data-original=').
replace(/.jpg/g, '.jpg?imageMogr2/thumbnail/750x/quality/90');
}
// 清空变量,释放内存
... ...
... ... @@ -229,7 +229,7 @@ const _getResources = (page, channel) => {
if (result && result.code === 200) {
return resourcesProcess(result.data);
} else {
logger.error('SALE 页面资源位返回 code 不是 200');
logger.error('SALE content resource code no 200');
return [];
}
});
... ... @@ -250,7 +250,7 @@ const _getBreakingSort = (yhChannel) => {
if (result && result.code === 200) {
return _processBreakingSort(result.data);
} else {
logger.error('断码区分类接口返回 code 不是 200');
logger.error('api app.sale.getBreakingSort code no 200');
return {};
}
});
... ... @@ -268,7 +268,7 @@ const getSearchData = (params, uid) => {
showSale: false
});
} else {
logger.error('SALE 商品搜索返回 code 不是 200');
logger.error('api SALE product search code no 200');
return [];
}
}),
... ... @@ -276,7 +276,7 @@ const getSearchData = (params, uid) => {
if (result && result.code === 200) {
return result.data.vip_info ? camelCase(result.data.vip_info) : {};
} else {
logger.error('获取用户信息返回 code 不是 200');
logger.error('api get user info code no 200');
return {};
}
})
... ... @@ -296,7 +296,7 @@ const getFilterData = (params) => {
hideSort: params.saleType === '1'
});
} else {
logger.error('SALE 商品搜索返回 code 不是 200');
logger.error('SALE search product code no 200');
return [];
}
});
... ... @@ -328,12 +328,12 @@ const getVipData = (channel) => {
const getBreakCodeData = (params) => {
params = params || {};
return Promise.all([_getResources('breakCode', params.yhChannel), _getBreakingSort(params.yhChannel)])
.then((result) => {
return {
content: result[0],
nav: result[1]
};
});
.then((result) => {
return {
content: result[0],
nav: result[1]
};
});
};
/**
... ... @@ -350,7 +350,7 @@ const getDiscountData = (yhChannel) => {
list: _processDiscount(result.data)
};
} else {
logger.error('折扣专场专题列表返回 code 不是 200');
logger.error('api discount list code no 200');
return {};
}
});
... ... @@ -383,7 +383,7 @@ const getDiscountDetailData = (id, yhChannel) => {
}
};
} else {
logger.error('折扣专场专题详情返回 code 不是 200');
logger.error('discount detail code no 200');
return {};
}
});
... ...
... ... @@ -28,13 +28,18 @@ const recommendForYou = require(`${cRoot}/recommend-for-you`);
// /pro_136349_455445/HEARTSOFARMianMaShuJiaoXiuXianKuPS1684.html
router.get(/\/pro_([\d]+)_([\d]+)\/(.*)/, detail.index); // 商品详情页
// /show_51047967.html
router.get(/\/show_([\d]+)/, detail.indexSkn); // 商品详情页 SKN 进入
router.get('/detail/intro/:productskn', detail.intro); // 商品内嵌页
router.get('/detail/preference', detail.preference); // 为你优选
router.get('/detail/consults', detail.consults); // 商品咨询页
router.get('/detail/consultform', auth, detail.consultform); // 商品咨询表单页
router.get('/detail/comments', detail.comments);
router.get('/detail/comments', detail.comments); // 商品评价
router.post('/detail/consultsubmit', auth, detail.consultsubmit); // 商品咨询提交接口
router.post('/detail/consultupvote', detail.consultUpvoteOrUseful); // 商品咨询提交接口
router.post('/detail/consultuseful', detail.consultUpvoteOrUseful); // 商品咨询提交接口
router.get('/sale', sale.index);
router.get('/sale/discount', sale.discount);
router.get('/sale/discount/detail', sale.discountDetail);
... ...
<ul id="nav-tab" class="nav-tab clearfix">
<li class="comment-nav tap-hightlight">商品评价(<span class="comments-num">{{commentsNum}}</span>)</li>
<li class="consult-nav tap-hightlight">购买咨询(<span class="consults-num">{{consultsNum}}</span>)</li>
{{#if commonConsults}}
<li class="consult-nav tap-hightlight">常见问题</li>
{{^}}
<li class="consult-nav tap-hightlight">购买咨询(<span class="consults-num">{{consultsNum}}</span>)</li>
{{/if}}
</ul>
<div id="feedback-content" >
<div class="comment-content content ">
{{#if commentsNum}}
<div class="comment-content-main content-main">
{{# comments}}
<span class="user-name">
{{userName}}
</span>
<div class="comment-content-main content-main">
{{# comments}}
<span class="user-name">
{{userName}}
</span>
<span class="goods-spec">
购买了{{desc}}
</span>
<p class="detail-content">
{{content}}
</p>
<p class="detail-content">
{{content}}
</p>
<span class="comment-time">
{{time}}
</span>
{{/ comments}}
</div>
<a class="comment-content-footer tap-hightlight" href="{{commentsUrl}}">
{{/ comments}}
</div>
<a class="comment-content-footer tap-hightlight" href="{{commentsUrl}}">
查看更多
<span class="iconfont">&#xe604;</span>
</a>
</a>
{{^}}
<div class="comment-content-main content-main no-item">
<span class="iconfont">&#xe63d;</span>暂无评论
</div>
<div class="comment-content-main content-main no-item">
<span class="iconfont">&#xe63d;</span>暂无评论
</div>
{{/if}}
</div>
<div class="consult-content content hide ">
{{#if consultsNum}}
<div class="consult-content-main content-main">
{{# consults}}
<div class="question">
<span class="iconfont">&#xe644;</span>
<p>
{{question}}<br>
<span class="time">{{time}}</span>
</p>
</div>
<div class="consult-content-main content-main">
{{# consults}}
<div class="question">
<span class="iconfont">&#xe644;</span>
<p>
{{question}}<br>
<span class="time">{{time}}</span>
</p>
</div>
<div class="answer">
<span class="iconfont">&#xe642;</span>
<p>{{answer}}</p>
<div class="answer">
<span class="iconfont">&#xe642;</span>
<p>{{answer}}</p>
</div>
{{/ consults}}
</div>
{{/ consults}}
</div>
<a class="consult-content-footer tap-hightlight" href="{{consultsUrl}}">
查看更多
<span class="iconfont">&#xe604;</span>
</a>
<a class="consult-content-footer tap-hightlight" href="{{consultsUrl}}">
查看更多
<span class="iconfont">&#xe604;</span>
</a>
{{else}}
<div class="consult-content-main content-main no-item">
<span class="iconfont">&#xe63f;</span>暂无咨询
</div>
<div class="consult-content-main content-main no-item">
<span class="iconfont">&#xe63f;</span>暂无咨询
</div>
<div class="consult-content-footer tap-hightlight">
<a href="{{consultsUrl}}">
我要咨询
<span class="iconfont">&#xe604;</span></a>
</div>
<div class="consult-content-footer tap-hightlight">
<a href="{{consultsUrl}}">
我要咨询
<span class="iconfont">&#xe604;</span></a>
</div>
{{/if}}
</div>
</div>
... ...
... ... @@ -34,9 +34,9 @@ module.exports = {
useOneapm: false,
useCache: false,
memcache: {
master: ['192.168.102.222:12111'],
slave: ['192.168.102.222:12111'],
session: ['192.168.102.222:12111'],
master: ['192.168.102.205:12111'],
slave: ['192.168.102.205:12111'],
session: ['192.168.102.205:12111'],
timeout: 1000,
retries: 0
},
... ... @@ -53,7 +53,6 @@ module.exports = {
handleExceptions: true
},
udp: { // send by udp
measurement: 'yohobuywap_node_log',
level: 'debug', // logger level
host: '192.168.102.162', // influxdb host
port: '4444' // influxdb port
... ... @@ -80,9 +79,9 @@ if (isProduction) {
service: 'http://service.yoho.yohoops.org/'
},
memcache: {
master: ['memcache1.yohoops.org:12111', 'memcache2.yohoops.org:12111'],
slave: ['memcache1.yohoops.org:12112', 'memcache2.yohoops.org:12112'],
session: ['memcache1.yohoops.org:12111', 'memcache2.yohoops.org:12111'],
master: ['memcache1.yohoops.org:12111', 'memcache2.yohoops.org:12111', 'memcache3.yohoops.org:12111'],
slave: ['memcache1.yohoops.org:12112', 'memcache2.yohoops.org:12112', 'memcache3.yohoops.org:12112'],
session: ['memcache1.yohoops.org:12111', 'memcache2.yohoops.org:12111', 'memcache3.yohoops.org:12111'],
timeout: 1000,
retries: 0
},
... ...
... ... @@ -56,7 +56,7 @@
"uuid": "^2.0.2",
"winston": "^2.2.0",
"winston-daily-rotate-file": "^1.1.4",
"yoho-node-lib": "0.0.31"
"yoho-node-lib": "0.0.32"
},
"devDependencies": {
"autoprefixer": "^6.3.7",
... ... @@ -100,7 +100,7 @@
"yoho-jquery": "^2.2.4",
"yoho-jquery-lazyload": "^1.9.7",
"yoho-mlellipsis": "0.0.3",
"yoho-node-lib": "0.0.31",
"yoho-node-lib": "0.0.32",
"yoho-swiper": "^3.3.1"
}
}
... ...
... ... @@ -41,6 +41,7 @@ var navtabEle = document.getElementById('nav-tab'),
$('#feedback-content .consult-content').removeClass('hide');
}
$('.goods-consults .consult-item:lt(2)').removeClass('hide');
}());
if (navtabHammer) {
... ... @@ -91,8 +92,7 @@ if ($('.goods-consults-page').length > 0) {
if (readmoreHammer) {
readmoreHammer.on('tap', function() {
$('.readmore').hide();
$('.goods-consults.customer-consults').removeClass('customer-consults');
$('.goods-consults').find('.consult-item').removeClass('hide');
return false;
});
}
... ...
... ... @@ -47,28 +47,27 @@ function hiddenTips($ele) {
// }
// }
function wrapElements(selector, count) {
var elArr = null;
// function wrapElements(selector, count) {
// var elArr = null;
$(selector).each(function(idx) {
elArr = $(selector).slice(idx, idx + count);
// $(selector).each(function(idx) {
// elArr = $(selector).slice(idx, idx + count);
if (elArr.length === count && idx % count === 0) {
$(elArr).wrapAll($('<div class="js-wraper"></div>'));
}
});
}
// if (elArr.length === count && idx % count === 0) {
// $(elArr).wrapAll($('<div class="js-wraper"></div>'));
// }
// });
// }
function search() {
if (searching || end) {
if (searching || end || !introUrl) {
return;
}
searching = true;
// alert($('#reference-swiper-container .swiper-wrapper').width());
loading.showLoadingMask();
$.ajax({
... ... @@ -98,7 +97,7 @@ function search() {
// if (!isFlexSupport()) {
// $('.detail .column').removeClass('column').addClass('oldbox');
// }
wrapElements('.detail .column', 2);
// wrapElements('.detail .column', 2);
searching = false;
end = true;
loading.hideLoadingMask();
... ...
... ... @@ -56,26 +56,28 @@ $basicBtnC: #eb0313;
&.table {
width: 100%;
.js-wraper {
display: flex;
flex-wrap: wrap;
justify-content: flex-start;
}
overflow: hidden;
.column {
display: flex;
flex-basis: 49.9%;
align-items: center;
box-sizing: border-box;
padding: 6px 3%;
width: 49.9%;
border: 1px solid #fff;
background-color: $tableCellC;
word-wrap: break-word;
text-overflow: ellipsis;
overflow: hidden;
white-space: nowrap;
font-size: 24px;
}
.column:nth-child(2n+1) {
float: left;
}
.column:nth-child(2n+2) {
float: right;
}
.oldbox {
float: left;
overflow: hidden;
... ... @@ -284,7 +286,7 @@ $basicBtnC: #eb0313;
.limit-sale {
position: absolute;
top: 50%;
right: 84px;
right: 24px;
margin-top: -24px;
padding: 4px 20px;
height: 48px;
... ... @@ -384,13 +386,13 @@ $basicBtnC: #eb0313;
text-align: left;
.vip-img {
background: resolve('product/silver.png') no-repeat;
background: resolve("product/silver.png") no-repeat;
}
}
&:nth-child(2) {
.vip-img {
background: resolve('product/golden.png') no-repeat;
background: resolve("product/golden.png") no-repeat;
}
}
... ... @@ -398,7 +400,7 @@ $basicBtnC: #eb0313;
text-align: right;
.vip-img {
background: resolve('product/platinum.png') no-repeat;
background: resolve("product/platinum.png") no-repeat;
}
}
}
... ... @@ -707,52 +709,53 @@ $basicBtnC: #eb0313;
a {
display: inline-block;
}
&.num-incart {
color: #444;
font-size: 47px;
}
.num-incart {
position: relative;
color: #444;
font-size: 47px;
}
&.favorite {
color: #ccc;
font-size: 34px;
}
.favorite {
color: #ccc;
font-size: 34px;
background-color: transparent;
}
&.favorite.liked {
color: $basicBtnC;
}
.favorite.liked {
color: $basicBtnC;
}
&.addto-cart,
&.sold-out {
margin: 0 100px 0 115px;
width: 260px;
height: 80px;
background-color: $basicBtnC;
color: #fff;
text-align: center;
font-size: 32px;
line-height: 80px;
}
.addto-cart,
.sold-out {
margin: 0 100px 0 115px;
width: 260px;
height: 80px;
background-color: $basicBtnC;
color: #fff;
text-align: center;
font-size: 32px;
line-height: 80px;
}
&.sold-out {
background-color: #f58189;
}
.sold-out {
background-color: #ccc;
}
.num-tag {
position: absolute;
top: 0;
left: 48px;
right: -15px;
display: block;
width: 72px;
height: 72px;
width: 30px;
height: 30px;
border-radius: 50%;
background: $basicBtnC;
color: #fff;
text-align: center;
font-size: 40px;
line-height: 72px;
transform: scale(0.5);
font-size: 20px;
line-height: 30px;
&.hide {
display: none;
... ... @@ -768,3 +771,7 @@ $basicBtnC: #eb0313;
top: 40%;
}
}
iframe {
display: none;
}
... ...
... ... @@ -4,10 +4,8 @@
padding-bottom: 20px;
.service {
margin-left: 50px;
width: 494px;
height: 28px;
background: resolve('product/service.png') no-repeat;
background: resolve("product/service.png") no-repeat;
background-size: cover;
}
... ...