Showing 52 changed files with 1870 additions and 1344 deletions

Too many changes to show.

To preserve performance only 52 of 52+ files are displayed.

phantomjs_cdnurl=http://npm.taobao.org/mirrors/phantomjs
registry=http://npm.yoho.cn
... ...
... ... @@ -43,8 +43,6 @@ exports.getCouponData = (channel, params) => {
break;
}
let i = 0;
coupon.data.forEach(function(val, index) {
// 头部banner
if (val.templateName === 'focus') {
... ... @@ -74,7 +72,6 @@ exports.getCouponData = (channel, params) => {
});
result.categories.push(obj);
i++;
}
});
}
... ... @@ -98,8 +95,6 @@ exports.getCouponStatus = (params) => {
break;
}
let i = 0;
coupon.data.forEach(function(val) {
if (val.template_name === 'getCoupon' && val.data.length) {
// 优惠券楼层
... ... @@ -120,7 +115,6 @@ exports.getCouponStatus = (params) => {
result.categories.push(cou);
}
});
i++;
}
});
}
... ...
... ... @@ -304,57 +304,55 @@ const _getIntroInfo = (productSkn, additionalData)=> {
* @return result Object 格式化数据
*/
const _detailDataPkg = (origin) => {
return co(function*() {
if (_.isEmpty(origin) || _.isEmpty(origin)) {
return {};
}
if (_.isEmpty(origin) || _.isEmpty(origin)) {
return {};
}
let result = {};
let propOrigin = _.partial(_.get, origin);
let result = {};
let propOrigin = _.partial(_.get, origin);
// 商品名称
if (!propOrigin('product_name')) {
return result;
}
// 商品名称
if (!propOrigin('product_name')) {
return result;
}
result.name = propOrigin('product_name');
result.skn = propOrigin('product_skn');
result.productId = propOrigin('product_id');
result.name = propOrigin('product_name');
result.skn = propOrigin('product_skn');
result.productId = propOrigin('product_id');
// 商品价格
result.marketPrice = propOrigin('format_market_price');
result.salePrice = propOrigin('format_sales_price');
result.hasOtherPrice = true;
// 商品价格
result.marketPrice = propOrigin('format_market_price');
result.salePrice = propOrigin('format_sales_price');
result.hasOtherPrice = true;
if (result.salePrice === '0') {
delete result.salePrice;
result.hasOtherPrice = false;
}
if (result.salePrice === '0') {
delete result.salePrice;
result.hasOtherPrice = false;
}
// 上市期
if (propOrigin('expect_arrival_time')) {
result.arrivalDate = `${propOrigin('expect_arrival_time')}月`;
result.presalePrice = propOrigin('format_sales_price');
delete result.salePrice;
result.hasOtherPrice = false;
}
// 上市期
if (propOrigin('expect_arrival_time')) {
result.arrivalDate = `${propOrigin('expect_arrival_time')}月`;
result.presalePrice = propOrigin('format_sales_price');
delete result.salePrice;
result.hasOtherPrice = false;
}
// sku商品信息
let skuData = _getSkuDataByProductBaseInfo(origin);
// sku商品信息
let skuData = _getSkuDataByProductBaseInfo(origin);
// 商品购买状态
let soldOut = !!(propOrigin('status') === 0 || skuData.totalStorageNum === 0);
let virtualGoods = propOrigin('attribute') === 3; // 虚拟商品
// 商品购买状态
let soldOut = !!(propOrigin('status') === 0 || skuData.totalStorageNum === 0);
let virtualGoods = propOrigin('attribute') === 3; // 虚拟商品
if (!soldOut && !virtualGoods) {
result.addToCart = 1;
}
if (!soldOut && !virtualGoods) {
result.addToCart = 1;
}
result.isCollect = propOrigin('is_collect');
result.colors = skuData.skuGoods;
result.isCollect = propOrigin('is_collect');
result.colors = skuData.skuGoods;
return result;
})();
return result;
};
/**
... ... @@ -377,13 +375,9 @@ const getProductInfoAsync = (pid) => {
}
let productSkn = _.get(productData, 'data.product_skn');
let requestData = yield Promise.all([
_getProductIntroAsync(productSkn), // 商品详细介绍
_detailDataPkg(productData.data) // 商品详细价格
]);
let productDescription = requestData[0];
let productInfo = requestData[1];
let productDescription = yield _getProductIntroAsync(productSkn);
let productInfo = _detailDataPkg(productData.data);
let intro = _getIntroInfo(productSkn, productDescription);
return Object.assign(productInfo, intro);
... ... @@ -707,7 +701,6 @@ const addToFav = (uid, skuList, hasPromotion, cartDelList) => {
* @return array
*/
const checkUserIsFav = (uid, skuList) => {
return co(function * () {
let result = {};
... ... @@ -724,7 +717,7 @@ const checkUserIsFav = (uid, skuList) => {
return result;
}
return cartApi.checkUserIsFavProductList(uid, skuList);
return yield cartApi.checkUserIsFavProductList(uid, skuList);
})();
};
... ...
... ... @@ -75,12 +75,12 @@
{{#with shoppingCartData}}
{{#isY is_multi_package}}
<div class="multi-package-row">
温馨提示:您购买的商品<em class="red">分属不同仓库</em>{{../package_title}}<em class="red">预计3-5天内发货给您</em>
温馨提示:您购买的商品<em class="red">分属不同仓库</em>{{../package_title}}
<span class="show-package"></span>
<div class="package-list hide">
{{#each ../package_list}}
<div class="package-item">
<p class="package-title bold">包裹{{math @index '+' 1}}:{{#isEqual supplier_id '0'}}总仓发货{{^}}异地调拨 <em class="red">预计3-5天内发货给您</em>{{/isEqual}}</p>
<p class="package-title bold">包裹{{math @index '+' 1}}:{{title}}</p>
<div class="toggle-btns">
<span class="toggle-icon left-icon"></span>
<span class="toggle-icon right-icon"></span>
... ...
... ... @@ -13,7 +13,7 @@ const helpers = global.yoho.helpers;
const config = global.yoho.config;
const processProduct = require(`${global.utils}/product-process`).processProduct;
const searchApi = require('../../product/models/search-api');
const searchApi = require('./search-api');
const api = global.yoho.API;
... ...
/**
* Created by TaoHuang on 2016/6/14.
*/
'use strict';
const _ = require('lodash');
const Fn = require('lodash/fp');
const md5 = require('md5');
const api = global.yoho.API;
const serviceApi = global.yoho.ServiceAPI;
const config = global.yoho.config;
const helpers = global.yoho.helpers;
const cache = global.yoho.cache;
const logger = global.yoho.logger;
// 判断用户是否收藏品牌
const isFavoriteBrandUrl = '/shops/service/v1/favorite/getUidBrandFav';
// 根据品牌查询相关文章
const relateArticleUrl = 'guang/service/v2/article/getArticleByBrand';
const GLOBAL_BASE_URI = '/product/global/list';
// 缓存生效时间
const CACHE_TIME_S = 60;
const getSearchCacheKey = params => {
let removeUnusedKey = Fn.omit(['page', 'limit', 'need_filter', 'order']);
let sortByKey = Fn.pipe(Fn.toPairs, Fn.sortBy(0), Fn.flatten);
let genKey = Fn.pipe(Fn.cloneDeep, removeUnusedKey, sortByKey, Fn.join('_'));
return 'search_custom_' + md5(genKey(params));
};
const saveCache = (key, kv, cacheTime) => {
cache.set(key, kv, cacheTime)
.catch(err => logger.debug(`product query save cache data fail:${err.toString()}`));
};
const getProductListOrig = finalParams => api.get('', finalParams);
const getKeyActivityAsync = (query) => {
return api.get('', {
method: 'app.search.word',
query: query
}, {
catch: true,
code: 200
});
};
/**
* 获取商品列表
* @return
*/
const getProductList = (params, from) => {
let finalParams = {
method: 'web.search.search',
sales: 'Y',
outlets: 2,
stocknumber: 1,
need_filter: 'yes',
limit: 60
};
Object.assign(finalParams, params);
// 店铺默认排序s_w_desc
if (params.shopId || params.shop_id || params.shop) {
finalParams.order = params.order || 's_w_desc';
}
if (from) {
finalParams.from = from;
}
if (!config.useCache) {
return getProductListOrig(finalParams);
} else {
let cKey = getSearchCacheKey(finalParams);
return cache.get(cKey)
.catch(err => logger.debug(`product query save cache data fail:${err.toString()}`))
.then(cdata => {
let hasCache = false;
if (cdata) {
try {
cdata = JSON.parse(cdata);
} catch (e) {
logger.debug('getProductList cache data parse fail.');
}
if (cdata.filter && cdata.standard) {
hasCache = true;
finalParams.need_filter = 'no';
}
}
return getProductListOrig(finalParams).then(result => {
if (hasCache && result && result.data) {
Object.assign(result.data, cdata);
} else {
if (result && result.data && result.data.filter) {
saveCache(cKey, Object.assign({}, {
filter: result.data.filter,
standard: result.data.standard
}), CACHE_TIME_S);
}
}
return result;
});
});
}
};
/**
* 获取seo商品列表
* @return
*/
const getSeoProductList = (params, from) => {
let finalParams = {
method: 'web.search.forseo',
sales: 'Y',
outlets: 2,
stocknumber: 1,
need_filter: 'no',
limit: 60
};
Object.assign(finalParams, params);
if (from) {
finalParams.from = from;
}
return getProductListOrig(finalParams);
};
const getSortListOrig = (finalParams) => api.get('', finalParams, config.apiCache);
/**
* 获取分类列表
* @return
*/
const getSortList = (params, channel) => {
let finalParams = {
method: 'web.regular.groupsort.sale',
sales: 'Y', // 在销售商品分类
status: 1, // 上架商品分类
stocknumber: 1 // 过滤掉已售罄
};
Object.assign(finalParams, params);
if (channel) {
switch (channel) {
case 'boys':
finalParams.yh_channel = 1;
break;
case 'girls':
finalParams.yh_channel = 2;
break;
case 'kids':
finalParams.yh_channel = 3;
break;
case 'lifestyle':
finalParams.yh_channel = 4;
break;
default:
break;
}
}
if (!config.useCache) {
return getSortListOrig(finalParams);
} else {
let cKey = getSearchCacheKey(finalParams);
return cache.get(cKey)
.catch(err => logger.debug(`product query save cache data fail:${err.toString()}`))
.then(cdata => {
let cdataObj;
if (cdata) {
try {
cdataObj = JSON.parse(cdata);
} catch (e) {
logger.debug('getSortList cache data parse fail.');
}
}
if (cdataObj) {
return cdataObj;
} else {
return getSortListOrig(finalParams).then(ret => {
if (ret && ret.code === 200) {
saveCache(cKey, ret, CACHE_TIME_S);
}
return ret;
});
}
});
}
};
/**
* 获取分类图文介绍
* @return
*/
const getSortIntro = (params) => {
let finalParams = {
method: 'web.search.banner'
};
Object.assign(finalParams, params);
return api.get('', finalParams, config.apiCache);
};
/**
* 获取分类广告
* @return
*/
const getSortAds = (params) => {
let finalParams = {
method: 'app.ads.list'
};
Object.assign(finalParams, params);
return api.get('', finalParams, config.apiCache);
};
/**
* 获取品牌系列
* @return
*/
const getBrandShopSeries = (params) => {
let finalParams = {
method: 'web.brand.series',
status: params.status || 1
};
if (params.brandId) {
finalParams.brand_id = params.brandId;
} else if (params.shopId) {
Object.assign(finalParams, {
method: 'web.shop.series',
shop_id: params.shopId
});
}
return api.get('', finalParams, config.apiCache);
};
/**
* 获取品牌folder
* @return
*/
const getBrandShopFolder = (params) => {
let finalParams = {
method: 'web.brand.folder',
status: params.status || 1
};
if (params.brandId) {
finalParams.brand_id = params.brandId;
} else if (params.shopId) {
Object.assign(finalParams, {
method: 'web.shop.folder',
shop_id: params.shopId
});
}
return api.get('', finalParams, config.apiCache);
};
/**
* 获取品牌水牌
* @return
*/
const getNodeContent = (params) => {
let finalParams = {
method: 'web.html.content',
mode: params.mode || 'release',
node: params.node || ''
};
return api.get('', finalParams, config.apiCache);
};
/**
* 一周新品上架
* @return
*/
const getWeekNew = (params) => {
let finalParams = {
method: 'web.regular.recent'
};
Object.assign(finalParams, params);
return api.get('', finalParams, config.apiCache);
};
const getBrandCouponAsync = (brandId, uid) => {
let extra = {code: 200};
if (!uid) {
extra.cache = true;
}
return api.get('', {
method: 'app.brand.getBrandIntro',
brand_id: brandId,
uid: uid
}, extra);
};
/**
* 根据关键词搜索品牌店铺信息
* @return
*/
const getBrandShop = (query) => {
let finalParams = {
method: 'web.search.shopListInfo'
};
return api.get('', Object.assign(finalParams, {keyword: query}), config.apiCache);
};
/**
* 根据搜索得到店铺/品牌
*/
const getShopList = params => {
if (!params || !params.query) {
return;
}
return getBrandShop(params.query).then(shops => {
let shopEntry = [];
_.forEach(_.get(shops, 'data.shopList', []), value => {
let shopInfo = {
home: helpers.urlFormat('', null, value.shop_domain || value.brand_domain),
logo: value.shop_logo || value.brand_ico,
shopName: value.shop_name || value.brand_name,
shopType: '',
sort: []
};
if (value.is_global === 'Y') {
shopInfo.home = helpers.urlFormat(GLOBAL_BASE_URI, {brand: value.global_brand_id});
shopInfo.shopType = 'global-brand';
}
// 店铺/品牌的小分类
_.forEach(_.get(value, 'sortInfo.sort', []), sortInfo => {
_.forEach(_.get(sortInfo, 'sub', []), subSort => {
let sortHref;
if (value.is_global !== 'Y') {
sortHref = helpers.urlFormat('', {misort: subSort.sort_id},
value.shop_domain || value.brand_domain);
} else {
sortHref = helpers.urlFormat(GLOBAL_BASE_URI, {
misort: subSort.sort_id,
brand: value.global_brand_id
});
}
shopInfo.sort.push({
href: sortHref,
name: subSort.sort_name
});
});
});
shopEntry.push(shopInfo);
});
return shopEntry;
});
};
/**
* 搜索提示
* @return
*/
const getSuggest = (params) => {
let finalParams = {
method: 'app.search.fuzzy',
keyword: params.keyword || ''
};
return api.get('', finalParams, config.apiCache);
};
/**
* 根据品牌域名获取品牌信息
* @return
*/
const getBrandData = (params) => {
let finalParams = {
method: 'web.brand.byDomain',
domain: params.domain || ''
};
return api.get('', finalParams, config.apiCache);
};
/**
* 根据uid和品牌id判断品牌是否收藏
* @return
*/
const isFavoriteBrand = (uid, brandId) => {
return serviceApi.get(isFavoriteBrandUrl, {
uid: uid,
brandId: brandId
});
};
/**
* 根据shopId获取店铺基本信息
* @return
*/
const getShopInfo = (shopId, uid) => {
let finalParams = {
method: 'app.shops.getIntro',
shop_id: shopId || 0,
uid: uid || 0
};
return api.get('', finalParams, config.apiCache);
};
/**
* 查询店铺下面的所有品牌
*/
const getShopBrands = (shopId) => {
return api.get('', {method: 'app.shops.getShopsBrands', shop_id: shopId || 0}, config.apiCache);
};
/**
* 查询店铺装修
*/
const getShopDecorator = (shopId) => {
return api.get('', {method: 'app.shopsdecorator.getList', shop_id: shopId || 0}, config.apiCache);
};
/**
* 通过品牌获取相关文章
*/
const getArticleByBrand = (brand, udid, limit) => {
let params = {
brand_id: brand || 0,
udid: udid,
limit: limit || 6
};
return serviceApi.get(relateArticleUrl, params);
};
const getBrands4Filter = (params) => {
return api.get('', Object.assign({
method: 'web.regular.aggBrand'
}, params));
};
/**
* 有可能喜欢的商品
* @param int $channel 频道,1代表男生,2代表女生,3代表潮童,4代表创意生活
* @param $uid 用户ID
* @param $udid 设备ID
* @param $rec_pos 位置码
* @param $limit 数量限制
* @return array 接口返回的数据
* */
const lessRecommend = (channelNum, uid, udid, recPos, limit) => {
let param = {
method: 'app.search.newLast7day',
yh_channel: channelNum,
udid: udid,
rec_pos: recPos,
limit: limit
};
if (uid) {
param.uid = uid;
}
return api.get('', param);
};
module.exports = {
getKeyActivityAsync,
getProductList,
getSeoProductList,
getSortList,
getSortIntro,
getSortAds,
getBrandShopFolder,
getBrandShopSeries,
getWeekNew,
getBrandCouponAsync,
getBrandShop,
getSuggest,
getBrandData,
getNodeContent,
isFavoriteBrand,
getShopInfo,
getShopBrands,
getShopDecorator,
getArticleByBrand,
getShopList,
getBrands4Filter,
getProductListOrig,
getSearchCacheKey,
lessRecommend
};
... ...
... ... @@ -754,20 +754,18 @@ module.exports = class extends global.yoho.BaseModel {
* 分-验证图形验证码-ajax
*/
checkVerifyCode(req) {
return co(function*() {
let captchaCode = _.trim(req.body.verifyCode || '').toLowerCase(),
resqData = {};
let captchaCode = _.trim(req.body.verifyCode || '').toLowerCase(),
resqData = {};
if (captchaCode && captchaCode !== req.session.captcha) {
resqData.code = 400;
resqData.message = '图形验证码不正确';
} else {
resqData.code = 200;
resqData.message = '';
}
if (captchaCode && captchaCode !== req.session.captcha) {
resqData.code = 400;
resqData.message = '图形验证码不正确';
} else {
resqData.code = 200;
resqData.message = '';
}
return resqData;
})();
return Promise.resolve(resqData);
}
/**
... ...
... ... @@ -262,12 +262,8 @@ exports.getCommentList4Order = (uid, orderCode) => {
};
exports.saveShareOrder = data => {
let process = function*() {
return api.post('', {
method: 'show.saveShareOrder',
parameters: JSON.stringify(data)
});
};
return co(process)();
return api.post('', {
method: 'show.saveShareOrder',
parameters: JSON.stringify(data)
});
};
... ...
... ... @@ -92,21 +92,15 @@ const getComplaintsList = (uid, page, limit) => {
* @return { Object } 添加投诉结果
*/
const addComplaints = (uid, params) => {
let process = function*() {
let res = api.post('', {
method: 'web.complaints.add',
uid: uid,
title: _.trim(params.title),
customer: _.trim(params.customer),
complaintsType: _.trim(params.complaintsType),
orderCode: _.trim(params.orderCode),
content: _.trim(params.content)
});
return res;
};
return co(process)();
return api.post('', {
method: 'web.complaints.add',
uid: uid,
title: _.trim(params.title),
customer: _.trim(params.customer),
complaintsType: _.trim(params.complaintsType),
orderCode: _.trim(params.orderCode),
content: _.trim(params.content)
});
};
/**
... ... @@ -117,17 +111,11 @@ const addComplaints = (uid, params) => {
* @return { Object } 撤销投诉结果
*/
const cancelComplaints = (uid, id) => {
let process = function*() {
let res = api.post('', {
method: 'web.complaints.cancel',
uid: uid,
id: id
});
return res;
};
return co(process)();
return api.post('', {
method: 'web.complaints.cancel',
uid: uid,
id: id
});
};
module.exports = {
... ...
... ... @@ -621,6 +621,13 @@ module.exports = class extends global.yoho.BaseModel {
orderType, attribute, refundStatus, links) {
let operation = {};
if (attribute === 9 || attribute === 11) {
Object.assign(operation, {
deposit: true
});
return operation;
}
// 立刻付款
if (_.includes(links, 'buyNow')) {
Object.assign(operation, {
... ... @@ -881,14 +888,18 @@ module.exports = class extends global.yoho.BaseModel {
detail.packageTitle = orderDetail.package_title;
detail.packages = that._getPackageInfo(orderDetail);
// 判断是否可以修改地址
if (orderDetail.can_update_delivery_address === 'Y') {
detail.changeable = true;
}
if (+orderDetail.attribute === 9 || +orderDetail.attribute === 11) {
// 定金预售不能操作
} else {
// 判断是否可以修改地址
if (orderDetail.can_update_delivery_address === 'Y') {
detail.changeable = true;
}
// 判断是否可以修改省份
if (orderDetail.is_support_change_province === 'N') {
detail.changeProvince = true;
// 判断是否可以修改省份
if (orderDetail.is_support_change_province === 'N') {
detail.changeProvince = true;
}
}
return detail;
... ...
... ... @@ -340,6 +340,12 @@
</p>
{{/if}}
{{#if deposit}}
<p>
<span class="op-dis">*定金预售商品只能在APP端操作</span>
</p>
{{/if}}
{{#if checkQrCode}}
<a class="check-qrcode oo-btn" href="{{checkQrCode}}" target="_blank">查看二维码</a>
{{/if}}
... ...
... ... @@ -73,7 +73,7 @@ const bind = {
let openId = req.body.openId;
let area = req.body.area;
if (req.session.verifyCode !== 'relateStep1') {
if (req.session.type !== 'relateStep1') {
return next();
}
... ...
... ... @@ -29,11 +29,18 @@ const checkAPI = (req, res) => {
};
const passwordRequired = (req, res, next) => {
if (req.session.type === 'needCaptcha' && req.body.loginType === 'password') {
return requiredAPI(req, res, next);
// 默认账户密码登录需要验证码
if (_.get(req.app.locals.pc, 'password.alwaysNeedCaptcha', false)) {
if (req.body.loginType === 'password') {
return requiredAPI(req, res, next);
}
} else {
return next();
if (req.session.type === 'needCaptcha' && req.body.loginType === 'password') {
return requiredAPI(req, res, next);
}
}
return next();
};
const tryGeetest = (req, res, next) => {
... ...
... ... @@ -2,99 +2,64 @@
* Created by TaoHuang on 2016/6/18.
*/
'use strict';
/**
* 验证码的形式: xxxx|page
*/
const captchaService = require('../models/captcha-img-service');
const CAPTCHA = global.yoho.config.UNIVERSAL_CAPTCHA;
const CaptchaServiceModel = require('../models/captcha-img-service');
const request = require('request');
const logger = global.yoho.logger;
const CAPTCHATIME = 1 * 60000; // 默认1分钟
// 对比函数
const _mustEqual = (req) => {
let result = req.session.captcha && (req.body.verifyCode === req.session.captcha ||
req.body.verifyCode === CAPTCHA);
const _mustEqualAsync = (req) => {
let id = req.session.id;
let verifyCode = req.body.verifyCode;
logger.info(`img captcha auth [${result ? 'success' : 'fail'}]`,
`CLIENT [${req.body.verifyCode}] SERVER [${req.session.captcha}]`);
if (!id || !verifyCode) {
return Promise.resolve({
code: 405,
message: '请将所有图片点击翻转至正向朝上'
});
}
return result;
return req.ctx(CaptchaServiceModel).check(id, verifyCode);
};
// 中间件
const requiredAPI = (req, res, next) => {
let count = req.session.captchaCount;
let time = new Date().getTime();
let firstTime = req.session.captchaTime;
if (count >= 4 || firstTime && (time - firstTime > CAPTCHATIME)) {
req.session.captcha = CAPTCHA;
return res.json({
code: 405,
message: '该验证码已失效,请刷新验证码',
data: {
needCaptcha: true
}
});
}
req.session.captchaCount = count + 1;
if (_mustEqual(req)) {
return next();
} else {
return res.json({
code: 405,
message: '请将图形验证码翻转至正确方向',
data: {
needCaptcha: true
}
});
}
_mustEqualAsync(req).then((result) => {
if (result.code === 200) {
return next();
} else {
return res.json({
code: 405,
message: result.message,
data: {
needCaptcha: true
}
});
}
}).catch(next);
};
// 七牛验证码
const generate = (req, res, next) => {
captchaService.generateCaptcha().then((result) => {
req.session.captcha = result.data.text;
req.ctx(CaptchaServiceModel).generateCaptcha(req.session.id).then((result) => {
req.session.captchaCount = 0;
req.session.captchaTime = new Date().getTime();
res.type('png');
if (result.code === 200) {
request(result.data.images).pipe(res);
request(result.data.url).pipe(res);
}
}).catch(next);
};
// 端到端检查
const checkAPI = (req, res) => {
let count = req.session.captchaCount;
let time = new Date().getTime();
let firstTime = req.session.captchaTime;
if (count >= 4 || firstTime && (time - firstTime > CAPTCHATIME)) {
req.session.captcha = CAPTCHA;
return res.json({
code: 405,
message: '该验证码已失效,请刷新验证码'
});
}
req.session.captchaCount = count + 1;
if (_mustEqual(req)) {
return res.json({
code: 200,
message: '验证成功'
});
} else {
return res.json({
code: 405,
message: '请将图形验证码翻转至正确方向'
});
}
const checkAPI = (req, res, next) => {
_mustEqualAsync(req).then(result => {
res.json(result);
}).catch(next);
};
module.exports = {
... ...
... ... @@ -4,20 +4,39 @@
'use strict';
const _ = require('lodash');
const CAPTCHA = require('../data/captcha.json');
const length = CAPTCHA.length - 1 || -1;
const apiUrl = global.yoho.config.domains.service;
exports.gen = () => {
if (length !== -1) {
return Promise.resolve({
code: 200,
data: CAPTCHA[_.random(0, length)]
});
} else {
return Promise.reject({
code: 400,
message: '验证码错误'
const PAGE = 'pc';
module.exports = class extends global.yoho.BaseModel {
constructor(ctx) {
super(ctx);
}
gen(id) {
if (id) {
return Promise.resolve({
code: 200,
data: {
url: `${apiUrl}passport/img-check.jpg?udid=${id}&fromPage=${PAGE}`
}
});
} else {
return Promise.reject({
code: 400,
message: '生成二维码失败,请重新刷新!'
});
}
}
check(id, captcha) {
return this.get({
data: {
method: 'app.verified.graphic',
udid: id,
fromPage: PAGE,
degrees: captcha
}
});
}
};
... ...
/**
* Created by TaoHuang on 2016/7/1.
*/
const CaptchaApi = require('./captcha-api');
const logger = global.yoho.logger;
'use strict';
module.exports = class extends global.yoho.BaseModel {
constructor(ctx) {
super(ctx);
const api = require('./captcha-api');
const uuid = require('uuid');
this.api = new CaptchaApi(ctx);
}
generateCaptcha(id) {
return this.api.gen(id)
.then(result => {
logger.info('get captcha from ', result.data.url);
return result;
});
}
check(id, captcha) {
return this.api.check(id, captcha).then((result) => {
if (result.code === 200) {
return {
code: 200,
message: '验证成功'
};
} else if (result.code === 503 || result.code === 504 || result.code === 501) {
return {
code: 403,
message: result.message
};
} else {
return {
code: 405,
message: result.message,
data: {
needCaptcha: true
}
};
}
});
}
exports.generateCaptcha = () => {
return api.gen().then((result) => {
if (result.code === 200) {
let codeStr = result.data.degrees.map((rotate) => {
return (4 - rotate / 90 % 4) % 4;
}).join('');
return {
code: 200,
data: {
text: codeStr,
images: `${result.data.verifiedGraphicCode}` +
`?imageView2/2/w/240/q/70/watermark/2/text/${uuid.v4()}/fontsize/120/dissolve/10`
}
};
} else {
return {
code: 400,
message: '生成二维码失败,请重新刷新!',
data: {
text: 'yoho9636'
}
};
}
});
};
... ...
... ... @@ -4,8 +4,7 @@
'use strict';
const mRoot = '../models';
const service = require(`${mRoot}/coupon-service`);
const service = require('../models/coupon-service');
const acquire = (req, res, next) => {
let uid = req.user.uid;
... ... @@ -18,7 +17,7 @@ const acquire = (req, res, next) => {
});
}
service.acquireAsync(cid, uid).then((result) => {
req.ctx(service).acquireAsync(cid, uid).then((result) => {
return res.json(result);
}).catch(next);
};
... ...
... ... @@ -6,16 +6,17 @@
'use strict';
const helpers = global.yoho.helpers;
const mRoot = '../models';
const service = require(`${mRoot}/detail-service`);
const detailHelper = require(`${mRoot}/detail-helper`);
const moment = require('moment');
const DEFAULT_AVATAR_ICO = 'https://static.yohobuy.com/images/v3/boy.jpg';
const _ = require('lodash');
const qs = require('querystring');
const helpers = global.yoho.helpers;
const DEFAULT_AVATAR_ICO = 'https://static.yohobuy.com/images/v3/boy.jpg';
/**
* 首屏渲染商品详情
*/
... ... @@ -32,7 +33,7 @@ const showMain = (req, res, next) => {
saveInCookies: null
};
return service.showMainAsync(req, Object.assign({
return req.ctx(service).showMainAsync(req, Object.assign({
skn: skn,
channel: channel,
gender: gender
... ... @@ -42,14 +43,13 @@ const showMain = (req, res, next) => {
page: 'detail'
}, result.seo, result));
}).catch(()=> next());
};
const showMainBack = (req, res) => {
let pid = req.params[0];
return service.showMainBackAsync({
return req.ctx(service).showMainBackAsync({
pid: pid
}).then((result)=> {
if (_.get(result, 'data.product_skn')) {
... ... @@ -61,7 +61,6 @@ const showMainBack = (req, res) => {
res.end();
}).catch();
};
/**
... ... @@ -73,7 +72,7 @@ const detailHeader = (req, res, next) => {
let vipLevel = detailHelper.vipLevel(req.user.vip);
let dataMd5 = req.query.md5 || 0;
let saveCurrentGoodsInCookies = _.partial(service.saveRecentGoodInCookies,
let saveCurrentGoodsInCookies = _.partial(req.ctx(service).saveRecentGoodInCookies,
req.cookies._browseskn,
res
);
... ... @@ -82,8 +81,9 @@ const detailHeader = (req, res, next) => {
return res.status(204).end();
}
return service.getDetailHeader({skn: skn}, uid, req.user.isStudent, vipLevel, dataMd5, saveCurrentGoodsInCookies)
.then((result) => {
return req.ctx(service).getDetailHeader(
{skn: skn}, uid, req.user.isStudent, vipLevel, dataMd5, saveCurrentGoodsInCookies
).then((result) => {
if (result.code === 200) {
return res.render('product/detail-header', Object.assign({layout: false}, result.data));
} else {
... ... @@ -105,7 +105,7 @@ const detailReturn = (req, res, next) => {
};
}
return service.saleReturn(skn).then(result => {
return req.ctx(service).saleReturn(skn).then(result => {
return res.json({
code: 200,
data: result
... ... @@ -119,7 +119,7 @@ const detailReturn = (req, res, next) => {
const indexHotArea = (req, res, next) => {
let pid = req.query.productId || 0;
return service.indexHotAreaAsync(pid).then((result) => {
return req.ctx(service).indexHotAreaAsync(pid).then((result) => {
res.render('product/hotarea', {
hotArea: result,
layout: false
... ... @@ -137,7 +137,7 @@ const indexComment = (req, res, next) => {
let size = req.query.size || 10;
let filterId = req.query.filterId || 7; // 7全部,6有图
return service.getShareOrderListAsync(pid, page, size, filterId).then((result) => {
return req.ctx(service).getShareOrderListAsync(pid, page, size, filterId).then((result) => {
let pageResponse = _.get(result, 'data.pageResponse', {});
return res.json({
... ... @@ -175,7 +175,7 @@ const indexConsult = (req, res, next) => {
let page = req.query.page || 1;
let size = req.query.size || 10;
return service.indexConsultAsync(uid, pid, page, size).then(result => {
return req.ctx(service).indexConsultAsync(uid, pid, page, size).then(result => {
return res.json({
code: 200,
... ... @@ -193,7 +193,7 @@ const createConsult = (req, res, next) => {
let content = req.body.content;
if (content && uid) {
return service.createConsultAsync(uid, pid, content).then(result => {
return req.ctx(service).createConsultAsync(uid, pid, content).then(result => {
res.json(result);
}).catch(next);
} else if (!content) {
... ... @@ -230,7 +230,7 @@ const likeConsult = (req, res, next) => {
});
}
service.likeAsync(uid, id).then((result) => {
req.ctx(service).likeAsync(uid, id).then((result) => {
return res.json(result);
}).catch(next);
};
... ... @@ -246,7 +246,7 @@ const usefulConsult = (req, res, next) => {
});
}
service.usefulAsync(uid, id).then((result) => {
req.ctx(service).usefulAsync(uid, id).then((result) => {
return res.json(result);
}).catch(next);
};
... ... @@ -263,7 +263,7 @@ const recommend = (req, res, next) => {
});
}
service.recommendAsync(skn, pageNum, pageSize)
req.ctx(service).recommendAsync(skn, pageNum, pageSize)
.then(result => res.json(result))
.catch(next);
};
... ... @@ -280,15 +280,11 @@ const getPackage = (req, res, next) => {
message: '服务器错误'
});
}
service.getPackage(skn)
req.ctx(service).getPackage(skn)
.then(result => res.json(result))
.catch(next);
};
const redirectNewRouter = (req, res) => {
return res.redirect(301, helpers.urlFormat(`/p${req.params[0]}.html${req.params[3]}`, null, 'item'));
};
module.exports = {
showMain,
showMainBack,
... ... @@ -301,6 +297,5 @@ module.exports = {
recommend,
getPackage,
likeConsult,
usefulConsult,
redirectNewRouter
usefulConsult
};
... ...
... ... @@ -18,7 +18,7 @@ const changeFavoriteBrand = (req, res, next) => {
let type = req.body.type || '';
if (uid && brandId) {
brandService.changeAsync(type, uid, brandId).then(result => {
req.ctx(brandService).changeAsync(type, uid, brandId).then(result => {
return res.json(result);
}).catch(next);
} else if (!uid) {
... ... @@ -42,7 +42,7 @@ const isFavoriteBrand = (req, res, next) => {
let brandId = req.query.brandId;
if (uid && brandId) {
brandService.isFavoriteAsync(uid, brandId).then(result => {
req.ctx(brandService).isFavoriteAsync(uid, brandId).then(result => {
return res.json(result);
}).catch(next);
} else {
... ... @@ -61,7 +61,7 @@ const collectProduct = (req, res, next) => {
if (uid && pid) {
switch (type) {
case 'add':
productService.createAsync(uid, pid)
req.ctx(productService).createAsync(uid, pid)
.then(result => {
if (result.code === 413) {
result.message = '该商品已经收藏';
... ... @@ -72,7 +72,7 @@ const collectProduct = (req, res, next) => {
.catch(next);
break;
case 'cancel':
productService.deleteAsync(uid, pid)
req.ctx(productService).deleteAsync(uid, pid)
.then(result => res.json(result))
.catch(next);
break;
... ... @@ -120,7 +120,7 @@ const collectShop = (req, res, next) => {
message: '收藏失败'
});
} else {
fav.toggleFavShop(shopId, uid, isadd).then(result => {
req.ctx(fav).toggleFavShop(shopId, uid, isadd).then(result => {
res.json(result);
}).catch(next);
}
... ... @@ -137,7 +137,7 @@ const isFavShop = (req, res, next) => {
});
}
fav.getFavStatus(uid, shopId, 'shop').then(result => {
req.ctx(fav).getFavStatus(uid, shopId, 'shop').then(result => {
return res.json(result);
}).catch(next);
};
... ... @@ -147,13 +147,13 @@ const num = (req, res, next) => {
let sid = _.parseInt(`0${req.query.sid}`) || 0;
if (sid) {
return brandService.getShopFavNumAsync(sid).then((result) => {
return req.ctx(brandService).getShopFavNumAsync(sid).then((result) => {
res.json(result);
}).catch(next);
}
if (bid) {
return brandService.getBrandFavNumAsync(bid).then((result) => {
return req.ctx(brandService).getBrandFavNumAsync(bid).then((result) => {
res.json(result);
}).catch(next);
}
... ...
... ... @@ -16,7 +16,7 @@ const globalModel = require(`${mRoot}/global`); // global model
* @return {[type]} [description]
*/
exports.list = (req, res, next) => {
globalModel.getGlobalProductListData(req.query, req.yoho).then(result => {
req.ctx(globalModel).getGlobalProductListData(req.query, req.yoho).then(result => {
res.render('list/index', Object.assign({
page: 'list',
pageClass: 'global-list-page'
... ... @@ -31,7 +31,7 @@ exports.list = (req, res, next) => {
* @return {[type]} [description]
*/
exports.detail = (req, res, next) => {
globalModel.getGlobalProductDetailData(req.params[0], req.yoho.channelNum,
req.ctx(globalModel).getGlobalProductDetailData(req.params[0], req.yoho.channelNum,
req.yoho.channel).then(result => {
res.render('global/detail', Object.assign({
page: 'detail'
... ...
... ... @@ -4,14 +4,14 @@
*/
'use strict';
const mRoot = '../models';
const list = require(`${mRoot}/list`);
const listSeoMap = require(`${global.middleware}/seo/listSeoMap`);
const helpers = global.yoho.helpers;
const _ = require('lodash');
// 搜索相关接口
const searchApi = require(`${mRoot}/search-api`);
const searchApi = require('../models/search-api');
const list = require('../models/list');
/**
* 商品分类列表页
... ... @@ -23,7 +23,7 @@ exports.index = (req, res, next) => {
let resData = {};
let qs = decodeURIComponent(req._parsedOriginalUrl.query || '');
list.getListData(Object.assign(req.query, {uid: req.user.uid, prid: req.user.prid}),
req.ctx(list).getListData(Object.assign(req.query, {uid: req.user.uid, prid: req.user.prid}),
req.yoho.channel).then(result => {
Object.assign(resData, result);
... ... @@ -58,7 +58,7 @@ exports.index = (req, res, next) => {
exports.new = (req, res, next) => {
let resData = {};
list.getListNewData(Object.assign({order: 's_t_desc'}, req.query), req.yoho.channel).then(result => {
req.ctx(list).getListNewData(Object.assign({order: 's_t_desc'}, req.query), req.yoho.channel).then(result => {
Object.assign(resData, result, {
hideInfo: {from: 'newProduct'}
});
... ... @@ -123,11 +123,11 @@ exports.brandAbout = (req, res, next) => {
}
if (shopId) {
list.getShopAbout(shopId, req.user.uid).then(result => {
req.ctx(list).getShopAbout(shopId, req.user.uid).then(result => {
res.render('list/brand', Object.assign(result, {page: 'list'}));
}).catch(next);
} else {
list.getBrandAbout(brandDomain, req.user.uid, req.yoho.channel).then(result => {
req.ctx(list).getBrandAbout(brandDomain, req.user.uid, req.yoho.channel).then(result => {
res.render('list/brand', Object.assign(result, {page: 'list'}));
}).catch(next);
}
... ... @@ -145,7 +145,7 @@ exports.getNodeContent = (req, res, next) => {
return next();
}
list.getNodeContentData(req.body).then(result => {
req.ctx(list).getNodeContentData(req.body).then(result => {
res.json(result);
}).catch(next);
};
... ... @@ -162,7 +162,7 @@ exports.getAdnav = (req, res, next) => {
return next();
}
list.getAdnav(req.body).then(result => {
req.ctx(list).getAdnav(req.body).then(result => {
res.json(result);
}).catch(next);
};
... ... @@ -187,7 +187,7 @@ exports.isFavoriteBrand = (req, res, next) => {
return res.json({code: 400, message: '用户未登录或缺少参数'});
}
searchApi.isFavoriteBrand(uid, brandId).then(result => {
req.ctx(searchApi).isFavoriteBrand(uid, brandId).then(result => {
res.json(result);
}).catch(next);
};
... ... @@ -211,7 +211,7 @@ exports.shopCouponSync = (req, res, next) => {
return res.json({code: 400, message: '用户未登录或缺少参数'});
}
list.getUserCoupunStatus(id, uid, 'shop').then(result => {
req.ctx(list).getUserCoupunStatus(id, uid, 'shop').then(result => {
res.json(result);
});
};
... ... @@ -234,7 +234,7 @@ exports.brandCouponSync = (req, res, next) => {
return res.json({code: 400, message: '用户未登录或缺少参数'});
}
list.getUserCoupunStatus(id, uid, 'brand').then(result => {
req.ctx(list).getUserCoupunStatus(id, uid, 'brand').then(result => {
res.json(result);
});
... ...
... ... @@ -19,7 +19,7 @@ exports.index = (req, res, next) => {
// 加载最新上架数据
if (pjax) {
arrive.getRecList(req).then(result => {
req.ctx(arrive).getRecList(req).then(result => {
Object.assign(result, {layout: false});
res.render('list/new-pro-list', result);
}).catch(next);
... ... @@ -28,7 +28,7 @@ exports.index = (req, res, next) => {
}
// 加载所有
arrive.index(req).then(result => {
req.ctx(arrive).index(req).then(result => {
res.render('list/new-arrive', result);
}).catch(next);
... ...
... ... @@ -4,7 +4,7 @@
'use strict';
const mRoot = '../models';
const notify = require(`${mRoot}/detail-notify-service`);
const NotifyModel = require(`${mRoot}/detail-notify-service`);
const add = (req, res, next) => {
let uid = req.user.uid;
... ... @@ -19,7 +19,7 @@ const add = (req, res, next) => {
});
}
notify.add(skn, sku, uid, mobile).then((result) => {
req.ctx(NotifyModel).add(skn, sku, uid, mobile).then((result) => {
return res.json(result);
}).catch(next);
};
... ... @@ -35,10 +35,9 @@ const cancel = (req, res, next) => {
});
}
notify.cancel(sku, uid).then((result) => {
req.ctx(NotifyModel).cancel(sku, uid).then((result) => {
return res.json(result);
}).catch(next);
};
const show = (req, res, next) => {
... ... @@ -52,7 +51,7 @@ const show = (req, res, next) => {
});
}
notify.show(sku, uid).then((result) => {
req.ctx(NotifyModel).show(sku, uid).then((result) => {
return res.json(result);
}).catch(next);
};
... ...
... ... @@ -5,6 +5,7 @@
*/
'use strict';
const mRoot = '../models';
const outlets = require(`${mRoot}/outlets`);
... ... @@ -19,7 +20,7 @@ const _ = require('lodash');
exports.index = (req, res, next) => {
let channel = req.query.channel || req.cookies._Channel || 'otltIdxDflt';
outlets.getOutletsIndexData(req.query, channel).then((result) => {
req.ctx(outlets).getOutletsIndexData(req.query, channel).then((result) => {
res.render('outlets/index', Object.assign({
module: 'product',
page: 'outlets'
... ... @@ -36,7 +37,7 @@ exports.index = (req, res, next) => {
exports.channel = (req, res, next) => {
let channel = req.params.channel || req.query.channel || req.cookies._Channel || 'boys';
outlets.getOutletsChannelData(req.query, channel).then((result) => {
req.ctx(outlets).getOutletsChannelData(req.query, channel).then((result) => {
res.render('outlets/channel', Object.assign({
module: 'product',
page: 'outlets'
... ... @@ -59,7 +60,7 @@ exports.special = (req, res, next) => {
return next();
}
outlets.getOutletsSpecialData(params, channel).then(result => {
req.ctx(outlets).getOutletsSpecialData(params, channel).then(result => {
res.render('outlets/special', Object.assign({
module: 'product',
page: 'outlets'
... ... @@ -79,7 +80,7 @@ exports.list = (req, res, next) => {
params.uid = req.user.uid || 0;
outlets.getOutletsCategoryData(params, channel).then((result) => {
req.ctx(outlets).getOutletsCategoryData(params, channel).then((result) => {
res.render('sale/other', Object.assign({
module: 'product',
page: 'outlets'
... ...
... ... @@ -44,7 +44,7 @@ exports.index = (req, res, next) => {
headerData = result.headerData;
});
list.getListData(params, channel).then((result) => {
req.ctx(list).getListData(params, channel).then((result) => {
responseData.saleList = result;
responseData.resultShow = JSON.stringify(result, null, 4);
responseData.headerData = headerData;
... ...
... ... @@ -26,7 +26,7 @@ exports.index = (req, res, next) => {
}
// 真实数据输出
sale.getSaleIndexData(channel).then(result => {
req.ctx(sale).getSaleIndexData(channel).then(result => {
res.render('sale/index', Object.assign({
module: 'product',
page: 'sale'
... ... @@ -55,7 +55,7 @@ exports.discount = (req, res, next) => {
page: 'sale'
};
sale.getSaleDiscountData(params, channel).then((result) => {
req.ctx(sale).getSaleDiscountData(params, channel).then((result) => {
responseData.result = result;
if (result) {
responseData.headerData = result.headerData;
... ... @@ -79,7 +79,7 @@ exports.vip = (req, res, next) => {
params.uid = req.user.uid || 0;
sale.getSaleOthersData(params, channel).then((result) => {
req.ctx(sale).getSaleOthersData(params, channel).then((result) => {
res.render('sale/other', Object.assign({
module: 'product',
page: 'sale'
... ... @@ -104,7 +104,7 @@ exports.newSale = (req, res, next) => {
let channel = req.yoho.channel;
sale.getSaleOthersData(params, channel).then((result) => {
req.ctx(sale).getSaleOthersData(params, channel).then((result) => {
res.render('sale/other', Object.assign({
module: 'product',
page: 'sale'
... ... @@ -133,7 +133,7 @@ exports.breakingYards = (req, res, next) => {
page: 'sale'
};
sale.getSalebreakingYardsData(params, channel).then((result) => {
req.ctx(sale).getSalebreakingYardsData(params, channel).then((result) => {
responseData.saleList = result;
if (result) {
responseData.headerData = result.headerData;
... ... @@ -157,7 +157,7 @@ exports.special = (req, res, next) => {
return next();
}
sale.getSaleSpecialData(specialId, params, req.yoho.channel).then(result => {
req.ctx(sale).getSaleSpecialData(specialId, params, req.yoho.channel).then(result => {
res.render('sale/special', result);
}).catch(next);
};
... ... @@ -173,7 +173,7 @@ exports.getGoodsList = (req, res, next) => {
params.uid = req.user.uid || 0;
sale.getSaleGoodsData(params).then(result => {
req.ctx(sale).getSaleGoodsData(params).then(result => {
let responseData = {};
responseData.footerTop = false;
... ...
... ... @@ -5,6 +5,7 @@
*/
'use strict';
const mRoot = '../models';
const search = require(`${mRoot}/search`);
const _ = require('lodash');
... ... @@ -24,14 +25,14 @@ const index = (req, res, next) => {
let params = req.query;
let resData = {};
search.getKeyActivity(params.query).then(activityUrl => {
req.ctx(search).getKeyActivity(params.query).then(activityUrl => {
if (activityUrl) {
activityUrl = encodeURI(activityUrl);
res.redirect(activityUrl);
return;
}
return search.getSearchData(Object.assign(params, {uid: req.user.uid, prid: req.user.prid}),
return req.ctx(search).getSearchData(Object.assign(params, {uid: req.user.uid, prid: req.user.prid}),
req.yoho.channel).then(result => {
let queryKey = req.query.query;
... ... @@ -63,7 +64,7 @@ const index = (req, res, next) => {
* @return {[type]} [description]
*/
const suggest = (req, res, next) => {
search.getSuggest(req.query).then(result => {
req.ctx(search).getSuggest(req.query).then(result => {
let dest = {
code: 200,
message: 'suggest',
... ... @@ -77,7 +78,7 @@ const suggest = (req, res, next) => {
};
const suggest4Old = (req, res, next) => {
search.getSuggest(Object.assign({}, req.query, { keyword: req.query.query })).then(result => {
req.ctx(search).getSuggest(Object.assign({}, req.query, { keyword: req.query.query })).then(result => {
let dest = {
code: 200,
message: 'suggest'
... ... @@ -105,7 +106,7 @@ const suggest4Old = (req, res, next) => {
};
const searchFilterBrands = (req, res, next) => {
search.getBrands4Filter(Object.assign({}, req.query, {
req.ctx(search).getBrands4Filter(Object.assign({}, req.query, {
keyword: req.query.query || ''
})).then(result => {
let dest = {
... ... @@ -163,7 +164,7 @@ const searchLessRecommend = (req, res, next) => {
page = 1;
}
search.getSearchLessProduct(channelNum, uid, udid, page).then(result => {
req.ctx(search).getSearchLessProduct(channelNum, uid, udid, page).then(result => {
return res.send(result);
}).catch(next);
... ... @@ -181,7 +182,7 @@ const keyword = (req, res, next) => {
let resData = {};
return search.getSearchKeywordData(Object.assign(params, {query: query}),
return req.ctx(search).getSearchKeywordData(Object.assign(params, {query: query}),
req.yoho.channel).then(result => {
Object.assign(resData, result, {
pageNoFollow: true,
... ... @@ -210,7 +211,7 @@ const keyId = (req, res, next) => {
let params = req.query;
let id = req.params.id;
return search.getSearchKeywordDataById(id, Object.assign({stocknumber: -1}, params),
return req.ctx(search).getSearchKeywordDataById(id, Object.assign({stocknumber: -1}, params),
req.yoho.channel).then(result => {
if (!result) {
... ...
... ... @@ -15,7 +15,7 @@ exports.index = (req, res, next) => {
}
if (req.xhr && req.query._pjax && shopId) {
return shopModel.getShopGoodsData(shopId, req.yoho.channel, req.query).then(result => {
return req.ctx(shopModel).getShopGoodsData(shopId, req.yoho.channel, req.query).then(result => {
Object.assign(result, {
shopId: shopId,
layout: false
... ... @@ -26,7 +26,7 @@ exports.index = (req, res, next) => {
return Promise.all([
tdk('shop', shopId, req),
shopModel.getShopInfoAsync(domain, req.yoho.channel, req.query)
req.ctx(shopModel).getShopInfoAsync(domain, req.yoho.channel, req.query)
]).then(result => {
let TDKObj = result[0],
shopObj = result[1];
... ... @@ -74,7 +74,7 @@ exports.list = (req, res, next) => {
return next();
}
return shopModel.getShopListInfoAsync(req.yoho.channel, req.query).then(result => {
return req.ctx(shopModel).getShopListInfoAsync(req.yoho.channel, req.query).then(result => {
Object.assign(result, {
page: 'shop',
shopId: shopId,
... ... @@ -97,7 +97,7 @@ exports.article = (req, res, next) => {
return next();
}
return shopModel.getShopArticleByBrandsAsync(brands).then(result => {
return req.ctx(shopModel).getShopArticleByBrandsAsync(brands).then(result => {
res.render('shop/article', Object.assign(result, {layout: false}));
}).catch(next);
};
... ...
... ... @@ -6,6 +6,7 @@
'use strict';
// TODO: ctxk
const mRoot = '../models';
const helpers = global.yoho.helpers;
... ... @@ -21,7 +22,7 @@ const studentsModel = require(`${mRoot}/students`); // students 页 model
exports.index = (req, res, next) => {
let channel = req.query.channel || req.cookies._Channel || 'boys';
studentsModel.getStudentsData(channel, req).then(result => {
req.ctx(studentsModel).getStudentsData(channel, req).then(result => {
if ('isStudent' in req.user && parseInt(req.user.isStudent, 10) === 1) {
result.realData.identityObj.verifyRusult = {isStudent: true};
... ... @@ -39,7 +40,7 @@ exports.index = (req, res, next) => {
* @return {[type]} [description]
*/
exports.schoolArea = (req, res, next) => {
studentsModel.getSchoolArea().then(result => {
req.ctx(studentsModel).getSchoolArea().then(result => {
res.json(result);
}).catch(next);
};
... ... @@ -53,7 +54,7 @@ exports.schoolArea = (req, res, next) => {
exports.schoolList = (req, res, next) => {
let areaCode = req.query.areaCode || 32;
studentsModel.getSchoolList(areaCode).then(result => {
req.ctx(studentsModel).getSchoolList(areaCode).then(result => {
res.json(result);
}).catch(next);
};
... ... @@ -65,7 +66,7 @@ exports.schoolList = (req, res, next) => {
* @return {[type]} [description]
*/
exports.eduLevel = (req, res, next) => {
studentsModel.getEduLevel().then(result => {
req.ctx(studentsModel).getEduLevel().then(result => {
res.json(result);
}).catch(next);
};
... ... @@ -81,7 +82,7 @@ exports.verify = (req, res, next) => {
res.send({code: 200, data: helpers.urlFormat('/signin.html')});
}
studentsModel.verifyIdentity(req.user.uid, req.query).then(result => {
req.ctx(studentsModel).verifyIdentity(req.user.uid, req.query).then(result => {
res.json(result);
}).catch(next);
... ... @@ -102,7 +103,7 @@ exports.userAcquireStatus = (req, res, next) => {
uid = req.user.uid;
}
studentsModel.userAcquireStatus(uid, req.query.couponIds).then(result => {
req.ctx(studentsModel).userAcquireStatus(uid, req.query.couponIds).then(result => {
res.json(result);
}).catch(next);
... ... @@ -118,7 +119,7 @@ exports.userAcquireStatus = (req, res, next) => {
exports.list = (req, res, next) => {
let resData = {};
studentsModel.getStudentsList(req.query, req.yoho.channel).then(result => {
req.ctx(studentsModel).getStudentsList(req.query, req.yoho.channel).then(result => {
Object.assign(resData, result);
res.render('list/index', resData);
}).catch(next);
... ...
/**
* Created by TaoHuang on 2016/11/3.
*/
'use strict';
module.exports = (url, width, height) => {
width = width || 750;
height = height || 420;
return `<div class="video-wrap">
<a href="javascript:;" class="video-close-btn"></a>
<object id="video_0" codebase="http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab"
classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000">
<param value="//cdn.yoho.cn/tool/VideoPlayerNew.swf?id=video_0&amp;url=${url}&amp;language=1&amp;sharepic=http://img01.yohoboys.com/contentimg/2016/06/12/14/0183fabea5332c5902cdd1d0d7fb63df04.jpg?imageMogr2/thumbnail/738x424|watermark/1/image/aHR0cDovL3Jlc2Nkbi55b2hvYm95cy5jb20vcmVzL25ldy9ib3lzL2ltYWdlcy9iYW5uZXJwbGF5LnBuZw==/dissolve/100/gravity/Center/dx/10/dy/10&amp;title1=Meet...Cody Sanderson &amp;shareurl=http://www.yohoboys.com/channel/detail/index/id/10657/time/1478052894&amp;coverpic=http://img01.yohoboys.com/contentimg/2016/06/12/14/0183fabea5332c5902cdd1d0d7fb63df04.jpg"
name="movie">
<param value="high" name="quality">
<param value="#ffffff" name="bgcolor">
<param name="allowFullScreen" value="true">
<param value="always" name="allowScriptAccess">
<param value="transparent" name="wmode">
<embed style="width: ${width}px;height: ${height}px;" id="flash" align="middle" pluginspage="http://www.macromedia.com/go/getflashplayer"
type="application/x-shockwave-flash" allowfullscreen="true" allowscriptaccess="always" loop="false"
play="true" bgcolor="#ffffff" quality="high" wmode="transparent" name="vMessage"
src="//cdn.yoho.cn/tool/VideoPlayerNew.swf?id=video_0&amp;url=${url}&amp;language=1&amp;sharepic=http://img01.yohoboys.com/contentimg/2016/06/12/14/0183fabea5332c5902cdd1d0d7fb63df04.jpg?imageMogr2/thumbnail/738x424|watermark/1/image/aHR0cDovL3Jlc2Nkbi55b2hvYm95cy5jb20vcmVzL25ldy9ib3lzL2ltYWdlcy9iYW5uZXJwbGF5LnBuZw==/dissolve/100/gravity/Center/dx/10/dy/10&amp;title1=Meet...Cody Sanderson &amp;shareurl=http://www.yohoboys.com/channel/detail/index/id/10657/time/1478052894&amp;coverpic=${url}?vframe/jpg/offset/0">
</object>
</div> `;
};
... ... @@ -4,27 +4,21 @@
'use strict';
const api = global.yoho.API;
const config = global.yoho.config;
const getBannerInfoAsync = bid => {
return api.get('', {
method: 'web.brand.banner',
brand_id: bid
}, config.apiCache);
};
const getBrandLogoByDomainAsync = domain => {
return api.get('', {
domain: domain,
method: 'web.brand.byDomain'
}, config.apiCache);
};
module.exports = {
getBannerInfoAsync,
getBrandLogoByDomainAsync
module.exports = class extends global.yoho.BaseModel {
constructor(ctx) {
super(ctx);
}
getBannerInfoAsync(bid) {
return this.get({data: {
method: 'web.brand.banner',
brand_id: bid
}, params: {
cache: config.apiCache
}});
}
};
... ...
... ... @@ -3,37 +3,13 @@
*/
'use strict';
const Promise = require('bluebird');
const co = Promise.coroutine;
const api = require('./brand-api');
const _ = require('lodash');
const Api = require('./brand-api');
const getBrandByDomainAsync = domain => {
return co(function*() {
let brandInfo = yield api.getBrandLogoByDomainAsync(domain);
module.exports = class extends global.yoho.BaseModel {
constructor(ctx) {
super(ctx);
if (!brandInfo.data || brandInfo.code !== 200) {
return {};
}
let result = {};
result.brandId = brandInfo.data.id || '';
result.node = brandInfo.data.static_content_code || false;
result.brandBanner = brandInfo.data.brand_banner || '';
result.brandNameEn = brandInfo.data.brand_name_en || '';
result.brandNameCn = brandInfo.data.brand_name_cn || '';
result.brandAbout = brandInfo.data.brand_intro || '';
result.shopTemplateType = brandInfo.data.shop_template_type ?
_.parseInt(brandInfo.data.shop_template_type) : '';
result.type = brandInfo.data.type ? +brandInfo.data.type : 0;
result.shopId = brandInfo.data.shop_id || '';
return result;
})();
};
module.exports = {
getBrandByDomainAsync,
getBannerInfoAsync: api.getBannerInfoAsync
this.api = new Api(ctx);
this.getBannerInfoAsync = this.api.getBannerInfoAsync.bind(this.api);
}
};
... ...
/**
* Created by TaoHuang on 2016/10/28.
*/
'use strict';
const api = global.yoho.API;
const listAsync = (bid, skn, uid) => {
let params = {
method: 'app.coupons.queryProdPageCoupons',
brandId: bid,
skn: skn
};
if (uid) {
params.uid = uid;
module.exports = class extends global.yoho.BaseModel {
constructor(ctx) {
super(ctx);
}
return api.get('', params);
};
acquireAsync(couponId, uid) {
return this.get({data: {
method: 'app.promotion.getCoupon',
couponId: couponId,
uid: uid
}});
}
const acquireAsync = (couponId, uid) => {
return api.get('', {
method: 'app.promotion.getCoupon',
couponId: couponId,
uid: uid
});
};
listAsync(bid, skn, uid) {
let params = {
method: 'app.coupons.queryProdPageCoupons',
brandId: bid,
skn: skn
};
if (uid) {
params.uid = uid;
}
module.exports = {
listAsync,
acquireAsync
return this.get({data: params});
}
};
... ...
... ... @@ -4,13 +4,23 @@
'use strict';
const api = require('./coupon-api');
const CouponApi = require('./coupon-api');
const _ = require('lodash');
const decrypt = _.partial(global.yoho.crypto.decrypt, null);
const acquireAsync = _.overArgs(api.acquireAsync, [decrypt, _1 => _1]);
module.exports = {
acquireAsync,
listAsync: api.listAsync
module.exports = class extends global.yoho.BaseModel {
constructor(ctx) {
super(ctx);
this.api = new CouponApi(ctx);
this.listAsync = this.api.listAsync.bind(this.api);
}
acquireAsync(cid, uid) {
let dcid = decrypt(cid);
return this.api.acquireAsync(dcid, uid);
}
};
... ...
... ... @@ -4,32 +4,30 @@
'use strict';
const api = global.yoho.API;
/**
* 商品详情页的评论列表
*
* @param pid 商品productId
* @param page 分页
* @param size 每页大小
*
* @returns {Promise}
* @see http://git.yoho.cn/yoho-documents/api-interfaces/blob/master/sns/show/show_productShareOrderList.md
*/
const getShareOrderListAsync = (pid, page, size, filterId) => {
filterId = filterId || 7;
return api.get('', {
method: 'show.productShareOrderList',
productId: pid,
page: page,
limit: size,
filterId: filterId
});
};
module.exports = class extends global.yoho.BaseModel {
constructor(ctx) {
super(ctx);
}
/**
* 商品详情页的评论列表
*
* @param pid 商品productId
* @param page 分页
* @param size 每页大小
*
* @returns {Promise}
* @see http://git.yoho.cn/yoho-documents/api-interfaces/blob/master/sns/show/show_productShareOrderList.md
*/
getShareOrderListAsync(pid, page, size, filterId) {
filterId = filterId || 7;
module.exports = {
getShareOrderListAsync
return this.get({data: {
method: 'show.productShareOrderList',
productId: pid,
page: page,
limit: size,
filterId: filterId
}});
}
};
... ...
... ... @@ -4,17 +4,15 @@
'use strict';
const api = require('./detail-comment-api');
const Api = require('./detail-comment-api');
/**
* 获取订单评论
*
* @param pid
* @param page
* @param size
*/
const getShareOrderListAsync = api.getShareOrderListAsync;
module.exports = {
getShareOrderListAsync
module.exports = class extends global.yoho.BaseModel {
constructor(ctx) {
super(ctx);
this.api = new Api(ctx);
this.getShareOrderListAsync = this.api.getShareOrderListAsync.bind(this.api);
}
};
... ...
... ... @@ -3,59 +3,56 @@
*/
'use strict';
module.exports = class extends global.yoho.BaseModel {
constructor(ctx) {
super(ctx);
}
const api = global.yoho.API;
/**
* 咨询内容列表
*/
const indexAsync = function(uid, pid, page, size) {
let param = {};
/**
* 咨询内容列表
*/
indexAsync(uid, pid, page, size) {
let param = {};
param.method = 'app.consult.li';
param.product_id = pid;
param.method = 'app.consult.li';
param.product_id = pid;
if (uid) {
param.uid = uid;
}
if (uid) {
param.uid = uid;
}
param.page = page;
param.limit = size;
param.page = page;
param.limit = size;
return api.get('', param);
};
return this.get({data: param});
}
/**
* 添加咨询操作
*/
const createAsync = function(uid, pid, content) {
return api.post('', {
method: 'h5.consult.add',
product_id: pid,
content: content,
uid: uid
});
};
/**
* 添加咨询操作
*/
createAsync(uid, pid, content) {
return this.post({data: {
method: 'h5.consult.add',
product_id: pid,
content: content,
uid: uid
}});
}
const likeAsync = (uid, id) => {
return api.get('', {
method: 'app.consult.like',
uid: uid,
id: id
});
};
const usefulAsync = (uid, id) => {
return api.get('', {
method: 'app.consult.useful',
uid: uid,
id: id
});
};
likeAsync(uid, id) {
return this.get({data: {
method: 'app.consult.like',
uid: uid,
id: id
}});
}
module.exports = {
indexAsync,
createAsync,
likeAsync,
usefulAsync
usefulAsync(uid, id) {
return this.get({data: {
method: 'app.consult.useful',
uid: uid,
id: id
}});
}
};
... ...
... ... @@ -7,38 +7,41 @@
const Promise = require('bluebird');
const co = Promise.coroutine;
const api = require('./detail-consult-api');
const Api = require('./detail-consult-api');
const detailHelper = require('./detail-helper');
const indexAsync = (uid, pid, page, size) => {
return co(function *() {
let consultList = yield api.indexAsync(uid, pid, page, size);
if (!consultList.code || consultList.code !== 200) {
return [];
}
return consultList.data.list.map(value => {
return {
avatar: detailHelper.DEFAULT_AVATAR_ICO,
question: value.ask,
date: value.ask_time,
answer: value.answer,
id: value.id,
isLike: value.is_like === 'Y',
like: parseInt(value.like, 10),
isUseful: value.is_useful === 'Y',
useful: parseInt(value.useful, 10),
total: value.total
};
});
})();
};
module.exports = {
indexAsync,
createAsync: api.createAsync,
likeAsync: api.likeAsync,
usefulAsync: api.usefulAsync
module.exports = class extends global.yoho.BaseModel {
constructor(ctx) {
super(ctx);
this.api = new Api(ctx);
this.createAsync = this.api.createAsync.bind(this.api);
this.likeAsync = this.api.likeAsync.bind(this.api);
this.usefulAsync = this.api.usefulAsync.bind(this.api);
}
indexAsync(uid, pid, page, size) {
return co(function *() {
let consultList = yield this.api.indexAsync(uid, pid, page, size);
if (!consultList.code || consultList.code !== 200) {
return [];
}
return consultList.data.list.map(value => {
return {
avatar: detailHelper.DEFAULT_AVATAR_ICO,
question: value.ask,
date: value.ask_time,
answer: value.answer,
id: value.id,
isLike: value.is_like === 'Y',
like: parseInt(value.like, 10),
isUseful: value.is_useful === 'Y',
useful: parseInt(value.useful, 10),
totakl: value.total
};
});
}).bind(this)();
}
};
... ...
/**
* Created by TaoHuang on 2016/6/13.
*/
'use strict';
const api = global.yoho.API;
const config = global.yoho.config;
/**
* 获取商品的热区
*/
const indexAsync = pid => {
return api.get('', {
method: 'web.productCollocation.list',
product_id: pid
}, config.apiCache);
};
module.exports = class extends global.yoho.BaseModel {
constructor(ctx) {
super(ctx);
}
/**
* 获取商品的热区
*/
indexAsync(pid) {
let data = {
method: 'web.productCollocation.list',
product_id: pid
};
module.exports = {
indexAsync
return this.get({data, params: {
cache: config.apiCache
}});
}
};
... ...
... ... @@ -8,73 +8,76 @@ const Promise = require('bluebird');
const co = Promise.coroutine;
const _ = require('lodash');
const helpers = global.yoho.helpers;
const api = require('./detail-hotarea-api');
/**
* 获取某一个商品的热区数据
*/
const indexAsync = pid => {
return co(function *() {
let data = yield api.indexAsync(pid);
if (!data || !data.code || data.code !== 200) {
return [];
}
return data.data.reduce((result, area) => {
if (!area.infos) {
return result;
const HorareaModel = require('./detail-hotarea-api');
module.exports = class extends global.yoho.BaseModel {
constructor(ctx) {
super(ctx);
this.api = new HorareaModel(ctx);
}
/**
* 获取某一个商品的热区数据
*/
indexAsync(pid) {
return co(function *() {
let data = yield this.api.indexAsync(pid);
if (!data || !data.code || data.code !== 200) {
return [];
}
let item = {};
return data.data.reduce((result, area) => {
if (!area.infos) {
return result;
}
if (area.imageUrl) {
item.img = helpers.getForceSourceUrl(area.imageUrl);
}
let item = {};
item.list = area.infos.reduce((acc, cur, index) => {
if (!cur.product || !cur.product.goodsList) {
return acc;
if (area.imageUrl) {
item.img = helpers.getForceSourceUrl(area.imageUrl);
}
let point = {
label: index + 1,
top: cur.top,
left: cur.left,
height: cur.height,
width: cur.width
};
let goods = _.head(cur.product.goodsList);
// 封面图
point.img = helpers.getForceSourceUrl(goods.colorImage, 60, 60);
// 商品相关信息
point.product = {
salePrice: cur.product.productPriceBo.formatSalesPrice,
marketPrice: cur.product.productPriceBo.formatMarketPrice,
productName: cur.product.productName,
href: helpers.getUrlBySkc(
_.get(cur.product, 'productPriceBo.productSkn', ''))
};
acc.push(point);
return acc;
}, []);
item.list = area.infos.reduce((acc, cur, index) => {
if (!cur.product || !cur.product.goodsList) {
return acc;
}
let point = {
label: index + 1,
top: cur.top,
left: cur.left,
height: cur.height,
width: cur.width
};
let goods = _.head(cur.product.goodsList);
// 封面图
point.img = helpers.getForceSourceUrl(goods.colorImage, 60, 60);
// 商品相关信息
point.product = {
salePrice: cur.product.productPriceBo.formatSalesPrice,
marketPrice: cur.product.productPriceBo.formatMarketPrice,
productName: cur.product.productName,
href: helpers.getUrlBySkc(
_.get(cur.product, 'productPriceBo.productSkn', ''))
};
acc.push(point);
if (_.isEmpty(item)) {
return result;
} else {
result.push(item);
return result;
}
return acc;
}, []);
}, []);
if (_.isEmpty(item)) {
return result;
} else {
result.push(item);
return result;
}
})();
};
}, []);
module.exports = {
indexAsync
}).bind(this)();
}
};
... ...
'use strict';
const api = global.yoho.API;
/**
* 增加到货通知
*/
const addNotifyAsync = (skn, sku, uid, mobile) => {
let params = {
method: 'app.arrivalNotice.add',
product_skn: skn,
erp_sku_id: sku,
uid: uid
};
if (mobile) {
params.mobile = mobile;
module.exports = class extends global.yoho.BaseModel {
constructor(ctx) {
super(ctx);
}
return api.get('', params);
};
/**
* 取消到货通知
*/
const cancelNotifyAsync = (sku, uid) => {
return api.get('', {
method: 'app.arrivalNotice.cancel',
erp_sku_id: sku,
uid: uid
});
};
/**
* 获得商品是否已经设置过到货通知
*/
getNotifyStatusAsync(sku, uid) {
let data = {
method: 'app.arrivalNotice.query',
erp_sku_id: sku,
uid: uid
};
return this.get({data});
}
/**
* 获得商品是否已经设置过到货通知
*/
const getNotifyStatusAsync = (sku, uid) => {
return api.get('', {
method: 'app.arrivalNotice.query',
erp_sku_id: sku,
uid: uid
});
};
/**
* 取消到货通知
*/
cancelNotifyAsync(sku, uid) {
let data = {
method: 'app.arrivalNotice.cancel',
erp_sku_id: sku,
uid: uid
};
return this.get({data});
}
module.exports = {
addNotifyAsync,
cancelNotifyAsync,
getNotifyStatusAsync
/**
* 增加到货通知
*/
addNotifyAsync(skn, sku, uid, mobile) {
let data = {
method: 'app.arrivalNotice.add',
product_skn: skn,
erp_sku_id: sku,
uid: uid
};
if (mobile) {
data.mobile = mobile;
}
return this.get({data});
}
};
... ...
... ... @@ -2,43 +2,45 @@
'use strict';
const api = require('./detail-notify-api');
const DetailNotifyApi = require('./detail-notify-api');
const _ = require('lodash');
const add = api.addNotifyAsync;
const cancel = api.cancelNotifyAsync;
const show = (sku, uid) => {
return api.getNotifyStatusAsync(sku, uid).then((result) => {
if (result.code === 200) {
if (!_.isEmpty(result.data)) {
return {
code: 200,
data: {
status: 'Y'
},
message: '已添加通知'
};
module.exports = class extends global.yoho.BaseModel {
constructor(ctx) {
super(ctx);
this.api = new DetailNotifyApi(ctx);
this.add = this.api.addNotifyAsync.bind(this.api);
this.cancel = this.api.cancelNotifyAsync.bind(this.api);
}
show(sku, uid) {
return this.api.getNotifyStatusAsync(sku, uid).then((result) => {
if (result.code === 200) {
if (!_.isEmpty(result.data)) {
return {
code: 200,
data: {
status: 'Y'
},
message: '已添加通知'
};
} else {
return {
code: 200,
data: {
status: 'N'
},
message: '没有添加通知'
};
}
} else {
return {
code: 200,
data: {
status: 'N'
},
message: '没有添加通知'
code: 401,
message: '服务器错误'
};
}
} else {
return {
code: 401,
message: '服务器错误'
};
}
});
};
module.exports = {
add,
show,
cancel
});
}
};
... ...
... ... @@ -4,15 +4,18 @@
'use strict';
const api = global.yoho.API;
const config = global.yoho.config;
const redis = global.yoho.redis;
const cache = global.yoho.cache;
const logger = global.yoho.logger;
const uuid = require('uuid');
const helpers = global.yoho.helpers;
const _ = require('lodash');
const SearchServiceModel = require('./search-api');
const GuangServiceModel = require('../../guang/models/guang-service');
const productProcess = require('../../../utils/product-process');
const uuid = require('uuid');
function _cacheGet(key) {
return cache.get(key).then((data) => {
if (data) {
... ... @@ -47,188 +50,259 @@ function _cached(fn, ctx) {
};
}
/**
* 商品的 banner
*/
const getProductBannerAsync = (pid) => {
return api.get('', {
method: 'web.productBanner.data',
product_id: pid
}, config.apiCache);
};
module.exports = class extends global.yoho.BaseModel {
constructor(ctx) {
super(ctx);
/**
* 商品尺寸
*/
const sizeInfoAsync = (skn) => {
return api.get('', {
method: 'h5.product.intro',
productskn: skn
}, config.apiCache);
this.searchApi = new SearchServiceModel(ctx);
this.guangService = new GuangServiceModel(ctx);
};
this.getNewProduct = _cached(this._getNewProduct, this);
this.getGuangArticles = _cached(this._getGuangArticles, this);
this.getRecommendKeywords = _cached(this._getRecommendKeywords, this);
}
/**
* 特殊商品退换货
*/
const isSupportReturnedSale = (skn) => {
return api.get('', {
method: 'web.product.refundExchange',
product_skn: skn
}, config.apiCache);
};
/**
* 商品的 banner
*/
getProductBannerAsync(pid) {
return this.get({
data: {
method: 'web.productBanner.data',
product_id: pid
}, params: {
cache: config.apiCache
}
});
}
/**
* 商品舒适度
*/
const getProductComfortAsync = (pid) => {
return api.get('', {
method: 'web.productComfort.data',
product_id: pid
}, config.apiCache);
/**
* 商品尺寸
*/
sizeInfoAsync(skn) {
return this.get({
data: {
method: 'h5.product.intro',
productskn: skn
}, params: {
cache: config.apiCache
}
});
}
};
/**
* 特殊商品退换货
*/
isSupportReturnedSale(skn) {
return this.get({
data: {
method: 'web.product.refundExchange',
product_skn: skn
}, params: {
cache: config.apiCache
}
});
}
/**
* 模特试穿
*/
const getProductModelTryAsync = (skn) => {
return api.get('', {
method: 'web.productModelTry.data',
product_skn: skn
}, config.apiCache);
};
/**
* 商品舒适度
*/
getProductComfortAsync(pid) {
return this.get({
data: {
method: 'web.productComfort.data',
product_id: pid
}, params: {
cache: config.apiCache
}
});
}
/**
* 获得产品信息
*/
const getProductAsync = (id, uid, isStudents, vipLevel) => {
/**
* 模特试穿
*/
getProductModelTryAsync(skn) {
return this.get({
data: {
method: 'web.productModelTry.data',
product_skn: skn
}, params: {
cache: config.apiCache
}
});
}
let params = {
method: 'app.product.data'
};
/**
* 获得产品信息
*/
getProductAsync(id, uid, isStudents, vipLevel) {
if (id.skn) {
params.product_skn = id.skn;
}
let data = {
method: 'app.product.data'
};
if (id.pid) {
params.product_id = id.pid;
}
if (id.skn) {
data.product_skn = id.skn;
}
if (uid) {
params.uid = uid;
}
if (id.pid) {
data.product_id = id.pid;
}
if (isStudents) {
params.is_student = isStudents;
}
if (uid) {
data.uid = uid;
}
if (vipLevel) {
params.current_vip_level = vipLevel;
if (isStudents) {
data.is_student = isStudents;
}
if (vipLevel) {
data.current_vip_level = vipLevel;
}
return this.get({
data, params: {
cache: config.apiCache
}
});
}
return api.get('', params, config.apiCache);
};
/**
* 促销信息
*/
getPromotionAsync(skn) {
let data = {
method: 'app.product.promotion',
product_skn: skn
};
return this.get({
data, params: {
cache: config.apiCache
}
});
}
/**
* 促销信息
*/
const getPromotionAsync = (skn) => {
let params = {
method: 'app.product.promotion',
product_skn: skn
};
/**
* 限购商品
*/
getLimitedProductStatusAsync(code, uid, skn) {
let data = {
method: 'app.limitProduct.productStatus',
limitProductCode: code
};
if (uid) {
data.uid = uid;
}
return api.get('', params, config.apiCache);
};
if (skn) {
data.product_skn = skn;
}
/**
* 限购商品
*/
const getLimitedProductStatusAsync = (code, uid, skn) => {
let params = {
method: 'app.limitProduct.productStatus',
limitProductCode: code
};
return this.get({
data, params: {
cache: config.apiCache
}
});
}
if (uid) {
params.uid = uid;
/**
* 店铺推荐
*/
getShopRecommendAsync(skn, page, limit) {
return this.get({
data: {
method: 'web.product.shopRecommend',
product_skn: skn,
page: page || 1,
limit: limit || 20
}
});
}
if (skn) {
params.product_skn = skn;
/**
* 套餐和量贩
*/
getBundleAsync(skn) {
return this.get({
data: {
method: 'app.query.bundleSkn',
product_skn: skn
}
});
}
return api.get('', params, config.apiCache);
};
/**
* 找相似
*/
getLikeAsync(skn, limit) {
return this.get({
data: {
method: 'web.search.findLike',
limit: limit || 10,
product_skn: skn
}, params: {
cache: 86400
}
});
}
/**
* 店铺推荐
*/
const getShopRecommendAsync = (skn, page, limit) => {
return api.get('', {
method: 'web.product.shopRecommend',
product_skn: skn,
page: page || 1,
limit: limit || 20
});
};
// 根据small_sort从redis获取分类下的关键词
_getRecommendKeywords(smallSort) {
return redis.all([['get', `global:yoho:seo:keywords:sortId:${smallSort}:page`]]).then(res => {
return redis.all([['get', `global:yoho:seo:keywords:sortId:${smallSort}:page:${res[0] || 1}`]]);
}).then(res => {
return this._getKeywordsInfo(JSON.parse(res[0] || '[]'));
});
}
/**
* 套餐和量贩
*/
const getBundleAsync = (skn) => {
return api.get('', {
method: 'app.query.bundleSkn',
product_skn: skn
});
};
// 返回6条推荐关键词页面
_getKeywordsInfo(keywords) {
let res = [];
/**
* 找相似
*/
const getLikeAsync = (skn, limit) => {
return api.get('', {
method: 'app.search.findLike',
limit: limit || 10,
product_skn: skn
}, {cache: 86400});
};
_.forEach(_.slice(_.shuffle(keywords), 0, 18), val => {
res.push({
url: helpers.urlFormat(`/chanpin/${val.id}.html`),
keyword: val.keyword
});
});
return res;
}
// 返回6条推荐关键词页面
function getKeywordsInfo(keywords) {
let res = [];
_getNewProduct(sort) {
return this.searchApi.getProductList({
limit: 10,
sort: sort,
order: 's_t_desc',
page: _.random(1, 6000)
}).then(result => {
if (result.code === 200) {
return productProcess.processProductList(result.data.product_list);
}
return [];
}).then(productList => {
return productList.map((it) => ({
url: it.url,
name: it.product_name
}));
});
}
_.forEach(_.slice(_.shuffle(keywords), 0, 12), val => {
res.push({
url: helpers.urlFormat(`/chanpin/${val.id}.html`),
keyword: val.keyword
_getGuangArticles(skn) { //eslint-disable-line
return this.guangService.getArticleList(
3, null, null, null, _.random(1, 700), null, null, 10, null, null
).then(result => {
return _.get(result, 'msgs', []).map((article) => ({
url: article.url,
name: article.title
}));
});
});
return res;
}
}
};
// 根据small_sort从redis获取分类下的关键词
// skn 用来key
function _getRecommendKeywords(smallSort, skn) { // eslint-disable-line
return redis.all([['get', `global:yoho:seo:keywords:sortId:${smallSort}:page:1`]]).then(res => {
return getKeywordsInfo(JSON.parse(res[0] || '[]'));
});
}
module.exports = {
getProductBannerAsync,
sizeInfoAsync,
getProductComfortAsync,
getProductModelTryAsync,
getProductAsync,
getPromotionAsync,
isSupportReturnedSale,
getLimitedProductStatusAsync,
getShopRecommendAsync,
getBundleAsync,
getLikeAsync,
getRecommendKeywords: _cached(_getRecommendKeywords)
};
... ...
... ... @@ -10,23 +10,21 @@ const Promise = require('bluebird');
const co = Promise.coroutine;
const _ = require('lodash');
const Fn = require('lodash/fp');
const cheerio = require('cheerio');
const helpers = global.yoho.helpers;
const config = global.yoho.config;
const crypto = global.yoho.crypto;
const logger = global.yoho.logger;
const videoPlayerTpl = require('../helper/video-player-tpl');
const productAPI = require('./detail-product-api');
const detailHelper = require('./detail-helper');
const consultService = require('./detail-consult-service');
const commentService = require('./detail-comment-service');
const hotAreaService = require('./detail-hotarea-service');
const couponService = require('./coupon-service');
const brandService = require('./brand-service');
const favoriteProductService = require('./favorite-product-service');
const shopService = require('./shop-service');
const ProductModel = require('./detail-product-api');
const ConsultServiceModel = require('./detail-consult-service');
const CommentServiceModel = require('./detail-comment-service');
const HotAreaServiceModel = require('./detail-hotarea-service');
const CouponServiceModel = require('./coupon-service');
const ShopServiceModel = require('./shop-service');
const BrandServiceModel = require('./brand-service');
const FavoriteProductServiceModel = require('./favorite-product-service');
const homeService = require('./home-service');
const HeaderModel = require('../../../doraemon/models/header');
... ... @@ -34,45 +32,46 @@ const HeaderModel = require('../../../doraemon/models/header');
const BLANK_STR = ' ';
const BUNDLE_PRODUCE = 2; // 量贩
const BUNDLE_PACKAGE = 1; // 套餐
const tdk = require('../../../utils/getTDK');
const productProcess = require('../../../utils/product-process');
const _getProductAdditionInfoAsync = (data) => {
return co(function * () {
function _getProductAdditionInfoAsync(data) {
return co(function* () {
let productId = _.get(data, 'product_id', 0);
let brandId = _.get(data, 'brand_info.brand_id', 0);
// 获取相关数据
let promiseData = {
productBanner: productAPI.getProductBannerAsync(productId),
bannerInfo: brandService.getBannerInfoAsync(brandId)
productBanner: this.productAPI.getProductBannerAsync(productId),
bannerInfo: this.brandService.getBannerInfoAsync(brandId)
};
let result = yield Promise.props(promiseData);
return result;
})();
};
}).bind(this)();
}
const _getProductIntroAsync = (productId, productSkn) => {
return co(function * () {
function _getProductIntroAsync(productId, productSkn) {
return co(function* () {
let result = yield Promise.props({
sizeInfo: productAPI.sizeInfoAsync(productSkn),
productComfort: productAPI.getProductComfortAsync(productId),
productModelTry: productAPI.getProductModelTryAsync(productSkn)
sizeInfo: this.productAPI.sizeInfoAsync(productSkn),
productComfort: this.productAPI.getProductComfortAsync(productId),
productModelTry: this.productAPI.getProductModelTryAsync(productSkn)
});
return result;
})();
};
}).bind(this)();
}
/**
* 获取商品的喜欢
* pid : product id
* bid : brand id
*/
const _getProductFavoriteDataAsync = (uid, pid) => {
return co(function*() {
function _getProductFavoriteDataAsync(uid, pid) {
return co(function* () {
let result = {
product: false,
brand: false
... ... @@ -85,7 +84,7 @@ const _getProductFavoriteDataAsync = (uid, pid) => {
let requestApi = {};
if (pid) {
requestApi.product = favoriteProductService.isFavoriteAsync(uid, pid);
requestApi.product = this.favoriteProductService.isFavoriteAsync(uid, pid);
}
let requestData = yield Promise.props(requestApi);
... ... @@ -97,11 +96,11 @@ const _getProductFavoriteDataAsync = (uid, pid) => {
}
return result;
})();
};
}).bind(this)();
}
// 商品标签
const _getTagsDataByProductInfo = (data) => {
function _getTagsDataByProductInfo(data) {
let tags = [];
_.get(data, 'tags', []).forEach((value) => {
... ... @@ -143,10 +142,10 @@ const _getTagsDataByProductInfo = (data) => {
});
return tags;
};
}
// vip 价格
const _getVipDataByProductBaseInfo = (data, vipLevel, uid) => {
function _getVipDataByProductBaseInfo(data, vipLevel, uid) {
vipLevel = vipLevel || 0;
uid = uid || 0;
... ... @@ -183,10 +182,10 @@ const _getVipDataByProductBaseInfo = (data, vipLevel, uid) => {
});
return vipData;
};
}
// 活动
const _getProductActivityBanner = (additionalData) => {
function _getProductActivityBanner(additionalData) {
let data = additionalData.productBanner;
if (_.isEmpty(data) ||
... ... @@ -199,18 +198,18 @@ const _getProductActivityBanner = (additionalData) => {
activityImg: helpers.getForceSourceUrl(data.data.bannerImg),
url: data.data.promotionUrl
};
};
}
const _getBundleAsync = (result) => {
function _getBundleAsync(result) {
return {
count: _.get(result, 'data[0].bundleInfo.bundleCount', 1),
phrase: _.get(result, 'data[0].bundleInfo.promotionPhrase', ''),
type: _.get(result, 'data[0].bundleInfo.discountType', 1),
discount: _.get(result, 'data[0].bundleInfo.discount', null)
};
};
}
const _getActivityDataByProductBaseInfo = (data) => {
function _getActivityDataByProductBaseInfo(data) {
return _.get(data, 'data', []).map(value => {
let des = value.promotionTitle.replace(/¥/g, '¥');
... ... @@ -222,60 +221,12 @@ const _getActivityDataByProductBaseInfo = (data) => {
)
};
});
};
/**
* 获取品牌数据
*/
const _getBrandDataByProductBaseInfo = (data, additionalData) => { // eslint-disable-line
if (!_.get(data, 'brand_info')) {
return {};
}
let brandId = data.brand_info.brand_id;
let logo = '';
let bannerInfo = null;
let result = _.get(additionalData, 'bannerInfo', {});
if (_.isEmpty(result)) {
return {};
}
if (_.get(data, 'brand_info.brand_ico')) {
logo = helpers.getForceSourceUrl(data.brand_info.brand_ico);
}
if (result.code && result.code === 200 && result.data) {
bannerInfo = result.data;
}
// banner的logo
if (bannerInfo && bannerInfo.logo) {
logo = helpers.getForceSourceUrl(bannerInfo.logo);
}
let homeUrl = 'javascript:void(0)'; // eslint-disable-line no-script-url
if (_.get(data, 'brand_info.brand_domain')) {
homeUrl = helpers.urlFormat('', null, data.brand_info.brand_domain);
}
// 导航的品牌banner
return {
brandId: brandId,
bgColor: '#000000',
logo: logo,
alt: data.brand_info.brand_name,
brandName: data.brand_info.brand_name,
brandDomain: data.brand_info.brand_domain,
homeUrl: homeUrl
};
};
}
/**
* 获得sku商品数据
*/
const _getSkuDataByProductBaseInfo = (data) => {
function _getSkuDataByProductBaseInfo(data) {
let totalStorageNum = 0;
let skuGoods = null;// sku商品
let defaultImage = '';// 默认图
... ... @@ -290,7 +241,7 @@ const _getSkuDataByProductBaseInfo = (data) => {
};
}
skuGoods = _.get(data, 'goods_list', []).reduce((goodsDetailList, goods)=> {
skuGoods = _.get(data, 'goods_list', []).reduce((goodsDetailList, goods) => {
// 如果status为0,即skc下架时就跳过该商品$value['status'] === 0
let goodsDetail = {};
... ... @@ -402,7 +353,7 @@ const _getSkuDataByProductBaseInfo = (data) => {
skuGoods: skuGoods,
totalStorageNum: totalStorageNum
};
};
}
/**
* 处理限购商品的有关按钮状态(或取现购买以及底部商品购买按钮)
... ... @@ -411,7 +362,7 @@ const _getSkuDataByProductBaseInfo = (data) => {
* @param int $showStatus 限购商品的关联状态
* @param boolean $isBeginSale 限购商品是否已开售
*/
const _getFashionTopGoodsStatus = (uid, showStatus, isBeginSale) => {
function _getFashionTopGoodsStatus(uid, showStatus, isBeginSale) {
// 潮流尖货状态
// getLimitedCode //限购码状态
// hadLimitedCode //是否已经获取限购码
... ... @@ -479,7 +430,7 @@ const _getFashionTopGoodsStatus = (uid, showStatus, isBeginSale) => {
break;
}
return result;
};
}
/**
* 获取分类导航列表
... ... @@ -516,7 +467,7 @@ function _getSortNavAsync(productInfo, gender) {
}
// 保存在 gids 和 skns ,最近流览功能
const saveRecentGoodInCookies = (oldSkns, res, addSkns) => {
function saveRecentGoodInCookies(oldSkns, res, addSkns) {
oldSkns = oldSkns ? oldSkns.split(',') : [];
oldSkns = _.reject(oldSkns, old => old === String(addSkns) ? true : false);
oldSkns.unshift(addSkns);
... ... @@ -525,12 +476,12 @@ const saveRecentGoodInCookies = (oldSkns, res, addSkns) => {
maxAge: 2000000000,
domain: config.cookieDomain
});
};
}
/**
* 获取商品的舒适度
*/
const _getProductComfort = (data) => {
function _getProductComfort(data) {
let comfort = data.productComfort;
if (_.isEmpty(comfort) || !comfort || !comfort.data) {
... ... @@ -567,12 +518,12 @@ const _getProductComfort = (data) => {
return all;
}, []);
};
}
/**
* 基础商品描述
*/
const _getBasicDescription = (productDescBo) => {
function _getBasicDescription(productDescBo) {
let sex = (function(gender) {
if (gender === 1) {
return '男款';
... ... @@ -603,12 +554,12 @@ const _getBasicDescription = (productDescBo) => {
return all;
}, basic);
};
}
/**
* 获得描述数据
*/
const _getDescriptionDataBySizeInfo = (sizeInfo, additionalData) => {
function _getDescriptionDataBySizeInfo(sizeInfo, additionalData) {
if (!sizeInfo.productDescBo || !sizeInfo.productDescBo.erpProductId) {
return false;
}
... ... @@ -617,18 +568,18 @@ const _getDescriptionDataBySizeInfo = (sizeInfo, additionalData) => {
basic: _getBasicDescription(sizeInfo.productDescBo),
comfort: _getProductComfort(additionalData)
};
};
}
/**
* 使sizeBoList id以 sizeAttributeBos id顺序一样
* @param sizeInfoBo
*/
const _sizeInfoBoSort = (sizeInfoBo) => {
function _sizeInfoBoSort(sizeInfoBo) {
if (!sizeInfoBo.sizeBoList || !sizeInfoBo.sizeAttributeBos) {
return {};
}
_.get(sizeInfoBo, 'sizeBoList', []).forEach((sizeBoList, sizek)=> {
_.get(sizeInfoBo, 'sizeBoList', []).forEach((sizeBoList, sizek) => {
let sortAttr = {};
sizeBoList.sortAttributes.forEach(sortAttributes => {
... ... @@ -638,7 +589,7 @@ const _sizeInfoBoSort = (sizeInfoBo) => {
sizeInfoBo.sizeBoList[sizek].sortAttributes = sortAttr;
});
_.get(sizeInfoBo, 'sizeBoList', []).forEach((sizeBoList, sizek)=> {
_.get(sizeInfoBo, 'sizeBoList', []).forEach((sizeBoList, sizek) => {
let sortAttr = [];
sizeInfoBo.sizeAttributeBos.forEach(val => {
... ... @@ -652,15 +603,14 @@ const _sizeInfoBoSort = (sizeInfoBo) => {
});
return sizeInfoBo;
};
}
/**
* 获取尺寸信息
* @param sizeInfo
* @returns {{}}
*/
const _getSizeData = (sizeInfo) => {
function _getSizeData(sizeInfo) {
// 尺码信息
if (!_.has(sizeInfo, 'sizeInfoBo')) {
return {};
... ... @@ -745,13 +695,13 @@ const _getSizeData = (sizeInfo) => {
}
return size;
};
}
/**
* 获取商品模特卡
* @param productId
*/
const _getProductModelCard = (sortId, sizeInfo) => {
function _getProductModelCard(sortId, sizeInfo) {
if (!sortId || !_.includes([1, 3, 4], sortId)) {
return [];
}
... ... @@ -796,13 +746,13 @@ const _getProductModelCard = (sortId, sizeInfo) => {
}, [])
};
});
};
}
/**
* 获取模特数据
* @param sizeInfo
*/
const getReferenceDataBySizeInfo = (sizeInfo) => {
function getReferenceDataBySizeInfo(sizeInfo) {
if (_.isEmpty(sizeInfo.modelBos)) {
return false;
}
... ... @@ -845,13 +795,13 @@ const getReferenceDataBySizeInfo = (sizeInfo) => {
});
return reference;
};
}
/**
* 获取洗涤材质
* @param sizeInfo
*/
const _getMaterialDataBySizeInfo = (sizeInfo) => {
function _getMaterialDataBySizeInfo(sizeInfo) {
// 洗涤提示
// 商品材质[洗涤说明]
return {
... ... @@ -870,63 +820,29 @@ const _getMaterialDataBySizeInfo = (sizeInfo) => {
img: _.replace(_.get(sizeInfo, 'washRemindTipsBo.img', ''), 'http:', '')
}
};
};
}
/**
* 获取商品详情页介绍
* @param sizeInfo
*/
const _getDetailDataBySizeInfo = (sizeInfo) => {
let details = '';
function _getDetailDataBySizeInfo(sizeInfo) {
let phrase = '';
// 详情文字
if (_.has(sizeInfo, 'productDescBo.phrase')) {
details += `<em class='details-word'>${sizeInfo.productDescBo.phrase}</em><br/>`;
phrase = `<em class='details-word'>${sizeInfo.productDescBo.phrase}</em><br/>`;
}
// 图片换成懒加载方式
const replacePairs = {
'<img src=': '<img class="lazy img-responsive" width="720" height="200" ' +
'src="data:image/gif;base64,R0lGODlhAQABAJEAAAAAAP///93d3f///yH5BAEAAAMALAAAAAABAAEAAAICVAEAOw==" ' +
'data-original=',
'<img border="0" src=': '<img border="0" class="lazy img-responsive" width="720" height="200" ' +
'src="data:image/gif;base64,R0lGODlhAQABAJEAAAAAAP///93d3f///yH5BAEAAAMALAAAAAABAAEAAAICVAEAOw==" ' +
'data-original=',
'.jpg"': '.jpg?imageslim"',
'http://': '//'
};
let intro = _.get(sizeInfo, 'productIntroBo.productIntro', '');
// 详情配图
_(replacePairs).forEach((value, key)=> {
intro = _.replace(intro, new RegExp(key, 'gm'), value);
});
// 视频链接处理
let $ = cheerio.load(intro);
$('.video-placeholder').each((idx, ele) => {
let $this = $(ele);
let videoSrc = $this.find('source').attr('src');
let $video = $this.find('video');
let width = $video.attr('width');
let height = $video.attr('height');
$this.empty().append(videoPlayerTpl(videoSrc, width, height));
});
details += $.html();
return details;
};
return `<script id="details-intro" type="text/x-handlebars-template">${phrase}${intro}</script>`;
}
/**
* 获取模特试穿
* @param productSkn
*/
const _getProductModelTry = (data) => {
function _getProductModelTry(data) {
let result = data.productModelTry;
if (_.isEmpty(result) || result.code !== 200 || _.isEmpty(result.data)) {
... ... @@ -963,7 +879,7 @@ const _getProductModelTry = (data) => {
}
return modelTry;
};
}
/**
* 商品尺码信息
... ... @@ -972,7 +888,7 @@ const _getProductModelTry = (data) => {
* @param maxSortId
* @return object
*/
const _getIntroInfo = (productSkn, maxSortId, additionalData)=> {
function _getIntroInfo(productSkn, maxSortId, additionalData) {
if (!productSkn) {
return {};
}
... ... @@ -1007,7 +923,7 @@ const _getIntroInfo = (productSkn, maxSortId, additionalData)=> {
result.details = _getDetailDataBySizeInfo(sizeInfo);
return result;
};
}
/**
* 获取seo信息
... ... @@ -1016,7 +932,7 @@ const _getIntroInfo = (productSkn, maxSortId, additionalData)=> {
* @param array $navs
* @return array
*/
const _getSeoByGoodsInfo = (goodsInfo, navs) => {
function _getSeoByGoodsInfo(goodsInfo, navs) {
let title = '';
let brandName = '';
let sortName = '';
... ... @@ -1050,10 +966,10 @@ const _getSeoByGoodsInfo = (goodsInfo, navs) => {
description: description,
cononicalURL: cononicalURL
};
};
}
// 优惠券
const _getCoupon = (coupons) => {
function _getCoupon(coupons) {
if (coupons.code !== 200 || _.isEmpty(_.get(coupons, 'data', []))) {
return false;
}
... ... @@ -1062,18 +978,18 @@ const _getCoupon = (coupons) => {
let pickProp = Fn.pick(['couponName', 'amount', 'couponId', 'acquireStatus', 'rule4ShortName']);
let encodeId = Fn.update('couponId', (cid) => crypto.encryption(null, cid + ''));
let replace = Fn.update('rule4ShortName', (r)=> r.replace(/¥/g, '¥'));
let replace = Fn.update('rule4ShortName', (r) => r.replace(/¥/g, '¥'));
return Fn.map(Fn.pipe(pickProp, encodeId, replace))(couponList);
};
}
// 预上架商品
const _isPreShelves = (product) => {
function _isPreShelves(product) {
let isUnShelves = _.get(product, 'status', -1) === 0;
let hasSetShelvesTime = _.get(product, 'advance_shelve_time', -1) > 0;
return isUnShelves && hasSetShelvesTime;
};
}
// 商品线下店状态
const OFFLINE_STATUS = {
... ... @@ -1090,8 +1006,8 @@ function _isOfflineSell(status) {
* @param origin Object 原始数据
* @return result Object 格式化数据
*/
const _detailDataPkg = (origin, uid, vipLevel, cookies) => {
return co(function*() {
function _detailDataPkg(origin, uid, vipLevel, cookies) {
return co(function* () {
if (_.isEmpty(origin) || _.isEmpty(origin.data)) {
return {};
}
... ... @@ -1141,16 +1057,16 @@ const _detailDataPkg = (origin, uid, vipLevel, cookies) => {
result.bundleType = propOrigin('bundle_type', 0);
let requestApi = {
addition: _getProductAdditionInfoAsync(origin), // 预处理所有的数据
fav: _getProductFavoriteDataAsync(uid, result.productId), // 处理收藏喜欢数据
promotion: productAPI.getPromotionAsync(result.skn), // 打折信息
coupon: couponService.listAsync(propOrigin('brand_info.brand_id'), result.skn, uid) // 优惠券
addition: _getProductAdditionInfoAsync.call(this, origin), // 预处理所有的数据
fav: _getProductFavoriteDataAsync.call(this, uid, result.productId), // 处理收藏喜欢数据
promotion: this.productAPI.getPromotionAsync(result.skn), // 打折信息
coupon: this.couponService.listAsync(propOrigin('brand_info.brand_id'), result.skn, uid) // 优惠券
};
if (propOrigin('isLimitBuy', false) && propOrigin('limitProductCode', '')) {
result.limitProductCode = propOrigin('limitProductCode');
requestApi.limited = productAPI.getLimitedProductStatusAsync(
requestApi.limited = this.productAPI.getLimitedProductStatusAsync(
propOrigin('limitProductCode'),
uid,
result.skn
... ... @@ -1158,19 +1074,25 @@ const _detailDataPkg = (origin, uid, vipLevel, cookies) => {
}
if (propOrigin('bundle_type') === BUNDLE_PRODUCE) {
requestApi.bundle = productAPI.getBundleAsync(result.skn); // 量贩
requestApi.bundle = this.productAPI.getBundleAsync(result.skn); // 量贩
}
// 找相似
if (skuData.totalStorageNum === 0) {
requestApi.alike = productAPI.getLikeAsync(result.skn);
requestApi.alike = this.productAPI.getLikeAsync(result.skn);
}
// 相关推荐词
requestApi.recommendKeywords = productAPI.getRecommendKeywords(result.smallSortId, result.skn);
requestApi.recommendKeywords = this.productAPI.getRecommendKeywords(result.smallSortId, result.skn);
// 店铺推荐直出(seo需要)
requestApi.shopRecommend = productAPI.getShopRecommendAsync(result.skn);
requestApi.shopRecommend = this.productAPI.getShopRecommendAsync(result.skn);
// 新品推荐
requestApi.newProduct = this.productAPI.getNewProduct(result.smallSortId);
// 文章推荐
requestApi.articles = this.productAPI.getGuangArticles(result.skn);
let requestData = yield Promise.props(requestApi);
... ... @@ -1180,16 +1102,28 @@ const _detailDataPkg = (origin, uid, vipLevel, cookies) => {
let coupon = requestData.coupon;
let limitedInfo = requestData.limited;
let bundle = requestData.bundle;
let shopRecommend = requestData.shopRecommend;
let alike = requestData.alike;
let newProduct = requestData.newProduct;
let articles = requestData.articles;
// 文章推荐
result.recommendArticles = articles;
// 推荐最新商品
result.recommendNewProducts = newProduct;
// 处理相似商品
result.alike = productProcess.processProductList(_.get(requestData, 'alike.data.product_list', ''));
result.alike = productProcess.processProductList(
_.get(alike, 'data.product_list', '')
);
// 推荐关键词页面
result.recommendKeywords = requestData.recommendKeywords;
// 处理店铺推荐
result.shopRecommend = productProcess.processProductList(
_.get(requestData, 'shopRecommend.data.product_list', '')
_.get(shopRecommend, 'data.product_list', '')
);
// 商品标签
... ... @@ -1471,8 +1405,8 @@ const _detailDataPkg = (origin, uid, vipLevel, cookies) => {
statGoodsInfo.productName = result.name.replace('\'', '’');
statGoodsInfo.brandName = (result.brandName || '').replace('\'', '’');
statGoodsInfo.marketPrice = (result.marketPrice ?
result.marketPrice :
result.presalePrice).replace('¥', ''); // 数字
result.marketPrice :
result.presalePrice).replace('¥', ''); // 数字
statGoodsInfo.salePrice = (result.salePrice ?
result.salePrice :
(result.marketPrice || result.presalePrice)).replace('¥', ''); // 数字
... ... @@ -1498,8 +1432,8 @@ const _detailDataPkg = (origin, uid, vipLevel, cookies) => {
if (result.shopId) {
let shopData = yield Promise.props({
bannerImg: shopService.getShopBannerAsync(result.shopId),
shopInfo: shopService.queryShopByBrandIdAsync(result.shopId, result.brandId)
bannerImg: this.shopService.getShopBannerAsync(result.shopId),
shopInfo: this.shopService.queryShopByBrandIdAsync(result.shopId, result.brandId)
});
if (!_.isEmpty(shopData.shopInfo)) {
... ... @@ -1525,16 +1459,16 @@ const _detailDataPkg = (origin, uid, vipLevel, cookies) => {
statGoodsInfo: statGoodsInfo
};
})();
};
}).bind(this)();
}
/**
* 获得商品价格,活动等数据
*/
const getDetailHeader = (id, uid, isStudent, vipLevel, dataMd5, cookie) => {
let currentUserProductInfo = _.partial(_detailDataPkg, _, uid, vipLevel, cookie);
function getDetailHeader(id, uid, isStudent, vipLevel, dataMd5, cookie) {
let currentUserProductInfo = _.partial(_detailDataPkg.bind(this), _, uid, vipLevel, cookie);
return productAPI.getProductAsync(id, uid, isStudent, vipLevel)
return this.productAPI.getProductAsync(id, uid, isStudent, vipLevel)
.then(currentUserProductInfo)
.then((result) => {
return {
... ... @@ -1542,34 +1476,32 @@ const getDetailHeader = (id, uid, isStudent, vipLevel, dataMd5, cookie) => {
data: result
};
});
};
}
/**
* 是否支持退换货,true 支持,false 不支持
*/
const saleReturn = (skn) => {
return productAPI.isSupportReturnedSale(skn)
function saleReturn(skn) {
return this.productAPI.isSupportReturnedSale(skn)
.then(result => _.get(result, `data.${skn}`, 0));
};
}
/**
* 第一次把售价隐藏,防爬虫的需要
*/
const _removeSalePrice = (productInfo) => {
delete productInfo.goodsInfo.salePrice;
delete productInfo.goodsInfo.hasOtherPrice;
delete productInfo.goodsInfo.promotion;
return productInfo;
};
function _removeSalePrice(productInfo) {
return _.omit(productInfo, ['goodsInfo.salePrice', 'goodsInfo.hasOtherPrice', 'goodsInfo.promotion']);
}
/**
* 获取某一个商品详情主页面
*/
const showMainAsync = (req, data) => {
return co(function * () {
function showMainAsync(req, data) {
return co(function* () {
// 获取商品基本信息
let productData = yield productAPI.getProductAsync({skn: data.skn}, data.uid, data.isStudent, data.vipLevel);
let productData = yield this.productAPI.getProductAsync(
{skn: data.skn}, data.uid, data.isStudent, data.vipLevel
);
if (_.isEmpty(productData.data)) {
logger.error('app.product.data api wrong');
... ... @@ -1582,13 +1514,15 @@ const showMainAsync = (req, data) => {
let maxSortId = _.get(productData, 'data.maxSortId');
let productId = _.get(productData, 'data.product_id');
let productSkn = _.get(productData, 'data.product_skn');
let curUserProduct = _.partial(_detailDataPkg, _, data.uid, data.vipLevel, data.gid, data.saveInCookies);
let curUserProduct = _.partial(
_detailDataPkg.bind(this), _, data.uid, data.vipLevel, data.gid, data.saveInCookies
);
let requestData = yield Promise.all([
HeaderModel.requestHeaderData(data.channel), // 通用头部数据
_getProductIntroAsync(productId, productSkn), // 商品详细介绍
curUserProduct(productData), // 商品详细价格
tdk('skn', data.skn, req) // seo
HeaderModel.requestHeaderData(data.channel), // 通用头部数据
_getProductIntroAsync.call(this, productId, productSkn), // 商品详细介绍
curUserProduct.call(this, productData), // 商品详细价格
tdk('skn', data.skn, req) // seo
]);
let navigatorHeader = requestData[0];
... ... @@ -1648,26 +1582,26 @@ const showMainAsync = (req, data) => {
// 最近浏览,最多5条记录
result.detail.latestWalk = 5;
return result;
})().catch(console.log);
};
}).bind(this)().catch(console.log);
}
/**
* 获取某一个商品详情主页面
*/
const showMainBackAsync = (data) => {
return co(function * () {
function showMainBackAsync(data) {
return co(function* () {
// 获取商品基本信息
let productData = yield productAPI.getProductAsync({pid: data.pid});
let productData = yield this.productAPI.getProductAsync({pid: data.pid});
return productData;
})();
};
}).bind(this)();
}
const recommendAsync = (skn, page, limit) => {
return co(function * () {
let recommendData = yield productAPI.getShopRecommendAsync(skn, page, limit);
function recommendAsync(skn, page, limit) {
return co(function* () {
let recommendData = yield this.productAPI.getShopRecommendAsync(skn, page, limit);
if (_.get(recommendData, 'code', 400) !== 200) {
return {
... ... @@ -1709,8 +1643,8 @@ const recommendAsync = (skn, page, limit) => {
products: products
}
};
})();
};
}).bind(this)();
}
/**
* 处理单个套餐
... ... @@ -1755,32 +1689,75 @@ function handlePackage(pack, index) {
/**
* 获取套餐
*/
const getPackage = co(function * (skn) {
let reqData = yield productAPI.getBundleAsync(skn);
let resData = {code: reqData.code};
if (reqData.code === 200 && !_.isEmpty(reqData.data)) {
resData.data = _.map(reqData.data, handlePackage);
} else {
resData.code = 400;
resData.message = '没有数据';
}
function getPackage(skn) {
return co(function* () {
let reqData = yield this.productAPI.getBundleAsync(skn);
let resData = {code: reqData.code};
if (reqData.code === 200 && !_.isEmpty(reqData.data)) {
resData.data = _.map(reqData.data, handlePackage);
} else {
resData.code = 400;
resData.message = '没有数据';
}
return resData;
}).bind(this)();
}
return resData;
});
module.exports = {
getShareOrderListAsync: commentService.getShareOrderListAsync, // 获取评论列表
indexConsultAsync: consultService.indexAsync, // 获取咨询列表
createConsultAsync: consultService.createAsync, // 添加咨询
likeAsync: consultService.likeAsync, // 咨询喜欢
usefulAsync: consultService.usefulAsync, // 咨询有用
showMainAsync: showMainAsync, // 获取某一个商品详情主页面
showMainBackAsync: showMainBackAsync, // 获取某一个商品详情主页面
indexHotAreaAsync: hotAreaService.indexAsync, // 获取某一个商品的热区数据
saveRecentGoodInCookies, // 保存最近的商品
getDetailHeader,
saleReturn,
recommendAsync,
getPackage
module.exports = class extends global.yoho.BaseModel {
constructor(ctx) {
super(ctx);
this.commentService = new CommentServiceModel(ctx);
this.consultService = new ConsultServiceModel(ctx);
this.hotAreaService = new HotAreaServiceModel(ctx);
this.productAPI = new ProductModel(ctx);
this.couponService = new CouponServiceModel(ctx);
this.shopService = new ShopServiceModel(ctx);
this.brandService = new BrandServiceModel(ctx);
this.favoriteProductService = new FavoriteProductServiceModel(ctx);
// 获取评论列表
this.getShareOrderListAsync = this.commentService.getShareOrderListAsync.bind(this.commentService);
// 获取咨询列表
this.indexConsultAsync = this.consultService.indexAsync.bind(this.consultService);
// 添加咨询
this.createConsultAsync = this.consultService.createAsync.bind(this.consultService);
// 添加咨询
this.createConsultAsync = this.consultService.createAsync.bind(this.consultService);
// 咨询喜欢
this.likeAsync = this.consultService.likeAsync.bind(this.consultService);
// 咨询有用
this.usefulAsync = this.consultService.usefulAsync.bind(this.consultService);
// 获取某一个商品详情主页面
this.showMainAsync = showMainAsync.bind(this);
// 获取某一个商品详情主页面
this.showMainBackAsync = showMainBackAsync.bind(this);
// 获取某一个商品的热区数据
this.indexHotAreaAsync = this.hotAreaService.indexAsync.bind(this.hotAreaService);
// 保存最近的商品
this.saveRecentGoodInCookies = saveRecentGoodInCookies;
// 变化的价格部分
this.getDetailHeader = getDetailHeader.bind(this);
// 特殊商品退换货
this.saleReturn = saleReturn.bind(this);
// 推荐商品
this.recommendAsync = recommendAsync.bind(this);
// 套餐
this.getPackage = getPackage.bind(this);
}
};
... ...
... ... @@ -4,63 +4,61 @@
* @date: 2016/7/17
*/
'use strict';
module.exports = class extends global.yoho.BaseModel {
constructor(ctx) {
super(ctx);
}
const api = global.yoho.API;
/**
* 是否收藏API
* @function cancelFavAsync
* @param { number } uid 用户uid
* @param { number } id 收藏id
* @param { string } type 类型 product--商品 brand--品牌 shop--店铺
* @return { Object } 收藏状态
*/
isFavAsync(uid, id, type) {
return this.get({ data: {
method: 'app.favorite.isFavorite',
id: id,
uid: uid,
type: type
}});
}
/**
* 是否收藏API
* @function cancelFavAsync
* @param { number } uid 用户uid
* @param { number } id 收藏id
* @param { string } type 类型 product--商品 brand--品牌 shop--店铺
* @return { Object } 收藏状态
*/
const isFavAsync = (uid, id, type) => {
return api.get('', {
method: 'app.favorite.isFavorite',
id: id,
uid: uid,
type: type
});
};
/**
* 收藏API
* @function addFavAsync
* @param { number } uid 用户uid
* @param { number } id 收藏id
* @param { string } type 收藏类型 product--商品 brand--品牌 shop--店铺
* @return { Object } 收藏结果
*/
addFavAsync(uid, id, type) {
return this.get({ data: {
method: 'app.favorite.add',
id: id,
uid: uid,
type: type
}});
}
/**
* 收藏API
* @function addFavAsync
* @param { number } uid 用户uid
* @param { number } id 收藏id
* @param { string } type 收藏类型 product--商品 brand--品牌 shop--店铺
* @return { Object } 收藏结果
*/
const addFavAsync = (uid, id, type) => {
return api.get('', {
method: 'app.favorite.add',
id: id,
uid: uid,
type: type
});
/**
* 取消收藏API
* @function cancelFavAsync
* @param { number } uid 用户uid
* @param { number } id 收藏id
* @param { string } type 收藏类型 product--商品 brand--品牌 shop--店铺
* @return { Object } 取消收藏结果
*/
cancelFavAsync(uid, id, type) {
return this.get({ data: {
method: 'app.favorite.cancel',
fav_id: id,
uid: uid,
type: type
}});
}
};
/**
* 取消收藏API
* @function cancelFavAsync
* @param { number } uid 用户uid
* @param { number } id 收藏id
* @param { string } type 收藏类型 product--商品 brand--品牌 shop--店铺
* @return { Object } 取消收藏结果
*/
const cancelFavAsync = (uid, id, type) => {
return api.get('', {
method: 'app.favorite.cancel',
fav_id: id,
uid: uid,
type: type
});
};
module.exports = {
isFavAsync, // 是否收藏
addFavAsync, // 收藏
cancelFavAsync // 取消收藏
};
... ...
... ... @@ -4,37 +4,42 @@
'use strict';
const api = require('./favorite-api');
const serviceApi = global.yoho.SingleAPI;
const ApiService = require('./favorite-api');
const _ = require('lodash');
const isFavoriteAsync = _.partial(api.isFavAsync, _, _, 'brand');
const addFavAsync = _.partial(api.addFavAsync, _, _, 'brand');
const cancelFavAsync = _.partial(api.cancelFavAsync, _, _, 'brand');
module.exports = class extends global.yoho.BaseModel {
constructor(ctx) {
super(ctx);
this.api = new ApiService(ctx);
this.isFavoriteAsync = _.partial(this.api.isFavAsync.bind(this.api), _, _, 'brand');
this.addFavAsync = _.partial(this.api.addFavAsync.bind(this.api), _, _, 'brand');
this.cancelFavAsync = _.partial(this.api.cancelFavAsync.bind(this.api), _, _, 'brand');
}
getShopFavNumAsync(sid) {
return this.post({
data: {
favIds: sid,
type: 'shop',
method: 'app.favorite.queryFavoriteCountByShopIds'
},
url: '/favorite',
api: global.yoho.SingleAPI
});
}
getBrandIdNumAsync(bid) {
return this.post({
data: {
brandId: bid,
type: 'brand',
method: 'app.favorite.queryFavoriteCountByBrandId'
},
url: '/favorite',
api: global.yoho.SingleAPI
});
}
const getShopFavNumAsync = (sid) => {
return serviceApi.post('/favorite', {
favIds: sid,
type: 'shop',
method: 'app.favorite.queryFavoriteCountByShopIds'
});
};
const getBrandIdNumAsync = (bid) => {
return serviceApi.post('/favorite', {
brandId: bid,
type: 'brand',
method: 'app.favorite.queryFavoriteCountByBrandId'
});
};
module.exports = {
isFavoriteAsync,
addFavAsync,
cancelFavAsync,
getShopFavNumAsync,
getBrandIdNumAsync
};
... ...
... ... @@ -4,62 +4,63 @@
'use strict';
const api = require('./favorite-brand-api');
const ApiModel = require('./favorite-brand-api');
const _ = require('lodash');
const changeAsync = (type, uid, brandId) => {
switch (type) {
case 'add':
return api.addFavAsync(uid, brandId);
case 'cancel' :
return api.cancelFavAsync(uid, brandId);
default:
return Promise.reject('favorite brand error');
module.exports = class extends global.yoho.BaseModel {
constructor(ctx) {
super(ctx);
this.api = new ApiModel(ctx);
this.isFavoriteAsync = this.api.isFavoriteAsync.bind(this.api);
}
};
const getShopFavNumAsync = (sid) => {
return api.getShopFavNumAsync(sid).then((result) => {
if (result.code === 200) {
return {
code: 200,
data: {
count: _.get(result, 'data[0].count')
}
};
} else {
return {
code: 500,
message: '服务器错误'
};
changeAsync(type, uid, brandId) {
switch (type) {
case 'add':
return this.api.addFavAsync(uid, brandId);
case 'cancel' :
return this.api.cancelFavAsync(uid, brandId);
default:
return Promise.reject('favorite brand error');
}
});
};
}
const getBrandFavNumAsync = (bid) => {
return api.getBrandIdNumAsync(bid).then((result) => {
if (result.code === 200) {
return {
code: 200,
data: {
count: _.get(result, 'data.count')
}
};
} else {
return {
code: 500,
message: '服务器错误'
};
}
});
};
getShopFavNumAsync(sid) {
return this.api.getShopFavNumAsync(sid).then((result) => {
if (result.code === 200) {
return {
code: 200,
data: {
count: _.get(result, 'data[0].count')
}
};
} else {
return {
code: 500,
message: '服务器错误'
};
}
});
}
const isFavoriteAsync = api.isFavoriteAsync;
getBrandFavNumAsync(bid) {
return this.api.getBrandIdNumAsync(bid).then((result) => {
if (result.code === 200) {
return {
code: 200,
data: {
count: _.get(result, 'data.count')
}
};
} else {
return {
code: 500,
message: '服务器错误'
};
}
});
}
module.exports = {
changeAsync,
isFavoriteAsync,
getShopFavNumAsync,
getBrandFavNumAsync
};
};
... ...
... ... @@ -4,38 +4,26 @@
'use strict';
const api = global.yoho.API;
const favApi = global.yoho.FavAPI;
const _ = require('lodash');
const FavoriteApiModel = require('./favorite-api');
const favoriteApi = require('./favorite-api');
module.exports = class extends global.yoho.BaseModel {
constructor(ctx) {
super(ctx);
this.favoriteApi = new FavoriteApiModel(ctx);
const isFavoriteAsync = (uid, pid) => {
let onNewApi = false;
this.createAsync = _.partial(this.favoriteApi.addFavAsync.bind(this.favoriteApi), _, _, 'product');
this.deleteAsync = _.partial(this.favoriteApi.cancelFavAsync.bind(this.favoriteApi), _, _, 'product');
}
if (onNewApi) {
return favApi.get('', {
method: 'app.favorite.isFavoriteNew',
id: pid,
uid: uid,
type: 'product'
});
} else {
return api.get('', {
method: 'app.favorite.isFavorite',
id: pid,
uid: uid,
type: 'product'
isFavoriteAsync(uid, pid) {
return this.get({
data: {
method: 'app.favorite.isFavorite',
id: pid,
uid: uid,
type: 'product'
}
});
}
};
const createAsync = _.partial(favoriteApi.addFavAsync, _, _, 'product');
const deleteAsync = _.partial(favoriteApi.cancelFavAsync, _, _, 'product');
module.exports = {
isFavoriteAsync,
createAsync,
deleteAsync
};
... ...
... ... @@ -4,6 +4,6 @@
'use strict';
const favoriteProductAPI = require('./favorite-product-api');
const FavoriteProductAPI = require('./favorite-product-api');
module.exports = favoriteProductAPI;
module.exports = FavoriteProductAPI;
... ...
... ... @@ -6,63 +6,65 @@
'use strict';
const favAPI = require('./favorite-api');
const FavAPI = require('./favorite-api');
/**
* 收藏商品
* @function toggleFavProduct
* @param { number } productId 商品id
* @param { number } uid 用户uid
* @param { string } isadd 是否收藏 true--添加收藏 false--取消收藏
* @return { Object } 收藏结果
*/
const toggleFavProduct = (productId, uid, isadd) => {
if (isadd) {
return favAPI.addFavAsync(uid, productId, 'product');
} else {
return favAPI.cancelFavAsync(uid, productId, 'product');
module.exports = class extends global.yoho.BaseModel {
constructor(ctx) {
super(ctx);
this.favAPI = new FavAPI(ctx);
}
};
/**
* 收藏品牌
* @function toggleFavBrand
* @param { number } brandId 品牌id
* @param { number } uid 用户uid
* @param { string } isadd 是否收藏 true--添加收藏 false--取消收藏
* @return { Object } 收藏结果
*/
const toggleFavBrand = (brandId, uid, isadd) => {
if (isadd) {
return favAPI.addFavAsync(uid, brandId, 'brand');
} else {
return favAPI.cancelFavAsync(uid, brandId, 'brand');
/**
* 收藏商品
* @function toggleFavProduct
* @param { number } productId 商品id
* @param { number } uid 用户uid
* @param { string } isadd 是否收藏 true--添加收藏 false--取消收藏
* @return { Object } 收藏结果
*/
toggleFavProduct(productId, uid, isadd) {
if (isadd) {
return this.favAPI.addFavAsync(uid, productId, 'product');
} else {
return this.favAPI.cancelFavAsync(uid, productId, 'product');
}
}
};
/**
* 收藏店铺
* @function toggleFavShop
* @param { number } shopId 店铺id
* @param { number } uid 用户uid
* @param { string } isadd 是否收藏 true--添加收藏 false--取消收藏
* @return { Object } 收藏结果
*/
const toggleFavShop = (shopId, uid, isadd) => {
if (isadd) {
return favAPI.addFavAsync(uid, shopId, 'shop');
} else {
return favAPI.cancelFavAsync(uid, shopId, 'shop');
/**
* 收藏品牌
* @function toggleFavBrand
* @param { number } brandId 品牌id
* @param { number } uid 用户uid
* @param { string } isadd 是否收藏 true--添加收藏 false--取消收藏
* @return { Object } 收藏结果
*/
toggleFavBrand(brandId, uid, isadd) {
if (isadd) {
return this.favAPI.addFavAsync(uid, brandId, 'brand');
} else {
return this.favAPI.cancelFavAsync(uid, brandId, 'brand');
}
}
};
const getFavStatus = (uid, id, type) => {
return favAPI.isFavAsync(uid, id, type);
};
/**
* 收藏店铺
* @function toggleFavShop
* @param { number } shopId 店铺id
* @param { number } uid 用户uid
* @param { string } isadd 是否收藏 true--添加收藏 false--取消收藏
* @return { Object } 收藏结果
*/
toggleFavShop(shopId, uid, isadd) {
if (isadd) {
return this.favAPI.addFavAsync(uid, shopId, 'shop');
} else {
return this.favAPI.cancelFavAsync(uid, shopId, 'shop');
}
}
getFavStatus(uid, id, type) {
return this.favAPI.isFavAsync(uid, id, type);
}
module.exports = {
getFavStatus, // 收藏状态
toggleFavProduct, // 收藏商品
toggleFavBrand, // 收藏品牌
toggleFavShop // 收藏店铺
};
... ...
... ... @@ -6,48 +6,63 @@
'use strict';
const globalApi = global.yoho.GlobalAPI;
const config = global.yoho.config;
const getGlobalProductListAsync = (params, from) => {
let finalParams = {
limit: 60
};
Object.assign(finalParams, params);
if (from) {
finalParams.fromPage = from;
module.exports = class extends global.yoho.BaseModel {
constructor(ctx) {
super(ctx);
}
return globalApi.get('product/api/v2/detail/getlist', finalParams, config.apiCache);
};
getGlobalProductListAsync(params, from) {
let finalParams = {
limit: 60
};
const getGlobalProductDetailAsync = (skn, channelNum) => {
return globalApi.get('product/api/v2/detail/get', {
physical_channel: channelNum,
product_skn: skn
}, config.apiCache);
};
Object.assign(finalParams, params);
const getGlobalProductHtmlAsync = (skn, channelNum) => {
return globalApi.get('product/api/v1/detail/gethtml', {
physical_channel: channelNum,
product_skn: skn,
return_type: 'html'
}, config.apiCache);
};
if (from) {
finalParams.fromPage = from;
}
const getGlobalBrandInfoAsync = brand => {
return globalApi.get('editor/api/v1/brand/get', {
brandId: brand
}, config.apiCache);
return this.get({
url: 'product/api/v2/detail/getlist',
data: finalParams,
params: {cache: config.apiCache},
api: global.yoho.GlobalAPI
});
}
};
getGlobalProductDetailAsync(skn, channelNum) {
return this.get({
url: 'product/api/v2/detail/get',
data: {
physical_channel: channelNum,
product_skn: skn
},
params: { cache: config.apiCache },
api: global.yoho.GlobalAPI
});
}
module.exports = {
getGlobalProductListAsync,
getGlobalProductDetailAsync,
getGlobalProductHtmlAsync,
getGlobalBrandInfoAsync
getGlobalProductHtmlAsync(skn, channelNum) {
return this.get({
url: 'product/api/v1/detail/gethtml',
data: {
physical_channel: channelNum,
product_skn: skn,
return_type: 'html'
},
params: {cache: config.apiCache},
api: global.yoho.GlobalAPI
});
}
getGlobalBrandInfoAsync(brand) {
return this.get({
url: 'editor/api/v1/brand/get',
data: { brandId: brand },
params: {cache: config.apiCache},
api: global.yoho.GlobalAPI
});
}
};
... ...
... ... @@ -12,12 +12,12 @@ const cheerio = require('cheerio');
const helpers = global.yoho.helpers;
const homeService = require('./home-service');
const globalApi = require('./global-api');
const headerModel = require('../../../doraemon/models/header');
const searchHandler = require('./search-handler');
const pager = require(`${global.utils}/pager`).setPager;
const productProcess = require(`${global.utils}/product-process`);
const GlobalApiModel = require('./global-api');
const GLOBAL_LIST_URI = '/product/global/list';
const _handelGlobalPathNav = (data, channel, page) => {
... ... @@ -157,7 +157,7 @@ const _getProductSeoData = (detail) => {
return resData;
};
const getGlobalProductListData = (params, yoho) => {
function getGlobalProductListData(params, yoho) {
let limitNum = params.limit ? params.limit - 1 : 59;
let dps = {};
... ... @@ -169,14 +169,14 @@ const getGlobalProductListData = (params, yoho) => {
return Promise.props({
header: headerModel.requestHeaderData(yoho.channel),
fullList: globalApi.getGlobalProductListAsync(Object.assign({
fullList: this.globalApi.getGlobalProductListAsync(Object.assign({
physical_channel: yoho.channelNum,
limit: 1
}, dps)),
list: globalApi.getGlobalProductListAsync(Object.assign({
list: this.globalApi.getGlobalProductListAsync(Object.assign({
physical_channel: yoho.channelNum
}, params, {limit: limitNum})),
brand: dps.brand ? globalApi.getGlobalBrandInfoAsync(dps.brand) : {}
brand: dps.brand ? this.globalApi.getGlobalBrandInfoAsync(dps.brand) : {}
}).then(result => {
let resData = {};
... ... @@ -253,13 +253,13 @@ const getGlobalProductListData = (params, yoho) => {
return resData;
});
};
}
const getGlobalProductDetailData = (skn, channelNum, channel) => {
function getGlobalProductDetailData(skn, channelNum, channel) {
return Promise.props({
header: headerModel.requestHeaderData(channel),
detail: globalApi.getGlobalProductDetailAsync(skn, channelNum),
html: globalApi.getGlobalProductHtmlAsync(skn, channelNum)
detail: this.globalApi.getGlobalProductDetailAsync(skn, channelNum),
html: this.globalApi.getGlobalProductHtmlAsync(skn, channelNum)
}).then(result => {
let resData = {};
let detailInfo, html = '';
... ... @@ -361,9 +361,15 @@ const getGlobalProductDetailData = (skn, channelNum, channel) => {
return resData;
});
};
}
module.exports = class extends global.yoho.BaseModel {
constructor(ctx) {
super(ctx);
module.exports = {
getGlobalProductListData,
getGlobalProductDetailData
this.globalApi = new GlobalApiModel(ctx);
this.getGlobalProductListData = getGlobalProductListData.bind(this);
this.getGlobalProductDetailData = getGlobalProductDetailData.bind(this);
}
};
... ...