diff --git a/app.js b/app.js
index c914d1d..ec96bdb 100644
--- a/app.js
+++ b/app.js
@@ -7,25 +7,33 @@
 
 const config = require('./config/common');
 
+global.Promise = require('bluebird');
+
+const yohoLib = require('yoho-node-lib');
+
+// 全局注册library
+yohoLib.global(config);
+
+const EventEmitter = require('events');
+
+EventEmitter.defaultMaxListeners = 100;
+
 const express = require('express');
+const compression = require('compression');
 const path = require('path');
 const bodyParser = require('body-parser');
 const cookieParser = require('cookie-parser');
 const favicon = require('serve-favicon');
-const session = require('yoho-express-session');
+const _ = require('lodash');
+const fp = require('lodash/fp');
 
-const memcached = require('connect-memcached');
-const hbs = require('express-handlebars');
+const session = require('cookie-session');
 const pkg = require('./package.json');
-
-const yohoLib = require('yoho-node-lib');
-
 const app = express();
+const helpers = global.yoho.helpers;
 
-const MemcachedStore = memcached(session);
-
-// 全局注册library
-yohoLib.global(config);
+// NOTE: 这里修改了图片质量的参数
+helpers.image = _.flow(helpers.image, fp.replace(/\/quality\/\d*$/, '/quality/90'));
 
 global.middleware = path.resolve('./doraemon/middleware');
 global.utils = path.resolve('./utils');
@@ -35,45 +43,34 @@ global.appRoot = path.resolve(__dirname);
 app.locals.devEnv = app.get('env') === 'development';
 app.locals.version = pkg.version;
 
+// zookeeper
+if (config.zookeeperServer) {
+    require('yoho-zookeeper')(config.zookeeperServer, 'pc', app.locals.pc = {});
+}
+
 app.set('subdomain offset', 2);
