Authored by Rock Zhang

Merge branch 'develop' of git.dev.yoho.cn:web/yohobuy into develop

@@ -3,9 +3,11 @@ nbproject @@ -3,9 +3,11 @@ nbproject
3 .idea 3 .idea
4 .gitignore 4 .gitignore
5 .gitmodules 5 .gitmodules
6 -compile/  
7 -assets/ 6 +compile
  7 +assets
8 script/nginx/logs 8 script/nginx/logs
9 npm-debug.log 9 npm-debug.log
10 composer.lock 10 composer.lock
11 vendor/ 11 vendor/
  12 +.jscsrc
  13 +.jshintrc
1 -<!DOCTYPE html>  
2 -<html>  
3 -<head>  
4 -<meta charset="utf-8">  
5 -<title>国际账号登录 | YOHO!有货</title>  
6 -<meta name="keywords" content="Yoho! 有货官网,潮流志,潮流男装,潮牌,美国潮牌,日本潮牌,香港潮牌,潮牌店,新品首发,欧美潮流,全球购,代购,时尚,流行,特卖,B2C,正品,购物网站,网上购物,货到付款">  
7 -<meta name="description" content="YOHO! 有货,年轻人潮流购物中心,中国最大的潮流商品购物网站。100%品牌正品保证,支持货到付款。作为YOHO!旗下的购物平台,汇集了全球潮流时尚商品和中国最流行的商品,也是国内最大的原创文化商品平台,也是香港,台湾地区流行商品的集中地。同时包含日本、韩国等众多国外潮流品牌,带给您全新潮流购物体验。">  
8 -<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, minimum-scale=1, user-scalable=no">  
9 -<meta http-equiv="cleartype" content="on">  
10 -<meta name="apple-mobile-web-app-status-bar-style" content="black" />  
11 -<meta content="telephone=no" name="format-detection" />  
12 -<meta content="email=no" name="format-detection" />  
13 -<script type="text/javascript">  
14 - (function(doc, win) {  
15 - var docEl = doc.documentElement;  
16 - (function() {  
17 - var clientWidth = docEl.clientWidth;  
18 - if (!clientWidth) {  
19 - return;  
20 - }  
21 - docEl.style.fontSize = 20 * (clientWidth / 320) + 'px';  
22 - }());  
23 - })(document, window);  
24 -</script>  
25 -<link rel="stylesheet" href="http://static.buy.test.yoho.cn/dist/myohobuy/0.0.6/index.css">  
26 -</head>  
27 -<body class=passport-body>  
28 - <div class="login-international-page passport-page yoho-page">  
29 - <div class="header">  
30 - <a class="go-back" href=/></a>  
31 - <p class="title">登录</p>  
32 - </div> <div class="content">  
33 - <div class="select-container row">  
34 - <span class="select-title">国家和地区</span>  
35 - <select id="country-select" class="country-select select in-android-uc">  
36 - <option value=+61 >澳大利亚</option>  
37 - <option value=+82 >韩国</option>  
38 - <option value=+1 >加拿大</option>  
39 - <option value=+60 >马来西亚</option>  
40 - <option value=+1 >美国</option>  
41 - <option value=+81 >日本</option>  
42 - <option value=+65 >新加坡</option>  
43 - <option value=+44 >英国</option>  
44 - <option value=+86 selected>中国</option>  
45 - <option value=+853 >中国澳门</option>  
46 - <option value=+886 >中国台湾</option>  
47 - <option value=+852 >中国香港</option>  
48 - </select>  
49 - <div class="arrow-right"></div>  
50 - </div> <div class="input-container phone-container row has-clear">  
51 - <span id="area-code" class="area-code">+86</span>  
52 - <input id="phone-num" class="input phone-num" type="text" placeholder="手机号" value=>  
53 - </div>  
54 - <div class="input-container row has-eye">  
55 - <input id="pwd" class="pwd input" type="password" placeholder="密码">  
56 - </div>  
57 - <span id="btn-login" class="btn btn-login disble row">登录</span>  
58 - </div>  
59 -</div>  
60 -<script src="http://static.buy.test.yoho.cn/dist/myohobuy/0.0.6/lib.js"></script>  
61 -<script src="http://static.buy.test.yoho.cn/dist/myohobuy/0.0.6/index.js"></script>  
62 -<script>  
63 - seajs.use('js/common');  
64 -</script>  
65 - <script>  
66 - seajs.use('js/passport/login/international');  
67 - </script>  
68 -</body>  
69 -</html>  
1 -<!DOCTYPE html>  
2 -<html>  
3 -<head>  
4 -<meta charset="utf-8">  
5 -<title>登录 | YOHO!有货</title>  
6 -<meta name="keywords" content="Yoho! 有货官网,潮流志,潮流男装,潮牌,美国潮牌,日本潮牌,香港潮牌,潮牌店,新品首发,欧美潮流,全球购,代购,时尚,流行,特卖,B2C,正品,购物网站,网上购物,货到付款">  
7 -<meta name="description" content="YOHO! 有货,年轻人潮流购物中心,中国最大的潮流商品购物网站。100%品牌正品保证,支持货到付款。作为YOHO!旗下的购物平台,汇集了全球潮流时尚商品和中国最流行的商品,也是国内最大的原创文化商品平台,也是香港,台湾地区流行商品的集中地。同时包含日本、韩国等众多国外潮流品牌,带给您全新潮流购物体验。">  
8 -<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, minimum-scale=1, user-scalable=no">  
9 -<meta http-equiv="cleartype" content="on">  
10 -<meta name="apple-mobile-web-app-status-bar-style" content="black" />  
11 -<meta content="telephone=no" name="format-detection" />  
12 -<meta content="email=no" name="format-detection" />  
13 -<script type="text/javascript">  
14 - (function(doc, win) {  
15 - var docEl = doc.documentElement;  
16 - (function() {  
17 - var clientWidth = docEl.clientWidth;  
18 - if (!clientWidth) {  
19 - return;  
20 - }  
21 - docEl.style.fontSize = 20 * (clientWidth / 320) + 'px';  
22 - }());  
23 - })(document, window);  
24 -</script>  
25 -<link rel="stylesheet" href="http://static.buy.test.yoho.cn/dist/myohobuy/0.0.6/index.css">  
26 -</head>  
27 -<body class=passport-body>  
28 - <div class="login-page passport-page yoho-page">  
29 - <div class="header">  
30 - <a class="go-back" href=/></a>  
31 - <div class="img-header"></div>  
32 - </div> <div class="content">  
33 - <div class="acc-container input-container row has-clear">  
34 - <div class="yoho-logo"></div>  
35 - <input id="account" class="input account" type="text" placeholder="手机号/邮箱" autocomplete="off" value=>  
36 - </div>  
37 - <div class="input-container row has-eye">  
38 - <input id="pwd" class="pwd input" type="password" placeholder="密码">  
39 - </div>  
40 - <span id="btn-login" class="btn btn-login disable">登录</span>  
41 - <p class="op-container">  
42 - <a class="go-register" href=/reg.html>免费注册</a>  
43 - <span id="forget-pwd" class="forget-pwd">忘记密码</span>  
44 - </p>  
45 - <div class="third-party-login">  
46 - <span>其他登录方式</span>  
47 - <div class="tp-link">  
48 - <a class="alipay" href=/passport/login/alipay></a>  
49 - <a class="weibo" href=/passport/login/sina></a>  
50 - <a class="qq" href=/passport/login/qq></a>  
51 - </div>  
52 - </div>  
53 - <a class="international" href=/login.html>International Customer</a>  
54 - <div class="login-tip">  
55 - <div class="info-icon"></div>  
56 - Yoho!Family账号可登录YOHO!有货  
57 - </div>  
58 - <div id="retrive-pwd-mask" class="mask"></div>  
59 - <ul id="retrive-pwd-ways" class="retrive-pwd-ways">  
60 - <li>  
61 - <a href=/passport/back/mobile>通过手机找回密码</a>  
62 - </li>  
63 - <li>  
64 - <a href=/passport/back/email>通过邮箱找回密码</a>  
65 - </li>  
66 - <li id="cancel-retrive">  
67 - 取消  
68 - </li>  
69 - </ul>  
70 - </div>  
71 -</div>  
72 -<script src="http://static.buy.test.yoho.cn/dist/myohobuy/0.0.6/lib.js"></script>  
73 -<script src="http://static.buy.test.yoho.cn/dist/myohobuy/0.0.6/index.js"></script>  
74 -<script>  
75 - seajs.use('js/common');  
76 -</script>  
77 -<script>  
78 - seajs.use('js/passport/login/login');  
79 -</script>  
80 -</body>  
81 -</html>  
@@ -210,7 +210,7 @@ class Yohobuy @@ -210,7 +210,7 @@ class Yohobuy
210 * @param int $timeout 超时时间,单位是秒 210 * @param int $timeout 超时时间,单位是秒
211 * @return array 211 * @return array
212 */ 212 */
213 - public static function getMulti($urlList = array(), $options = array(), $cache = false, $timeout = 3) 213 + public static function getMulti($urlList = array(), $options = array(), $cache = false, $timeout = 5)
214 { 214 {
215 /* 开启缓存的情况 */ 215 /* 开启缓存的情况 */
216 if ($cache && USE_CACHE) { 216 if ($cache && USE_CACHE) {
@@ -40,6 +40,7 @@ class CacheConfig @@ -40,6 +40,7 @@ class CacheConfig
40 const KEY_ACTION_PRODUCT_BRAND_NAMES = 'key_action_product_brand_names'; // 所有品牌名称列表 40 const KEY_ACTION_PRODUCT_BRAND_NAMES = 'key_action_product_brand_names'; // 所有品牌名称列表
41 const KEY_ACTION_PRODUCT_BRAND_LOGO = 'key_action_product_brand_logo'; // 品牌信息 41 const KEY_ACTION_PRODUCT_BRAND_LOGO = 'key_action_product_brand_logo'; // 品牌信息
42 42
43 - const KEY_ACTION_INDEX_SEARCH = 'key_action_search_search'; // 搜索的数据 43 + const KEY_ACTION_SEARCH_SEARCH = 'key_action_search_search'; // 搜索的数据
  44 + const KEY_ACTION_SEARCH_FILTER = 'key_action_search_filter'; // 搜索的过滤条件
44 45
45 } 46 }
@@ -143,7 +143,8 @@ class SearchData @@ -143,7 +143,8 @@ class SearchData
143 143
144 $param = array(); 144 $param = array();
145 $param['status'] = 1; // 是否上架,1表示在架,2表示不在 145 $param['status'] = 1; // 是否上架,1表示在架,2表示不在
146 - if (!isset($orderMaps[ $condition['order'] ] )) { 146 + // $param['needFilter'] = 1; // 是否需要返回筛选条件
  147 + if (!isset($condition['order'])) {
147 $param['order'] = $orderMaps['s_t_desc']; 148 $param['order'] = $orderMaps['s_t_desc'];
148 } else { 149 } else {
149 $param['order'] = $orderMaps[ $condition['order'] ]; 150 $param['order'] = $orderMaps[ $condition['order'] ];
@@ -154,11 +154,11 @@ class TemplateLayout implements View_Interface @@ -154,11 +154,11 @@ class TemplateLayout implements View_Interface
154 else { 154 else {
155 $template = file_get_contents($viewName, false, null); 155 $template = file_get_contents($viewName, false, null);
156 $phpStr = LightnCandy::compile($template, array( 156 $phpStr = LightnCandy::compile($template, array(
157 - // DEBUG: LightnCandy::FLAG_RENDER_DEBUG | LightnCandy::FLAG_ERROR_EXCEPTION  
158 - 'flags' => LightnCandy::FLAG_RENDER_DEBUG | LightnCandy::FLAG_ERROR_EXCEPTION | LightnCandy::FLAG_MUSTACHE | LightnCandy::FLAG_HANDLEBARS, // 使用MUSTACHE和HANDLEBARS的模板格式  
159 - 'basedir' => array($config->template->partials), // 模板里使用 {{> partial_name}} 时查找的目录  
160 - 'fileext' => array($tplExt), // 允许查找文件的后缀  
161 - 'lcrun' => 'Plugin\LCRun3', // 指定编译模板的runtime 157 + // DEBUG: LightnCandy::FLAG_RENDER_DEBUG | LightnCandy::FLAG_ERROR_EXCEPTION
  158 + 'flags' => LightnCandy::FLAG_ERROR_EXCEPTION | LightnCandy::FLAG_MUSTACHE | LightnCandy::FLAG_HANDLEBARS, // 使用MUSTACHE和HANDLEBARS的模板格式
  159 + 'basedir' => array($config->template->partials), // 模板里使用 {{> partial_name}} 时查找的目录
  160 + 'fileext' => array($tplExt), // 允许查找文件的后缀
  161 + 'lcrun' => 'Plugin\LCRun3', // 指定编译模板的runtime
162 )); 162 ));
163 // 文件流方式读取PHP方法 163 // 文件流方式读取PHP方法
164 $renderer = LightnCandy::prepare($phpStr); 164 $renderer = LightnCandy::prepare($phpStr);
@@ -291,7 +291,7 @@ class SearchController extends AbstractAction @@ -291,7 +291,7 @@ class SearchController extends AbstractAction
291 } 291 }
292 292
293 // 区别各种列表页面的筛选数据 293 // 区别各种列表页面的筛选数据
294 - $data = Product\FilterModel::getFilterData($condition); 294 + $data = Product\SearchModel::getFilterData($condition);
295 } 295 }
296 296
297 if (empty($data)) { 297 if (empty($data)) {
@@ -60,8 +60,18 @@ class BrandModel @@ -60,8 +60,18 @@ class BrandModel
60 // 搜索链接地址 60 // 搜索链接地址
61 $result['searchUrl'] = Helpers::url('/brands/search', null); 61 $result['searchUrl'] = Helpers::url('/brands/search', null);
62 62
63 - /* 顶部的轮翻广告列表 */  
64 - if (!empty($brand['brandTop'][0]['data'])) { 63 + /* 顶部的轮翻广告或热门品牌列表(当没有轮翻广告的情况下会是这个样子的! 此处是根据接口改造成的逻辑) */
  64 + if (!empty($brand['brandTop'][0]['data']['list'])) {
  65 + $build = array();
  66 + foreach ($brand['brandTop'][0]['data']['list'] as $value) {
  67 + $build['url'] = Helpers::getFilterUrl($value['url']);
  68 + $build['img'] = Helpers::getImageUrl($value['src'], 144, 144);
  69 + $build['name'] = $value['name'];
  70 + $result['hotBrand']['list'][] = $build;
  71 + }
  72 + }
  73 + // 顶部的轮翻广告列表
  74 + elseif (!empty($brand['brandTop'][0]['data'])) {
65 $build = array(); 75 $build = array();
66 foreach ($brand['brandTop'][0]['data'] as $value) { 76 foreach ($brand['brandTop'][0]['data'] as $value) {
67 $build['url'] = Helpers::getFilterUrl($value['url']); 77 $build['url'] = Helpers::getFilterUrl($value['url']);
@@ -71,7 +81,7 @@ class BrandModel @@ -71,7 +81,7 @@ class BrandModel
71 } 81 }
72 } 82 }
73 83
74 - /* 顶部的热门品牌列表 */ 84 + /* 顶部的热门品牌列表 (备注: 当没有轮翻广告的时候,此处内部的foreach不会被执行) */
75 if (!empty($brand['brandTop'][1]['data']['list'])) { 85 if (!empty($brand['brandTop'][1]['data']['list'])) {
76 $build = array(); 86 $build = array();
77 foreach ($brand['brandTop'][1]['data']['list'] as $value) { 87 foreach ($brand['brandTop'][1]['data']['list'] as $value) {
1 -<?php  
2 -  
3 -namespace Product;  
4 -  
5 -use Configs\CacheConfig;  
6 -use LibModels\Wap\Product\SearchData;  
7 -use LibModels\Wap\Category\BrandData;  
8 -use LibModels\Wap\Category\ClassData;  
9 -use Plugin\DataProcess\ListProcess;  
10 -  
11 -/**  
12 - * 搜索相关的模板数据模型  
13 - *  
14 - * @name Filter  
15 - * @package Product  
16 - * @copyright yoho.inc  
17 - * @version 1.0 (2015-11-1 17:35:52)  
18 - */  
19 -class FilterModel  
20 -{  
21 -  
22 - /**  
23 - * 获取筛选的数据  
24 - *  
25 - * @param array $condition 查询条件  
26 - * @return array  
27 - */  
28 - public static function getFilterData($condition)  
29 - {  
30 - $result = array();  
31 -  
32 - // 区别各种列表页面的筛选数据  
33 - if (isset($condition['brand'])) {  
34 - $listData = BrandData::filterBrandData($condition);  
35 - } else if(isset($condition['sort'])) {  
36 - $listData = ClassData::filterClassData($condition);  
37 - } else {  
38 - $listData = SearchData::searchByCondition($condition);  
39 - }  
40 -  
41 - if (isset($listData['data']) && isset($listData['data']['filter'])) {  
42 - $result['filter'] = ListProcess::getFilterData($listData['data']['filter']);  
43 - }  
44 -  
45 - return $result;  
46 - }  
47 -  
48 -}  
@@ -4,6 +4,8 @@ namespace Product; @@ -4,6 +4,8 @@ namespace Product;
4 4
5 use Configs\CacheConfig; 5 use Configs\CacheConfig;
6 use LibModels\Wap\Product\SearchData; 6 use LibModels\Wap\Product\SearchData;
  7 +use LibModels\Wap\Category\BrandData;
  8 +use LibModels\Wap\Category\ClassData;
7 use Plugin\DataProcess\ListProcess; 9 use Plugin\DataProcess\ListProcess;
8 use Plugin\Cache; 10 use Plugin\Cache;
9 11
@@ -29,7 +31,7 @@ class SearchModel @@ -29,7 +31,7 @@ class SearchModel
29 $result = array(); 31 $result = array();
30 32
31 if (USE_CACHE) { 33 if (USE_CACHE) {
32 - $key = CacheConfig::KEY_ACTION_INDEX_SEARCH; 34 + $key = CacheConfig::KEY_ACTION_SEARCH_SEARCH;
33 if (!empty($condition)) { 35 if (!empty($condition)) {
34 $key .= http_build_query($condition, null, '&'); 36 $key .= http_build_query($condition, null, '&');
35 } 37 }
@@ -41,7 +43,7 @@ class SearchModel @@ -41,7 +43,7 @@ class SearchModel
41 } 43 }
42 44
43 // 调用接口查询数据 (使用新的 Elastic Engine) 45 // 调用接口查询数据 (使用新的 Elastic Engine)
44 - $listData = SearchData::searchElasticByCondition($condition); 46 + $listData = SearchData::searchElasticByCondition($condition);
45 // 调用接口查询数据 (使用老的 Sphinx Engine) 47 // 调用接口查询数据 (使用老的 Sphinx Engine)
46 // $listData = SearchData::searchByCondition($condition); 48 // $listData = SearchData::searchByCondition($condition);
47 // 处理返回的数据 49 // 处理返回的数据
@@ -63,4 +65,53 @@ class SearchModel @@ -63,4 +65,53 @@ class SearchModel
63 return $result; 65 return $result;
64 } 66 }
65 67
  68 + /**
  69 + * 获取筛选的数据
  70 + *
  71 + * @param array $condition 查询条件
  72 + * @return array
  73 + */
  74 + public static function getFilterData($condition)
  75 + {
  76 + $result = array();
  77 +
  78 + if (USE_CACHE) {
  79 + $key = CacheConfig::KEY_ACTION_SEARCH_FILTER;
  80 + if (!empty($condition)) {
  81 + $key .= http_build_query($condition, null, '&');
  82 + }
  83 + // 先尝试获取一级缓存(master), 有数据则直接返回.
  84 + $result = Cache::get($key, 'master');
  85 + if (!empty($result)) {
  86 + return $result;
  87 + }
  88 + }
  89 +
  90 + // 区别各种列表页面的筛选数据
  91 + if (isset($condition['brand'])) {
  92 + $listData = BrandData::filterBrandData($condition);
  93 + } else if (isset($condition['sort'])) {
  94 + $listData = ClassData::filterClassData($condition);
  95 + } else {
  96 + $listData = SearchData::searchByCondition($condition);
  97 + }
  98 +
  99 + if (isset($listData['data']['filter'])) {
  100 + $result['filter'] = ListProcess::getFilterData($listData['data']['filter']);
  101 + }
  102 +
  103 + if (USE_CACHE) {
  104 + // 接口调用异常时, 不害怕,从我们的二级缓存(slave)里再取数据.
  105 + if (empty($result)) {
  106 + $result = Cache::get($key, 'slave');
  107 + }
  108 + // 接口调用正常,数据封装完成, 则设置一级(master)和二级(slave)数据缓存
  109 + else {
  110 + Cache::set($key, $result, 1800); // 缓存30分钟
  111 + }
  112 + }
  113 +
  114 + return $result;
  115 + }
  116 +
66 } 117 }
@@ -15,7 +15,7 @@ use Plugin\Helpers; @@ -15,7 +15,7 @@ use Plugin\Helpers;
15 */ 15 */
16 class OptController extends AbstractAction 16 class OptController extends AbstractAction
17 { 17 {
18 - 18 +
19 /** 19 /**
20 * 品牌[店铺]收藏/取消收藏 20 * 品牌[店铺]收藏/取消收藏
21 * 21 *
@@ -25,44 +25,47 @@ class OptController extends AbstractAction @@ -25,44 +25,47 @@ class OptController extends AbstractAction
25 */ 25 */
26 public function favoriteBrandAction() 26 public function favoriteBrandAction()
27 { 27 {
28 - $result = array('code' => 400, 'message' => '未登录', 'data' => false);  
29 - 28 + $result = array('code' => 401, 'message' => '未登录', 'data' => false);
  29 +
30 do { 30 do {
31 /* 判断是否是AJAX请求 */ 31 /* 判断是否是AJAX请求 */
32 if (!$this->isAjax()) { 32 if (!$this->isAjax()) {
33 break; 33 break;
34 } 34 }
35 - 35 +
36 /* 判断品牌ID是否有效 */ 36 /* 判断品牌ID是否有效 */
37 $id = $this->post('id'); 37 $id = $this->post('id');
38 if (!is_numeric($id)) { 38 if (!is_numeric($id)) {
39 break; 39 break;
40 } 40 }
41 - 41 +
42 /* 判断用户是否登录 */ 42 /* 判断用户是否登录 */
43 $uid = $this->getUdid(); 43 $uid = $this->getUdid();
44 if (!$uid) { 44 if (!$uid) {
45 break; 45 break;
46 } 46 }
47 - 47 +
48 /* 取消收藏 */ 48 /* 取消收藏 */
49 $opt = $this->post('opt', 'ok'); 49 $opt = $this->post('opt', 'ok');
50 if ($opt !== 'ok') { 50 if ($opt !== 'ok') {
51 $result = BrandData::favoriteCancel($id, $uid); 51 $result = BrandData::favoriteCancel($id, $uid);
52 break; 52 break;
53 } 53 }
54 - 54 +
55 /* 收藏 */ 55 /* 收藏 */
56 $result = BrandData::favorite($id, $uid); 56 $result = BrandData::favorite($id, $uid);
57 - }  
58 - while (false);  
59 -  
60 - if (isset($result['code']) && $result['code'] == 412) {  
61 - $referer = $this->server('HTTP_REFERER', SITE_MAIN);  
62 - $result['data'] = Helpers::url('/signin.html', array('refer' => $referer));  
63 - }  
64 - 57 + if (!isset($result['code'])) {
  58 + break;
  59 + }
  60 +
  61 + /* 未登录的情况,加跳转链接 */
  62 + if ($result['code'] == 412 || $result['code'] == 400) {
  63 + $referer = $this->server('HTTP_REFERER', SITE_MAIN);
  64 + $result['data'] = Helpers::url('/signin.html', array('refer' => $referer));
  65 + }
  66 + } while (false);
  67 +
65 $this->echoJson($result); 68 $this->echoJson($result);
66 } 69 }
67 - 70 +
68 } 71 }