Authored by 李靖

开发完成

@@ -175,7 +175,8 @@ exports.resourcesGoodsList = (req, res, next) => { @@ -175,7 +175,8 @@ exports.resourcesGoodsList = (req, res, next) => {
175 }; 175 };
176 176
177 plusstarModel.getProductBatch(param, { 177 plusstarModel.getProductBatch(param, {
178 - isApp: isApp 178 + isApp: isApp,
  179 + showSimilar: true
179 }).then(result => { 180 }).then(result => {
180 res.render('plusstar/resources-goodsList', { 181 res.render('plusstar/resources-goodsList', {
181 layout: false, 182 layout: false,
@@ -207,6 +207,10 @@ const getNewProduct = (brandId, gender, url, isApp) => { @@ -207,6 +207,10 @@ const getNewProduct = (brandId, gender, url, isApp) => {
207 }); 207 });
208 } 208 }
209 209
  210 + obj = _.assign(obj, {
  211 + similar: true
  212 + });
  213 +
210 newArrival.naList.push(obj); 214 newArrival.naList.push(obj);
211 215
212 } 216 }
@@ -34,6 +34,12 @@ @@ -34,6 +34,12 @@
34 {{# is_solded}} 34 {{# is_solded}}
35 <p class="out-tag">已售罄</p> 35 <p class="out-tag">已售罄</p>
36 {{/ is_solded}} 36 {{/ is_solded}}
  37 + {{#if similar}}
  38 + <div class="similar-c">
  39 + <div class="bg"></div>
  40 + <a href="//m.yohobuy.com/product/similar?skn={{id}}">找相似</a>
  41 + </div>
  42 + {{/if}}
37 </div> 43 </div>
38 <div class="good-detail-text"> 44 <div class="good-detail-text">
39 <div class="name"> 45 <div class="name">
@@ -53,6 +59,9 @@ @@ -53,6 +59,9 @@
53 {{/price}} 59 {{/price}}
54 {{/if}} 60 {{/if}}
55 </div> 61 </div>
  62 + {{#if similar}}
  63 + <a class="similar-btn iconfont">&#xe606;</a>
  64 + {{/if}}
56 </div> 65 </div>
57 </div> 66 </div>
58 {{/if}} 67 {{/if}}
  1 +'use strict';
  2 +
  3 +const headerModel = require('../../../doraemon/models/header'); // 头部model
  4 +const similarModel = require('../models/similar');
  5 +
  6 +exports.index = (req, res, next) => {
  7 + let responseData = {
  8 + pageHeader: headerModel.setNav({
  9 + navTitle: '找相似',
  10 + }),
  11 + module: 'product',
  12 + page: 'similar',
  13 + title: '找相似',
  14 + width750: true,
  15 + pageFooter: true,
  16 + localCss: true
  17 + };
  18 +
  19 + req.ctx(similarModel).list({skn: req.query.skn}).then(result => {
  20 + res.render('similar/index', Object.assign(responseData, result));
  21 + }).catch(next);
  22 +};
@@ -75,7 +75,10 @@ const getSearchData = (params) => { @@ -75,7 +75,10 @@ const getSearchData = (params) => {
75 if (result && result.code === 200) { 75 if (result && result.code === 200) {
76 let newList = {}; 76 let newList = {};
77 77
78 - newList.list = productProcess.processProductList(result.data.product_list || [], {showTags: true}); 78 + newList.list = productProcess.processProductList(result.data.product_list || [], {
  79 + showTags: true,
  80 + showSimilar: true
  81 + });
79 82
80 if (parseInt(params.page, 10) === 1) { 83 if (parseInt(params.page, 10) === 1) {
81 newList.total = result.data.total; 84 newList.total = result.data.total;
@@ -23,7 +23,9 @@ const mayLike = (uid, page, limit, gender, udid, recPos, channel, clientId) => { @@ -23,7 +23,9 @@ const mayLike = (uid, page, limit, gender, udid, recPos, channel, clientId) => {
23 if (result.data.page_total && page <= result.data.page_total) { 23 if (result.data.page_total && page <= result.data.page_total) {
24 if (result.data.product_list) { 24 if (result.data.product_list) {
25 25
26 - return productProcess.processProductList(result.data.product_list); 26 + return productProcess.processProductList(result.data.product_list, {
  27 + showSimilar: true
  28 + });
27 29
28 } else { 30 } else {
29 return false; 31 return false;
@@ -51,7 +53,9 @@ const mayLikeKids = (page, limit, channel) => { @@ -51,7 +53,9 @@ const mayLikeKids = (page, limit, channel) => {
51 53
52 if (result.data.product_list) { 54 if (result.data.product_list) {
53 55
54 - return productProcess.processProductList(result.data.product_list); 56 + return productProcess.processProductList(result.data.product_list, {
  57 + showSimilar: true
  58 + });
55 59
56 } 60 }
57 } else { 61 } else {
@@ -77,7 +81,10 @@ const mayLikelife = (page, limit) => { @@ -77,7 +81,10 @@ const mayLikelife = (page, limit) => {
77 81
78 build.show = true; 82 build.show = true;
79 83
80 - build.goods = productProcess.processProductList(result.data.product_list.top, {showTags: false}); 84 + build.goods = productProcess.processProductList(result.data.product_list.top, {
  85 + showTags: false,
  86 + showSimilar: true
  87 + });
81 88
82 formData.goodsContainer.push(build); 89 formData.goodsContainer.push(build);
83 } 90 }
@@ -87,7 +94,10 @@ const mayLikelife = (page, limit) => { @@ -87,7 +94,10 @@ const mayLikelife = (page, limit) => {
87 94
88 build.show = true; 95 build.show = true;
89 96
90 - build.goods = productProcess.processProductList(result.data.product_list.new, {showTags: false}); 97 + build.goods = productProcess.processProductList(result.data.product_list.new, {
  98 + showTags: false,
  99 + showSimilar: true
  100 + });
91 101
92 formData.goodsContainer.push(build); 102 formData.goodsContainer.push(build);
93 } 103 }
@@ -63,6 +63,7 @@ const getPreferenceData = (data) => { @@ -63,6 +63,7 @@ const getPreferenceData = (data) => {
63 // tags.is_solded = true; 63 // tags.is_solded = true;
64 64
65 goods.tags = tags; 65 goods.tags = tags;
  66 + goods.similar = true;
66 67
67 if (tags.is_solded === true) { 68 if (tags.is_solded === true) {
68 goods.is_solded = true; 69 goods.is_solded = true;
@@ -247,7 +247,8 @@ const getSearchData = (params) => { @@ -247,7 +247,8 @@ const getSearchData = (params) => {
247 247
248 newList.list = productProcess.processProductList(result.data.product_list || [], { 248 newList.list = productProcess.processProductList(result.data.product_list || [], {
249 isApp: params.isApp || (params.appVersion && params.appVersion !== 'false'), 249 isApp: params.isApp || (params.appVersion && params.appVersion !== 'false'),
250 - gender: _coverChannel[params.coverChannel] 250 + gender: _coverChannel[params.coverChannel],
  251 + showSimilar: params.shop_id ? false : true
251 }); 252 });
252 253
253 if (result.data.rec_shop_list && result.data.rec_shop_list.length > 0 && 254 if (result.data.rec_shop_list && result.data.rec_shop_list.length > 0 &&
@@ -278,7 +279,8 @@ const getSearchData = (params) => { @@ -278,7 +279,8 @@ const getSearchData = (params) => {
278 termsSuggestion: productProcess.termsSuggestion( 279 termsSuggestion: productProcess.termsSuggestion(
279 result.data.suggestion && result.data.suggestion.terms_suggestion || [], params 280 result.data.suggestion && result.data.suggestion.terms_suggestion || [], params
280 ), 281 ),
281 - isMaybeLike: result.data.total < 20 // 搜索过来的 小于 20条 猜你喜欢显示不显示判断 282 + isMaybeLike: result.data.total < 20, // 搜索过来的 小于 20条 猜你喜欢显示不显示判断
  283 + showSimilar: true
282 }; 284 };
283 suggestion.isNeedSuggestionOne = suggestion.termsSuggestion.length > 1;// 如果只有一个<或者试试不显示> 285 suggestion.isNeedSuggestionOne = suggestion.termsSuggestion.length > 1;// 如果只有一个<或者试试不显示>
284 } 286 }
@@ -300,7 +302,9 @@ const getSearchData = (params) => { @@ -300,7 +302,9 @@ const getSearchData = (params) => {
300 const getFilterData = (params) => { 302 const getFilterData = (params) => {
301 return _searchGoods(params).then((result) => { 303 return _searchGoods(params).then((result) => {
302 if (result && result.code === 200) { 304 if (result && result.code === 200) {
303 - return productProcess.processFilter(result.data.filter || []); 305 + return productProcess.processFilter(result.data.filter || [], {
  306 + showSimilar: true
  307 + });
304 } else { 308 } else {
305 logger.error('get filter data api return code is not 200'); 309 logger.error('get filter data api return code is not 200');
306 return []; 310 return [];
  1 +'use strict';
  2 +
  3 +const utils = '../../../utils';
  4 +const _ = require('lodash');
  5 +const productProcess = require(`${utils}/product-process`);
  6 +
  7 +module.exports = class extends global.yoho.BaseModel {
  8 + constructor(ctx) {
  9 + super(ctx);
  10 + }
  11 +
  12 + list(params) {
  13 + let options = {
  14 + data: {
  15 + method: 'app.search.findLike',
  16 + product_skn: params.skn
  17 + },
  18 + param: {
  19 + code: 200
  20 + }
  21 + };
  22 +
  23 + return this.get(options).then(result => {
  24 + let resu = {
  25 + goodInfo: [],
  26 + list: []
  27 + };
  28 +
  29 + if (_.get(result, 'data', false)) {
  30 + resu.goodInfo = productProcess.processProductList(result.data);
  31 + }
  32 +
  33 + if (_.get(result, 'data.product_list', false)) {
  34 + resu.list = productProcess.processProductList(result.data.product_list);
  35 + }
  36 +
  37 + return resu;
  38 + });
  39 + }
  40 +};
@@ -56,6 +56,9 @@ const bundle = require(`${cRoot}/bundle`); @@ -56,6 +56,9 @@ const bundle = require(`${cRoot}/bundle`);
56 // 全球购 56 // 全球购
57 const globalPro = require(`${cRoot}/global`); 57 const globalPro = require(`${cRoot}/global`);
58 58
  59 +// 找相似
  60 +const similar = require(`${cRoot}/similar`);
  61 +
59 // routers 62 // routers
60 63
61 // /pro_136349_455445/HEARTSOFARMianMaShuJiaoXiuXianKuPS1684.html 64 // /pro_136349_455445/HEARTSOFARMianMaShuJiaoXiuXianKuPS1684.html
@@ -209,4 +212,6 @@ router.get('/global/search', globalPro.search); // 全球购列表页搜索数 @@ -209,4 +212,6 @@ router.get('/global/search', globalPro.search); // 全球购列表页搜索数
209 router.get(/^\/global\/(\d+)\.html/, globalPro.detail); // 全球购店铺详情页 212 router.get(/^\/global\/(\d+)\.html/, globalPro.detail); // 全球购店铺详情页
210 router.get('/global/gethtml', globalPro.gethtml); // 全球购商品信息 213 router.get('/global/gethtml', globalPro.gethtml); // 全球购商品信息
211 214
  215 +router.get('/similar', similar.index); // 找相似
  216 +
212 module.exports = router; 217 module.exports = router;
  1 +<div class="similar-c">
  2 + <div class="good-c">
  3 + {{# goodInfo}}
  4 + <div class="good-item clearfix" href="#">
  5 + <div class="pic">
  6 + <a href="{{url}}">
  7 + <img src="{{image2 default_images w=152 h=203 q=60}}"/>
  8 + </a>
  9 + </div>
  10 + <div class="info">
  11 + <a href="{{url}}">
  12 + <p class="name">{{product_name}}</p>
  13 + </a>
  14 + <div class="price">
  15 + {{#if @root.saleViplogin}}
  16 + <span class="now">¥
  17 + {{#if @root.vipPrice1}}{{round vip1_price}}{{/if}}
  18 + {{#if @root.vipPrice2}}{{round vip2_price}}{{/if}}
  19 + {{#if @root.vipPrice3}}{{round vip3_price}}{{/if}}
  20 + </span>
  21 + {{else}}
  22 + <span class="now">¥{{round sales_price}}</span>
  23 + {{/if}}
  24 + {{#market_price}}
  25 + <span class="old">¥{{round .}}</span>
  26 + {{/market_price}}
  27 + </div>
  28 + </div>
  29 + </div>
  30 + {{/goodInfo}}
  31 + </div>
  32 + {{#if list}}
  33 + <p class="big-title">相似商品</p>
  34 + {{/if}}
  35 + <div class="good-c">
  36 + {{#list}}
  37 + <div class="good-item clearfix" href="#">
  38 + <div class="pic">
  39 + <a href="{{url}}">
  40 + <img class="lazy" data-original="{{image2 default_images w=152 h=203 q=60}}"/>
  41 + </a>
  42 + </div>
  43 + <div class="info">
  44 + <a href="{{url}}">
  45 + <p class="name">{{product_name}}</p>
  46 + </a>
  47 + <div class="price">
  48 + {{#if @root.saleViplogin}}
  49 + <span class="now">¥
  50 + {{#if @root.vipPrice1}}{{round vip1_price}}{{/if}}
  51 + {{#if @root.vipPrice2}}{{round vip2_price}}{{/if}}
  52 + {{#if @root.vipPrice3}}{{round vip3_price}}{{/if}}
  53 + </span>
  54 + {{else}}
  55 + <span class="now">¥{{round sales_price}}</span>
  56 + {{/if}}
  57 + {{#market_price}}
  58 + <span class="old">¥{{round .}}</span>
  59 + {{/market_price}}
  60 + </div>
  61 + <a class="btn" href="//m.yohobuy.com/product/similar?skn={{product_skn}}">找相似</a>
  62 + </div>
  63 + </div>
  64 + {{/list}}
  65 + </div>
  66 +</div>
@@ -52,6 +52,12 @@ @@ -52,6 +52,12 @@
52 <div class="no-storage-img"></div> 52 <div class="no-storage-img"></div>
53 </div> 53 </div>
54 {{/ noStorage}} --}} 54 {{/ noStorage}} --}}
  55 + {{#if similar}}
  56 + <div class="similar-c">
  57 + <div class="bg"></div>
  58 + <a href="//m.yohobuy.com/product/similar?skn={{product_skn}}">找相似</a>
  59 + </div>
  60 + {{/if}}
55 </div> 61 </div>
56 <div class="good-detail-text"> 62 <div class="good-detail-text">
57 <div class="name"> 63 <div class="name">
@@ -77,6 +83,9 @@ @@ -77,6 +83,9 @@
77 <i class="vip-icon"></i>更优惠 83 <i class="vip-icon"></i>更优惠
78 </div> 84 </div>
79 {{/if}} 85 {{/if}}
  86 + {{#if similar}}
  87 + <a class="similar-btn iconfont">&#xe606;</a>
  88 + {{/if}}
80 </div> 89 </div>
81 </div> 90 </div>
82 {{/if}} 91 {{/if}}
@@ -71,6 +71,12 @@ @@ -71,6 +71,12 @@
71 <div class="no-storage-img"></div> 71 <div class="no-storage-img"></div>
72 </div> 72 </div>
73 {{/ noStorage}} --}} 73 {{/ noStorage}} --}}
  74 + {{#if similar}}
  75 + <div class="similar-c">
  76 + <div class="bg"></div>
  77 + <a href="//m.yohobuy.com/product/similar?skn={{product_skn}}">找相似</a>
  78 + </div>
  79 + {{/if}}
74 </div> 80 </div>
75 <div class="good-detail-text"> 81 <div class="good-detail-text">
76 <div class="name"> 82 <div class="name">
@@ -96,6 +102,9 @@ @@ -96,6 +102,9 @@
96 <i class="vip-icon"></i>更优惠 102 <i class="vip-icon"></i>更优惠
97 </div> 103 </div>
98 {{/if}} 104 {{/if}}
  105 + {{#if similar}}
  106 + <a class="similar-btn iconfont">&#xe606;</a>
  107 + {{/if}}
99 </div> 108 </div>
100 </div> 109 </div>
101 {{/if}} 110 {{/if}}
@@ -302,6 +302,15 @@ $('.nav-home').on('touchstart', function() { @@ -302,6 +302,15 @@ $('.nav-home').on('touchstart', function() {
302 $('.homebuttom').toggleClass('hide'); 302 $('.homebuttom').toggleClass('hide');
303 }); 303 });
304 304
  305 +// 商品列表找相似按钮
  306 +$('*').on('touchstart', '.similar-btn', function() {
  307 + let $thisP = $(this).parents('.good-info');
  308 +
  309 + $thisP.find('.similar-c').toggle();
  310 + $thisP.siblings('.good-info').find('.similar-c').hide();
  311 + return false;
  312 +});
  313 +
305 (function() { 314 (function() {
306 let lastTime = 0, 315 let lastTime = 0,
307 prefixes = 'webkit moz ms o'.split(' '), 316 prefixes = 'webkit moz ms o'.split(' '),
  1 +'use strict';
  2 +
  3 +import {
  4 + Controller
  5 +} from 'yoho-mvc';
  6 +
  7 +require('yoho-jquery');
  8 +const lazyLoad = require('yoho-jquery-lazyload');
  9 +
  10 +class SimilarController extends Controller {
  11 + constructor() {
  12 + super();
  13 + lazyLoad($('img.lazy'));
  14 + }
  15 +}
  16 +
  17 +module.exports = SimilarController;
  1 +require('product/similar/similar.page.css');
  2 +
  3 +const SimilarController = require('./controller');
  4 +
  5 +new SimilarController();
@@ -156,9 +156,46 @@ @@ -156,9 +156,46 @@
156 background-size: contain; 156 background-size: contain;
157 } 157 }
158 } 158 }
  159 +
  160 + .similar-c {
  161 + display: none;
  162 + width: 100%;
  163 + height: 100%;
  164 + position: absolute;
  165 + top: 0;
  166 + left: 0;
  167 + right: 0;
  168 + bottom: 0;
  169 +
  170 + .bg {
  171 + width: 100%;
  172 + height: 100%;
  173 + background-color: #000;
  174 + opacity: 0.6;
  175 + }
  176 +
  177 + a {
  178 + display: block;
  179 + width: 120px;
  180 + height: 120px;
  181 + position: absolute;
  182 + top: 50%;
  183 + left: 50%;
  184 + margin-left: -60px;
  185 + margin-top: -60px;
  186 + color: #fff;
  187 + background-color: #d0021b;
  188 + font-size: 28px;
  189 + line-height: 120px;
  190 + text-align: center;
  191 + border-radius: 50%;
  192 + }
  193 + }
159 } 194 }
160 195
161 .good-detail-text { 196 .good-detail-text {
  197 + position: relative;
  198 +
162 .name a { 199 .name a {
163 transform: scale(0.9); 200 transform: scale(0.9);
164 margin: 15px 0 10px; 201 margin: 15px 0 10px;
@@ -235,6 +272,18 @@ @@ -235,6 +272,18 @@
235 vertical-align: bottom; 272 vertical-align: bottom;
236 } 273 }
237 } 274 }
  275 +
  276 + .similar-btn {
  277 + color: #b0b0b0;
  278 + width: 40px;
  279 + height: 40px;
  280 + line-height: 40px;
  281 + text-align: center;
  282 + position: absolute;
  283 + bottom: -10px;
  284 + right: 0;
  285 + font-weight: bold;
  286 + }
238 } 287 }
239 288
240 .width750 { 289 .width750 {
  1 +.similar-c {
  2 + background-color: #f0f0f0;
  3 + padding-bottom: 30px;
  4 +
  5 + .good-c {
  6 + border-top: solid 1px #e0e0e0;
  7 +
  8 + .good-item {
  9 + display: block;
  10 + padding: 20px 30px;
  11 + border-bottom: solid 1px #e0e0e0;
  12 + position: relative;
  13 + background-color: #fff;
  14 +
  15 + .pic {
  16 + width: 152px;
  17 + height: 203px;
  18 + float: left;
  19 + }
  20 +
  21 + img {
  22 + width: 100%;
  23 + height: 100%;
  24 + }
  25 +
  26 + .info {
  27 + width: 508px;
  28 + float: left;
  29 + margin-left: 30px;
  30 + }
  31 +
  32 + .name {
  33 + padding: 5px 0;
  34 + font-size: 28px;
  35 + color: #444;
  36 + line-height: 40px;
  37 + height: 170px;
  38 + overflow: hidden;
  39 + }
  40 +
  41 + .price {
  42 + line-height: 33px;
  43 + }
  44 +
  45 + .now {
  46 + font-size: 34px;
  47 + color: #d0021b;
  48 + margin-right: 10px;
  49 + }
  50 +
  51 + .old {
  52 + font-size: 20px;
  53 + color: #444;
  54 + text-decoration: line-through;
  55 + }
  56 +
  57 + .btn {
  58 + width: 86px;
  59 + height: 36px;
  60 + line-height: 36px;
  61 + color: #d0021b;
  62 + font-size: 20px;
  63 + border: solid 2px #d0021b;
  64 + border-radius: 3px;
  65 + position: absolute;
  66 + bottom: 20px;
  67 + right: 30px;
  68 + text-align: center;
  69 + }
  70 + }
  71 + }
  72 +
  73 + .big-title {
  74 + font-size: 28px;
  75 + color: #b0b0b0;
  76 + line-height: 88px;
  77 + text-align: center;
  78 + }
  79 +}
@@ -199,6 +199,11 @@ exports.processProductList = (list, options) => { @@ -199,6 +199,11 @@ exports.processProductList = (list, options) => {
199 199
200 } 200 }
201 201
  202 + // 显示相似商品按钮
  203 + if (options.showSimilar) {
  204 + product.similar = true;
  205 + }
  206 +
202 pruductList.push(product); 207 pruductList.push(product);
203 }); 208 });
204 209