Merge branch 'hotfix/apple' into 'release/5.9'
促销标签 See merge request !702
Showing
15 changed files
with
145 additions
and
26 deletions
@@ -154,8 +154,9 @@ class BuyNowController { | @@ -154,8 +154,9 @@ class BuyNowController { | ||
154 | * @param {*} next | 154 | * @param {*} next |
155 | */ | 155 | */ |
156 | orderSub(req, res, next) { | 156 | orderSub(req, res, next) { |
157 | + let uid = req.user.uid; | ||
157 | let params = { | 158 | let params = { |
158 | - uid: req.user.uid, | 159 | + uid: uid, |
159 | product_sku: req.body.product_sku, | 160 | product_sku: req.body.product_sku, |
160 | sku_type: req.body.sku_type, | 161 | sku_type: req.body.sku_type, |
161 | buy_number: req.body.buy_number, | 162 | buy_number: req.body.buy_number, |
@@ -170,7 +171,8 @@ class BuyNowController { | @@ -170,7 +171,8 @@ class BuyNowController { | ||
170 | product_sku_list: req.body.product_sku_list, | 171 | product_sku_list: req.body.product_sku_list, |
171 | is_print_price: req.body.is_print_price, | 172 | is_print_price: req.body.is_print_price, |
172 | remark: req.body.remark, | 173 | remark: req.body.remark, |
173 | - activity_id: req.body.activity_id | 174 | + activity_id: req.body.activity_id, |
175 | + ip: req.yoho.clientIp | ||
174 | }; | 176 | }; |
175 | 177 | ||
176 | // 是否开发票 | 178 | // 是否开发票 |
@@ -186,6 +188,13 @@ class BuyNowController { | @@ -186,6 +188,13 @@ class BuyNowController { | ||
186 | } | 188 | } |
187 | } | 189 | } |
188 | 190 | ||
191 | + if (req.cookies.mkt_code || req.cookies._QYH_UNION) { | ||
192 | + let unionInfo = paymentProcess.unionInfoHandle(req.cookies, uid); | ||
193 | + | ||
194 | + params.qhy_union = _.get(unionInfo, 'unionKey', false); | ||
195 | + params.userAgent = _.get(unionInfo, 'userAgent', ''); | ||
196 | + } | ||
197 | + | ||
189 | co(function * () { | 198 | co(function * () { |
190 | let result = yield req.ctx(BuyNowModel).submit(params); | 199 | let result = yield req.ctx(BuyNowModel).submit(params); |
191 | 200 |
@@ -231,7 +231,7 @@ exports.orderSub = (req, res, next) => { | @@ -231,7 +231,7 @@ exports.orderSub = (req, res, next) => { | ||
231 | unionKey: unionInfo.unionKey, // 友盟数据 | 231 | unionKey: unionInfo.unionKey, // 友盟数据 |
232 | userAgent: unionInfo.userAgent, | 232 | userAgent: unionInfo.userAgent, |
233 | isWechat: req.yoho.isWechat, | 233 | isWechat: req.yoho.isWechat, |
234 | - ip: req.ip || '', | 234 | + ip: req.yoho.clientIp, |
235 | udid: req.cookies._yasvd || 'yoho' | 235 | udid: req.cookies._yasvd || 'yoho' |
236 | }; | 236 | }; |
237 | 237 |
@@ -159,7 +159,16 @@ class BuyNowModel extends global.yoho.BaseModel { | @@ -159,7 +159,16 @@ class BuyNowModel extends global.yoho.BaseModel { | ||
159 | finalParams.promotion_code = params.promotion_code; | 159 | finalParams.promotion_code = params.promotion_code; |
160 | } | 160 | } |
161 | 161 | ||
162 | - return api.post('', finalParams, {cache: false}); | 162 | + if (params.qhy_union) { |
163 | + finalParams.qhy_union = params.qhy_union; | ||
164 | + } | ||
165 | + | ||
166 | + return api.post('', finalParams, { | ||
167 | + headers: { | ||
168 | + 'X-Forwarded-For': params.ip || '', | ||
169 | + 'User-Agent': params.userAgent | ||
170 | + } | ||
171 | + }); | ||
163 | } | 172 | } |
164 | 173 | ||
165 | /** | 174 | /** |
@@ -304,11 +304,47 @@ const keyword = (req, res, next) => { | @@ -304,11 +304,47 @@ const keyword = (req, res, next) => { | ||
304 | }).catch(next); | 304 | }).catch(next); |
305 | }; | 305 | }; |
306 | 306 | ||
307 | +// 关键词页with id | ||
308 | +const keyId = (req, res, next) => { | ||
309 | + let params = { | ||
310 | + isSearch: true, // 搜索列表将最新改成默认的标识 | ||
311 | + cartUrl: helpers.urlFormat('/cart/index/index') | ||
312 | + }; | ||
313 | + | ||
314 | + params.isApp = req.yoho.isApp; | ||
315 | + params.physical_channel = req.yoho.channel && searchProcess.getChannelType(req.yoho.channel); | ||
316 | + | ||
317 | + return searchModel.getSearchKeywordDataById(req.params.id, params, req.user.uid).then(result => { | ||
318 | + let queryKey = result.queryKey; | ||
319 | + | ||
320 | + // 唤起 APP 的路径 | ||
321 | + res.locals.appPath = `yohobuy://yohobuy.com/goapp?openby:yohobuy={"action":"go.list","params":${JSON.stringify(params)}}`; | ||
322 | + | ||
323 | + res.render('search/list', { | ||
324 | + _noLazy: true, | ||
325 | + module: 'product', | ||
326 | + page: 'search-list', | ||
327 | + pageHeader: headerModel.setNav({ | ||
328 | + navTitle: queryKey | ||
329 | + }), | ||
330 | + goodList: params, | ||
331 | + firstPageGoods: result || [], | ||
332 | + fuzzyWord: result.fuzzyWord, | ||
333 | + title: `${queryKey}价格_图片_品牌_怎么样-YOHO!BUY有货`, | ||
334 | + keywords: `${queryKey},${queryKey}价格,${queryKey}图片,${queryKey}怎么样,${queryKey}品牌,YOHO!BUY有货`, | ||
335 | + description: `YOHO!BUY有货网yohobuy.com是国内专业的${queryKey}网上潮流购物商城,为您找到${_.get(result, | ||
336 | + 'total', 0)}条${queryKey}、产品的详细参数,实时报价,价格行情,图片、评价、品牌等信息。买${queryKey},就上YOHO!BUY有货`, | ||
337 | + pageFooter: true | ||
338 | + }); | ||
339 | + }).catch(next); | ||
340 | +}; | ||
341 | + | ||
307 | module.exports = { | 342 | module.exports = { |
308 | list, | 343 | list, |
309 | filter, | 344 | filter, |
310 | search, | 345 | search, |
311 | index, | 346 | index, |
312 | fuzzyDatas, | 347 | fuzzyDatas, |
313 | - keyword | 348 | + keyword, |
349 | + keyId | ||
314 | }; | 350 | }; |
@@ -13,6 +13,7 @@ const logger = global.yoho.logger; | @@ -13,6 +13,7 @@ const logger = global.yoho.logger; | ||
13 | const api = global.yoho.API; | 13 | const api = global.yoho.API; |
14 | const cache = require('memory-cache'); | 14 | const cache = require('memory-cache'); |
15 | const helpers = global.yoho.helpers; | 15 | const helpers = global.yoho.helpers; |
16 | +const redis = global.yoho.redis; | ||
16 | 17 | ||
17 | /** | 18 | /** |
18 | * 封面图 | 19 | * 封面图 |
@@ -539,6 +540,41 @@ const getSearchKeywordData = (params, uid) => { | @@ -539,6 +540,41 @@ const getSearchKeywordData = (params, uid) => { | ||
539 | }); | 540 | }); |
540 | }; | 541 | }; |
541 | 542 | ||
543 | +const getSearchKeywordDataById = (id, params, uid) => { | ||
544 | + return redis.all([ | ||
545 | + ['get', `golobal:yoho:seo:keywords:id:${id}`] | ||
546 | + ]).then(redisData => { | ||
547 | + if (!redisData[0]) { | ||
548 | + return Promise.reject('get redis canpin keywords by id error!' + | ||
549 | + `key: golobal:yoho:seo:keywords:id:${id} value: ${redisData[0]}`); | ||
550 | + } | ||
551 | + | ||
552 | + redisData = JSON.parse(redisData[0]); | ||
553 | + params.query = redisData.name; | ||
554 | + | ||
555 | + return getSearchKeywordData(params, uid).then(result => { | ||
556 | + result.queryKey = params.query; | ||
557 | + | ||
558 | + if (!_.isEmpty(redisData.data)) { | ||
559 | + _.forEach(redisData.data, value => { | ||
560 | + if (!value) { | ||
561 | + return; | ||
562 | + } | ||
563 | + | ||
564 | + Object.assign(value, { | ||
565 | + name: value.keyword, | ||
566 | + link: helpers.urlFormat(`/chanpin/${value.id}.html`, null) | ||
567 | + }); | ||
568 | + }); | ||
569 | + | ||
570 | + _.set(result, 'fuzzyWord', redisData.data); | ||
571 | + } | ||
572 | + | ||
573 | + return result; | ||
574 | + }); | ||
575 | + }); | ||
576 | +}; | ||
577 | + | ||
542 | module.exports = { | 578 | module.exports = { |
543 | getSearchData, | 579 | getSearchData, |
544 | getFilterData, | 580 | getFilterData, |
@@ -549,5 +585,6 @@ module.exports = { | @@ -549,5 +585,6 @@ module.exports = { | ||
549 | getFuzzyDatas, | 585 | getFuzzyDatas, |
550 | searchKeyActivity, | 586 | searchKeyActivity, |
551 | getBrandDomain, | 587 | getBrandDomain, |
552 | - getSearchKeywordData | 588 | + getSearchKeywordData, |
589 | + getSearchKeywordDataById | ||
553 | }; | 590 | }; |
@@ -134,8 +134,9 @@ router.get('/seckill/get-product-list', seckill.getProductList); // 秒杀列表 | @@ -134,8 +134,9 @@ router.get('/seckill/get-product-list', seckill.getProductList); // 秒杀列表 | ||
134 | // 搜索主页 | 134 | // 搜索主页 |
135 | router.get('/search/index', search.index); | 135 | router.get('/search/index', search.index); |
136 | 136 | ||
137 | -// 搜索落地页 | ||
138 | -router.get('/search/keyword/:query', rewrite.sortParams, search.keyword); | 137 | +// 推广落地页 |
138 | +router.get('/search/so/:query.html', rewrite.sortParams, search.keyword); | ||
139 | +router.get('/search/chanpin/:id.html', rewrite.sortParams, search.keyId); | ||
139 | 140 | ||
140 | // 搜索落地页 | 141 | // 搜索落地页 |
141 | router.get('/search/list', rewrite.sortParams, search.list); | 142 | router.get('/search/list', rewrite.sortParams, search.list); |
@@ -104,7 +104,8 @@ const cachePage = { | @@ -104,7 +104,8 @@ const cachePage = { | ||
104 | '/activity/shopNav': 30 * SECOND, | 104 | '/activity/shopNav': 30 * SECOND, |
105 | 105 | ||
106 | // 关键词页面 | 106 | // 关键词页面 |
107 | - '/product/search/keyword/:query': 7 * DAY | 107 | + '/product/search/so/:query.html': 7 * DAY, |
108 | + '/product/search/chanpin/:id.html': 7 * DAY | ||
108 | 109 | ||
109 | }; | 110 | }; |
110 | 111 |
1 | + | ||
2 | +const _ = require('lodash'); | ||
1 | const redis = require('redis'); | 3 | const redis = require('redis'); |
2 | const bluebird = require('bluebird'); | 4 | const bluebird = require('bluebird'); |
3 | const config = require('../../config/common'); | 5 | const config = require('../../config/common'); |
@@ -9,6 +11,18 @@ try { | @@ -9,6 +11,18 @@ try { | ||
9 | bluebird.promisifyAll(redis.RedisClient.prototype); | 11 | bluebird.promisifyAll(redis.RedisClient.prototype); |
10 | bluebird.promisifyAll(redis.Multi.prototype); | 12 | bluebird.promisifyAll(redis.Multi.prototype); |
11 | 13 | ||
14 | + client.all = args => { | ||
15 | + if (!client.ready) { | ||
16 | + if (Array.isArray(args)) { | ||
17 | + return Promise.resolve(_.fill(args, false)); | ||
18 | + } else { | ||
19 | + return Promise.resolve(false); | ||
20 | + } | ||
21 | + } | ||
22 | + | ||
23 | + return client.multi.call(client, args).execAsync(); | ||
24 | + }; | ||
25 | + | ||
12 | client.on('error', function() { | 26 | client.on('error', function() { |
13 | global.yoho.redis = ''; | 27 | global.yoho.redis = ''; |
14 | }); | 28 | }); |
@@ -84,14 +84,8 @@ module.exports = () => { | @@ -84,14 +84,8 @@ module.exports = () => { | ||
84 | } | 84 | } |
85 | break; | 85 | break; |
86 | } | 86 | } |
87 | - } else { | ||
88 | - let soReg = /\/so\/(.*).html/; | ||
89 | - | ||
90 | - if (soReg.test(req.path)) { | ||
91 | - soReg.exec(req.url); | ||
92 | - req.url = `/product/search/keyword/${RegExp.$1}`; | ||
93 | - } | ||
94 | } | 87 | } |
88 | + | ||
95 | next(); | 89 | next(); |
96 | }; | 90 | }; |
97 | }; | 91 | }; |
@@ -61,6 +61,11 @@ module.exports = () => { | @@ -61,6 +61,11 @@ module.exports = () => { | ||
61 | req.url = '/activity/couponSend'; | 61 | req.url = '/activity/couponSend'; |
62 | } | 62 | } |
63 | 63 | ||
64 | + if (/\/chanpin\/(.*).html/.test(req.url) || /\/so\/(.*).html/.test(req.url)) { | ||
65 | + // 获取seo兼容 | ||
66 | + req.url = `/product/search${req.path}`; | ||
67 | + } | ||
68 | + | ||
64 | next(); | 69 | next(); |
65 | }; | 70 | }; |
66 | }; | 71 | }; |
@@ -3,10 +3,10 @@ | @@ -3,10 +3,10 @@ | ||
3 | <div class="goods-discount" id="goodsDiscount"> | 3 | <div class="goods-discount" id="goodsDiscount"> |
4 | {{#each promotion}} | 4 | {{#each promotion}} |
5 | {{#if @first}} | 5 | {{#if @first}} |
6 | - <h1 class="first-item short-text tap-hightlight">{{promotionTitle}}<span class="icon-down iconfont dropdown"></span></h1> | 6 | + <h1 class="first-item short-text tap-hightlight"><span class="promotion-icon">促</span>{{promotionTitle}}<span class="icon-down iconfont dropdown"></span></h1> |
7 | {{else}} | 7 | {{else}} |
8 | <div class="discount-folder"> | 8 | <div class="discount-folder"> |
9 | - <h1 class="folder-item tap-hightlight">{{promotionTitle}}</h1> | 9 | + <h1 class="folder-item tap-hightlight"><span class="promotion-icon">促</span>{{promotionTitle}}</h1> |
10 | </div> | 10 | </div> |
11 | {{/if}} | 11 | {{/if}} |
12 | {{/each}} | 12 | {{/each}} |
@@ -11,7 +11,7 @@ let $ = require('yoho-jquery'), | @@ -11,7 +11,7 @@ let $ = require('yoho-jquery'), | ||
11 | 11 | ||
12 | require('./detail/page-render')(function() { | 12 | require('./detail/page-render')(function() { |
13 | let $discountFolder = $('.goods-discount .discount-folder'), | 13 | let $discountFolder = $('.goods-discount .discount-folder'), |
14 | - $discountArrow = $('.goods-discount .first-item span'); | 14 | + $discountArrow = $('.goods-discount .first-item .iconfont'); |
15 | 15 | ||
16 | let goodsDiscountEl = document.getElementById('goodsDiscount'), | 16 | let goodsDiscountEl = document.getElementById('goodsDiscount'), |
17 | goodsDiscountHammer = goodsDiscountEl && new Hammer(goodsDiscountEl), | 17 | goodsDiscountHammer = goodsDiscountEl && new Hammer(goodsDiscountEl), |
@@ -304,7 +304,7 @@ setTimeout(() => { | @@ -304,7 +304,7 @@ setTimeout(() => { | ||
304 | let $goodsDiscount = $('#goodsDiscount'); | 304 | let $goodsDiscount = $('#goodsDiscount'); |
305 | let $discountFirstItem = $goodsDiscount.find('.first-item'); | 305 | let $discountFirstItem = $goodsDiscount.find('.first-item'); |
306 | let $discountFolder = $goodsDiscount.find('.discount-folder'); | 306 | let $discountFolder = $goodsDiscount.find('.discount-folder'); |
307 | - let $discountArrow = $goodsDiscount.find('.first-item span'); | 307 | + let $discountArrow = $goodsDiscount.find('.first-item .iconfont'); |
308 | 308 | ||
309 | // 初始化goods-discount | 309 | // 初始化goods-discount |
310 | if ($discountFolder.children().length === 0) { | 310 | if ($discountFolder.children().length === 0) { |
@@ -711,6 +711,17 @@ $basicBtnC: #eb0313; | @@ -711,6 +711,17 @@ $basicBtnC: #eb0313; | ||
711 | line-height: 36px; | 711 | line-height: 36px; |
712 | } | 712 | } |
713 | 713 | ||
714 | + .first-item > .promotion-icon, | ||
715 | + .folder-item > .promotion-icon { | ||
716 | + background-color: #d0021b; | ||
717 | + color: #fff; | ||
718 | + padding: 0 4px; | ||
719 | + border-radius: 4px; | ||
720 | + margin-right: 10px; | ||
721 | + font-size: 22px; | ||
722 | + float: left; | ||
723 | + } | ||
724 | + | ||
714 | .short-text { | 725 | .short-text { |
715 | overflow: hidden; | 726 | overflow: hidden; |
716 | text-overflow: ellipsis; | 727 | text-overflow: ellipsis; |
@@ -336,10 +336,10 @@ function coupon(count, orderInfo, orderComputeData) { | @@ -336,10 +336,10 @@ function coupon(count, orderInfo, orderComputeData) { | ||
336 | count: count | 336 | count: count |
337 | }; | 337 | }; |
338 | 338 | ||
339 | - if ( | ||
340 | - orderComputeData.coupon_amount || | ||
341 | - (orderComputeData.coupon_amount === 0 && orderComputeData.shipping_cost === 0) | ||
342 | - ) { | 339 | + let couponAmount = _.get(orderComputeData, 'coupon_amount', false); |
340 | + let shippingCost = _.get(orderComputeData, 'shipping_cost', false); // shipping_cost 是普通运费 | ||
341 | + | ||
342 | + if (couponAmount || (couponAmount === 0 && shippingCost === 0)) { | ||
343 | coupons.couponName = orderInfo.couponName; | 343 | coupons.couponName = orderInfo.couponName; |
344 | } | 344 | } |
345 | 345 | ||
@@ -443,8 +443,10 @@ function unionInfoHandle(cookies, uid) { | @@ -443,8 +443,10 @@ function unionInfoHandle(cookies, uid) { | ||
443 | } | 443 | } |
444 | 444 | ||
445 | /* 模拟APP的User-Agent */ | 445 | /* 模拟APP的User-Agent */ |
446 | - userAgent = clientId ? 'YOHO!Buy/3.8.2.259(Model/PC;Channel/' + | ||
447 | - clientId + ';uid/' + uid + ')' : null; | 446 | + let clientIdSub = _.split(clientId, ',')[0]; |
447 | + | ||
448 | + userAgent = clientIdSub ? 'YOHO!Buy/3.8.2.259(Model/H5;Channel/' + | ||
449 | + clientIdSub + ';uid/' + uid + ')' : null; | ||
448 | 450 | ||
449 | return { | 451 | return { |
450 | unionKey: unionKey, | 452 | unionKey: unionKey, |
-
Please register or login to post a comment