Authored by 沈志敏

全球购详情页

@@ -36,16 +36,20 @@ const list = (req, res, next) => { @@ -36,16 +36,20 @@ const list = (req, res, next) => {
36 } 36 }
37 37
38 Promise.all(arrs).then((result) => { 38 Promise.all(arrs).then((result) => {
  39 + let t = (result[1] || {}).brand_name || title;
  40 +
  41 + param.title = t;
39 res.render('global/list', { 42 res.render('global/list', {
40 module: 'product', 43 module: 'product',
41 page: 'global-list', 44 page: 'global-list',
42 pageHeader: headerModel.setNav({ 45 pageHeader: headerModel.setNav({
43 - navTitle: (result[1] || {}).brand_name || title 46 + navTitle: t
44 }), 47 }),
45 list: result[0].list, 48 list: result[0].list,
46 filter: result[0].filter, 49 filter: result[0].filter,
47 pageFooter: true, 50 pageFooter: true,
48 - localCss: true 51 + localCss: true,
  52 + appPath: `yohobuy://yohobuy.com/goapp?openby:yohobuy={"action":"go.globalpurchase","params":${JSON.stringify(param)}}`
49 }); 53 });
50 }).catch(next); 54 }).catch(next);
51 }; 55 };
@@ -76,6 +80,11 @@ const detail = (req, res, next) => { @@ -76,6 +80,11 @@ const detail = (req, res, next) => {
76 }; 80 };
77 81
78 model.detail(params).then((result) => { 82 model.detail(params).then((result) => {
  83 + let appParams = {
  84 + skn: skn
  85 + };
  86 + let appPath = `yohobuy://yohobuy.com/goapp?openby:yohobuy={"action":"go.globalpurchase","params":${JSON.stringify(appParams)}}`;
  87 +
79 res.render('global/detail', { 88 res.render('global/detail', {
80 module: 'product', 89 module: 'product',
81 page: 'global-detail', 90 page: 'global-detail',
@@ -83,14 +92,17 @@ const detail = (req, res, next) => { @@ -83,14 +92,17 @@ const detail = (req, res, next) => {
83 navTitle: '商品详情' 92 navTitle: '商品详情'
84 }), 93 }),
85 result: result, 94 result: result,
  95 + cartUrl: '//m.yohobuy.com/cart/index/index',
86 pageFooter: true, 96 pageFooter: true,
87 - localCss: true 97 + localCss: true,
  98 + appPath: appPath
88 }); 99 });
89 }).catch(next); 100 }).catch(next);
90 }; 101 };
91 102
92 const gethtml = (req, res, next) => { 103 const gethtml = (req, res, next) => {
93 let skn = req.query.skn; 104 let skn = req.query.skn;
  105 +
94 if (!skn) { 106 if (!skn) {
95 return next(); 107 return next();
96 } 108 }
@@ -104,8 +116,7 @@ const gethtml = (req, res, next) => { @@ -104,8 +116,7 @@ const gethtml = (req, res, next) => {
104 model.gethtml(params).then((html) => { 116 model.gethtml(params).then((html) => {
105 res.send(html); 117 res.send(html);
106 }).catch(next); 118 }).catch(next);
107 -}  
108 - 119 +};
109 120
110 module.exports = { 121 module.exports = {
111 list, 122 list,
@@ -43,6 +43,7 @@ exports.detail = (param) => { @@ -43,6 +43,7 @@ exports.detail = (param) => {
43 result = result.data; 43 result = result.data;
44 44
45 let goods = result.goods_list || []; 45 let goods = result.goods_list || [];
  46 +
46 if (goods.length === 1) { 47 if (goods.length === 1) {
47 result.bannerTop = { 48 result.bannerTop = {
48 img: (goods[0].images_list[0] || {}).image_url 49 img: (goods[0].images_list[0] || {}).image_url
@@ -52,9 +53,9 @@ exports.detail = (param) => { @@ -52,9 +53,9 @@ exports.detail = (param) => {
52 list: goods.map((g) => { 53 list: goods.map((g) => {
53 return { 54 return {
54 img: (g.images_list[0] || {}).image_url 55 img: (g.images_list[0] || {}).image_url
55 - } 56 + };
56 }) 57 })
57 - } 58 + };
58 } 59 }
59 60
60 result.show_final_price = result.formart_final_price; 61 result.show_final_price = result.formart_final_price;
@@ -71,18 +72,27 @@ exports.detail = (param) => { @@ -71,18 +72,27 @@ exports.detail = (param) => {
71 result.brand_info.brand_url = `//m.yohobuy.com/product/global/list?brand=${result.brand_info.brand_id}`; 72 result.brand_info.brand_url = `//m.yohobuy.com/product/global/list?brand=${result.brand_info.brand_id}`;
72 } 73 }
73 74
  75 + if (result.illustrate_contents && result.illustrate_contents.length) {
  76 + result.illustrate = {
  77 + title1: (result.illustrate_contents[0] || {}).title,
  78 + content1: (result.illustrate_contents[0] || {}).content,
  79 + title2: (result.illustrate_contents[1] || {}).title,
  80 + content2: (result.illustrate_contents[1] || {}).content
  81 + };
  82 + }
  83 +
74 return result; 84 return result;
75 }); 85 });
76 }; 86 };
77 87
78 exports.gethtml = (param) => { 88 exports.gethtml = (param) => {
79 - return globalapi.get('product/api/v1/detail/gethtml', param,{ 89 + return globalapi.get('product/api/v1/detail/gethtml', param, {
80 cache: true 90 cache: true
81 }).then((result) => { 91 }).then((result) => {
82 result = result || ''; 92 result = result || '';
83 result = $.load(result); 93 result = $.load(result);
84 result = result('.good-detail-page'); 94 result = result('.good-detail-page');
85 - 95 +
86 return (result.html() || '').replace(/<img src=/g, '<img class="lazy" src="data:image/gif;' + 96 return (result.html() || '').replace(/<img src=/g, '<img class="lazy" src="data:image/gif;' +
87 'base64,R0lGODlhAQABAJEAAAAAAP///93d3f///yH5BAEAAAMALAAAAAABAAEAAAICVAEAOw=="' + 97 'base64,R0lGODlhAQABAJEAAAAAAP///93d3f///yH5BAEAAAMALAAAAAABAAEAAAICVAEAOw=="' +
88 ' data-original=').replace(/<img border="0" src=/g, '<img border="0" class="lazy" ' + 98 ' data-original=').replace(/<img border="0" src=/g, '<img border="0" class="lazy" ' +
@@ -90,4 +100,4 @@ exports.gethtml = (param) => { @@ -90,4 +100,4 @@ exports.gethtml = (param) => {
90 'R0lGODlhAQABAJEAAAAAAP///93d3f///yH5BAEAAAMALAAAAAABAAEAAAICVAEAOw=="' + 100 'R0lGODlhAQABAJEAAAAAAP///93d3f///yH5BAEAAAMALAAAAAABAAEAAAICVAEAOw=="' +
91 ' data-original='); 101 ' data-original=');
92 }); 102 });
93 -} 103 +};
@@ -41,12 +41,28 @@ @@ -41,12 +41,28 @@
41 <span class="country-name">{{country_name}}</span> 41 <span class="country-name">{{country_name}}</span>
42 <span class="product-source">{{product_source}}</span> 42 <span class="product-source">{{product_source}}</span>
43 </div> 43 </div>
44 - 44 +
  45 + {{# illustrate}}
45 <div class="illustrate"> 46 <div class="illustrate">
46 - <div class="illustrate-title"></div>  
47 - <div class="illustrate-contents"></div> 47 + <div class="illustrate-title">
  48 + <div class="title checked"><i class="iconfont checked"></i>{{title1}}</div>
  49 + <div class="title notice"><i class="iconfont notice"></i>{{title2}}</div>
  50 + <div class="illustrate-down"><i class="iconfont down"></i></div>
  51 + </div>
  52 + <div class="illustrate-contents">
  53 + <div class="content checked">
  54 + <i class="iconfont checked"></i>{{title1}}
  55 + <div class="text">{{content1}}</div>
  56 + </div>
  57 + <div class="content notice">
  58 + <i class="iconfont notice"></i>{{title2}}
  59 + <div class="text">{{content2}}</div>
  60 + </div>
  61 + <div class="illustrate-up"><i class="iconfont up"></i></div>
  62 + </div>
48 </div> 63 </div>
49 - 64 + {{/ illustrate}}
  65 +
50 {{# brand_info}} 66 {{# brand_info}}
51 <div class="enter-store"> 67 <div class="enter-store">
52 {{#if brand_ico}} 68 {{#if brand_ico}}
@@ -69,8 +85,11 @@ @@ -69,8 +85,11 @@
69 <div id="productDesc" class="product-desc"></div> 85 <div id="productDesc" class="product-desc"></div>
70 86
71 <div class="cart-bar"> 87 <div class="cart-bar">
72 - <a href="javascript:;" class="num-incart iconfont">&#xe62c;</a>  
73 - <a href="javascript:;" class="addto-cart add-to-cart-url">下载APP购买</a> 88 + {{#unless @root.wap.common.removeCartCount}}
  89 + <input type="hidden" id="remove-cart-count" value="1">
  90 + {{/unless}}
  91 + <a href="{{../cartUrl}}" class="num-incart iconfont"><span class="num-tag hide"></span>&#xe62c;</a>
  92 + <a href="javascript:;" class="addto-cart">下载APP购买</a>
74 </div> 93 </div>
75 </div> 94 </div>
76 {{/ result}} 95 {{/ result}}
@@ -15,26 +15,44 @@ import { @@ -15,26 +15,44 @@ import {
15 class ListController extends Controller { 15 class ListController extends Controller {
16 constructor() { 16 constructor() {
17 super(); 17 super();
18 - 18 +
19 this.detail = new DetailView(); 19 this.detail = new DetailView();
20 20
21 this.created(); 21 this.created();
22 } 22 }
23 23
24 created() { 24 created() {
25 - let skn = this.detail.getSkn();  
26 - if (!skn) {  
27 - return;  
28 - }  
29 -  
30 - setTimeout(()=> {  
31 - search('//m.yohobuy.com/product/global/gethtml', {  
32 - skn: skn  
33 - }).then((html)=>{  
34 - this.detail.setDetailHtml(html)  
35 - })  
36 - }, 500); 25 + let skn = this.detail.getSkn();
  26 +
  27 + if (!skn) {
  28 + return;
  29 + }
  30 +
  31 + setTimeout(() => {
  32 + search('//m.yohobuy.com/product/global/gethtml', {
  33 + skn: skn
  34 + }).then((html) => {
  35 + this.detail.setDetailHtml(html);
  36 + });
  37 +
  38 + if (this.detail.getCart()) {
  39 + search('/cart/index/count').then((data) => {
  40 + let count;
  41 +
  42 + if (data.code === 200) {
  43 + count = data.data.cart_goods_count || 0;
  44 + if (count === 0) {
  45 + return false;
  46 + }
  47 + if (count > 99) {
  48 + count = '99+';
  49 + }
  50 + this.detail.setCartCount(count);
  51 + }
  52 + });
  53 + }
  54 + }, 500);
37 } 55 }
38 } 56 }
39 57
40 -module.exports = ListController;  
  58 +module.exports = ListController;
@@ -4,11 +4,19 @@ import { @@ -4,11 +4,19 @@ import {
4 4
5 let Swiper = require('yoho-swiper'); 5 let Swiper = require('yoho-swiper');
6 let lazyLoad = require('yoho-jquery-lazyload'); 6 let lazyLoad = require('yoho-jquery-lazyload');
  7 +let dialog = require('plugin/dialog');
7 8
8 export class DetailView extends View { 9 export class DetailView extends View {
9 constructor() { 10 constructor() {
10 super('#global-detail-page'); 11 super('#global-detail-page');
11 12
  13 + this.on('click', '.addto-cart', this.showDownLoadDialog.bind(this));
  14 + this.on('click', '.illustrate-title', this.illustrateDown.bind(this));
  15 + this.on('click', '.illustrate-contents', this.illustrateUp.bind(this));
  16 + this.illustrateTitle = $('.illustrate-title');
  17 + this.illustrateContents = $('.illustrate-contents');
  18 + this.illustrateContents.hide().addClass('down-animate');
  19 +
12 setTimeout(() => { 20 setTimeout(() => {
13 new Swiper('.banner-swiper', { 21 new Swiper('.banner-swiper', {
14 preloadImages: false, 22 preloadImages: false,
@@ -34,11 +42,70 @@ export class DetailView extends View { @@ -34,11 +42,70 @@ export class DetailView extends View {
34 }, 500); 42 }, 500);
35 } 43 }
36 44
  45 + showDownLoadDialog() {
  46 + dialog.showDialog({
  47 + dialogText: '进入有货APP',
  48 + hasFooter: {
  49 + rightBtnText: '打开Yoho!Buy有货APP'
  50 + }
  51 + }, function() {
  52 + let appUrl = $('#main-wrap').data('apppath');
  53 + let ifr = document.createElement('iframe');
  54 +
  55 + ifr.src = appUrl;
  56 + ifr.style.display = 'none';
  57 + document.body.appendChild(ifr);
  58 + window.location.href = appUrl;
  59 +
  60 + let time = Date.now();
  61 +
  62 + window.setTimeout(function() {
  63 + document.body.removeChild(ifr);
  64 + if (Date.now() - time < 3200) {
  65 + window.location.href = 'http://a.app.qq.com/o/simple.jsp?pkgname=com.yoho';
  66 + }
  67 + }, 3000);
  68 +
  69 + }, null, true);
  70 +
  71 + $('.dialog-wrapper').off('touchstart').on('touchstart', function(para) {
  72 + para.stopPropagation();
  73 + if ($(para.target).hasClass('dialog-wrapper')) {
  74 + dialog.hideDialog();
  75 + }
  76 + });
  77 + }
  78 +
  79 + illustrateDown() {
  80 + this.illustrateTitle.hide();
  81 + this.illustrateContents.show();
  82 + setTimeout(()=>{
  83 + this.illustrateContents.removeClass('down-animate');
  84 + }, 10);
  85 + }
  86 +
  87 + illustrateUp() {
  88 + this.illustrateContents.addClass('down-animate');
  89 + setTimeout(()=>{
  90 + this.illustrateContents.hide();
  91 + this.illustrateTitle.show();
  92 + }, 500);
  93 + }
  94 +
  95 + getCart() {
  96 + return $('#remove-cart-count').length;
  97 + }
  98 +
  99 + setCartCount(count) {
  100 + $('.cart-bar').find('.num-tag').html(count).removeClass('hide');
  101 + }
  102 +
37 setDetailHtml(htmldata) { 103 setDetailHtml(htmldata) {
38 let $productDesc = $('#productDesc'); 104 let $productDesc = $('#productDesc');
  105 +
39 $productDesc.append(htmldata); 106 $productDesc.append(htmldata);
40 -  
41 - window.rePosFooter && window.rePosFooter(); 107 +
  108 + window.rePosFooter && window.rePosFooter();
42 109
43 lazyLoad($productDesc.find('img.lazy')); 110 lazyLoad($productDesc.find('img.lazy'));
44 111
@@ -54,10 +121,10 @@ export class DetailView extends View { @@ -54,10 +121,10 @@ export class DetailView extends View {
54 watchSlidesVisibility: true 121 watchSlidesVisibility: true
55 }); 122 });
56 123
57 - var $service = $('.service-cont'), 124 + let $service = $('.service-cont'),
58 serviceH = $service.height(), 125 serviceH = $service.height(),
59 serviceLi = $service.find('li'), 126 serviceLi = $service.find('li'),
60 - showH = parseInt(serviceLi.eq(0).height()) + parseInt(serviceLi.eq(1).height()) - parseInt(serviceLi.eq(1).find('.service-answer').height()) / 2; 127 + showH = parseInt(serviceLi.eq(0).height()) + parseInt(serviceLi.eq(1).height()) - parseInt(serviceLi.eq(1).find('.service-answer').height()) / 2; // eslint-disable-line
61 128
62 $service.css({ 129 $service.css({
63 height: showH, 130 height: showH,
@@ -67,11 +134,11 @@ export class DetailView extends View { @@ -67,11 +134,11 @@ export class DetailView extends View {
67 this.operation = { 134 this.operation = {
68 showH, 135 showH,
69 serviceH 136 serviceH
70 - } 137 + };
71 this.on('click', '.service-operation', this.serviceOperation.bind(this)); 138 this.on('click', '.service-operation', this.serviceOperation.bind(this));
72 } 139 }
73 140
74 - serviceOperation(e,) { 141 + serviceOperation(e) {
75 function serviceState(opt) { 142 function serviceState(opt) {
76 opt.dom.html(opt.txt + '<i class="service-icon shrink-btn-' + opt.btnClass + '"></i>'); 143 opt.dom.html(opt.txt + '<i class="service-icon shrink-btn-' + opt.btnClass + '"></i>');
77 144
@@ -89,19 +156,19 @@ export class DetailView extends View { @@ -89,19 +156,19 @@ export class DetailView extends View {
89 156
90 if (curState) { 157 if (curState) {
91 serviceState({ 158 serviceState({
92 - 'dom': $this,  
93 - 'txt': '展开',  
94 - 'btnClass': 'down',  
95 - 'height': this.operation.showH,  
96 - 'of': 'hidden' 159 + dom: $this,
  160 + txt: '展开',
  161 + btnClass: 'down',
  162 + height: this.operation.showH,
  163 + of: 'hidden'
97 }); 164 });
98 } else { 165 } else {
99 serviceState({ 166 serviceState({
100 - 'dom': $this,  
101 - 'txt': '收起',  
102 - 'btnClass': 'up',  
103 - 'height': this.operation.serviceH,  
104 - 'of': 'visible' 167 + dom: $this,
  168 + txt: '收起',
  169 + btnClass: 'up',
  170 + height: this.operation.serviceH,
  171 + of: 'visible'
105 }); 172 });
106 } 173 }
107 } 174 }
@@ -109,4 +176,4 @@ export class DetailView extends View { @@ -109,4 +176,4 @@ export class DetailView extends View {
109 getSkn() { 176 getSkn() {
110 return this.$base.data('skn'); 177 return this.$base.data('skn');
111 } 178 }
112 -};  
  179 +}
@@ -8,7 +8,7 @@ @@ -8,7 +8,7 @@
8 z-index: 2; 8 z-index: 2;
9 } 9 }
10 10
11 - .global-country { 11 + .global-country {
12 float: left; 12 float: left;
13 background: rgb(70, 46, 61); 13 background: rgb(70, 46, 61);
14 color: #fff; 14 color: #fff;
@@ -20,7 +20,7 @@ @@ -20,7 +20,7 @@
20 } 20 }
21 } 21 }
22 22
23 - .global-plane { 23 + .global-plane {
24 width: 21px; 24 width: 21px;
25 height: 21px; 25 height: 21px;
26 background-image: resolve("product/airplane.png"); 26 background-image: resolve("product/airplane.png");
@@ -224,6 +224,92 @@ @@ -224,6 +224,92 @@
224 } 224 }
225 } 225 }
226 226
  227 + .illustrate {
  228 + .iconfont {
  229 + font-size: 25px;
  230 + margin-right: 8px;
  231 + }
  232 +
  233 + .iconfont.checked:before {
  234 + content: "\E646";
  235 + }
  236 +
  237 + .iconfont.notice:before {
  238 + content: "\E628";
  239 + }
  240 +
  241 + .iconfont.down:before {
  242 + content: "\E616";
  243 + }
  244 +
  245 + .iconfont.up:before {
  246 + content: "\E615";
  247 + }
  248 + }
  249 +
  250 + .illustrate-title {
  251 + height: 88px;
  252 + padding: 30px;
  253 + font-size: 25px;
  254 + line-height: 25px;
  255 + border-bottom: 1px solid #eee;
  256 + background: #fff;
  257 +
  258 + .title {
  259 + float: left;
  260 + margin-right: 20px;
  261 + }
  262 +
  263 + .notice {
  264 + color: #b0b0b0;
  265 + }
  266 + }
  267 +
  268 + .illustrate-contents {
  269 + height: 215px;
  270 + border-bottom: 1px solid #eee;
  271 + background: #fff;
  272 + position: relative;
  273 + padding: 30px;
  274 + font-size: 22px;
  275 + line-height: 22px;
  276 + transition: height 500ms;
  277 + overflow: hidden;
  278 +
  279 + &.down-animate {
  280 + height: 50px;
  281 + }
  282 +
  283 + .notice {
  284 + margin-top: 20px;
  285 + color: #b0b0b0;
  286 + }
  287 +
  288 + .text {
  289 + margin-top: 10px;
  290 + margin-left: 25px;
  291 + color: #b0b0b0;
  292 + font-size: 18px;
  293 + }
  294 + }
  295 +
  296 + .illustrate-down {
  297 + float: right;
  298 + margin-right: 0;
  299 + font-size: 30px;
  300 + font-weight: 700;
  301 + color: #b0b0b0;
  302 + }
  303 +
  304 + .illustrate-up {
  305 + position: absolute;
  306 + top: 30px;
  307 + right: 30px;
  308 + font-size: 30px;
  309 + font-weight: 700;
  310 + color: #b0b0b0;
  311 + }
  312 +
227 .enter-store { 313 .enter-store {
228 position: relative; 314 position: relative;
229 margin-top: 30px; 315 margin-top: 30px;
@@ -282,7 +368,7 @@ @@ -282,7 +368,7 @@
282 font-size: 28px; 368 font-size: 28px;
283 border-top: 1px solid #eee; 369 border-top: 1px solid #eee;
284 border-bottom: 1px solid #eee; 370 border-bottom: 1px solid #eee;
285 - 371 +
286 a { 372 a {
287 display: block; 373 display: block;
288 height: 100%; 374 height: 100%;
@@ -355,5 +441,4 @@ @@ -355,5 +441,4 @@
355 } 441 }
356 } 442 }
357 } 443 }
358 -  
359 } 444 }