-app.set('view engine', '.hbs');
-app.set('views', './doraemon/views');
-app.set('view cache', true);
-app.engine('.hbs', hbs({
+app.use(global.yoho.hbs({
     extname: '.hbs',
     defaultLayout: 'layout',
-    layoutsDir: './doraemon/views',
-    partialsDir: './doraemon/views/partial',
+    layoutsDir: path.join(__dirname, 'doraemon/views'),
+    partialsDir: path.join(__dirname, 'doraemon/views/partial'),
+    views: path.join(__dirname, 'doraemon/views'),
     helpers: global.yoho.helpers
 }));
 
+app.use(global.yoho.middleware());
+
 app.use(favicon(path.join(__dirname, '/public/favicon.ico')));
 app.use(express.static(path.join(__dirname, 'public')));
 app.use(bodyParser.json());
 app.use(bodyParser.urlencoded({extended: false}));
 app.use(cookieParser());
+app.use(compression());
 
 app.use(session({
-    proxy: true,
-    resave: false,
-    saveUninitialized: true,
-    unset: 'destroy',
+    name: 'yohobuy_session_cookie',
     secret: '82dd7e724f2c6870472c89dfa43cf48d',
-    name: 'yohobuy_session',
-    cookie: {
-        domain: 'yohobuy.com',
-        httpOnly: false
-    },
-
-    store: new MemcachedStore({
-        hosts: config.memcache.session,
-        prefix: 'yohobuy_session:',
-        poolSize: 25,
-        reconnect: 5000,
-        timeout: 1000,
-        retries: 1,
-        retry: 3000
-    })
+    domain: config.cookieDomain
 }));
 
 app.use((req, res, next) => {
@@ -88,6 +85,7 @@ const logger = global.yoho.logger;
 // dispatcher
 try {
     const subDomain = require('./doraemon/middleware/sub-domain');
+    const mobileRefer = require('./doraemon/middleware/mobile-refer');
     const itemNameHandler = require('./doraemon/middleware/item-name-handler');
     const mobileCheck = require('./doraemon/middleware/mobile-check');
     const user = require('./doraemon/middleware/user');
@@ -95,9 +93,11 @@ try {
     const setYohoData = require('./doraemon/middleware/set-yoho-data');
     const errorHanlder = require('./doraemon/middleware/error-handler');
     const setPageInfo = require('./doraemon/middleware/set-pageinfo');
+    const pageCache = require('./doraemon/middleware/page-cache');
 
     // YOHO 前置中间件
     app.use(subDomain());
+    app.use(mobileRefer());
     app.use(itemNameHandler);
     app.use(mobileCheck());
     app.use(setYohoData());
@@ -105,6 +105,7 @@ try {
     app.use(seo());
     app.use(setPageInfo());
 
+    app.use(pageCache());
     require('./dispatch')(app);
 
     app.all('*', errorHanlder.notFound()); // 404
diff --git a/apps/activity/index.js b/apps/activity/index.js
index f6d8ceb..8520cd0 100644
--- a/apps/activity/index.js
+++ b/apps/activity/index.js
@@ -5,8 +5,7 @@
  */
 
 var express = require('express'),
-    path = require('path'),
-    hbs = require('express-handlebars');
+    path = require('path');
 
 var app = express();
 
@@ -17,12 +16,12 @@ app.on('mount', function(parent) {
     delete parent.locals.settings; // 不继承父 App 的设置
     Object.assign(app.locals, parent.locals);
 });
-app.set('views', path.join(__dirname, 'views/action'));
-app.engine('.hbs', hbs({
+app.use(global.yoho.hbs({
     extname: '.hbs',
     defaultLayout: 'layout',
     layoutsDir: doraemon,
-    partialsDir: [path.join(__dirname, 'views/partial'), `${doraemon}/partial`],
+    partialsDir: [path.join(__dirname, 'views/partial')],
+    views: path.join(__dirname, 'views/action'),
     helpers: global.yoho.helpers
 }));
 
diff --git a/apps/brands/controllers/brands.js b/apps/brands/controllers/brands.js
index ccddc9a..48b749d 100644
--- a/apps/brands/controllers/brands.js
+++ b/apps/brands/controllers/brands.js
@@ -20,7 +20,10 @@ exports.index = (req, res, next) => {
     let channel = req.query.channel || req.cookies._Channel || 'boys';
 
     brandsService.getBrandViewList(channel, req).then(result => {
-
+        // 返回null,不cashe
+        if (result.noCashe) {
+            res.set('Cashe-Control', 'no-cashe');
+        }
         res.render('brands/brands', result);
 
     }).catch(next);
@@ -50,6 +53,10 @@ exports.brandInfo = (req, res, next) => {
     let brandId = req.query.brandId || 0;
 
     brandsService.brandInfo(brandId, req.user.uid).then(result => {
+        // 返回null,不cashe
+        if (result.noCashe) {
+            res.set('Cashe-Control', 'no-cashe');
+        }
         res.json(result);
     }).catch(next);
 };
@@ -61,6 +68,10 @@ exports.plusstarList = (req, res, next) => {
     let channel = req.query.channel || req.cookies._Channel || 'boys';
 
     brandsService.plusstarList(channel, req).then(result => {
+        // 返回null,不cashe
+        if (result.noCashe) {
+            res.set('Cashe-Control', 'no-cashe');
+        }
         res.render('brands/plusstar', result);
     }).catch(next);
 };
diff --git a/apps/brands/index.js b/apps/brands/index.js
index 90093ef..c28208e 100644
--- a/apps/brands/index.js
+++ b/apps/brands/index.js
@@ -5,8 +5,7 @@
  */
 
 var express = require('express'),
-    path = require('path'),
-    hbs = require('express-handlebars');
+    path = require('path');
 
 var app = express();
 
@@ -18,12 +17,12 @@ app.on('mount', function(parent) {
     Object.assign(app.locals, parent.locals);
 });
 
-app.set('views', path.join(__dirname, 'views/action'));
-app.engine('.hbs', hbs({
+app.use(global.yoho.hbs({
     extname: '.hbs',
     defaultLayout: 'layout',
     layoutsDir: doraemon,
-    partialsDir: [path.join(__dirname, 'views/partial'), `${doraemon}/partial`],
+    partialsDir: [path.join(__dirname, 'views/partial')],
+    views: path.join(__dirname, 'views/action'),
     helpers: global.yoho.helpers
 }));
 
diff --git a/apps/brands/models/brands-api.js b/apps/brands/models/brands-api.js
index e666740..95c013f 100644
--- a/apps/brands/models/brands-api.js
+++ b/apps/brands/models/brands-api.js
@@ -6,6 +6,7 @@
 'use strict';
 const api = global.yoho.API;
 const serviceAPI = global.yoho.ServiceAPI;
+const config = global.yoho.config;
 
 /**
  * 分开取数,品牌一览 顶部的轮翻广告及热门品牌数据-PC
@@ -15,7 +16,7 @@ const serviceAPI = global.yoho.ServiceAPI;
 const getBrandTopData = (contentCode) => {
     return serviceAPI.get('operations/api/v5/resource/get', {
         content_code: contentCode
-    }, {cache: 3600});
+    }, config.apiCache);
 };
 
 /**
@@ -28,7 +29,7 @@ const getBrandListData = channel => {
     if (!isNaN(channel)) {
         params.yh_channel = channel;
     }
-    return api.get('', params);
+    return api.get('', params, config.apiCache);
 };
 
 /**
@@ -48,7 +49,7 @@ const getBrandIntro = (brandId, uid) => {
         method: 'app.brand.getBrandIntro',
         brand_id: brandId,
         uid: uid
-    }, param);
+    }, param, config.apiCache);
 };
 
 /**
@@ -61,7 +62,7 @@ const getProductByBrand = (brandId, limit) => {
         method: 'web.search.search',
         brand: brandId,
         limit: limit
-    });
+    }, config.apiCache);
 };
 
 /**
@@ -74,7 +75,7 @@ const getBrandInfoByIds = (ids) => {
     return api.get('', {
         method: 'web.brand.info',
         ids: ids instanceof Array ? ids.join(',') : parseInt(ids, 10)
-    }, {cache: 3600});
+    }, config.apiCache);
 };
 
 /**
@@ -89,7 +90,7 @@ const getPlusstarList = (brandType, gender) => {
     return serviceAPI.get('guang/api/v3/plustar/getlist', {
         gender: gender,
         brand_type: brandType
-    }, {cache: 3600});
+    }, config.apiCache);
 };
 
 module.exports = {
diff --git a/apps/brands/models/brands-service.js b/apps/brands/models/brands-service.js
index 8a3f6f5..744fcd7 100644
--- a/apps/brands/models/brands-service.js
+++ b/apps/brands/models/brands-service.js
@@ -101,13 +101,14 @@ exports.getBrandViewList = (channel) => {
     let apiMethod = [
         headerModel.requestHeaderData(channel),
         brandsModel.getBrandViewTop(channel),
-        brandsModel.getBrandViewList(channel, 1, 5) // 分屏加载
+        brandsModel.getBrandViewList(channel) // 分屏加载
     ];
 
     return api.all(apiMethod).then(result => {
         let responseData = {
             module: 'brands',
-            page: 'brands'
+            page: 'brands',
+            noCashe: false
         };
 
         // 头部数据
@@ -135,6 +136,10 @@ exports.getBrandViewList = (channel) => {
         // SEO
         Object.assign(responseData, seoMap[channel]);
 
+        // 数据出错不cashe
+        if (_.isEmpty(result[0].headerData) || _.isEmpty(result[1]) || _.isEmpty(result[2])) {
+            responseData.noCashe = true;
+        }
         return responseData;
     });
 };
@@ -168,11 +173,17 @@ exports.brandInfo = (brandId, uid) => {
     ];
 
     return api.all(apiMethod).then(result => {
-
-        return {
+        let responseData = {
             code: _.isEmpty(result[0]) ? 400 : 200,
-            brand: _.isEmpty(result[0]) ? '' : result[0]
+            brand: _.isEmpty(result[0]) ? '' : result[0],
+            noCashe: false
         };
+
+        // 数据出错不cashe
+        if (_.isEmpty(result[0])) {
+            responseData.noCashe = true;
+        }
+        return responseData;
     });
 };
 
@@ -189,7 +200,8 @@ exports.plusstarList = (channel, req) => {
         let responseData = {
             module: 'brands',
             page: 'brands',
-            brandsHomePage: true
+            brandsHomePage: true,
+            noCashe: false
         };
 
         let id = req.query.id || '',
@@ -208,6 +220,10 @@ exports.plusstarList = (channel, req) => {
 
         let list = plustarList.data;
 
+        // 数据出错不cashe
+        if (_.isEmpty(headerData.headerData) || _.isEmpty(items) || _.isEmpty(list)) {
+            responseData.noCashe = true;
+        }
         let brandIds = [],
             brands = [],
             pageList = {};
@@ -232,6 +248,11 @@ exports.plusstarList = (channel, req) => {
                 }
                 brands.push(list[brandId]);
             });
+
+            // 数据出错不cashe
+            if (_.isEmpty(brandsInfo)) {
+                responseData.noCashe = true;
+            }
         }
         let data = {
             brandsHomePage: true,
diff --git a/apps/brands/views/action/brands/brands.hbs b/apps/brands/views/action/brands/brands.hbs
index 1beaac5..5fa2c92 100644
--- a/apps/brands/views/action/brands/brands.hbs
+++ b/apps/brands/views/action/brands/brands.hbs
@@ -48,7 +48,7 @@
             {{/each}}
         </div>
     </div>
-    <div class="brands-list" >
+    <div class="brands-list" data-ishover="{{@root.pc.brands.disBrandNameHover}}">
         {{> brand-list}}
     </div>
     {{/ brands}}
diff --git a/apps/cart/index.js b/apps/cart/index.js
index 25d93fd..c6dbe6d 100644
--- a/apps/cart/index.js
+++ b/apps/cart/index.js
@@ -7,25 +7,24 @@
 'use strict';
 
 var express = require('express'),
-    path = require('path'),
-    hbs = require('express-handlebars');
+    path = require('path');
 
 var app = express();
 
 // set view engin
-var doraemon = path.join(__dirname, '../../doraemon/views'); //parent view root
+var doraemon = path.join(__dirname, '../../doraemon/views'); // parent view root
 
 app.on('mount', function(parent) {
     delete parent.locals.settings; // 不继承父 App 的设置
     Object.assign(app.locals, parent.locals);
 });
 
-app.set('views', path.join(__dirname, 'views/action'));
-app.engine('.hbs', hbs({
+app.use(global.yoho.hbs({
     extname: '.hbs',
     defaultLayout: 'layout',
     layoutsDir: doraemon,
-    partialsDir: [path.join(__dirname, 'views/partial'), `${doraemon}/partial`],
+    partialsDir: [path.join(__dirname, 'views/partial')],
+    views: path.join(__dirname, 'views/action'),
     helpers: global.yoho.helpers
 }));
 
diff --git a/apps/channel/controllers/index.js b/apps/channel/controllers/index.js
index 36ee641..067f077 100644
--- a/apps/channel/controllers/index.js
+++ b/apps/channel/controllers/index.js
@@ -17,6 +17,11 @@ exports.index = (req, res, next) => {
     channelType === 'woman' ? channelType = 'girls' : null;
 
     channelModel.getContent(channelType).then(data => {
+
+        // channel为空不缓存
+        if (_.isEmpty(data.channel)) {
+            res.set('Cache-Control', 'no-cache');
+        }
         res.render('channel', data);
     }).catch(next);
 };
diff --git a/apps/channel/index.js b/apps/channel/index.js
index 4e48e31..3b7f544 100644
--- a/apps/channel/index.js
+++ b/apps/channel/index.js
@@ -5,14 +5,12 @@
  */
 
 var express = require('express'),
-    path = require('path'),
-    hbs = require('express-handlebars');
+    path = require('path');
 
 var app = express();
 
 // set view engin
 var doraemon = path.join(__dirname, '../../doraemon/views'); // parent view root
-var partials = path.join(__dirname, './views'); // parent view root
 
 
 app.on('mount', function(parent) {
@@ -20,16 +18,15 @@ app.on('mount', function(parent) {
     Object.assign(app.locals, parent.locals);
 });
 
-app.set('views', path.join(__dirname, 'views/action'));
-app.engine('.hbs', hbs({
+app.use(global.yoho.hbs({
     extname: '.hbs',
     defaultLayout: 'layout',
     layoutsDir: doraemon,
-    partialsDir: [`${partials}/partial`, `${doraemon}/partial`],
+    partialsDir: [path.join(__dirname, 'views/partial')],
+    views: path.join(__dirname, 'views/action'),
     helpers: global.yoho.helpers
 }));
 
-
 // router
 app.use(require('./router'));
 
diff --git a/apps/channel/models/index.js b/apps/channel/models/index.js
index 194f7d3..af6a49a 100644
--- a/apps/channel/models/index.js
+++ b/apps/channel/models/index.js
@@ -10,6 +10,7 @@ const _ = require('lodash');
 const dataMap = require('../../../config/data-map');
 
 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');
@@ -335,7 +336,7 @@ const _getGirlsSingleHot = (args, type) => {
         page: 1,
         gender: channelMap[type].gender,
         limit: 60
-    });
+    }, config.apiCache);
 };
 
 
@@ -592,18 +593,18 @@ const _processFloorData = (rawData, type) => {
         let queryParam = '';
 
         if (data.template_name === 'recommend_content_three' ||
-           (data.template_intro === '焦点图' && index === 0)) { // 处理banner
+            (data.template_intro === '焦点图' && index === 0)) { // 处理banner
             floorData = floorMap.slide.call(null, data.data);
         } else if (data.template_intro === '热门品类') { // 处理热门品类
             floorData = floorMap.hot.call(null, rawData.slice(index, index + hotCategoryLength), type);
         } else if (data.data && data.data.text) { // 处理一般楼层
             let text = _getText(data.data.text);
             let lastIndex = index + bigFloorLength < rawData.length ?
-                            index + bigFloorLength : index + (rawData.length - index - 1);
+            index + bigFloorLength : index + (rawData.length - index - 1);
 
 
             floorData = floorMap[text] &&
-                        floorMap[text].call(null, rawData.slice(index, lastIndex), type);
+                floorMap[text].call(null, rawData.slice(index, lastIndex), type);
 
             if (needQuery[text]) {
                 queryParam = getQuery(rawData.slice(index, lastIndex));
@@ -657,9 +658,7 @@ const _processFloorData = (rawData, type) => {
 };
 
 const _formatResourceParams = (channel, code) => {
-    return serviceApi.get('operations/api/v5/resource/get', {content_code: code}, {
-        cache: true
-    }).then(data => {
+    return serviceApi.get('operations/api/v5/resource/get', {content_code: code}, config.apiCache).then(data => {
         let result = data && data.data[0] && data.data[0].data[0];
 
         if (result) {
@@ -834,8 +833,6 @@ const getNewArrival = channel => {
 };
 
 
-
-
 /**
  * 获取频道页数据
  * @param  {String} type 传入频道页类型,值可以是: boys, girls, kids, lifestyle
@@ -956,9 +953,7 @@ const getIndexGuideData = () => {
         private_key: '0ed29744ed318fd28d2c07985d3ba633'
     };
 
-    return serviceApi.get('operations/api/v6/category/getCategory', params, {
-        cache: true
-    });
+    return serviceApi.get('operations/api/v6/category/getCategory', params, config.apiCache);
 };
 
 module.exports = {
diff --git a/apps/common/index.js b/apps/common/index.js
index 84aaeb5..561895d 100644
--- a/apps/common/index.js
+++ b/apps/common/index.js
@@ -4,28 +4,15 @@
  * @date: 2016/10/11
  */
 
-var express = require('express'),
-    path = require('path'),
-    hbs = require('express-handlebars');
+var express = require('express');
 
 var app = express();
 
-// set view engin
-var doraemon = path.join(__dirname, '../../doraemon/views'); // parent view root
-
 app.on('mount', function(parent) {
     delete parent.locals.settings; // 不继承父 App 的设置
     Object.assign(app.locals, parent.locals);
 });
 
-app.set('views', path.join(__dirname, 'views/action'));
-app.engine('.hbs', hbs({
-    extname: '.hbs',
-    defaultLayout: 'layout',
-    layoutsDir: doraemon,
-    partialsDir: [path.join(__dirname, 'views/partial'), `${doraemon}/partial`],
-    helpers: global.yoho.helpers
-}));
 
 // router
 app.use(require('./router'));
diff --git a/apps/guang/controllers/index.js b/apps/guang/controllers/index.js
index caf5109..ff99a4c 100644
--- a/apps/guang/controllers/index.js
+++ b/apps/guang/controllers/index.js
@@ -26,16 +26,23 @@ exports.index = (req, res, next) => {
     let uid = req.user.uid;
     let udid = ghelper.getUdid(req, res);
     let gender = ghelper.getGenderByCookie(req);
+    let isHotDegrade = _.get(req.app.locals.pc, 'guang.removeHotTag', false);
+    let isAdDegrade = _.get(req.app.locals.pc, 'guang.removeAd', false);
 
     Promise.all([
         guangModel.getBanner(channel),
         guangModel.getCategory(type, channel),
         guangModel.getArticleList(gender, type, uid, udid, page, '', '', pageSize, channel, true),
-        guangModel.getHotTags(page, pageSize, channel),
-        guangModel.getAds(channel),
+        guangModel.getHotTags(page, pageSize, channel, isHotDegrade),
+        guangModel.getAds(channel, isAdDegrade),
         guangModel.getRecoArticles(gender, 1, 10, channel),
         headerModel.requestHeaderData(channel)
     ]).then(ret => {
+
+        if (_.isEmpty(ret[2]) || _.isEmpty(ret[2].msgs)) {
+            res.set('Cache-Control', 'no-cache');
+        }
+
         res.render('guang/index', {
             title: '逛' + (res.locals.title || ''),
             guang: {
@@ -77,17 +84,23 @@ exports.tags = (req, res, next) => {
     let gender = ghelper.getGenderByCookie(req);
     let channel = req.yoho.channel;
     let pathNav = guangModel.getPathNav(channel, query);
+    let isHotDegrade = _.get(req.app.locals.pc, 'guang.removeHotTag', false);
+    let isAdDegrade = _.get(req.app.locals.pc, 'guang.removeAd', false);
 
     Promise.all([
         guangModel.getBanner(channel),
 
         guangModel.getArticleList(gender, 0, uid, udid, page, query, '', pageSize, channel, true),
-        guangModel.getHotTags(1, 20, channel),
-        guangModel.getAds(channel),
+        guangModel.getHotTags(1, 20, channel, isHotDegrade),
+        guangModel.getAds(channel, isAdDegrade),
         guangModel.getRecoArticles(gender, 1, 10, channel),
         headerModel.requestHeaderData(channel)
     ]).then(ret => {
 
+        if (_.isEmpty(ret[1]) || _.isEmpty(ret[1].msgs)) {
+            res.set('Cache-Control', 'no-cache');
+        }
+
         res.render('guang/tag', {
             title: query + (res.locals.title || ''),
             guang: {
@@ -121,6 +134,8 @@ exports.editor = (req, res, next) => {
     let authorId = req.query.author_id;
     let channel = req.yoho.channel;
     let gender = ghelper.getGenderByCookie(req);
+    let isHotDegrade = _.get(req.app.locals.pc, 'guang.removeHotTag', false);
+    let isAdDegrade = _.get(req.app.locals.pc, 'guang.removeAd', false);
 
     let uid = req.user.uid;
     let udid = ghelper.getUdid(req, res);
@@ -133,11 +148,16 @@ exports.editor = (req, res, next) => {
     Promise.all([
         guangModel.getAuthor(authorId),
         guangModel.getArticleList(gender, null, uid, udid, page, '', authorId, pageSize, channel, true),
-        guangModel.getHotTags(1, 20, channel),
-        guangModel.getAds(channel),
+        guangModel.getHotTags(1, 20, channel, isHotDegrade),
+        guangModel.getAds(channel, isAdDegrade),
         guangModel.getRecoArticles(gender, 1, 10, channel),
         headerModel.requestHeaderData(channel)
     ]).then(ret => {
+
+        if (_.isEmpty(ret[1]) || _.isEmpty(ret[1].msgs)) {
+            res.set('Cache-Control', 'no-cache');
+        }
+
         res.render('guang/editor', {
             title: _.get(ret[0], 'name', '') + (res.locals.title || ''),
             guang: {
@@ -175,9 +195,11 @@ exports.detail = (req, res, next) => {
     let udid = ghelper.getUdid(req, res);
     let gender = ghelper.getGenderByCookie(req);
     let channel = req.yoho.channel;
+    let isHotDegrade = _.get(req.app.locals.pc, 'guang.removeHotTag', false);
+    let isAdDegrade = _.get(req.app.locals.pc, 'guang.removeAd', false);
 
     if (!_.isNumber(id)) {
-        id = parseInt(id);
+        id = _.parseInt(id);
     }
 
     if (pjax) {
@@ -212,12 +234,12 @@ exports.detail = (req, res, next) => {
         let promises = [
             headerModel.requestHeaderData(channel),
             guangModel.getArticleContent(id),
-            guangModel.getHotTags(1, 20, channel),
+            guangModel.getHotTags(1, 20, channel, isHotDegrade),
             guangModel.getArticleComments(id, page, pageSize),
             guangModel.getArticleBaseInfo(id, uid, udid),
             guangModel.getArticleRelateBrand(id),
             guangModel.getRecoArticles(gender, 1, 10, channel),
-            guangModel.getAds(channel)
+            guangModel.getAds(channel, isAdDegrade)
         ];
 
         if (info.authorId) {
@@ -236,6 +258,10 @@ exports.detail = (req, res, next) => {
 
         Promise.all(promises).then(ret => {
 
+            if (_.isEmpty(ret[1])) {
+                res.set('Cache-Control', 'no-cache');
+            }
+
             res.render('guang/detail', Object.assign({
                 module: 'guang',
                 page: 'detail',
diff --git a/apps/guang/helpers/pager.js b/apps/guang/helpers/pager.js
index 2de780e..cce5a11 100644
--- a/apps/guang/helpers/pager.js
+++ b/apps/guang/helpers/pager.js
@@ -44,7 +44,7 @@ exports.pager = function() {
         base = base.replace(clearSizeReg, '');
     }
 
-    base += (base.indexOf('?') < 0 ? '?' : (base.charAt(base.length - 1) !== '?' ? '&' : '')) +
+    base += (base.indexOf('?') < 0 ? '?' : (/(\?|&)$/.test(base) ? '' : '&')) +
             (options.hash.pageSize ? (pageSizeVar + '=' + pageSize + '&') : '') +
             pageVar + '=';
 
diff --git a/apps/guang/index.js b/apps/guang/index.js
index 82d5844..5311f91 100644
--- a/apps/guang/index.js
+++ b/apps/guang/index.js
@@ -6,27 +6,24 @@
  'use strict';
 
  var express = require('express'),
-     path = require('path'),
-     hbs = require('express-handlebars');
+     path = require('path');
 
  var app = express();
 
 // set view engin
  var doraemon = path.join(__dirname, '../../doraemon/views'); // parent view root
- var partials = path.join(__dirname, './views'); // parent view root
-
 
  app.on('mount', function(parent) {
      delete parent.locals.settings; // 不继承父 App 的设置
      Object.assign(app.locals, parent.locals);
  });
 
- app.set('views', path.join(__dirname, 'views/action'));
- app.engine('.hbs', hbs({
+ app.use(global.yoho.hbs({
      extname: '.hbs',
      defaultLayout: 'layout',
      layoutsDir: doraemon,
-     partialsDir: [`${partials}/partial`, `${doraemon}/partial`],
+     partialsDir: [path.join(__dirname, 'views/partial')],
+     views: path.join(__dirname, 'views/action'),
      helpers: Object.assign(require('./helpers/pager'), global.yoho.helpers)
  }));
 
diff --git a/apps/guang/models/index.js b/apps/guang/models/index.js
index e056b7e..9af394a 100644
--- a/apps/guang/models/index.js
+++ b/apps/guang/models/index.js
@@ -121,7 +121,8 @@ const _formatArticle = (articleData, showTag, showAuthor, channel) => {
     let result = {
         id: articleData.id,
         classification: articleData.category_name,
-        isReco: articleData.is_recommended && Number(articleData.is_recommended) === 1 ? true : false,
+
+        // isReco: articleData.is_recommended && Number(articleData.is_recommended) === 1 ? true : false,
         url: ghelper.getArticleUrl(articleData.url, articleData.id, channel),
         img: helpers.image(articleData.src, width, height, 1),
         isSquareImg: isSquareImage,
@@ -133,6 +134,26 @@ const _formatArticle = (articleData, showTag, showAuthor, channel) => {
         comment: articleData.comment_num
     };
 
+    if (showTag && articleData.category_id) {
+        switch (String(articleData.category_id)) {
+            case '1': // 话题
+                result.isTopic = true;
+                break;
+            case '2': // 搭配
+                result.isCollocation = true;
+                break;
+            case '3': // 潮人
+                result.isFashionMan = true;
+                break;
+            case '4': // 潮品
+                result.isFashionGood = true;
+                break;
+            case '19': // 专题
+                result.isSpecialTopic = true;
+                break;
+        }
+    }
+
     if (!articleData.author) {
         articleData.author = {
             name: '',
@@ -305,7 +326,7 @@ const getArticleList = (gender, sortId, uid, udid, page, tag, authorId, limit, c
  * @param  {String} type 传入频道页类型,值可以是: boys, girls, kids, lifestyle
  * @return {Object}
  */
-const getHotTags = (page, limit, channel) => {
+const getHotTags = (page, limit, channel, isDegrade) => {
 
     let data = {
         client_type: 'web',
@@ -313,6 +334,10 @@ const getHotTags = (page, limit, channel) => {
         limit: limit || 10
     };
 
+    if (isDegrade) {
+        return null;
+    }
+
     return serviceApi.get('guang/api/v2/article/getTagTop', data, {
         cache: true
     }).then(res => {
@@ -338,10 +363,14 @@ const getHotTags = (page, limit, channel) => {
  * @param  {String} channelType 传入频道页类型,值可以是: boys, girls, kids, lifestyle
  * @return {Object}
  */
-const getAds = channelType => {
+const getAds = (channelType, isDegrade) => {
 
     let contentCode = ADS_CODE[channelType] || ADS_CODE.boys;
 
+    if (isDegrade) {
+        return null;
+    }
+
     return serviceApi.get(URL_OPERATIONS_RESOURCE_GET, {
         content_code: contentCode
     }, {cache: true}).then(res => {
diff --git a/apps/guang/views/action/guang/detail.hbs b/apps/guang/views/action/guang/detail.hbs
index 5004eec..e9d398e 100644
--- a/apps/guang/views/action/guang/detail.hbs
+++ b/apps/guang/views/action/guang/detail.hbs
@@ -130,18 +130,20 @@
                 </div>
             {{/if}}
 
-            <div id="comment-area" class="comment-area">
-                <div class="comment-textarea">
-                    <textarea id="comment-info" placeholder="我有话要说。。。">{{commentInfo}}</textarea>
-                </div>
-                <div class="comment-publish clearfix">
-                    <span id="word-count-tip" class="word-count-tip"></span>
-                    <a id="comment-btn" class="publish-btn disable">评论</a>
-                </div>
-                <div id="pjax-container" class="comments-wrap">
-                    {{> comment}}
+            {{#unless @root.pc.guang.removeItemComment}}
+                <div id="comment-area" class="comment-area">
+                    <div class="comment-textarea">
+                        <textarea id="comment-info" placeholder="我有话要说。。。">{{commentInfo}}</textarea>
+                    </div>
+                    <div class="comment-publish clearfix">
+                        <span id="word-count-tip" class="word-count-tip"></span>
+                        <a id="comment-btn" class="publish-btn disable">评论</a>
+                    </div>
+                    <div id="pjax-container" class="comments-wrap">
+                        {{> comment}}
+                    </div>
                 </div>
-            </div>
+            {{/unless}}
         </div>
         <div class="right-side detail-side">
             {{> right-side}}
diff --git a/apps/guang/views/partial/msg.hbs b/apps/guang/views/partial/msg.hbs
index 11fb04d..5e1d1b9 100644
--- a/apps/guang/views/partial/msg.hbs
+++ b/apps/guang/views/partial/msg.hbs
@@ -3,9 +3,21 @@
         <div class="classification">
             {{classification}}
         </div>
-        {{#if isReco}}
-            <div class="reco"></div>
-        {{/if}}
+        {{# isCollocation}}
+            <div class="type-icon collocation"></div>
+        {{/ isCollocation}}
+        {{# isFashionMan}}
+            <div class="type-icon fashion-man"></div>
+        {{/ isFashionMan}}
+        {{# isFashionGood}}
+            <div class="type-icon fashion-good"></div>
+        {{/ isFashionGood}}
+        {{# isTopic}}
+            <div class="type-icon topic"></div>
+        {{/ isTopic}}
+        {{# isSpecialTopic}}
+            <div class="type-icon special-topic"></div>
+        {{/ isSpecialTopic}}
         <a href="{{url}}" target="_blank">
             <img class="lazy{{#if isSquareImg}} square{{/if}}" data-original="{{img}}">
         </a>
@@ -46,4 +58,4 @@
             </div>
         </div>
     </div>
-</div>
\ No newline at end of file
+</div>
diff --git a/apps/guang/views/partial/right-side.hbs b/apps/guang/views/partial/right-side.hbs
index fff0cbe..8063196 100644
--- a/apps/guang/views/partial/right-side.hbs
+++ b/apps/guang/views/partial/right-side.hbs
@@ -14,16 +14,18 @@
     </div>
 </div>
 
-<div class="hot">
-    <h1 class="hot-title">热门标签</h1>
-    <div class="hot-tag-list">
-        {{#hotTags}}
-            <a class="hot-tag" href="{{url}}" target="_blank">
-                {{tagName}}
-            </a>
-        {{/hotTags}}
+{{#unless @root.pc.guang.removeHotTag}}
+    <div class="hot">
+        <h1 class="hot-title">热门标签</h1>
+        <div class="hot-tag-list">
+            {{#hotTags}}
+                <a class="hot-tag" href="{{url}}" target="_blank">
+                    {{tagName}}
+                </a>
+            {{/hotTags}}
+        </div>
     </div>
-</div>
+{{/unless}}
 
 <div class="ads">
     {{# ads}}
@@ -31,4 +33,4 @@
             <img class="lazy" data-original="{{img}}">
         </a>
     {{/ ads}}
-</div>
\ No newline at end of file
+</div>
diff --git a/apps/home/index.js b/apps/home/index.js
index 7dcd7b7..e112dc9 100644
--- a/apps/home/index.js
+++ b/apps/home/index.js
@@ -5,8 +5,7 @@
  */
 
 var express = require('express'),
-    path = require('path'),
-    hbs = require('express-handlebars');
+    path = require('path');
 
 var app = express();
 
@@ -17,12 +16,13 @@ app.on('mount', function(parent) {
     delete parent.locals.settings; // 不继承父 App 的设置
     Object.assign(app.locals, parent.locals);
 });
-app.set('views', path.join(__dirname, 'views/action'));
-app.engine('.hbs', hbs({
+
+app.use(global.yoho.hbs({
     extname: '.hbs',
     defaultLayout: 'layout',
     layoutsDir: doraemon,
-    partialsDir: [path.join(__dirname, 'views/partial'), `${doraemon}/partial`],
+    partialsDir: [path.join(__dirname, 'views/partial')],
+    views: path.join(__dirname, 'views/action'),
     helpers: global.yoho.helpers
 }));
 
diff --git a/apps/passport/auth.js b/apps/passport/auth.js
index 88a95ff..c092451 100644
--- a/apps/passport/auth.js
+++ b/apps/passport/auth.js
@@ -15,7 +15,7 @@ const DoubanStrategy = require('passport-douban').Strategy;
 const RenrenStrategy = require('passport-renren').Strategy;
 const AlipayStrategy = require('./models/passport-alipay').Strategy;
 
-const AuthHelper = require('./models/auth-helper');
+const LoginApi = require('./models/login-service');
 
 const config = global.yoho.config;
 const helpers = global.yoho.helpers;
@@ -26,6 +26,16 @@ const cache = global.yoho.cache;
 let siteUrl = config.siteUrl.indexOf('//') === 0 ? 'http:' + config.siteUrl : config.siteUrl;
 
 
+function getLoginStat(account) {
+    let errorLoginKey = 'account_errorlogin_' + account;
+    let accountKey = 'account_signin_' + account;
+    let cacheGet = [cache.get(errorLoginKey), cache.get(accountKey)];
+
+    return Promise.all(cacheGet).catch(() => {
+        return [0, 0];
+    });
+}
+
 // 本地登录
 passport.use('local', new LocalStrategy({
     usernameField: 'account',
@@ -54,25 +64,23 @@ passport.use('local', new LocalStrategy({
     let errorLoginKey = 'account_errorlogin_' + account;
     let accountKey = 'account_signin_' + account;
 
-    let cacheGet = [cache.get(errorLoginKey), cache.get(accountKey)];
-
-    Promise.all(cacheGet).then(times => {
+    getLoginStat(account).then(times => {
         let errLoginTimes = _.parseInt(times[0]) || 0;
         let accountTimes = _.parseInt(times[1]) || 0;
 
         if (accountTimes >= 10) {
             done({message: '您的账号已被暂时锁定,请稍后再试'}, null);
         } else {
-            return AuthHelper.signin(type, area, username, password, shoppingKey).then((result) => {
+            return LoginApi.signin(type, area, username, password, shoppingKey).then((result) => {
                 if (result.code && result.code === 200 && result.data.uid) {
-                    cache.del(errorLoginKey);
+                    cache.del(errorLoginKey).catch(() => {});
 
                     done(null, result.data);
                 } else {
                     errLoginTimes = errLoginTimes + 1;
                     accountTimes = accountTimes + 1;
-                    cache.set(errorLoginKey, errLoginTimes);
-                    cache.set(accountKey, accountTimes, 1800);
+                    cache.set(errorLoginKey, errLoginTimes).catch(() => {});
+                    cache.set(accountKey, accountTimes, 1800).catch(() => {});
 
                     // 再次校验
                     if (accountTimes >= 10) {
@@ -116,8 +124,8 @@ passport.use('wechat', new WeixinStrategy({
 
 // sina 登录
 passport.use('sina', new SinaStrategy({
-    clientID: '3739328910',
-    clientSecret: '9d44cded26d048e23089e5e975c93df1',
+    clientID: config.thirdLogin.sina.appID,
+    clientSecret: config.thirdLogin.sina.appSecret,
     callbackURL: `${siteUrl}/passport/login/sina/callback`,
     requireState: false
 }, (accessToken, refreshToken, profile, done) => {
@@ -126,8 +134,8 @@ passport.use('sina', new SinaStrategy({
 
 // qq 登录
 passport.use('qq', new QQStrategy({
-    clientID: '100229394',
-    clientSecret: 'c0af9c29e0900813028c2ccb42021792',
+    clientID: config.thirdLogin.qq.appID,
+    clientSecret: config.thirdLogin.qq.appSecret,
     callbackURL: `${siteUrl}/passport/login/qq/callback`,
     requireState: false
 }, (accessToken, refreshToken, profile, done) => {
@@ -136,8 +144,8 @@ passport.use('qq', new QQStrategy({
 
 // alipay 登录
 passport.use('alipay', new AlipayStrategy({
-    partner: '2088701661478015',
-    key: 'kcxawi9bb07mzh0aq2wcirsf9znusobw',
+    partner: config.thirdLogin.alipay.appID,
+    key: config.thirdLogin.alipay.appSecret,
     return_url: `${siteUrl}/passport/login/alipay/callback`
 }, (profile, done) => {
     done(null, profile);
@@ -145,8 +153,8 @@ passport.use('alipay', new AlipayStrategy({
 
 // douban 登录
 passport.use('douban', new DoubanStrategy({
-    clientID: '03b4e36bf13dc75a0b1eaa43d3b9560e',
-    clientSecret: 'f16d5913e8610672',
+    clientID: config.thirdLogin.douban.appID,
+    clientSecret: config.thirdLogin.douban.appSecret,
     callbackURL: `${siteUrl}/passport/autosign/doubanback`
 }, (accessToken, refreshToken, profile, done) => {
     done(null, profile);
@@ -154,8 +162,8 @@ passport.use('douban', new DoubanStrategy({
 
 // renren 登录
 passport.use('renren', new RenrenStrategy({
-    clientID: '783130c654c94a77ace97054ae266019',
-    clientSecret: '05e430de8c1e40d3a1f39ca8d3f8252c',
+    clientID: config.thirdLogin.renren.appID,
+    clientSecret: config.thirdLogin.renren.appSecret,
     callbackURL: `${siteUrl}/passport/login/renren/callback`
 }, (accessToken, refreshToken, profile, done) => {
     done(null, profile);
diff --git a/apps/passport/controllers/back.js b/apps/passport/controllers/back.js
index 9c33d6a..5ebe3a9 100644
--- a/apps/passport/controllers/back.js
+++ b/apps/passport/controllers/back.js
@@ -6,6 +6,7 @@
 'use strict';
 
 const helpers = global.yoho.helpers;
+const config = global.yoho.config;
 const service = require('../models/back-service');
 const passportHelper = require('../models/passport-helper');
 const simpleHeaderModel = require('../../../doraemon/models/simple-header');
@@ -17,12 +18,15 @@ const _ = require('lodash');
 const index = (req, res, next) => {
     // 清除cookie
     res.clearCookie('_UID', {
-        domain: 'yohobuy.com'
+        domain: config.cookieDomain
     });
     res.clearCookie('_TOKEN', {
-        domain: 'yohobuy.com'
+        domain: config.cookieDomain
     });
 
+    // 清除 session
+    req.session = null;
+
     service.indexPageDataAsync()
         .then(result => {
             res.render('back/index', Object.assign({
@@ -102,21 +106,18 @@ const sendCodePage = (req, res, next) => {
 
 const saveInSession = (req, res) => {
     switch (req.inputInfo.type) {
-        case 'email': {
+        case 'email':
             req.session.email = req.inputInfo.phone;
             res.redirect(helpers.urlFormat('/passport/back/sendEmail'));
             break;
-        }
-        case 'mobile': {
+        case 'mobile':
             req.session.mobile = req.inputInfo.phone;
             req.session.area = req.inputInfo.area;
             req.session.verifyCode = req.session.captcha;
             res.redirect(helpers.urlFormat('/passport/back/verification'));
             break;
-        }
-        default: {
+        default:
             res.redirect(helpers.urlFormat('/passport/back/index'));
-        }
     }
 };
 
@@ -133,10 +134,9 @@ const sendBackMobileAPI = (req, res, next) => {
 
 const validateMobileAPI = (req, res, next) => {
     let mobile = req.body.mobile || '';
-    let area = req.body.area || '86';
     const ERR = {code: 400, message: '验证失败'};
 
-    if (!passportHelper.validator.isAreaMobile(passportHelper.makeAreaMobile(area, mobile))) {
+    if (!passportHelper.validator.isMobile(mobile)) {
         return res.json(ERR);
     }
 
diff --git a/apps/passport/controllers/bind.js b/apps/passport/controllers/bind.js
index c894829..b6d925c 100644
--- a/apps/passport/controllers/bind.js
+++ b/apps/passport/controllers/bind.js
@@ -8,9 +8,10 @@
 
 const _ = require('lodash');
 const helpers = global.yoho.helpers;
-const PassportHelper = require('../models/passport-helper');
-const BindService = require('../models/bind-service');
-const AuthHelper = require('../models/auth-helper');
+const passportHelper = require('../models/passport-helper');
+const bindService = require('../models/bind-service');
+const loginService = require('../models/login-service');
+const userService = require('../models/user-service');
 
 // const UserService = require('../models/user-service');
 const simpleHeaderModel = require('../../../doraemon/models/simple-header');
@@ -33,7 +34,7 @@ const bind = {
             thirdLogin: true,
             openId: openId,
             sourceType: sourceType,
-            region: PassportHelper.getCountry(),
+            region: passportHelper.getCountry(),
             serviceUrl: helpers.urlFormat('/help', {
                 category_id: 9
             }),
@@ -80,7 +81,7 @@ const bind = {
         //     }
         // })
 
-        PassportHelper.getUserInfo(area, mobile).then(user => {
+        userService.getUserInfo(area, mobile).then(user => {
             let data = _.assign(user, {
                 phoneNum: mobile,
                 areaCode: area,
@@ -121,49 +122,59 @@ const bind = {
         let sourceType = req.body.sourceType;
 
         if (mobile && openId && area && sourceType) {
-            BindService.bindCheck(mobile, openId, sourceType, area).then(result => {
+
+            /**
+             * 接口绑定返回值:
+             * code:200,is_register=0     // 绑定流程:未注册,可绑定
+             * code:200,is_register=1     // 绑定流程:已注册绑定过其他第三方
+             * code:200:is_register=3     // 关联流程
+             * code:505                   // 手机号码注册过,而且该第三方也已经绑定过手机号
+             * code:506                   // 手机号码注册过,而且该手机号码也已经绑定过该类型第三方
+             */
+
+            bindService.bindCheck(mobile, openId, sourceType, area).then(result => {
                 if (!result || !result.code) {
-                    return { code: 400, message: '', data: '' };
+                    return {code: 400, message: '', data: ''};
                 } else if (result.code === 200 && result.data.is_register === 0) {
                     let nextUrl = helpers.urlFormat('/passport/thirdlogin/noregist');
 
                     // 绑定流程:code=200 未注册,可绑定
-                    return { code: 200, message: result.message, data: { next: nextUrl } };
+                    return {code: 200, message: result.message, data: {next: nextUrl}};
                 } else if (result.code === 200 && result.data.is_register === 1) {
-                    return PassportHelper.getUserInfo(area, mobile).then(user => {
+                    return userService.getUserInfo(area, mobile).then(user => {
                         // 绑定流程:code=201 已注册 绑定过其他第三方
-                        return {code: 201, message: result.message, data: { user: user } };
+                        return {code: 201, message: result.message, data: {user: user}};
                     });
                 } else if (result.code === 200 && result.data.is_register === 3) {
                     let nextUrl = helpers.urlFormat('/passport/thirdlogin/relate');
 
                     // 关联流程
-                    return { code: 203, message: result.message, data: { next: nextUrl } };
+                    return {code: 203, message: result.message, data: {next: nextUrl}};
                 } else if (result.code === 506 || result.code === 505) {
-                    return PassportHelper.getUserInfo(area, mobile).then(user => {
+                    return userService.getUserInfo(area, mobile).then(user => {
                         // 绑定流程:code=506 手机号码注册过,而且该手机号码也已经绑定过该类型第三方
                         // code=505 手机号码注册过,而且该第三方也已经绑定过手机号
-                        return { code: 205, message: result.message, data: { user: user } };
+                        return {code: 205, message: result.message, data: {user: user}};
                     });
                 } else {
-                    return { code: result.code, message: result.message, data: result.data ? result.data : '' };
+                    return {code: result.code, message: result.message, data: result.data ? result.data : ''};
                 }
             }).then(result => {
-                res.json(result);
+                return res.json(result);
             }).catch(next);
         } else {
-            res.json({ code: 400, message: '', data: '' });
+            return res.json({code: 400, message: '', data: ''});
         }
     },
     sendBindMsg: (req, res, next) => {
         let mobile = req.body.mobile;
         let area = req.body.area;
 
-        BindService.sendBindMsg(area, mobile).then(result => {
+        bindService.sendBindMsg(area, mobile).then(result => {
             if (result && result.code) {
-                res.json(result);
+                return res.json(result);
             } else {
-                res.json({ code: 400, message: '', data: '' });
+                return res.json({code: 400, message: '', data: ''});
             }
         }).catch(next);
     },
@@ -172,11 +183,11 @@ const bind = {
         let area = req.body.area;
         let code = req.body.code;
 
-        BindService.checkBindCode(area, mobile, code).then(result => {
+        bindService.checkBindCode(area, mobile, code).then(result => {
             if (result && result.code) {
-                res.json(result);
+                return res.json(result);
             } else {
-                res.json({ code: 400, message: '', data: '' });
+                return res.json({code: 400, message: '', data: ''});
             }
         }).catch(next);
     },
@@ -188,11 +199,11 @@ const bind = {
         let code = _.trim(req.body.code);
         let password = _.trim(req.body.password) || '';
 
-        BindService.checkBindCode(area, mobile, code).then(result => {
+        bindService.checkBindCode(area, mobile, code).then(result => {
             if (result && result.code !== 200) {
-                return { code: 402, message: '短信验证码不正确', data: '' };
+                return {code: 402, message: '短信验证码不正确', data: ''};
             } else {
-                return BindService.bindMobile(openId, sourceType, mobile, area, password);
+                return bindService.bindMobile(openId, sourceType, mobile, area, password);
             }
         }).then(result => {
             if (result && result.code) {
@@ -201,17 +212,17 @@ const bind = {
                         sourceType: sourceType + '_bind'
                     });
 
-                    return AuthHelper.syncUserSession(result.data.uid, req, res).then(() => {
-                        return { code: 200, message: result.message, data: {refer: refer }};
+                    return loginService.syncUserSession(result.data.uid, req, res).then(() => {
+                        return {code: 200, message: result.message, data: {refer: refer}};
                     });
                 } else {
-                    return { code: result.code, message: result.message, data: { refer: ''} };
+                    return {code: result.code, message: result.message, data: {refer: ''}};
                 }
             } else {
                 return {code: 400, message: '', data: ''};
             }
         }).then(result => {
-            res.json(result);
+            return res.json(result);
         }).catch(next);
     },
     relateMobile: (req, res, next) => {
@@ -221,12 +232,12 @@ const bind = {
         let sourceType = req.body.sourceType;
         let code = req.body.code;
 
-        if (_.isNumber(parseInt(mobile, 0)) && openId && areaCode && sourceType && code) {
-            BindService.checkBindCode(areaCode, mobile, code).then(result => {
+        if (_.toNumber(mobile) && openId && areaCode && sourceType && code) {
+            bindService.checkBindCode(areaCode, mobile, code).then(result => {
                 if (result && result.code && result.code === 200) {
-                    return BindService.relateMobile(openId, sourceType, mobile, areaCode);
+                    return bindService.relateMobile(openId, sourceType, mobile, areaCode);
                 } else {
-                    return { code: 402, message: '短信验证码错误', data: '' };
+                    return {code: 402, message: '短信验证码错误', data: ''};
                 }
             }).then(result => {
                 if (result && result.code) {
@@ -235,20 +246,20 @@ const bind = {
                             sourceType: sourceType + '_relate'
                         });
 
-                        return AuthHelper.syncUserSession(result.data.uid, req, res).then(() => {
-                            return { code: 200, message: result.message, data: {refer: refer }};
+                        return loginService.syncUserSession(result.data.uid, req, res).then(() => {
+                            return {code: 200, message: result.message, data: {refer: refer}};
                         });
                     } else {
-                        return { code: result.code, message: result.message, data: { refer: ''} };
+                        return {code: result.code, message: result.message, data: {refer: ''}};
                     }
                 } else {
                     return {code: 400, message: '', data: ''};
                 }
             }).then(result => {
-                res.json(result);
+                return res.json(result);
             }).catch(next);
         } else {
-            res.json({ code: 400, message: '', data: '' });
+            return res.json({code: 400, message: '', data: ''});
         }
     }
 };
diff --git a/apps/passport/controllers/login.js b/apps/passport/controllers/login.js
index 0905150..6e38169 100644
--- a/apps/passport/controllers/login.js
+++ b/apps/passport/controllers/login.js
@@ -6,7 +6,7 @@
 'use strict';
 
 const _ = require('lodash');
-const Fp = require('lodash/fp');
+const Fn = require('lodash/fp');
 const Promise = require('bluebird');
 const qs = require('querystring');
 
@@ -17,7 +17,7 @@ const helpers = global.yoho.helpers;
 const log = global.yoho.logger;
 const config = global.yoho.config;
 const cache = global.yoho.cache;
-const AuthHelper = require('../models/auth-helper');
+const loginService = require('../models/login-service');
 const PassportHelper = require('../models/passport-helper');
 const simpleHeaderModel = require('../../../doraemon/models/simple-header');
 const loginPage = `${config.siteUrl}/signin.html`;
@@ -40,8 +40,9 @@ function doPassportCallback(req, res, user) {
             user.openId = user.unionId;
         }
 
-        return AuthHelper.signinByOpenID(user.nickname, user.openId, user.sourceType, shoppingKey)
+        return loginService.signinByOpenID(user.nickname, user.openId, user.sourceType, shoppingKey)
             .then((result) => {
+                console.log(result);
                 if (result.code !== 200) {
                     return res.redirect(config.siteUrl);
                 }
@@ -51,8 +52,8 @@ function doPassportCallback(req, res, user) {
                         sourceType: user.sourceType,
                         refer: refer
                     });
-                } else if (result.code === 200 && result.data.uid) {
-                    return AuthHelper.syncUserSession(result.data.uid, req, res).then(() => {
+                } else if (result.data['is_bind'] === 'Y' && result.data.uid) {//eslint-disable-line
+                    return loginService.syncUserSession(result.data.uid, req, res, result.data.session_key).then(() => {
                         return refer;
                     });
                 }
@@ -70,7 +71,7 @@ const common = {
         let refer = req.query.refer || req.get('Referer');
 
         refer && res.cookie('refer', encodeURI(refer), {
-            domain: '.yohobuy.com'
+            domain: config.cookieDomain
         });
         next();
     },
@@ -86,10 +87,10 @@ const common = {
                 if (!isNaN(errloginTimes) && errloginTimes >= 3) {
                     result.data = {needCaptcha: true};
                 }
-                res.json(result);
+                return res.json(result);
             }).catch(next);
         } else {
-            res.json(result);
+            return res.json(result);
         }
     }
 };
@@ -98,12 +99,14 @@ const local = {
     loginPage: (req, res) => {
         // 清除cookie
         res.clearCookie('_UID', {
-            domain: 'yohobuy.com'
+            domain: config.cookieDomain
         });
         res.clearCookie('_TOKEN', {
-            domain: 'yohobuy.com'
+            domain: config.cookieDomain
         });
 
+        req.session = null;
+
         let bindMobile = _.trim(req.query.bindMobile || '');
         let bindArea = '+' + _.trim(req.query.bindArea || '86');
         let areaArr = PassportHelper.getCountry();
@@ -148,52 +151,52 @@ const local = {
     login: (req, res, next) => {
         passport.authenticate('local', (err, user) => {
             if (err) {
-                res.json({
+                return res.json({
                     code: 400,
                     message: err.message,
                     data: {
                         needCaptcha: err.needCaptcha
                     }
                 });
-            } else {
-                if (_.get(req, 'body.isRemember', false)) {
-                    AuthHelper.rememberAccount({
-                        area: req.body.areaCode || '86',
-                        account: req.body.account,
-                        password: req.body.password
-                    }, req, res);
+            }
+
+            if (_.get(req.body, 'isRemember', 'false') === 'true') {
+                loginService.rememberAccount({
+                    area: req.body.areaCode || '86',
+                    account: req.body.account,
+                    password: req.body.password
+                }, req, res);
+            }
+
+            let refer = (function() {
+                if (/sign|login|reg|passport/.test(_.get(req.cookies, 'refer', ''))) {
+                    return `${config.siteUrl}/home`;
+                } else if (_.get(req.cookies, 'refer')) {
+                    return decodeURI(req.cookies.refer);
+                } else {
+                    return `${config.siteUrl}/home`;
                 }
+            }());
 
-                let refer = (function() {
-                    if (/sign|login|reg|passport/.test(_.get(req, 'cookies.refer', ''))) {
-                        return `${config.siteUrl}/home`;
-                    } else if (_.get(req, 'cookies.refer')) {
-                        return decodeURI(req.cookies.refer);
-                    } else {
-                        return `${config.siteUrl}/home`;
+            loginService.syncUserSession(user.uid, req, res, user.session_key).then(() => {
+                return res.json({
+                    code: 200,
+                    data: {
+                        session: refer,
+                        href: refer
                     }
-                }());
-
-                AuthHelper.syncUserSession(user.uid, req, res).then(() => {
-                    res.json({
-                        code: 200,
-                        data: {
-                            session: refer,
-                            href: refer
-                        }
-                    });
                 });
-            }
+            });
         })(req, res, next);
     },
     logout: (req, res) => {
         req.session = null;
 
         res.clearCookie('_UID', {
-            domain: 'yohobuy.com'
+            domain: config.cookieDomain
         });
-        res.clearCookie('_TOKEN', {
-            domain: 'yohobuy.com'
+        res.clearCookie('TOKEN_', {
+            domain: config.cookieDomain
         });
         res.clearCookie('_SPK');
         res.clearCookie('_g');
@@ -201,7 +204,7 @@ const local = {
         res.clearCookie('remem');
         let refer = req.get('Referer') || config.siteUrl;
 
-        res.redirect(refer);
+        return res.redirect(refer);
     },
     sms: {
         send: (req, res, next) => {
@@ -215,7 +218,7 @@ const local = {
                 });
             }
 
-            AuthHelper.sendPasswordBySMS(area, mobile).then((result) => {
+            loginService.sendPasswordBySMS(area, mobile).then((result) => {
                 return res.json(result);
             }).catch(next);
         },
@@ -231,7 +234,7 @@ const local = {
                 });
             }
 
-            AuthHelper.verifyPasswordBySMS(area, mobile, code).then((result) => {
+            loginService.verifyPasswordBySMS(area, mobile, code).then((result) => {
                 if (_.get(result, 'code', 200) !== 200) {
                     return Promise.reject('error');
                 }
@@ -261,18 +264,18 @@ const local = {
                 });
             }
 
-            AuthHelper.checkUserExitBySMS(area, mobile).then((result) => {
+            loginService.checkUserExitBySMS(area, mobile).then((result) => {
                 if (_.get(result, 'code') !== 200) {
                     return Promise.reject('check user by sms error');
                 }
 
                 if (_.get(result, 'data.is_register', 'N') === 'Y') {
-                    res.json({
+                    return res.json({
                         code: 200,
                         message: '用户已注册'
                     });
                 } else {
-                    res.json({
+                    return res.json({
                         code: 402,
                         message: '手机号尚未注册,请核对后重新输入或<a href="/reg.html?' +
                         qs.stringify({mobile: mobile, area: (area ? '+' + area : '+86') || '+86'}) +
@@ -284,7 +287,7 @@ const local = {
     },
     qrcode: {
         refresh: (req, res, next) => {
-            AuthHelper.fetchByQrCode().then((result) => {
+            loginService.fetchByQrCode().then((result) => {
                 if (result.code === 200) {
                     return res.json({
                         code: 200,
@@ -319,7 +322,7 @@ const local = {
 
             let token = qrcode.substring(qrcode.indexOf('=') + 1);
 
-            AuthHelper.checkByQrCode(token).then((result) => {
+            loginService.checkByQrCode(token).then((result) => {
                 if (_.isEmpty(result)) {
                     return res.json({
                         code: 400,
@@ -366,7 +369,6 @@ const local = {
 
 const wechat = {
     login: (req, res, next) => {
-        req.session = req.session || {};
         req.session.authState = uuid.v4();
         return passport.authenticate('wechat', {
             state: req.session.authState
@@ -389,14 +391,13 @@ const wechat = {
                 }
             })(req, res, next);
         } else {
-            return next(new Error('Auth State Mismatch'));
+            return next(new Error('Wechat Auth State Mismatch'));
         }
     }
 };
 
 const sina = {
     login: (req, res, next) => {
-        req.session = req.session || {};
         req.session.authState = uuid.v4();
         return passport.authenticate('sina', {
             state: req.session.authState
@@ -419,15 +420,13 @@ const sina = {
                 }).catch(next);
             })(req, res, next);
         } else {
-            return next(new Error('Auth State Mismatch'));
+            return next(new Error('Sina Auth State Mismatch'));
         }
     }
 };
 
 const qq = {
     login: (req, res, next) => {
-        req.session = req.session || {};
-
         let type = req.query.type || 'yohobuy';
         let authState = req.session.authState = (req.query.state || uuid.v4()) + '::' + type;
 
@@ -436,8 +435,8 @@ const qq = {
         })(req, res, next);
     },
     callback: (req, res, next) => {
-        let auth = Fp.compose(Fp.head, Fp.split('::'))(req.query.state);
-        let type = Fp.compose(Fp.nth(1), Fp.split('::'))(req.query.state);
+        let auth = Fn.compose(Fn.head, Fn.split('::'))(req.query.state);
+        let type = Fn.compose(Fn.nth(1), Fn.split('::'))(req.query.state);
 
         if (req.session && req.session.authState && req.session.authState === req.query.state) {
             passport.authenticate('qq', (err, user) => {
@@ -460,7 +459,7 @@ const qq = {
                 }
             })(req, res, next);
         } else {
-            return next(new Error('Auth State Mismatch'));
+            return next(new Error('QQ Auth State Mismatch'));
         }
     }
 };
@@ -489,7 +488,6 @@ const alipay = {
 
 const douban = {
     login: (req, res, next) => {
-        req.session = req.session || {};
         req.session.authState = uuid.v4();
         return passport.authenticate('douban', {
             state: req.session.authState
@@ -516,7 +514,6 @@ const douban = {
 
 const renren = {
     login: (req, res, next) => {
-        req.session = req.session || {};
         req.session.authState = uuid.v4();
         return passport.authenticate('renren', {
             state: req.session.authState
diff --git a/apps/passport/controllers/reg.js b/apps/passport/controllers/reg.js
index 92dbef3..dc2f8e5 100644
--- a/apps/passport/controllers/reg.js
+++ b/apps/passport/controllers/reg.js
@@ -7,7 +7,7 @@ const Promise = require('bluebird');
 const passportHelper = require('../models/passport-helper');
 const regService = require('../models/reg-service');
 const userService = require('../models/user-service');
-const authHelper = require('../models/auth-helper');
+const loginService = require('../models/login-service');
 const config = require('../../../config/common');
 const simpleHeaderModel = require('../../../doraemon/models/simple-header');
 let helpers = global.yoho.helpers;
@@ -33,10 +33,10 @@ let checkCode = (req, res, next) => {
  * 检查手机格式
  */
 let checkMobileMiddleware = (req, res, next) => {
-    let mobile = +req.body.mobile;
-    let area = +req.body.area;
+    let mobile = req.body.mobile;
+    let area = req.body.area;
 
-    if (!_.isNumber(mobile) || !_.isNumber(area)) {
+    if (!(_.toNumber(mobile) && _.toNumber(area))) {
         return res.json({
             code: 400,
             message: '手机号码格式不正确'
@@ -66,7 +66,7 @@ let checkPassword = (req, res, next) => {
  */
 let index = (req, res, next) => {
     // 设置注册有效时间30分钟, 防机器刷
-    req.session._REG_EXPIRE = Date.now() + 1800000;
+    req.session.REG_EXPIRE_ = Date.now() + 1800000;
 
     let refer = req.query.refer;
     let mobile = req.query.mobile;
@@ -106,11 +106,11 @@ let checkMobile = (req, res, next) => {
     let data = {
         code: 400
     };
-    let mobile = +req.body.mobile;
-    let area = +req.body.area;
+    let mobile = req.body.mobile;
+    let area = req.body.area || '86';
 
     // 判断手机号是否检查超过指定次数
-    let regCheckKey = 'regCheckMobileNum_' + passportHelper.makeAreaMobile(area, mobile);
+    let regCheckKey = `regCheckMobileNum_${area}-${mobile}`;
 
     cache.get(regCheckKey).then((checkNum) => {
         checkNum = +(checkNum || 0);
@@ -168,8 +168,8 @@ let sendBindMsg = (req, res, next) => {
             data: ''
         };
 
-        let mobile = +req.body.mobile;
-        let area = +req.body.area;
+        let mobile = req.body.mobile;
+        let area = req.body.area;
 
         // 校验是否发送过多
         let sendCodeKey = `send_code_${area}_${mobile}`;
@@ -204,9 +204,9 @@ let msgCaptcha = (req, res, next) => {
         message: '',
         data: ''
     };
-    let area = +req.body.area;
-    let mobile = +req.body.mobile;
-    let code = +req.body.code; // 短信验证码
+    let area = req.body.area;
+    let mobile = req.body.mobile;
+    let code = req.body.code; // 短信验证码
 
     regService.validMobileCode(area, mobile, code).then((result) => {
         if (result.code) {
@@ -230,7 +230,7 @@ let mobileRegister = (req, res, next) => {
         };
 
         /* 判断是否是有效的注册方式,防注册机刷 */
-        let regExpireTime = req.session._REG_EXPIRE;
+        let regExpireTime = req.session.REG_EXPIRE_;
 
         if (!regExpireTime || regExpireTime < Date.now()) {
             data.message = '注册超时';
@@ -254,9 +254,9 @@ let mobileRegister = (req, res, next) => {
 
         yield cache.set(ipKey, ipTimes + 1, 3600);
 
-        let area = +req.body.area;
-        let mobile = +req.body.mobile;
-        let code = +req.body.code; // 短信验证码
+        let area = req.body.area;
+        let mobile = req.body.mobile;
+        let code = req.body.code; // 短信验证码
         let password = req.body.password;
         let result = yield regService.validMobileCode(area, mobile, code); // 验证注册的标识码是否有效
 
@@ -273,7 +273,7 @@ let mobileRegister = (req, res, next) => {
             return res.json(data);
         }
 
-        return authHelper.syncUserSession(regResult.data.uid, req, res).then(() => {
+        return loginService.syncUserSession(regResult.data.uid, req, res).then(() => {
             return res.json({
                 code: 200,
                 message: '注册成功',
diff --git a/apps/passport/index.js b/apps/passport/index.js
index 3d6258a..0172f45 100644
--- a/apps/passport/index.js
+++ b/apps/passport/index.js
@@ -5,8 +5,7 @@
  */
 'use strict';
 var express = require('express'),
-    path = require('path'),
-    hbs = require('express-handlebars');
+    path = require('path');
 
 var passport = require('passport');
 
@@ -20,12 +19,12 @@ app.on('mount', function(parent) {
     Object.assign(app.locals, parent.locals);
 });
 
-app.set('views', path.join(__dirname, 'views/action'));
-app.engine('.hbs', hbs({
+app.use(global.yoho.hbs({
     extname: '.hbs',
     defaultLayout: 'layout',
     layoutsDir: doraemon,
-    partialsDir: [path.join(__dirname, 'views/partial'), `${doraemon}/partial`],
+    partialsDir: [path.join(__dirname, 'views/partial')],
+    views: path.join(__dirname, 'views/action'),
     helpers: global.yoho.helpers
 }));
 
diff --git a/apps/passport/models/back-service.js b/apps/passport/models/back-service.js
index e23a7b3..0f04cac 100644
--- a/apps/passport/models/back-service.js
+++ b/apps/passport/models/back-service.js
@@ -24,13 +24,13 @@ const validateEmailOrMobileAsync = (userInput, areaCode) => {
     return new Promise(function(resolve, rejected) {
         let result = {type: 'email', area: '', phone: ''};
 
-        if (passportHelper.validator.verifyEmail(userInput)) {
+        if (passportHelper.validator.isEmail(userInput)) {
             result.type = 'email';
             result.area = '';
             result.phone = userInput;
 
             resolve(result);
-        } else if (passportHelper.validator.isAreaMobile(passportHelper.makeAreaMobile(areaCode, userInput))) {
+        } else if (passportHelper.validator.isMobile(userInput)) {
             result.type = 'mobile';
             result.area = areaCode;
             result.phone = userInput;
@@ -57,7 +57,7 @@ const findUserAsync = (type, phone, area) => {
 
         const findBy = {
             email: userService.findByEmailAsync,
-            mobile: (phone1, area1) => userService.findByMobileAsync(area1, phone1) // 交换参数
+            mobile: _.rearg(userService.findByMobileAsync, [1, 0]) // 交换参数
         };
 
         const OK = {code: 200, message: MESSAGE.ok};
diff --git a/apps/passport/models/bind-api.js b/apps/passport/models/bind-api.js
new file mode 100644
index 0000000..c6623af
--- /dev/null
+++ b/apps/passport/models/bind-api.js
@@ -0,0 +1,99 @@
+/**
+ * 注册数据接口
+ *
+ * @author JiangFeng<jeff.jiang@yoho.cn>
+ * @date 2016/06/21
+ */
+
+'use strict';
+
+const api = global.yoho.API;
+
+const bindCheck = (mobile, openId, sourceType, area) => {
+    let params = {
+        method: 'app.passport.signCheck',
+        area: area,
+        mobile: mobile,
+        open_id: openId,
+        source_type: sourceType
+    };
+
+    return api.get('', params);
+};
+
+const sendBindMsg = (area, mobile) => {
+    let params = {
+        method: 'app.passport.smsbind',
+        mobile: mobile,
+        area: area
+    };
+
+    return api.get('', params);
+};
+
+const checkBindCode = (area, mobile, code) => {
+    return api.get('', {
+        method: 'app.register.validRegCode',
+        mobile: mobile,
+        area: area,
+        code: code
+    });
+};
+
+const bindMobile = (openId, sourceType, mobile, area, password, nickname) => {
+    let params = {
+        method: 'app.passport.bind',
+        mobile: mobile,
+        open_id: openId,
+        source_type: sourceType,
+        area: area
+    };
+
+    if (password) {
+        params.password = password;
+    }
+
+    if (nickname) {
+        params.nickname = nickname;
+    }
+
+    return api.get('', params);
+};
+
+const relateMobile = (openId, sourceType, mobile, area) => {
+    return api.get('', {
+        method: 'app.passport.relatedMobile',
+        mobile: mobile,
+        openId: openId,
+        source_type: sourceType,
+        area: area
+    });
+};
+
+const changeCheck = (mobile, area) => {
+    return api.get('', {
+        method: 'app.passport.changeCheck',
+        mobile: mobile,
+        area: area
+    });
+};
+
+const changeMobile = (uid, mobile, area, code) => {
+    return api.get('', {
+        method: 'app.passport.changeMobile',
+        mobile: mobile,
+        uid: uid,
+        code: code,
+        area: area
+    });
+};
+
+module.exports = {
+    bindCheck,
+    sendBindMsg,
+    checkBindCode,
+    bindMobile,
+    relateMobile,
+    changeCheck,
+    changeMobile
+};
diff --git a/apps/passport/models/bind-service.js b/apps/passport/models/bind-service.js
index 73eee51..ae61f4c 100644
--- a/apps/passport/models/bind-service.js
+++ b/apps/passport/models/bind-service.js
@@ -7,81 +7,6 @@
 
 'use strict';
 
-const api = global.yoho.API;
+const api = require('./bind-api');
 
-const BindService = {
-    bindCheck(mobile, openId, sourceType, area) {
-        let params = {
-            method: 'app.passport.signCheck',
-            area: area,
-            mobile: mobile,
-            open_id: openId,
-            source_type: sourceType
-        };
-
-        return api.get('', params);
-    },
-    sendBindMsg(area, mobile) {
-        let params = {
-            method: 'app.passport.smsbind',
-            mobile: mobile,
-            area: area
-        };
-
-        return api.get('', params);
-    },
-    checkBindCode(area, mobile, code) {
-        return api.get('', {
-            method: 'app.register.validRegCode',
-            mobile: mobile,
-            area: area,
-            code: code
-        });
-    },
-    bindMobile(openId, sourceType, mobile, area, password, nickname) {
-        let params = {
-            method: 'app.passport.bind',
-            mobile: mobile,
-            open_id: openId,
-            source_type: sourceType,
-            area: area
-        };
-
-        if (password) {
-            params.password = password;
-        }
-
-        if (nickname) {
-            params.nickname = nickname;
-        }
-
-        return api.get('', params);
-    },
-    relateMobile(openId, sourceType, mobile, area) {
-        return api.get('', {
-            method: 'app.passport.relatedMobile',
-            mobile: mobile,
-            openId: openId,
-            source_type: sourceType,
-            area: area
-        });
-    },
-    changeCheck(mobile, area) {
-        return api.get('', {
-            method: 'app.passport.changeCheck',
-            mobile: mobile,
-            area: area
-        });
-    },
-    changeMobile(uid, mobile, area, code) {
-        return api.get('', {
-            method: 'app.passport.changeMobile',
-            mobile: mobile,
-            uid: uid,
-            code: code,
-            area: area
-        });
-    }
-};
-
-module.exports = BindService;
+module.exports = api;
diff --git a/apps/passport/models/index-api.js b/apps/passport/models/index-api.js
index ccb90ca..bf99462 100644
--- a/apps/passport/models/index-api.js
+++ b/apps/passport/models/index-api.js
@@ -6,13 +6,15 @@
 
 const serviceAPI = global.yoho.ServiceAPI;
 
+const config = global.yoho.config;
+
 /**
  * 资源码找资源
  */
 const getResourceAsync = resourceCode => {
     return serviceAPI.get('/operations/api/v5/resource/get', {
         content_code: resourceCode
-    });
+    }, config.apiCache);
 };
 
 module.exports = {
diff --git a/apps/passport/models/auth-helper.js b/apps/passport/models/login-api.js
index 923807f..05f1da2 100644
--- a/apps/passport/models/auth-helper.js
+++ b/apps/passport/models/login-api.js
@@ -1,193 +1,124 @@
-'use strict';
+/**
+ * Created by TaoHuang on 2016/10/21.
+ */
 
-const md5 = require('md5');
+'use strict';
 
 const aes = require('./aes-pwd');
-const cache = global.yoho.cache;
-const sign = global.yoho.sign;
 const api = global.yoho.API;
-const cookie = global.yoho.cookie;
-
-const Promise = require('bluebird');
-
-const cartService = require('./cart-service');
-
-const Auth = {
-    signin(type, area, profile, password, shoppingKey) {
-        let _that = this;
-        let loginBy = {
-            password: _that.signinByPasswordWithAes,
-            sms: _that.signinBySMS,
-            qrcode: _that.signinByQrCode
-        };
-
-        return loginBy[type](area, profile, password, shoppingKey);
-    },
-    signinByPasswordWithAes(area, profile, password, shoppingKey) {
-        let param = {
-            method: 'app.passport.signinAES',
-            area: area,
-            profile: profile,
-            password: aes.aesPwd(password)
-        };
-
-        if (shoppingKey) {
-            param.shopping_key = shoppingKey;
-        }
-
-        return api.post('', param);
-    },
-    signinBySMS(area, mobile, token, shoppingKey) {
-        let param = {
-            method: 'app.passport.autoSignin',
-            area: area,
-            profile: mobile,
-            code: token
-        };
-
-        if (shoppingKey) {
-            param.shopping_key = shoppingKey;
-        }
-
-        return api.post('', param);
-    },
-    signinByQrCode(__1, __2, code, shoppingKey) { // eslint-disable-line
-        let param = {
-            method: 'app.twoDimen.qrCodeLogin',
-            code: code.substring(code.indexOf('=') + 1)
-        };
-
-        if (shoppingKey) {
-            param.shopping_key = shoppingKey;
-        }
-
-        return api.post('', param);
-    },
-    fetchByQrCode() {
-        let param = {
-            method: 'app.twoDimen.getCode'
-        };
-
-        return api.post('', param);
-    },
-    checkByQrCode(code) {
-        let param = {
-            method: 'app.twoDimen.loginCheck',
-            code: code
-        };
-
-        return api.post('', param);
-    },
-    sendPasswordBySMS(area, mobile) {
-        let param = {
-            method: 'app.message.sendSms',
-            area: area,
-            mobile: mobile,
-            type: 1 // 手机快捷登录短信验证码
-        };
-
-        return api.get('', param);
-    },
-    checkUserExitBySMS(area, mobile) {
-        return api.get('', {
-            method: 'app.passport.checkUserExist',
-            area: area,
-            mobile: mobile
-        });
-    },
-    verifyPasswordBySMS(area, mobile, code) {
-        return api.get('', {
-            method: 'app.message.verifySmsCode',
-            area: area,
-            mobile: mobile,
-            code: code,
-            type: 1 // 手机快捷登录短信验证码
-        });
-    },
-    signinByOpenID(nickname, openId, sourceType, shoppingKey) {
-        let param = {
-            nickname: nickname,
-            openId: openId,
-            source_type: sourceType,
-            method: 'app.passport.signinByOpenID'
-        };
-
-        if (shoppingKey) {
-            param.shopping_key = shoppingKey;
-        }
-
-        return api.get('', param);
-    },
-    signinByWechat(nickname, openId, unionId, sourceType, shoppingKey) {
-        let param = {
-            nickname: nickname,
-            openId: openId,
-            unionId: unionId,
-            source_type: sourceType,
-            method: 'app.passport.signinByWechat'
-        };
-
-        if (shoppingKey) {
-            param.shopping_key = shoppingKey;
-        }
-
-        return api.get('', param);
-    },
-    profile(uid) {
-        let param = {
-            uid: uid,
-            method: 'app.passport.profile'
-        };
-
-        return api.get('', param);
-    },
-    syncUserSession(uid, req, res) {
-        return Promise.all([Auth.profile(uid), cartService.goodsCount(uid)]).spread((userInfo, count) => {
-            let token = sign.makeToken(uid);
-            let data = userInfo.data;
-            let encryptionUid = aes.encryptionUid(data.uid);
-
-            if (data) {
-                let uidCookie = `${data.profile_name}::${encryptionUid}::${data.vip_info.title}::${token}`;
-                let isStudent = data.vip_info.is_student || 0;
-
-                req.session._TOKEN = token;
-                req.session._LOGIN_UID = uid;
-
-                res.cookie('_UID', uidCookie, {
-                    domain: 'yohobuy.com'
-                });
-                res.cookie('isStudent', isStudent, {
-                    domain: 'yohobuy.com'
-                });
-
-                // 购物车中商品的数量
-                res.cookie('_g', JSON.stringify({
-                    _k: cookie.getShoppingKey(req),
-                    _nac: count,
-                    _ac: 0,
-                    _c: 1
-                }), {
-                    domain: 'yohobuy.com'
-                });
-            }
-            req.session._TOKEN = token; // esline-disable-line
-            req.session._LOGIN_UID = uid; // esline-disable-line
-            res.cookie('_TOKEN', token, {
-                domain: 'yohobuy.com'
-            }); // esline-disable-line
-        }).catch(console.log);
-    },
-    rememberAccount(accountInfo, req, res) {
-        let aWeek = (new Date()).getTime() / 1000 + 504000; // 504000-一周
-        let rememKey = md5(md5(accountInfo.account + accountInfo.password + accountInfo.area));
-
-        res.cookie('isRemember', true, aWeek);
-        res.cookie('remem', rememKey, aWeek);
-        if (!cache.get(rememKey)) {
-            cache.set(rememKey, accountInfo, aWeek);
-        }
+
+const signinByPasswordWithAes = (area, profile, password, shoppingKey) => {
+    let param = {
+        method: 'app.passport.signinAES',
+        area: area,
+        profile: profile,
+        password: aes.aesPwd(password)
+    };
+
+    if (shoppingKey) {
+        param.shopping_key = shoppingKey;
+    }
+
+    return api.post('', param);
+};
+
+const signinBySMS = (area, mobile, token, shoppingKey) => {
+    let param = {
+        method: 'app.passport.autoSignin',
+        area: area,
+        profile: mobile,
+        code: token
+    };
+
+    if (shoppingKey) {
+        param.shopping_key = shoppingKey;
+    }
+
+    return api.post('', param);
+};
+
+const signinByQrCode = (__1, __2, code, shoppingKey) => { // eslint-disable-line
+    let param = {
+        method: 'app.twoDimen.qrCodeLogin',
+        code: code.substring(code.indexOf('=') + 1)
+    };
+
+    if (shoppingKey) {
+        param.shopping_key = shoppingKey;
+    }
+
+    return api.post('', param);
+};
+
+const fetchByQrCode = () => {
+    let param = {
+        method: 'app.twoDimen.getCode'
+    };
+
+    return api.post('', param);
+};
+
+const checkByQrCode = (code) => {
+    let param = {
+        method: 'app.twoDimen.loginCheck',
+        code: code
+    };
+
+    return api.post('', param);
+};
+
+const sendPasswordBySMS = (area, mobile) => {
+    let param = {
+        method: 'app.message.sendSms',
+        area: area,
+        mobile: mobile,
+        type: 1 // 手机快捷登录短信验证码
+    };
+
+    return api.get('', param);
+};
+
+const checkUserExitBySMS = (area, mobile) => {
+    return api.get('', {
+        method: 'app.passport.checkUserExist',
+        area: area,
+        mobile: mobile
+    });
+};
+
+const verifyPasswordBySMS = (area, mobile, code) => {
+    return api.get('', {
+        method: 'app.message.verifySmsCode',
+        area: area,
+        mobile: mobile,
+        code: code,
+        type: 1 // 手机快捷登录短信验证码
+    });
+};
+
+const signinByOpenID = (nickname, openId, sourceType, shoppingKey) => {
+    let param = {
+        nickname: nickname,
+        openId: openId,
+        source_type: sourceType,
+        method: 'app.passport.signinByOpenID'
+    };
+
+    if (shoppingKey) {
+        param.shopping_key = shoppingKey;
     }
+
+    return api.get('', param);
 };
 
-module.exports = Auth;
+module.exports = {
+    signinByPasswordWithAes,
+    signinBySMS,
+    signinByQrCode,
+    fetchByQrCode,
+    checkByQrCode,
+    sendPasswordBySMS,
+    checkUserExitBySMS,
+    verifyPasswordBySMS,
+    signinByOpenID
+};
diff --git a/apps/passport/models/login-service.js b/apps/passport/models/login-service.js
new file mode 100644
index 0000000..9e889b7
--- /dev/null
+++ b/apps/passport/models/login-service.js
@@ -0,0 +1,99 @@
+'use strict';
+
+const md5 = require('md5');
+
+const aes = require('./aes-pwd');
+const cache = global.yoho.cache;
+const sign = global.yoho.sign;
+const cookie = global.yoho.cookie;
+const config = global.yoho.config;
+
+const Promise = require('bluebird');
+
+const cartService = require('./cart-service');
+const userService = require('./user-service');
+const api = require('./login-api');
+
+const signin = (type, area, profile, password, shoppingKey) => {
+    let loginBy = {
+        password: api.signinByPasswordWithAes,
+        sms: api.signinBySMS,
+        qrcode: api.signinByQrCode
+    };
+
+    return loginBy[type](area, profile, password, shoppingKey);
+};
+
+const syncUserSession = (uid, req, res, sessionKey) => {
+    if (sessionKey) {
+        cache.set(`java_session_key:${uid}`, sessionKey).catch(() => {
+            global.yoho.logger.error('write session key fail');
+        });
+    }
+
+    return Promise.all([userService.profile(uid), cartService.goodsCount(uid)]).spread((userInfo, count) => {
+        let token = sign.makeToken(uid);
+        let data = userInfo.data;
+        let encryptionUid = aes.encryptionUid(data.uid);
+
+        if (data) {
+            let uidCookie = `${data.profile_name}::${encryptionUid}::${data.vip_info.title}::${token}`;
+            let isStudent = data.vip_info.is_student || 0;
+
+            res.cookie('_UID', uidCookie, {
+                domain: config.cookieDomain
+            });
+            res.cookie('isStudent', isStudent, {
+                domain: config.cookieDomain
+            });
+
+            // 购物车中商品的数量
+            res.cookie('_g', JSON.stringify({
+                _k: cookie.getShoppingKey(req),
+                _nac: count,
+                _ac: 0,
+                _c: 1
+            }), {
+                domain: config.cookieDomain
+            });
+        }
+
+        req.session.TOKEN_ = token;
+        req.session.LOGIN_UID_ = uid;
+
+        res.cookie('_TOKEN', token, {
+            domain: config.cookieDomain
+        });
+
+    }).catch(console.log);
+};
+
+const rememberAccount = (accountInfo, req, res) => {
+    let aWeek = (new Date()).getTime() / 1000 + 504000; // 504000-一周
+    let rememKey = md5(md5(accountInfo.account + accountInfo.password + accountInfo.area));
+
+    res.cookie('isRemember', true, {
+        maxAge: aWeek,
+        domain: config.cookieDomain
+    });
+    res.cookie('remem', rememKey, {
+        maxAge: aWeek,
+        domain: config.cookieDomain
+    });
+
+    // if (!cache.get(rememKey)) {
+    //     cache.set(rememKey, accountInfo, aWeek);
+    // }
+};
+
+module.exports = {
+    signin,
+    syncUserSession,
+    rememberAccount,
+    fetchByQrCode: api.fetchByQrCode,
+    checkByQrCode: api.checkByQrCode,
+    sendPasswordBySMS: api.sendPasswordBySMS,
+    checkUserExitBySMS: api.checkUserExitBySMS,
+    verifyPasswordBySMS: api.verifyPasswordBySMS,
+    signinByOpenID: api.signinByOpenID
+};
diff --git a/apps/passport/models/passport-helper.js b/apps/passport/models/passport-helper.js
index db64da9..64ba154 100644
--- a/apps/passport/models/passport-helper.js
+++ b/apps/passport/models/passport-helper.js
@@ -9,9 +9,6 @@ const _ = require('lodash');
 
 const helpers = global.yoho.helpers;
 const indexService = require('./index-service');
-const UserService = require('./user-service');
-
-const DEFAULT_HEAD_IMG_ICO = 'http://img10.static.yhbimg.com/headimg/2013/11/28/09/01cae078abe5fe320c88cdf4c220212688.gif?imageView/2/w/100/h/100';
 
 /**
  * 获得图片
@@ -109,125 +106,14 @@ const getCountry = () => {
 };
 
 /**
- * 各国手机号规则
- */
-const _areaMobileVerify = (phone, area) => {
-    area = area || '86';
-    phone = phone.trim();
-
-    let verify = {
-        86: {
-            name: '中国',
-            match: /^1[3|4|5|8|7][0-9]{9}$/.test(phone)
-        },
-        852: {
-            name: '中国香港',
-            match: /^[9|6|5][0-9]{7}$/.test(phone)
-        },
-        853: {
-            name: '中国澳门',
-            match: /^[0-9]{8}$/.test(phone)
-        },
-        886: {
-            name: '中国台湾',
-            match: /^[0-9]{10}$/.test(phone)
-        },
-        65: {
-            name: '新加坡',
-            match: /^[9|8][0-9]{7}$/.test(phone)
-        },
-        60: {
-            name: '马来西亚',
-            match: /^1[1|2|3|4|6|7|9][0-9]{8}$/.test(phone)
-        },
-        1: {
-            name: '加拿大&美国',
-            match: /^[0-9]{10}$/.test(phone)
-        },
-        82: {
-            name: '韩国',
-            match: /^01[0-9]{9}$/.test(phone)
-        },
-        44: {
-            name: '英国',
-            match: /^7[7|8|9][0-9]{8}$/.test(phone)
-        },
-        81: {
-            name: '日本',
-            match: /^0[9|8|7][0-9]{9}$/.test(phone)
-        },
-        61: {
-            name: '澳大利亚',
-            match: /^[0-9]{11}$/.test(phone)
-        }
-    };
-
-    if (verify[area]) {
-        return verify[area].match;
-    } else {
-        return false;
-    }
-};
-
-/**
  * 验证国际手机号是否合法
  */
-const isAreaMobile = areaMobile => {
-    if (!areaMobile) {
-        return false;
-    }
-
-    let mobile = {
-        area: '86',
-        phone: ''
-    };
-
-    let splitMobile = areaMobile.split('-');
-
-    if (splitMobile.length === 2) {
-        mobile.area = splitMobile[0];
-        mobile.phone = splitMobile[1];
-    } else {
-        mobile.phone = splitMobile[0];
-    }
-
-    return _areaMobileVerify(mobile.phone, mobile.area);
-};
+const isMobile = _.toNumber;
 
 /**
  * 验证邮箱是否合法
  */
-const verifyEmail = email => {
-    if (!email) {
-        return false;
-    }
-
-    const emailRegExp = /^[\.a-zA-Z0-9_-]+@[a-zA-Z0-9_-]+(\.[a-zA-Z0-9_-]+)+$/;
-
-    return emailRegExp.test(email);
-};
-
-/**
- *  验证手机是否合法
- */
-const verifyMobile = phone => {
-    if (!phone) {
-        return false;
-    }
-
-    return /^1[3|4|5|8|7][0-9]{9}$/.test(phone);
-};
-
-/**
- * 生成带区号的手机号码
- */
-const makeAreaMobile = (area, mobile) => {
-    if (!area || area === '86') {
-        return mobile;
-    }
-
-    return `${area}-${mobile}`;
-};
+const isEmail = email => _.includes(email, '@');
 
 /**
  * 密码是否合法
@@ -242,35 +128,13 @@ const isPassword = pwd => {
     return pwdRegexp.test(_.trim(pwd));
 };
 
-/**
- * 第三方登录 根据手机号获取用户相关信息
- */
-const getUserInfo = (area, mobile) => {
-    return UserService.findByMobileAsync(area, mobile).then(user => {
-        let profile = (user.profile_name || mobile).toString();
-
-        if ((profile.length === 11 && profile.indexOf('*') < 0) || (profile.indexOf('-') >= 0 &&
-            profile.indexOf('*') < 0)) {
-            profile = profile.substring(0, 3) + '****' + profile.substring(7, 11);
-        }
-
-        return {
-            username: profile,
-            headImg: user.head_ico ? helpers.image(user.head_ico, 100, 100, 2) : DEFAULT_HEAD_IMG_ICO,
-            bindLogin: helpers.urlFormat('/signin.html', { bindMobile: mobile, bindArea: area })
-        };
-    });
-};
 
 module.exports = {
     validator: {
-        verifyMobile,
-        isAreaMobile,
-        verifyEmail,
+        isMobile,
+        isEmail,
         isPassword
     },
-    makeAreaMobile,
     getCountry,
-    getLeftBannerAsync,
-    getUserInfo
+    getLeftBannerAsync
 };
diff --git a/apps/passport/models/reg-api.js b/apps/passport/models/reg-api.js
new file mode 100644
index 0000000..3013e9d
--- /dev/null
+++ b/apps/passport/models/reg-api.js
@@ -0,0 +1,68 @@
+/**
+ * Created by TaoHuang on 2016/10/21.
+ */
+
+/**
+ * 注册 model
+ */
+'use strict';
+const aes = require('./aes-pwd');
+const api = global.yoho.API;
+
+let sendCodeToMobile = (area, mobile) => {
+    let params = {
+        method: 'app.register.sendRegCodeToMobile',
+        area: area,
+        mobile: mobile
+    };
+
+    return api.post('', params);
+};
+
+let validMobileCode = (area, mobile, code) => {
+    let params = {
+        method: 'app.register.validRegCode',
+        area: area,
+        mobile: mobile,
+        code: code
+    };
+
+    return api.post('', params);
+};
+
+let regMobile = (area, mobile, password, shoppingKey)=> {
+    let params = {
+        method: 'app.passport.register',
+        area: area,
+        profile: mobile,
+        password: password
+    };
+
+    if (shoppingKey) {
+        params.shopping_key = shoppingKey;
+    }
+
+    return api.post('', params);
+};
+
+let regMobileAes = (area, mobile, password, shoppingKey)=> {
+    let params = {
+        method: 'app.passport.registerAES',
+        area: area,
+        profile: mobile,
+        password: aes.aesPwd(password)
+    };
+
+    if (shoppingKey) {
+        params.shopping_key = shoppingKey;
+    }
+
+    return api.post('', params);
+};
+
+module.exports = {
+    sendCodeToMobile,
+    validMobileCode,
+    regMobile,
+    regMobileAes
+};
diff --git a/apps/passport/models/reg-service.js b/apps/passport/models/reg-service.js
index 2f0bf70..bb36eba 100644
--- a/apps/passport/models/reg-service.js
+++ b/apps/passport/models/reg-service.js
@@ -3,69 +3,14 @@
  */
 'use strict';
 const passportHelper = require('./passport-helper');
-const aes = require('./aes-pwd');
+const api = require('./reg-api');
+
 const REGISTER_LEFT_BANNER_CODE = 'c479ec90120cae7f96e52922b4917064'; // 注册左边的banner
-const api = global.yoho.API;
 
 let getRegData = () => {
     return passportHelper.getLeftBannerAsync(REGISTER_LEFT_BANNER_CODE);
 };
 
-let sendCodeToMobile = (area, mobile) => {
-    let params = {
-        method: 'app.register.sendRegCodeToMobile',
-        area: area,
-        mobile: mobile
-    };
-
-    return api.post('', params);
-};
-
-let validMobileCode = (area, mobile, code) => {
-    let params = {
-        method: 'app.register.validRegCode',
-        area: area,
-        mobile: mobile,
-        code: code
-    };
-
-    return api.post('', params);
-};
-
-let regMobile = (area, mobile, password, shoppingKey)=> {
-    let params = {
-        method: 'app.passport.register',
-        area: area,
-        profile: mobile,
-        password: password
-    };
-
-    if (shoppingKey) {
-        params.shopping_key = shoppingKey;
-    }
-
-    return api.post('', params);
-};
-
-let regMobileAes = (area, mobile, password, shoppingKey)=> {
-    let params = {
-        method: 'app.passport.registerAES',
-        area: area,
-        profile: mobile,
-        password: aes.aesPwd(password)
-    };
-
-    if (shoppingKey) {
-        params.shopping_key = shoppingKey;
-    }
-
-    return api.post('', params);
-};
-
-module.exports = {
-    getRegData,
-    sendCodeToMobile,
-    validMobileCode,
-    regMobile,
-    regMobileAes
-};
+module.exports = Object.assign(api, {
+    getRegData
+});
diff --git a/apps/passport/models/user-api.js b/apps/passport/models/user-api.js
index fb1df1a..8d9f456 100644
--- a/apps/passport/models/user-api.js
+++ b/apps/passport/models/user-api.js
@@ -34,21 +34,30 @@ const findByEmailAsync = (email) => {
     return api.get('', {
         email: email,
         method: 'app.passport.getProfileByEmail'
-    })
-        .then(result => {
-            if (!result.code || result.code !== 200 || !result.data || _.isEmpty(result.data)) {
-                return EMPTY;
-            }
+    }).then(result => {
+        if (!result.code || result.code !== 200 || !result.data || _.isEmpty(result.data)) {
+            return EMPTY;
+        }
 
-            return result.data;
+        return result.data;
 
-        })
-        .catch(() => {
-            return EMPTY;
-        });
+    }).catch(() => {
+        return EMPTY;
+    });
+};
+
+const profile = (uid) => {
+    let param = {
+        uid: uid,
+        method: 'app.passport.profile'
+    };
+
+    return api.get('', param);
 };
 
+
 module.exports = {
     findByMobileAsync,
-    findByEmailAsync
+    findByEmailAsync,
+    profile
 };
diff --git a/apps/passport/models/user-service.js b/apps/passport/models/user-service.js
index f6ec65f..0bbf0fc 100644
--- a/apps/passport/models/user-service.js
+++ b/apps/passport/models/user-service.js
@@ -5,4 +5,30 @@
 
 const api = require('./user-api');
 
-module.exports = api;
+const helpers = global.yoho.helpers;
+
+const DEFAULT_HEAD_IMG_ICO = 'http://img10.static.yhbimg.com/headimg/2013/11/28/09/01cae078abe5fe320c88cdf4c220212688.gif?imageView/2/w/100/h/100';
+
+/**
+ * 第三方登录 根据手机号获取用户相关信息
+ */
+const getUserInfo = (area, mobile) => {
+    return api.findByMobileAsync(area, mobile).then(user => {
+        let profile = (user.profile_name || mobile).toString();
+
+        if ((profile.length === 11 && profile.indexOf('*') < 0) || (profile.indexOf('-') >= 0 &&
+            profile.indexOf('*') < 0)) {
+            profile = profile.substring(0, 3) + '****' + profile.substring(7, 11);
+        }
+
+        return {
+            username: profile,
+            headImg: user.head_ico ? helpers.image(user.head_ico, 100, 100, 2) : DEFAULT_HEAD_IMG_ICO,
+            bindLogin: helpers.urlFormat('/signin.html', {bindMobile: mobile, bindArea: area})
+        };
+    });
+};
+
+module.exports = Object.assign(api, {
+    getUserInfo
+});
diff --git a/apps/passport/views/action/login/index.hbs b/apps/passport/views/action/login/index.hbs
index 0e1b0c7..a8eb139 100644
--- a/apps/passport/views/action/login/index.hbs
+++ b/apps/passport/views/action/login/index.hbs
@@ -92,7 +92,7 @@
                             <span id="login-btn" class="login-btn btn">登录</span>
                         </li>
                         <li class="other-opts">
-                    <span class="remember-me">
+                    <span class="remember-me checked">
                         <i class="iconfont">&#xe613;</i>
                         记住登录状态
                     </span>
diff --git a/apps/product/controllers/list.js b/apps/product/controllers/list.js
index 4054cfc..3e75ee1 100644
--- a/apps/product/controllers/list.js
+++ b/apps/product/controllers/list.js
@@ -7,6 +7,7 @@
 const mRoot = '../models';
 const list = require(`${mRoot}/list`);
 const helpers = global.yoho.helpers;
+const _ = require('lodash');
 
 // 搜索相关接口
 const searchApi = require(`${mRoot}/search-api`);
@@ -32,12 +33,22 @@ const shop = (shopId, req, res, next, brandInfo) => {
                     page: 'shop',
                     shopId: shopId
                 });
+
+                // 店铺装修为空则不cache
+                if (!result.shopTopBanner) {
+                    res.set('Cache-Control', 'no-cache');
+                }
                 res.render('list/shop-index', result);
             }).catch(next);
         } else { // 基础模板
             list.getBaseShopData(req.query, Object.assign({uid: req.user.uid}, brandInfo),
                 req.yoho.channel, shopId).then(result => {
                     Object.assign(result, {page: 'list'});
+
+                    // 基础店铺装修为空则不cache
+                    if (!result.shopTopBannerBase) {
+                        res.set('Cache-Control', 'no-cache');
+                    }
                     res.render('list/brand', result);
                 }).catch(next);
         }
@@ -55,6 +66,11 @@ exports.index = (req, res, next) => {
 
     list.getListData(req.query, req.yoho.channel).then(result => {
         Object.assign(resData, result);
+
+        // 查询结果为空则不cache
+        if (_.isEmpty(_.get(resData, 'list.goods', []))) {
+            res.set('Cache-Control', 'no-cache');
+        }
         res.render('list/index', resData);
     }).catch(next);
 
@@ -73,6 +89,12 @@ exports.new = (req, res, next) => {
         Object.assign(resData, result, {
             hideInfo: {from: 'newProduct'}
         });
+
+        // 查询结果为空则不cache
+        if (_.isEmpty(_.get(resData, 'list.goods', []))) {
+            res.set('Cache-Control', 'no-cache');
+        }
+
         res.render('list/index', resData);
     }).catch(next);
 
@@ -168,6 +190,11 @@ exports.shopList = (req, res, next) => {
         if (req.query.query) {
             result.shopKey = req.query.query;
         }
+
+        // 店铺装修为空则不cache
+        if (!result.shopTopBanner) {
+            res.set('Cache-Control', 'no-cache');
+        }
         res.render('list/shop-list', result);
     }).catch(next);
 };
diff --git a/apps/product/index.js b/apps/product/index.js
index 2f3d33f..e26e9a3 100644
--- a/apps/product/index.js
+++ b/apps/product/index.js
@@ -5,8 +5,7 @@
  */
 
 var express = require('express'),
-    path = require('path'),
-    hbs = require('express-handlebars');
+    path = require('path');
 
 var app = express();
 
@@ -18,12 +17,12 @@ app.on('mount', function(parent) {
     Object.assign(app.locals, parent.locals);
 });
 
-app.set('views', path.join(__dirname, 'views/action'));
-app.engine('.hbs', hbs({
+app.use(global.yoho.hbs({
     extname: '.hbs',
     defaultLayout: 'layout',
     layoutsDir: doraemon,
-    partialsDir: [path.join(__dirname, 'views/partial'), `${doraemon}/partial`],
+    partialsDir: [path.join(__dirname, 'views/partial')],
+    views: path.join(__dirname, 'views/action'),
     helpers: global.yoho.helpers
 }));
 
diff --git a/apps/product/models/brand-api.js b/apps/product/models/brand-api.js
index 2c3152e..9fff972 100644
--- a/apps/product/models/brand-api.js
+++ b/apps/product/models/brand-api.js
@@ -5,12 +5,13 @@
 '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);
 
 };
 
@@ -18,7 +19,7 @@ const getBrandLogoByDomainAsync = domain => {
     return api.get('', {
         domain: domain,
         method: 'web.brand.byDomain'
-    });
+    }, config.apiCache);
 };
 
 module.exports = {
diff --git a/apps/product/models/detail-comment-api.js b/apps/product/models/detail-comment-api.js
index ee391eb..ca06a43 100644
--- a/apps/product/models/detail-comment-api.js
+++ b/apps/product/models/detail-comment-api.js
@@ -7,18 +7,6 @@
 const api = global.yoho.API;
 
 /**
- * 获取评论
- */
-const indexAsync = (pid, page, size) => {
-    return api.get('', {
-        method: 'app.comment.li',
-        product_id: pid,
-        page: page,
-        limit: size
-    });
-};
-
-/**
  * 商品详情页的评论列表
  *
  * @param pid 商品productId
@@ -39,7 +27,6 @@ const getShareOrderListAsync = (pid, page, size) => {
 };
 
 module.exports = {
-    indexAsync,
     getShareOrderListAsync
 };
 
diff --git a/apps/product/models/detail-comment-service.js b/apps/product/models/detail-comment-service.js
index 09df24a..33790d8 100644
--- a/apps/product/models/detail-comment-service.js
+++ b/apps/product/models/detail-comment-service.js
@@ -4,45 +4,7 @@
 
 'use strict';
 
-const Promise = require('bluebird');
-const co = Promise.coroutine;
-const _ = require('lodash');
-const helpers = global.yoho.helpers;
 const api = require('./detail-comment-api');
-const detailHelper = require('./detail-helper');
-
-
-const indexAsync = (pid, page, size) => {
-    return co(function *() {
-        let commentList = yield api.indexAsync(pid, page, size);
-
-        if (!(commentList.code && commentList.code === 200)) {
-            return [];
-        }
-
-        return commentList.data.map(value => {
-            let item = {};
-
-            let avatar = detailHelper.DEFAULT_AVATAR_ICO;
-
-            if (value.head_ico) {
-                avatar = `${_.last(value.head_ico.split('headimg'))}`;
-                avatar = helpers.image(avatar, 30, 30);
-            }
-
-            item.avatar = avatar;
-            item.userName = value.nickname;
-            item.color = value.color_name;
-            item.size = value.size_name;
-            item.comment = value.content || '';
-            item.date = value.create_time;
-            item.total = value.total;
-
-            return item;
-        });
-
-    })();
-};
 
 /**
  * 获取订单评论
@@ -51,11 +13,8 @@ const indexAsync = (pid, page, size) => {
  * @param page
  * @param size
  */
-const getShareOrderListAsync = (pid, page, size) => {
-    return api.getShareOrderListAsync(pid, page, size);
-};
+const getShareOrderListAsync = api.getShareOrderListAsync;
 
 module.exports = {
-    indexAsync,
     getShareOrderListAsync
 };
diff --git a/apps/product/models/detail-hotarea-api.js b/apps/product/models/detail-hotarea-api.js
index d4b36b4..ae1bbfb 100644
--- a/apps/product/models/detail-hotarea-api.js
+++ b/apps/product/models/detail-hotarea-api.js
@@ -5,6 +5,7 @@
 'use strict';
 
 const api = global.yoho.API;
+const config = global.yoho.config;
 
 /**
  * 获取商品的热区
@@ -13,7 +14,7 @@ const indexAsync = pid => {
     return api.get('', {
         method: 'web.productCollocation.list',
         product_id: pid
-    });
+    }, config.apiCache);
 };
 
 module.exports = {
diff --git a/apps/product/models/detail-product-api.js b/apps/product/models/detail-product-api.js
index e2b068a..645ae7b 100644
--- a/apps/product/models/detail-product-api.js
+++ b/apps/product/models/detail-product-api.js
@@ -5,12 +5,13 @@
 'use strict';
 
 const api = global.yoho.API;
+const config = global.yoho.config;
 
 const getProductBannerAsync = (pid) => {
     return api.get('', {
         method: 'web.productBanner.data',
         product_id: pid
-    });
+    }, config.apiCache);
 
 };
 
@@ -18,7 +19,7 @@ const sizeInfoAsync = skn => {
     return api.get('', {
         method: 'h5.product.intro',
         productskn: skn
-    });
+    }, config.apiCache);
 
 };
 
@@ -27,14 +28,14 @@ const isSupportReturnedSale = skn => {
     return api.get('', {
         method: 'app.product.refundExchange',
         product_skn: skn
-    });
+    }, config.apiCache);
 };
 
 const getProductComfortAsync = pid => {
     return api.get('', {
         method: 'web.productComfort.data',
         product_id: pid
-    });
+    }, config.apiCache);
 
 };
 
@@ -42,14 +43,14 @@ const getProductModelCardAsync = pid => {
     return api.get('', {
         method: 'web.productModelcard.list',
         product_id: pid
-    });
+    }, config.apiCache);
 };
 
 const getProductModelTryAsync = skn => {
     return api.get('', {
         method: 'web.productModelTry.data',
         product_skn: skn
-    });
+    }, config.apiCache);
 };
 
 /**
@@ -74,7 +75,7 @@ const getProductAsync = (pid, uid, isStudents, vipLevel) => {
     if (vipLevel) {
         params.current_vip_level = vipLevel;
     }
-    return api.get('', params);
+    return api.get('', params, config.apiCache);
 };
 
 const getPromotionAsync = (skn) => {
@@ -83,7 +84,7 @@ const getPromotionAsync = (skn) => {
         product_skn: skn
     };
 
-    return api.get('', params);
+    return api.get('', params, config.apiCache);
 };
 
 const getLimitedProductStatusAsync = (code, uid, skn) => {
@@ -100,7 +101,7 @@ const getLimitedProductStatusAsync = (code, uid, skn) => {
         params.product_skn = skn;
     }
 
-    return api.get('', params);
+    return api.get('', params, config.apiCache);
 };
 
 module.exports = {
diff --git a/apps/product/models/detail-service.js b/apps/product/models/detail-service.js
index 7914228..bc244d6 100644
--- a/apps/product/models/detail-service.js
+++ b/apps/product/models/detail-service.js
@@ -19,7 +19,6 @@ const consultService = require('./detail-consult-service');
 const commentService = require('./detail-comment-service');
 const hotAreaService = require('./detail-hotarea-service');
 const brandService = require('./brand-service');
-const favoriteBrandService = require('./favorite-brand-service');
 const favoriteProductService = require('./favorite-product-service');
 const shopService = require('./shop-service');
 
@@ -1406,7 +1405,6 @@ const showMainAsync = (data) => {
 };
 
 module.exports = {
-    indexCommentAsync: commentService.indexAsync, // 获取评论列表
     getShareOrderListAsync: commentService.getShareOrderListAsync, // 获取评论列表
     indexConsultAsync: consultService.indexAsync, // 获取咨询列表
     createConsultAsync: consultService.createAsync, // 添加咨询
diff --git a/apps/product/models/outlets-api.js b/apps/product/models/outlets-api.js
index c7d7378..5cad5c7 100644
--- a/apps/product/models/outlets-api.js
+++ b/apps/product/models/outlets-api.js
@@ -10,6 +10,7 @@
 const serviceApi = global.yoho.ServiceAPI;
 const api = global.yoho.API;
 const _ = require('lodash');
+const config = global.yoho.config;
 
 const yhChannel = {
     boys: {
@@ -49,7 +50,7 @@ exports.getOutletsActivityOrigin = (params) => {
         size: params.size || 0,
         yh_channel: yhChannel[tempChannel].channel,
         type: params.type || 0
-    });
+    }, config.apiCache);
 };
 
 /**
@@ -58,7 +59,7 @@ exports.getOutletsActivityOrigin = (params) => {
  * @return {[type]}
  */
 exports.getChannelResouceData = (params) => {
-    return serviceApi.get('operations/api/v5/resource/home', params);
+    return serviceApi.get('operations/api/v5/resource/home', params, config.apiCache);
 };
 
 /**
@@ -77,7 +78,7 @@ exports.getOutletsTrendData = (params) => {
         stocknumber: 1, // 过滤出库存 > 1的商品
         limit: params.limit || 5,
         outlets: params.outlets || 1 // 默认取奥莱商品
-    });
+    }, config.apiCache);
 };
 
 
@@ -110,5 +111,5 @@ exports.getOutletsGoodsList = (params) => {
             tempParams[paramsName] = params[paramsName];
         }
     });
-    return api.get('', tempParams);
+    return api.get('', tempParams, config.apiCache);
 };
diff --git a/apps/product/models/sale-api.js b/apps/product/models/sale-api.js
index a785f9f..4818bed 100644
--- a/apps/product/models/sale-api.js
+++ b/apps/product/models/sale-api.js
@@ -10,6 +10,7 @@
 const serviceAPI = global.yoho.ServiceAPI;
 const api = global.yoho.API;
 const _ = require('lodash');
+const config = global.yoho.config;
 
 const yhChannel = {
     boys: {
@@ -42,7 +43,7 @@ exports.getSaleGoodsList = (params) => {
         finalParams.yh_channel = yhChannel[params.channel].channel;
     }
 
-    return api.get('', Object.assign(finalParams, params));
+    return api.get('', Object.assign(finalParams, params), config.apiCache);
 };
 
 /**
@@ -55,7 +56,7 @@ exports.getSalebreakingYardsSortList = (params) => {
     return api.get('', {
         method: 'app.sale.getBreakingSort',
         yh_channel: yhChannel[tempChannel].channel
-    });
+    }, config.apiCache);
 };
 
 /**
@@ -71,7 +72,7 @@ exports.getSaleActivityList = (params, channel) => {
         sort: '2',
         plateform: '1',
         yh_channel: tempChannel.channel
-    });
+    }, config.apiCache);
 };
 
 /**
@@ -81,7 +82,7 @@ exports.getSaleActivityList = (params, channel) => {
 exports.getSaleBannerList = (cCode) => {
     return serviceAPI.get('operations/api/v5/resource/get', {
         content_code: cCode
-    });
+    }, config.apiCache);
 };
 
 /**
@@ -91,7 +92,7 @@ exports.getSaleBannerList = (cCode) => {
 exports.getLeftContentList = () => {
     return api.get('', {
         method: 'app.sort.get'
-    });
+    }, config.apiCache);
 };
 
 /**
diff --git a/apps/product/models/search-api.js b/apps/product/models/search-api.js
index 6f52c26..eac7a1c 100644
--- a/apps/product/models/search-api.js
+++ b/apps/product/models/search-api.js
@@ -7,17 +7,17 @@ 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 config = require('../../../config/common');
 const images = require('../../../utils/images.js');
 
 const getSortByConditionAsync = (condition) => {
     return api.get('', Object.assign({
         method: 'web.regular.groupsort'
-    }, condition));
+    }, condition), config.apiCache);
 };
 
 // 判断用户是否收藏品牌
@@ -111,7 +111,7 @@ const getProductList = (params, from) => {
     }
 };
 
-const getSortListOrig = (finalParams) => api.get('', finalParams);
+const getSortListOrig = (finalParams) => api.get('', finalParams, config.apiCache);
 
 /**
  * 获取分类列表
@@ -167,7 +167,7 @@ const getSortIntro = (params) => {
     };
 
     Object.assign(finalParams, params);
-    return api.get('', finalParams);
+    return api.get('', finalParams, config.apiCache);
 };
 
 /**
@@ -180,7 +180,7 @@ const getSortAds = (params) => {
     };
 
     Object.assign(finalParams, params);
-    return api.get('', finalParams);
+    return api.get('', finalParams, config.apiCache);
 };
 
 /**
@@ -195,7 +195,7 @@ const getBrandSeries = (params) => {
         status: params.status || 1
     };
 
-    return api.get('', finalParams);
+    return api.get('', finalParams, config.apiCache);
 };
 
 /**
@@ -210,7 +210,7 @@ const getBrandFolder = (params) => {
         status: params.status || 1
     };
 
-    return api.get('', finalParams);
+    return api.get('', finalParams, config.apiCache);
 };
 
 /**
@@ -224,7 +224,7 @@ const getNodeContent = (params) => {
         node: params.node || ''
     };
 
-    return api.get('', finalParams);
+    return api.get('', finalParams, config.apiCache);
 };
 
 /**
@@ -238,7 +238,7 @@ const getWeekNew = (params) => {
     };
 
     Object.assign(finalParams, params);
-    return api.get('', finalParams);
+    return api.get('', finalParams, config.apiCache);
 };
 
 /**
@@ -441,7 +441,7 @@ const getSuggest = (params) => {
         keyword: params.keyword || ''
     };
 
-    return api.get('', finalParams);
+    return api.get('', finalParams, config.apiCache);
 };
 
 
@@ -455,7 +455,7 @@ const getBrandData = (params) => {
         domain: params.domain || ''
     };
 
-    return api.get('', finalParams);
+    return api.get('', finalParams, config.apiCache);
 };
 
 /**
@@ -466,7 +466,7 @@ const isFavoriteBrand = (uid, brandId) => {
     return serviceApi.get(isFavoriteBrandUrl, {
         uid: uid,
         brandId: brandId
-    });
+    }, config.apiCache);
 };
 
 /**
diff --git a/apps/product/models/shop-api.js b/apps/product/models/shop-api.js
index 8f8f56a..2a7633e 100644
--- a/apps/product/models/shop-api.js
+++ b/apps/product/models/shop-api.js
@@ -4,6 +4,7 @@
 'use strict';
 
 const api = global.yoho.API;
+const config = global.yoho.config;
 
 /**
  * 获取店铺装修的所有资源接口
@@ -12,5 +13,5 @@ exports.shopsDecoratorListAsync = shopId => {
     return api.get('', {
         method: 'app.shopsdecorator.getList',
         shop_id: shopId
-    });
+    }, config.apiCache);
 };
diff --git a/apps/product/models/students-api.js b/apps/product/models/students-api.js
index e6ae0d7..8540c07 100644
--- a/apps/product/models/students-api.js
+++ b/apps/product/models/students-api.js
@@ -6,7 +6,7 @@
 'use strict';
 
 const api = global.yoho.API;
-const config = require('../../../config/common');
+const config = global.yoho.config;
 const searchApi = require('./search-api');
 const cache = global.yoho.cache;
 const logger = global.yoho.logger;
@@ -17,7 +17,7 @@ const logger = global.yoho.logger;
  */
 exports.getVerifiedTotal = () => {
 
-    return api.get('', {method: 'app.student.verifiedStudentTotal'});
+    return api.get('', {method: 'app.student.verifiedStudentTotal'}, config.apiCache);
 };
 
 /**
@@ -26,7 +26,7 @@ exports.getVerifiedTotal = () => {
  */
 exports.getEduLevelList = () => {
 
-    return api.get('', {method: 'app.studentMarket.getEducationLevelList'});
+    return api.get('', {method: 'app.studentMarket.getEducationLevelList'}, config.apiCache);
 };
 
 /**
@@ -38,7 +38,7 @@ exports.getArea = () => {
         method: 'app.studentMarket.getAddressList'
     };
 
-    return api.get('', finalParams);
+    return api.get('', finalParams, config.apiCache);
 };
 
 /**
@@ -51,7 +51,7 @@ exports.getSchool = (areaCode) => {
         areaCode: areaCode
     };
 
-    return api.get('', finalParams);
+    return api.get('', finalParams, config.apiCache);
 };
 
 /**
@@ -66,7 +66,7 @@ exports.getStuProducts = (params) => {
     };
 
     Object.assign(finalParams, params);
-    return api.get('', finalParams);
+    return api.get('', finalParams, config.apiCache);
 };
 
 /**
@@ -82,7 +82,7 @@ exports.verifyIdentity = (uid, certNo, name, pageUrl) => {
         page_url: pageUrl
     };
 
-    return api.get('', finalParams);
+    return api.get('', finalParams, config.apiCache);
 };
 
 /**
@@ -99,7 +99,7 @@ exports.verifyStudent = (uid, collegeName, educationDegree, enrollmentYear) => {
         enrollment_year: enrollmentYear
     };
 
-    return api.get('', finalParams);
+    return api.get('', finalParams, config.apiCache);
 };
 
 /**
@@ -117,7 +117,7 @@ exports.userAcquireStatus = (uid, couponIds) => {
         finalParams.uid = uid;
     }
 
-    return api.get('', finalParams);
+    return api.get('', finalParams, config.apiCache);
 };
 
 
diff --git a/apps/product/models/students.js b/apps/product/models/students.js
index 42eff78..747c4cd 100644
--- a/apps/product/models/students.js
+++ b/apps/product/models/students.js
@@ -149,7 +149,7 @@ exports.verifyIdentity = (uid, params) => {
         educationDegree: params.educationDegree,
         enrollmentYear: params.enrollmentYear
     }) + '&';
-    
+
     return studentsApi.verifyIdentity(uid, params.certNo, params.name, pageUrl);
 };
 
@@ -238,7 +238,7 @@ exports.getStudentsList = (params, channel) => {
 
         // 获取商品数据和顶部筛选条件
         if (result[2].code === 200) {
-            //删掉student_price,不让页面显示
+            // 删掉student_price,不让页面显示
             _.forEach(result[2].data.product_list, goods => {
                 delete goods.student_price;
             });
diff --git a/apps/product/views/action/product/detail.hbs b/apps/product/views/action/product/detail.hbs
index 58d5da8..19b8dd4 100644
--- a/apps/product/views/action/product/detail.hbs
+++ b/apps/product/views/action/product/detail.hbs
@@ -660,16 +660,18 @@
 
 
                 <div class="service"></div>
-                {{#if latestWalk}}
-                    <div class="info-block latest-walk">
-                        <input id="latest-walk-count" type="hidden" value="{{latestWalk}}">
-                        <p class="block-title">
-                            <span class="title cur">最近浏览 RECENT REVIEW</span>
-                        </p>
-                        <div id="latest-walk-goods" class="goods clearfix"></div>
-                        {{> product/latest-walk-tpl}}
-                    </div>
-                {{/if}}
+                {{#unless @root.pc.product.removeRecentView}}
+                    {{#if latestWalk}}
+                        <div class="info-block latest-walk">
+                            <input id="latest-walk-count" type="hidden" value="{{latestWalk}}">
+                            <p class="block-title">
+                                <span class="title cur">最近浏览 RECENT REVIEW</span>
+                            </p>
+                            <div id="latest-walk-goods" class="goods clearfix"></div>
+                            {{> product/latest-walk-tpl}}
+                        </div>
+                    {{/if}}
+                {{/unless}}
             </div>
         </div>
     {{/ detail}}
diff --git a/config/cache.js b/config/cache.js
new file mode 100644
index 0000000..15b423c
--- /dev/null
+++ b/config/cache.js
@@ -0,0 +1,61 @@
+
+'use strict';
+
+const SECOND = 1;
+const MINUTE = 60 * SECOND;
+
+const cachePage = {
+
+    // 频道页
+    '/': 30 * SECOND,
+    '/woman': 30 * SECOND,
+    '/kids': 30 * SECOND,
+    '/lifestyle': 30 * SECOND,
+
+    // 商品详情页
+    '/product/\\/pro_([\\d]+)_([\\d]+)\\/(.*)/': 30 * MINUTE,
+
+    // 逛
+    '/guang/': 1 * MINUTE,
+    '/guang/info/index': 10 * MINUTE,
+    '/guang/detail/:id': 10 * MINUTE,
+    '/guang/index/editor': 1 * MINUTE,
+    '/guang/tags/index': 1 * MINUTE,
+
+    // 领券中心
+    '/coupon/index': 5 * MINUTE,
+
+    // 商品列表
+    '/product/list/index': 5 * MINUTE,
+    '/product/index/index': 5 * MINUTE,
+
+    // 秒杀列表
+    '/product/seckill': 30 * SECOND,
+
+    // 秒杀详情
+
+    // sale
+    '/product/sale': 5 * MINUTE,
+    '/product/sale/vip': 5 * MINUTE,
+    '/product/sale/breakingYards': 5 * MINUTE,
+    '/product/sale/newSale': 5 * MINUTE,
+    '/product/sale/discount/detail': 5 * MINUTE,
+
+    '/product/outlet': 30 * SECOND,
+
+    '/product/index/brand': 2 * MINUTE,
+    '/product/index/about': 10 * MINUTE,
+    '/product/shoplist': 2 * MINUTE,
+
+    '/product/list/new': 30 * SECOND,
+
+    // 品牌一览
+    '/brands/': 5 * MINUTE,
+    '/brands/plusstar': 5 * MINUTE,
+
+    '/special/(\\d+)_(.*)\\.html': 5 * MINUTE
+
+
+};
+
+module.exports = cachePage;
diff --git a/config/common.js b/config/common.js
index 24d6199..d359926 100644
--- a/config/common.js
+++ b/config/common.js
@@ -14,6 +14,7 @@ module.exports = {
     appVersion: '4.9.0', // 调用api的版本
     port: 6002,
     siteUrl: 'http://www.yohobuy.com',
+    cookieDomain: '.yohobuy.com',
     domains: {
         favApi: 'http://192.168.102.31:8092/brower',
         api: 'http://api.yoho.cn/',
@@ -44,6 +45,7 @@ module.exports = {
     },
     loggers: {
         infoFile: {
+            close: true,
             name: 'info',
             level: 'info',
             filename: 'logs/info.log',
@@ -62,7 +64,7 @@ module.exports = {
             port: '4444' // influxdb port
         },
         console: {
-            level: 'debug',
+            level: 'error',
             colorize: 'all',
             prettyPrint: true
         }
@@ -71,8 +73,32 @@ module.exports = {
         wechat: {
             appID: 'wx3ae21dcbb82ad672',
             appSecret: 'e78afb2321e6a19085767e1a0f0d52c1'
+        },
+        sina: {
+            appID: '3739328910',
+            appSecret: '9d44cded26d048e23089e5e975c93df1'
+        },
+        qq: {
+            appID: '100229394',
+            appSecret: 'c0af9c29e0900813028c2ccb42021792'
+        },
+        alipay: {
+            appID: '2088701661478015',
+            appSecret: 'kcxawi9bb07mzh0aq2wcirsf9znusobw'
+        },
+        douban: {
+            appID: '03b4e36bf13dc75a0b1eaa43d3b9560e',
+            appSecret: 'f16d5913e8610672'
+        },
+        renren: {
+            appID: '783130c654c94a77ace97054ae266019',
+            appSecret: '05e430de8c1e40d3a1f39ca8d3f8252c'
         }
-    }
+    },
+    apiCache: {
+        cache: true
+    },
+    zookeeperServer: '192.168.102.168:2188'
 };
 
 if (isProduction) {
@@ -98,7 +124,8 @@ if (isProduction) {
         interfaceShunt: {
             open: false,
             url: 'http://123.206.2.55/strategy'
-        }
+        },
+        zookeeperServer: '10.66.1.97:2181'
     });
 } else if (isTest) {
     Object.assign(module.exports, {
diff --git a/doraemon/middleware/mobile-refer.js b/doraemon/middleware/mobile-refer.js
new file mode 100644
index 0000000..099fd83
--- /dev/null
+++ b/doraemon/middleware/mobile-refer.js
@@ -0,0 +1,72 @@
+/**
+ * page cache 前端js跳转url中间件
+ */
+'use strict';
+
+const _ = require('lodash');
+const querystring = require('querystring');
+
+const ptm = {
+    // 首页
+    '/': '',
+    '/woman': '/girls',
+    '/kids': '/kids',
+    '/lifestyle': '/lifestyle',
+
+    // 登录注册
+    '/signin.html': '/signin.htm',
+    '/reg.html': '/passport/reg/index',
+    '/passport/back/index': '/passport/back/mobile',
+
+    // 列表
+    '/product/list/new': '/product/new',
+
+    // 品牌列表
+    '/brands': '/brands',
+
+    // 领券中心
+    '/coupon/index': '/coupon/floor?title=领券中心&code=b78b32ed81b18dde8ac84fd33602b88b'
+
+};
+
+module.exports = () => {
+    return (req, res, next) => {
+        let domain = 'm.yohobuy.com';
+        let proReg = /^\/product\/pro/,
+            guangReg = /^\/guang/,
+            guangDetailReg = /.html$/,
+            qsReg = /\?/;
+
+        if (!req.xhr) {
+            let url = _.head(_.split(req.url, '?'));
+            let data = {};
+
+            if (ptm.hasOwnProperty(url)) {
+                data.mobileRefer = `//${domain}${ptm[url]}`;
+            } else if (url === '/product/list/index') {
+                data.mobileRefer = `//list.${domain}`;
+            } else if (url === '/product/index/brand') {
+                data.mobileRefer = `//${req.query.domain}.${domain}`;
+            } else if (url === '/product/search/index') {
+                data.mobileRefer = `//search.${domain}`;
+            } else if (guangReg.test(url)) {
+                data.mobileRefer = `//guang.${domain}`;
+
+                if (guangDetailReg.test(url)) {
+                    data.mobileRefer += url.replace(/\/guang\/detail\/([\d]+).html/, '/info/index?id=$1');
+                } else if (url === '/guang/Index/editor') {
+                    data.mobileRefer += `/author/index?id=${req.query.author_id}`;
+                }
+            } else if (proReg.test(url)) {
+                data.mobileRefer = `//${domain}${url}`;
+            }
+
+            if (!_.isEmpty(req.query) && !qsReg.test(data.mobileRefer)) {
+                data.mobileRefer += `?${querystring.stringify(req.query)}`;
+            }
+
+            Object.assign(res.locals, data);
+        }
+        next();
+    };
+};
diff --git a/doraemon/middleware/page-cache.js b/doraemon/middleware/page-cache.js
new file mode 100644
index 0000000..32dc892
--- /dev/null
+++ b/doraemon/middleware/page-cache.js
@@ -0,0 +1,57 @@
+
+'use strict';
+
+const cachePage = require('../../config/cache');
+const logger = global.yoho.logger;
+const _ = require('lodash');
+
+function urlJoin(a, b) {
+    if (_.endsWith(a, '/') && _.startsWith(b, '/')) {
+        return a + b.substring(1, b.length);
+    } else if (!_.endsWith(a, '/') && !_.startsWith(b, '/')) {
+        return a + '/' + b;
+    } else {
+        return a + b;
+    }
+}
+
+module.exports = () => {
+    return (req, res, next) => {
+
+        function onRender() {
+            let route = req.route ? req.route.path : '';
+            let appPath = req.app.mountpath;
+
+            if (_.isArray(route) && route.length > 0) {
+                route = route[0];
+            }
+
+            let key = urlJoin(appPath, route.toString()); // route may be a regexp
+
+            req.app.set('etag', false);
+
+            logger.debug(`route: ${key}   cache = ${cachePage[key]}`);
+
+            // 如果存在cache配置,并且业务代码中没有设置
+            if (cachePage[key] && res.get('Cache-Control') !== 'no-cache') {
+                res.set({
+                    'Cache-Control': 'max-age=' + cachePage[key]
+                });
+                res.removeHeader('Pragma');
+                res.removeHeader('Expires');
+            } else if (req.get('X-Requested-With') === 'XMLHttpRequest') {
+                res.set('Cache-Control', 'no-cache');
+            } else {
+                res.set({
+                    'Cache-Control': 'no-cache',
+                    Pragma: 'no-cache',
+                    Expires: new Date(1900, 0, 1, 0, 0, 0, 0)
+                });
+            }
+
+        }
+
+        res.on('render', onRender);
+        next();
+    };
+};
diff --git a/doraemon/middleware/sub-domain.js b/doraemon/middleware/sub-domain.js
index 989c59d..2e3b1d9 100644
--- a/doraemon/middleware/sub-domain.js
+++ b/doraemon/middleware/sub-domain.js
@@ -22,7 +22,15 @@ module.exports = () => {
                 case 'guang': // 逛
                 case 'cdnsrcguang': // 逛CDN回源解析
                     if (guangDetailReg.test(req.path)) {
-                        req.url = '/guang/detail' + req.url;
+                        // req.url = '/guang/detail' + req.url;
+                        /\/([\d]*).html(\?)?(.*)/.exec(req.url);
+                        req.url = '/guang/info/index?id=' + RegExp.$1;
+                        if (RegExp.$3) {
+                            req.url += '&' + RegExp.$3;
+                        }
+                        req.query.id = RegExp.$1;
+
+                        console.log(req.url);
                     } else if (!guangReg.test(req.path)) {
                         req.url = '/guang' + req.url;
                     }
diff --git a/doraemon/middleware/user.js b/doraemon/middleware/user.js
index 68cf55c..21d48d8 100644
--- a/doraemon/middleware/user.js
+++ b/doraemon/middleware/user.js
@@ -1,28 +1,54 @@
 'use strict';
 
-const Fp = require('lodash/fp');
+const Fn = require('lodash/fp');
+const _ = require('lodash');
+const cache = global.yoho.cache;
 const cookie = global.yoho.cookie;
+const loginService = require('../../apps/passport/models/login-service');
 
 module.exports = () => {
     return (req, res, next) => {
 
-        // session 没有读取到的时候,从 cookie 读取 UID
+        // 获得原始请求 url
+        req.fullUrl = () => req.protocol + '://' + req.get('host') + req.originalUrl;
+
+        // 从 cookie 读取 UID
         if (req.cookies._UID) {
-            req.user.uid = cookie.getUid(req);
 
-            let getVip = Fp.pipe(Fp.split('::'), Fp.nth(2));
+            let uidCookie = req.cookies._UID.split('::');
 
-            req.user.vip = getVip(req.cookies._UID);
-        }
+            let getName = Fn.nth(0);
+            let getVip = Fn.nth(2);
+            let getToken = Fn.nth(3);
 
-        // 用户是否学生
-        if (req.user.uid && req.cookies.isStudent) {
+            req.user.name = getName(uidCookie);    // 0
+            req.user.uid = cookie.getUid(req);     // 1
+            req.user.vip = getVip(uidCookie);      // 2
+            req.user.token = getToken(uidCookie);  // 3
             req.user.isStudent = req.cookies.isStudent || 0;
         }
 
-        // 从 SESSION 中获取到当前登录用户的 UID
-        // if (req.session && _.isNumber(req.session._LOGIN_UID)) {
-        //    req.user.uid = req.session._LOGIN_UID;
+        // 记住我
+        // if (_.isEmpty(req.user) && req.cookies.isRemember === 'true' && req.cookies.remem) {
+        //     return cache.get(req.cookies.remem).then((result) => {
+        //         let data = JSON.parse(result || '{}');
+
+        //         let area = data.area;
+        //         let account = data.account;
+        //         let password = data.password;
+
+        //         return loginService.signin('password', area, account, password);
+        //     }).then((result) => {
+        //         if (result.code !== 200) {
+        //             return Promise.reject();
+        //         }
+
+        //         return loginService.syncUserSession(result.data.uid, req, res);
+        //     }).then(() => {
+        //         return res.redirect(req.fullUrl());
+        //     }).catch(next);
+        // } else {
+        //     return next();
         // }
 
         next();
diff --git a/doraemon/views/layout.hbs b/doraemon/views/layout.hbs
index 003cae5..79a713d 100644
--- a/doraemon/views/layout.hbs
+++ b/doraemon/views/layout.hbs
@@ -1,41 +1,45 @@
-<!DOCTYPE html>
-<html>
-    <head>
-        <meta charset="utf-8">
-        <title>{{title}}</title>
-        <meta name="keywords" content="{{keywords}}">
-        <meta name="description" content="{{description}}">
-        <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, minimum-scale=1, user-scalable=no">
-        <meta http-equiv="cleartype" content="on">
-        <meta name="apple-mobile-web-app-status-bar-style" content="black" />
-        <meta content="telephone=no" name="format-detection" />
-        <meta content="email=no" name="format-detection" />
-        <link rel="dns-prefetch" href="//cdn.yoho.cn">
-        <link rel="dns-prefetch" href="//static.yohobuy.com">
-        <link rel="dns-prefetch" href="//img12.static.yhbimg.com">
-        <link rel="dns-prefetch" href="//img13.static.yhbimg.com">
-        {{#if devEnv}}
-            <link rel="stylesheet" href="//localhost:5002/css/index.css">
-        {{^}}
-            <link rel="stylesheet" href="//cdn.yoho.cn/yohobuy-node/{{version}}/index.css">
-        {{/if}}
-    </head>
-    <body>
-        {{> header}}
-        {{> common/simple-header}}
-        {{#if pageErr}}
-            {{> 404}}
-        {{^}}
-            {{{body}}}
-        {{/if}}
-        {{> footer}}
-        {{#if devEnv}}
-            <script src="//localhost:5002/libs.js"></script>
-            <script src="//localhost:5002/{{module}}.{{page}}.js"></script>
-        {{^}}
-            <script src="//cdn.yoho.cn/yohobuy-node/{{version}}/libs.js"></script>
-            <script src="//cdn.yoho.cn/yohobuy-node/{{version}}/{{module}}.{{page}}.js"></script>
-            {{> analysis}}
-        {{/if}}
-    </body>
-</html>
+<!DOCTYPE html>
+<html>
+    <head>
+        <meta charset="utf-8">
+        <title>{{title}}</title>
+        <meta name="keywords" content="{{keywords}}">
+        <meta name="description" content="{{description}}">
+        <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, minimum-scale=1, user-scalable=no">
+        <meta http-equiv="cleartype" content="on">
+        <meta name="apple-mobile-web-app-status-bar-style" content="black" />
+        <meta content="telephone=no" name="format-detection" />
+        <meta content="email=no" name="format-detection" />
+        <link rel="dns-prefetch" href="//cdn.yoho.cn">
+        <link rel="dns-prefetch" href="//static.yohobuy.com">
+        <link rel="dns-prefetch" href="//img12.static.yhbimg.com">
+        <link rel="dns-prefetch" href="//img13.static.yhbimg.com">
+        {{#if devEnv}}
+            <link rel="stylesheet" href="//localhost:5002/css/index.css">
+        {{^}}
+            <link rel="stylesheet" href="//cdn.yoho.cn/yohobuy-node/{{version}}/index.css">
+        {{/if}}
+    </head>
+    <body>
+        {{#if mobileRefer}}
+            <input type="hidden" id="m-refer" value="{{mobileRefer}}">
+        {{/if}}
+
+        {{> header}}
+        {{> common/simple-header}}
+        {{#if pageErr}}
+            {{> 404}}
+        {{^}}
+            {{{body}}}
+        {{/if}}
+        {{> footer}}
+        {{#if devEnv}}
+            <script src="//localhost:5002/libs.js"></script>
+            <script src="//localhost:5002/{{module}}.{{page}}.js"></script>
+        {{^}}
+            <script src="//cdn.yoho.cn/yohobuy-node/{{version}}/libs.js"></script>
+            <script src="//cdn.yoho.cn/yohobuy-node/{{version}}/{{module}}.{{page}}.js"></script>
+            {{> analysis}}
+        {{/if}}
+    </body>
+</html>
diff --git a/doraemon/views/partial/header.hbs b/doraemon/views/partial/header.hbs
index cb1a6ef..78260c1 100644
--- a/doraemon/views/partial/header.hbs
+++ b/doraemon/views/partial/header.hbs
@@ -26,7 +26,9 @@
                             <span class="tag-seprate"></span>
                             <a href="//www.yohobuy.com/home?t=1453340799.4986">MY有货</a>
                             <span class="icon-bottomarrow"></span>
-                            <div class="simple-user-center"></div>
+                            {{#unless @root.pc.common.disMyYohoHover}}
+                                <div class="simple-user-center"></div>
+                            {{/unless}}
                         </li>
                         <li class="myorder">
                             <span class="tag-seprate"></span>
@@ -66,7 +68,8 @@
                 <div class="main-logo"><a href="//www.yohobuy.com/" class="main-link"></a></div>
                 <ul class="main-nav-list">
                     {{# navbars}}
-                        <li class="{{type}}"{{#if ico}} style="background: url({{image ico 54 32}}) no-repeat center center"{{/if}}>
+                        <li class="{{type}}"{{#if ico}}
+                            style="background: url({{image ico 54 32}}) no-repeat center center"{{/if}}>
                             {{#if ico}}
                                 <a href="{{link}}"{{#if isNewPage}} target="_blank"{{/if}} class="menu-ico"></a>
                             {{^}}
@@ -81,7 +84,9 @@
                     {{/ navbars}}
                 </ul>
                 <div class="func-area hide">
-                    <ul class="search-suggest"></ul>
+                    {{#unless @root.pc.common.disSearchAssociation}}
+                        <ul class="search-suggest"></ul>
+                    {{/unless}}
                     <div class="search-2016">
                         <form action="//search.yohobuy.com" method="get" id="search-form">
                             <input type="hidden" id="defaultsearch" value="{{defaultSearch}}">
@@ -92,16 +97,20 @@
                     <div class="go-cart">
                         <a href="//www.yohobuy.com/shopping/cart">
                             <span class="iconfont ">&#xe600;</span>
-                            <span class="goods-num-tip">0</span>
+                            {{#unless @root.pc.common.removeCartCount}}
+                                <span class="goods-num-tip">0</span>
+                            {{/unless}}
                         </a>
-                        <div class="mini-cart-wrapper">
-                            <div class="loading-cart">
-                                <h3>加载中,请稍后</h3>
-                            </div>
-                            <div class="empty-cart">
-                                <h3>您的购物车暂无商品</h3>
+                        {{#unless @root.pc.common.disCartHover}}
+                            <div class="mini-cart-wrapper">
+                                <div class="loading-cart">
+                                    <h3>加载中,请稍后</h3>
+                                </div>
+                                <div class="empty-cart">
+                                    <h3>您的购物车暂无商品</h3>
+                                </div>
                             </div>
-                        </div>
+                        {{/unless}}
                     </div>
                 </div>
             </div>
@@ -109,39 +118,40 @@
         <div class="nav-wrapper clearfix">
             <div class="center-content">
                 {{# subNavGroup}}
-                <ul class="sub-nav-list {{subType}}">
-                    {{# subNav}}
-                        <li {{#if thirdNav}}class="contain-third"{{/if}}>
-                            <a  href="{{link}}">{{name}}
-                                {{#if isNew}}
-                                    <span class="newlogo"></span>
-                                {{/if}}
-                            </a>
-                            {{#if thirdNav}}
-                                <div class="third-nav-wrapper">
-                                    <div class="center-content">
-                                        <dl class="hide-list hide">
-                                            {{# thirdNav}}
-                                                <dt>
-                                                    <h1 class=""><a href="{{link}}">{{title}}</a> </h1>
-                                                </dt>
-                                                {{#brandItems}}
-                                                <dd>
-                                                    <a href="{{link}}"{{#if hot}} class="hot"{{/if}}>{{brandName}}</a>
-                                                </dd>
-                                                {{/brandItems}}
-                                            {{/thirdNav}}
-                                        </dl>
-                                        <div class="show-detail" data-code="{{imgCode}}">
-                                            <a><img src="data:image/gif;base64,R0lGODlhAQABAJEAAAAAAP///93d3f///yH5BAEAAAMALAAAAAABAAEAAAICVAEAOw=="></a>
-                                            <a class="title">热门小物优选</a>
+                    <ul class="sub-nav-list {{subType}}">
+                        {{# subNav}}
+                            <li {{#if thirdNav}}class="contain-third"{{/if}}>
+                                <a href="{{link}}">{{name}}
+                                    {{#if isNew}}
+                                        <span class="newlogo"></span>
+                                    {{/if}}
+                                </a>
+                                {{#if thirdNav}}
+                                    <div class="third-nav-wrapper">
+                                        <div class="center-content">
+                                            <dl class="hide-list hide">
+                                                {{# thirdNav}}
+                                                    <dt>
+                                                    <h1 class=""><a href="{{link}}">{{title}}</a></h1>
+                                                    </dt>
+                                                    {{#brandItems}}
+                                                        <dd>
+                                                            <a href="{{link}}"{{#if hot}}
+                                                               class="hot"{{/if}}>{{brandName}}</a>
+                                                        </dd>
+                                                    {{/brandItems}}
+                                                {{/thirdNav}}
+                                            </dl>
+                                            <div class="show-detail" data-code="{{imgCode}}">
+                                                <a><img src="data:image/gif;base64,R0lGODlhAQABAJEAAAAAAP///93d3f///yH5BAEAAAMALAAAAAABAAEAAAICVAEAOw=="></a>
+                                                <a class="title">热门小物优选</a>
+                                            </div>
                                         </div>
                                     </div>
-                                </div>
-                            {{/if}}
-                        </li>
-                    {{/ subNav}}
-                </ul>
+                                {{/if}}
+                            </li>
+                        {{/ subNav}}
+                    </ul>
                 {{/ subNavGroup}}
             </div>
         </div>
@@ -153,7 +163,7 @@
         </script>
         <script type="text/html" id="simple-account-info-tpl">
             <div class="account-info-header">
-                <div class="user-img" >
+                <div class="user-img">
                     <img src="\{{headIco}}">
                 </div>
                 <div class="user-name">
@@ -163,15 +173,15 @@
                     VIP: <span>\{{curTitle}}</span>
                 </h3>
                 \{{#unless vip3}}
-                    <div class="level-detail">
-                        <div class="level-view-bar">
-                            <div class="text-span">
-                                \{{curYearCost}}/\{{nextVipNeedCost}}
-                            </div>
-                            <p class="\{{#if curYearCostPer}}integrate\{{/if}}" style="width: \{{curYearCostPer}}%;"></p>
+                <div class="level-detail">
+                    <div class="level-view-bar">
+                        <div class="text-span">
+                            \{{curYearCost}}/\{{nextVipNeedCost}}
                         </div>
-                        <span>\{{nextVipTitle}}</span>
+                        <p class="\{{#if curYearCostPer}}integrate\{{/if}}" style="width: \{{curYearCostPer}}%;"></p>
                     </div>
+                    <span>\{{nextVipTitle}}</span>
+                </div>
                 \{{/unless}}
             </div>
             <ul class="account-info-content">
@@ -197,79 +207,82 @@
                 </li>
             </ul>
             <div class="account-info-footer">
-                <a href="//www.yohobuy.com/home/user?t=\{{timestamp}}">完善资料  <span>(学生认证)</span></a>
+                <a href="//www.yohobuy.com/home/user?t=\{{timestamp}}">完善资料 <span>(学生认证)</span></a>
             </div>
         </script>
         <script type="text/html" id="mini-cart-tpl">
-            \{{#carData}}
-                <div class="rich-cart">
-                    <div class="goods-list">
-                        \{{# totalGoods}}
-                            \{{#notzero buy_number}}
-                                <div class="goods-item">
-                                    <div class="goods-img">
-                                        <a href="\{{product_url}}">
-                                            <img src="\{{default_img}}"/>
-                                        </a>
-                                    </div>
-                                    <div class="goods-info">
-                                        <p class="title">
-                                            <a href="\{{product_url}}">\{{product_name}}</a>
-                                        </p>
-                                        <p>
-                                            颜色:\{{color_name}}
-                                            尺码:\{{size_name}}
-                                        </p>
-                                    </div>
-                                    <div class="goods-price">
-                                        <p>\{{show_price}} x \{{buy_number}}</p>
-                                        <p>
-                                            <a href="javascript:void(0)" class="cart-goods-del" data-id="\{{goods_incart_id}}" data-cheapest="\{{is_cheapest_free}}" data-sku="\{{product_sku}}" data-proid="\{{promotion_id}}" data-num="\{{buy_number}}">删除</a>
-                                        </p>
-                                    </div>
-                                </div>
-                            \{{/notzero}}
-                        \{{/ totalGoods}}
-                        \{{#if has_promotion}}
-                            <div class="activity-item">
-                                <label class="activity-name">活动</label>
-                                <h3 class="activity-content">
-                                    \{{#if fit_outlet_promotion }}
-                                        购outlet商品,满¥1999再享9折
-                                    \{{/if}}
-                                    \{{#if has_other_promotion}}
-                                        <span class="mycart_i_down" title="更多" ></span>
-                                    \{{/if}}
-                                    \{{#if has_first_promotion}}
-                                        \{{first_promotions.promotion_title}}
-                                    \{{/if}}
-                                </h3>
-                            </div>
-                        \{{/if}}
-                        \{{#if fit_free_shipping }}
-                            <div class="activity-item">
-                                <label class="activity-name">免运费</label>
-                                <h3 class="activity-content">全场满 ¥\{{fit_free_shipping}}免运费</h3>
-                            </div>
-                        \{{/if}}
-                    </div>
-                    <div class="go-full-cart">
-                        <div>
-                            <a href="//www.yohobuy.com/shopping/cart">去购物车结算</a>
+                \{{#carData}}
+            <div class="rich-cart">
+                <div class="goods-list">
+                    \{{# totalGoods}}
+                    \{{#notzero buy_number}}
+                    <div class="goods-item">
+                        <div class="goods-img">
+                            <a href="\{{product_url}}">
+                                <img src="\{{default_img}}"/>
+                            </a>
+                        </div>
+                        <div class="goods-info">
+                            <p class="title">
+                                <a href="\{{product_url}}">\{{product_name}}</a>
+                            </p>
+                            <p>
+                                颜色:\{{color_name}}
+                                尺码:\{{size_name}}
+                            </p>
                         </div>
+                        <div class="goods-price">
+                            <p>\{{show_price}} x \{{buy_number}}</p>
+                            <p>
+                                <a href="javascript:void(0)" class="cart-goods-del" data-id="\{{goods_incart_id}}"
+                                   data-cheapest="\{{is_cheapest_free}}" data-sku="\{{product_sku}}"
+                                   data-proid="\{{promotion_id}}" data-num="\{{buy_number}}">删除</a>
+                            </p>
+                        </div>
+                    </div>
+                    \{{/notzero}}
+                    \{{/ totalGoods}}
+                    \{{#if has_promotion}}
+                    <div class="activity-item">
+                        <label class="activity-name">活动</label>
+                        <h3 class="activity-content">
+                            \{{#if fit_outlet_promotion }}
+                            购outlet商品,满¥1999再享9折
+                            \{{/if}}
+                            \{{#if has_other_promotion}}
+                            <span class="mycart_i_down" title="更多"></span>
+                            \{{/if}}
+                            \{{#if has_first_promotion}}
+                            \{{first_promotions.promotion_title}}
+                            \{{/if}}
+                        </h3>
+                    </div>
+                    \{{/if}}
+                    \{{#if fit_free_shipping }}
+                    <div class="activity-item">
+                        <label class="activity-name">免运费</label>
+                        <h3 class="activity-content">全场满 ¥\{{fit_free_shipping}}免运费</h3>
+                    </div>
+                    \{{/if}}
+                </div>
+                <div class="go-full-cart">
+                    <div>
+                        <a href="//www.yohobuy.com/shopping/cart">去购物车结算</a>
                     </div>
                 </div>
-            \{{/carData}}
+            </div>
+                \{{/carData}}
         </script>
         <script type="text/html" id="search-suggest-tml">
-            \{{#data}}
-                <li>
-                    <a style="display: block;" href="\{{href}}" class="clearfix clear search-item" title="\{{keyword}}" act="\{{href}}">
-                        <span class="searchvalue" >\{{keyword}}</span>
-                        <span class="valuenum">约\{{count}}个商品</span>
-                    </a>
-                </li>
-            \{{/data}}
+                \{{#data}}
+            <li>
+                <a style="display: block;" href="\{{href}}" class="clearfix clear search-item" title="\{{keyword}}"
+                   act="\{{href}}">
+                    <span class="searchvalue">\{{keyword}}</span>
+                    <span class="valuenum">约\{{count}}个商品</span>
+                </a>
+            </li>
+                \{{/data}}
         </script>
     </div>
 
diff --git a/doraemon/views/partial/product/latest-walk.hbs b/doraemon/views/partial/product/latest-walk.hbs
index 53fcf36..9b393ad 100644
--- a/doraemon/views/partial/product/latest-walk.hbs
+++ b/doraemon/views/partial/product/latest-walk.hbs
@@ -1,9 +1,11 @@
-{{#if latestWalk}}
-    <input id="latest-walk-count" type="hidden" value="{{latestWalk}}">
-    <div class="latest-walk">
-        <h2>最近浏览的商品</h2>
-        <div id="latest-walk-goods" class="goods clearfix"></div>
-    </div>
+{{#unless @root.pc.product.removeRecentView}}
+    {{#if latestWalk}}
+        <input id="latest-walk-count" type="hidden" value="{{latestWalk}}">
+        <div class="latest-walk">
+            <h2>最近浏览的商品</h2>
+            <div id="latest-walk-goods" class="goods clearfix"></div>
+        </div>
 
-    {{> product/latest-walk-tpl}}
-{{/if}}
+        {{> product/latest-walk-tpl}}
+    {{/if}}
+{{/unless}}
diff --git a/package.json b/package.json
index f10ca9b..6eaa18a 100644
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
 {
   "name": "yohobuy-node",
-  "version": "5.1.1",
+  "version": "5.1.2",
   "private": true,
   "description": "A New Yohobuy Project With Express",
   "repository": {
@@ -34,19 +34,14 @@
     "bluebird": "^3.4.0",
     "body-parser": "^1.15.0",
     "captchapng": "0.0.1",
-    "connect-memcached": "^0.2.0",
+    "compression": "^1.6.2",
     "cookie-parser": "^1.4.3",
+    "cookie-session": "^1.2.0",
     "express": "^4.13.1",
-    "handlebars": "^4.0.5",
-    "express-handlebars": "^3.0.0",
-    "express-session": "^1.13.0",
-    "influxdb-winston": "^1.0.1",
     "lodash": "^4.13.1",
     "md5": "^2.1.0",
-    "memcached": "^2.2.2",
     "moment": "^2.14.1",
     "morgan": "^1.7.0",
-    "oneapm": "^1.2.20",
     "passport": "^0.3.2",
     "passport-douban": "0.0.1",
     "passport-local": "^1.0.0",
@@ -56,13 +51,10 @@
     "passport-strategy": "1.x.x",
     "passport-weixin": "^0.1.0",
     "request-ip": "^1.2.2",
-    "request-promise": "^3.0.0",
     "serve-favicon": "^2.3.0",
     "uuid": "^2.0.2",
-    "winston": "^2.2.0",
-    "winston-daily-rotate-file": "^1.1.4",
-    "yoho-express-session": "^1.14.1",
-    "yoho-node-lib": "0.1.28"
+    "yoho-node-lib": "0.1.28",
+    "yoho-zookeeper": "^1.0.3"
   },
   "devDependencies": {
     "autoprefixer": "^6.3.6",
diff --git a/public/img/guang/collocation.png b/public/img/guang/collocation.png
new file mode 100644
index 0000000..8e5f46f
Binary files /dev/null and b/public/img/guang/collocation.png differ
diff --git a/public/img/guang/fashion-good.png b/public/img/guang/fashion-good.png
new file mode 100644
index 0000000..508d7b4
Binary files /dev/null and b/public/img/guang/fashion-good.png differ
diff --git a/public/img/guang/fashion-man.png b/public/img/guang/fashion-man.png
new file mode 100644
index 0000000..05a6275
Binary files /dev/null and b/public/img/guang/fashion-man.png differ
diff --git a/public/img/guang/topic.png b/public/img/guang/topic.png
new file mode 100644
index 0000000..e832ae4
Binary files /dev/null and b/public/img/guang/topic.png differ
diff --git a/public/img/sprite.home.png b/public/img/sprite.home.png
index afc26e6..b53b663 100644
Binary files a/public/img/sprite.home.png and b/public/img/sprite.home.png differ
diff --git a/public/js/brands/brands.page.js b/public/js/brands/brands.page.js
index 1d6c1bb..5c29160 100644
--- a/public/js/brands/brands.page.js
+++ b/public/js/brands/brands.page.js
@@ -13,7 +13,6 @@ var $tabs = $('.brands-tabs');
 var $list = $('.brands-list');
 var $gory = $('.brands-category');
 var $news = $('.news-txt ul');
-var $clearfix = $list.find('dl.clearfix');
 var $brand = $list.find('li>a');
 var $category = $gory.find('a');
 var $tab = $tabs.find('li>a');
@@ -175,6 +174,9 @@ function bindTemplete($select, data, tmp) {
 
 // 鼠标悬浮品牌,请求数据,并且展示
 function bindHoverEvent() {
+    if (String($list.data('ishover')) === 'true') {
+        return;
+    }
     $brand.unbind('mouseenter').unbind('mouseleave').hover(function() {
         var $this = $(this);
         var key = $this.attr('data-key');
@@ -210,21 +212,4 @@ function bindHoverEvent() {
     });
 }
 
-if ($clearfix.length < 26) {
-    $.ajax({
-        url: '/brands/brandList',
-        type: 'POST',
-        data: {
-            start: $clearfix.length ? ($clearfix.length + 1) : 1
-        },
-        success: function(_data) {
-            if (_data) {
-                $list.append(_data);
-                $brand = $list.find('li>a');
-                bindHoverEvent();
-            }
-        }
-    });
-}
-
 bindHoverEvent();
diff --git a/public/js/common.js b/public/js/common.js
index c571b17..58182eb 100644
--- a/public/js/common.js
+++ b/public/js/common.js
@@ -94,6 +94,15 @@ function getShoppingKey() {
     return JSON.parse(c).k;
 }
 
+// page cache改造-前端移动端检测
+(function() {
+    var mrefer = $('#m-refer').val();
+
+    if (mrefer && window.navigator.userAgent.match(/(nokia|iphone|android|ipad|motorola|^mot\-|softbank|foma|docomo|kddi|up\.browser|up\.link|htc|dopod|blazer|netfront|helio|hosin|huawei|novarra|CoolPad|webos|techfaith|palmsource|blackberry|alcatel|amoi|ktouch|nexian|samsung|^sam\-|s[cg]h|^lge|ericsson|philips|sagem|wellcom|bunjalloo|maui|symbian|smartphone|midp|wap|phone|windows ce|iemobile|^spice|^bird|^zte\-|longcos|pantech|gionee|^sie\-|portalmmm|jig\s browser|hiptop|^ucweb|^benq|haier|^lct|opera\s*mobi|opera\*mini|320x320|240x320|176x220)/i)) { // eslint-disable-line
+        window.location = mrefer;
+    }
+}());
+
 // YAS统计代码
 (function(w, d, s, j, f) {
     var a = d.createElement(s);
diff --git a/public/js/guang/detail.page.js b/public/js/guang/detail.page.js
index c2dde86..26f1b77 100644
--- a/public/js/guang/detail.page.js
+++ b/public/js/guang/detail.page.js
@@ -109,10 +109,15 @@ $('#collect-btn').click(function() {
             case 401:
 
                 // 防止从已有col的页面再次进行跳转后出错的情况
-                if (/\?col=(1|0)/.test(location.href)) {
-                    hrefUrl = location.href.replace(/\?col=(1|0)/, '?col=' + col);
+                if (/(\?|&)col=(1|0)/.test(location.href)) {
+                    // hrefUrl = location.href.replace(/\?col=(1|0)/, '?col=' + col);
+                    hrefUrl = location.href.replace(/(\?|&)col=(1|0)/, '$1col=x');
                 } else {
-                    hrefUrl = location.href + '?col=' + col;
+                    if (location.href.indexOf('?') >= 0) {
+                        hrefUrl = location.href + '&col=' + col;
+                    } else {
+                        hrefUrl = location.href + '?col=' + col;
+                    }
                 }
                 location.href = '//www.yohobuy.com/signin.html?refer=' + encodeURI(hrefUrl);
                 break;
@@ -121,10 +126,10 @@ $('#collect-btn').click(function() {
                 // alert(data.message);
                 break;
             case 200:
-                if (/\?col=(1|0)/.test(location.href)) {
+                if (/(\?|&)col=(1|0)/.test(location.href)) {
 
                     // 如果页面url中含有col,为了防止页面刷新时收藏或者取消收藏会根据col来的问题,进行页面跳转拿掉参数
-                    location.href = location.href.replace(/\?col=(1|0)/, '');
+                    location.href = location.href.replace(/(\?|&)col=(1|0)/, '');
                 } else {
                     $this.toggleClass('collected');
                 }
diff --git a/public/js/header.js b/public/js/header.js
index 8474dcc..4f30ba2 100644
--- a/public/js/header.js
+++ b/public/js/header.js
@@ -39,6 +39,8 @@ var logoAngle = 0,
 
 var dataLayer = [];
 
+var cartTimer;
+
 // banner和地址的映射
 var bannerMap = {
         listboys: '4f78b0f418fc42314d8b6e791cfb7fa8',
@@ -76,11 +78,8 @@ var bannerMap = {
     },
     cookieMap = {};
 
-var $signinBtn = $('#signin-url');
-var $regBtn = $('#reg-url');
-
-$signinBtn.attr('href', '//www.yohobuy.com/signin.html?refer=' + window.location.href);
-$regBtn.attr('href', '//www.yohobuy.com/reg.html?refer=' + window.location.href);
+$('#signin-url').attr('href', '//www.yohobuy.com/signin.html?refer=' + window.location.href);
+$('#reg-url').attr('href', '//www.yohobuy.com/reg.html?refer=' + window.location.href);
 
 // handlebars模板
 centerFn = handlebars.compile($('#simple-account-info-tpl').html() || '');
@@ -321,6 +320,11 @@ function syncCratInfo(strG) {
             domain: '.yohobuy.com'
         });
     }
+
+    if (!$goodsNum || !$goodsNum.length) {
+        return cartTimer ? clearInterval(cartTimer) : false;
+    }
+
     if (window.cookie('_g')) {
         info = $.parseJSON(window.cookie('_g'));
         total = parseInt(info._nac, 10) + parseInt(info._ac, 10);
@@ -538,7 +542,8 @@ if (isSupportCss3Animation()) {
 syncPageChannel();
 getBannerAndNotice(); // 获取头部banner
 formatThirdMenu(); // 格式化三级菜单
-setInterval(syncCratInfo, 2000); // 定时同步购物车数量
+
+cartTimer = setInterval(syncCratInfo, 2000); // 定时同步购物车数量
 
 // 获取头部登陆信息
 (function() {
@@ -558,7 +563,12 @@ setInterval(syncCratInfo, 2000); // 定时同步购物车数量
     $loginBox.show();
 }());
 
-fetchUserInfoEvent.add(syncLoginInfo);
+fetchUserInfoEvent.add(function() {
+    if ($('.simple-user-center').length === 0) {
+        return;
+    }
+    syncLoginInfo();
+});
 
 $myYohoBox.hover(function() {
     var uid = getUid();  // eslint-disable-line
@@ -612,10 +622,10 @@ $searchKey.keyup(function(e) {
     } else if (e.which === 13) {
         submitSearch();
     } else {
-        val = val.replace(new RegExp('\'', 'gm'), ''); // 去掉特殊字符
-
-        $(this).val(val);
-        searchSuggest(val);
+        if ($searchSug && $searchSug.length) {
+            val = val.replace(new RegExp('\'', 'gm'), ''); // 去掉特殊字符
+            searchSuggest(val);
+        }
     }
 }).focus(function() {
     var val = $.trim($(this).val());
@@ -636,39 +646,41 @@ $searchKey.keyup(function(e) {
     }, 200);
 });
 
-$goCart.hover(function() {
-    var data, _html = '';
+if ($miniCart && $miniCart.length) {
+    $goCart.hover(function() {
+        var data, _html = '';
 
-    if ($goCart.hasClass('on-hover')) {
-        return;
-    }
-
-    data = $goCart.data();
-    if (data && data.num * 1) {
-        _html = '<div class="loading-cart"><h3>加载中,请稍后</h3></div>';
-        loadCartDetail(data.key);
-    } else {
-        _html = '<div class="empty-cart"><h3>您的购物车暂无商品</h3></div>';
-    }
-    $miniCart.html(_html);
-    $goCart.addClass('on-hover');
-}, function() {
-    $goCart.removeClass('on-hover');
-});
+        if ($goCart.hasClass('on-hover')) {
+            return;
+        }
 
-$goCart.on('click', '.cart-goods-del', function() {
-    var $dom = $(this),
-        data = $dom.data(),
-        callback;
+        data = $goCart.data();
+        if (data && data.num * 1) {
+            _html = '<div class="loading-cart"><h3>加载中,请稍后</h3></div>';
+            loadCartDetail(data.key);
+        } else {
+            _html = '<div class="empty-cart"><h3>您的购物车暂无商品</h3></div>';
+        }
+        $miniCart.html(_html);
+        $goCart.addClass('on-hover');
+    }, function() {
+        $goCart.removeClass('on-hover');
+    });
 
-    if (data) {
-        callback = function() {
-            $dom.closest('.goods-item').remove();
-        };
-        data.key = $goCart.data().key;
-        delCartGoods(data, callback);
-    }
-});
+    $goCart.on('click', '.cart-goods-del', function() {
+        var $dom = $(this),
+            data = $dom.data(),
+            callback;
+
+        if (data) {
+            callback = function() {
+                $dom.closest('.goods-item').remove();
+            };
+            data.key = $goCart.data().key;
+            delCartGoods(data, callback);
+        }
+    });
+}
 
 $subNav.on({
     mouseenter: function() {
diff --git a/public/scss/guang/_index.css b/public/scss/guang/_index.css
index 8eb32c8..859d2a8 100644
--- a/public/scss/guang/_index.css
+++ b/public/scss/guang/_index.css
@@ -167,15 +167,36 @@
             z-index: 99;
         }
 
-        .reco {
+        .type-icon{
+
             position: absolute;
             top: 0;
             left: 66px;
             height: 32px;
             width: 32px;
-            background: resolve("guang/msg-reco.png");
+            background: resolve("guang/msg-reco.png") no-repeat;
             background-size: 100% 100%;
             z-index: 100;
+
+            &.collocation {
+                background: resolve('guang/collocation.png') no-repeat;
+            }
+
+            &.fashion-good {
+                background: resolve('guang/fashion-good.png') no-repeat;
+            }
+
+            &.fashion-man {
+                background: resolve('guang/fashion-man.png') no-repeat;
+            }
+
+            &.reco {
+                background: resolve('guang/msg-reco.png') no-repeat;
+            }
+
+            &.topic {
+                background: resolve('guang/topic.png') no-repeat;
+            }
         }
 
         .msg-info {
diff --git a/utils/product-process.js b/utils/product-process.js
index 1fb45e1..e694717 100644
--- a/utils/product-process.js
+++ b/utils/product-process.js
@@ -1,6 +1,5 @@
 'use strict';
 const _ = require('lodash');
-const fp = require('lodash/fp');
 
 const camelCase = global.yoho.camelCase;
 const helpers = global.yoho.helpers;
@@ -16,9 +15,6 @@ const itemFromBase = {
     saleSpecial: {domain: 'sale', module: 's'}// sale.yohobuy.com
 };
 
-// NOTE: 这里修改了图片质量的参数
-helpers.image = _.flow(helpers.image, fp.replace(/\/quality\/\d*$/, '/quality/90'));
-
 /**
  * 根据性别来决定  默认图片获取字段   如果是 2、3
  *