Authored by ccbikai

Merge branch 'feature/star' into develop

@@ -45,6 +45,7 @@ app.use(bodyParser.urlencoded({ @@ -45,6 +45,7 @@ app.use(bodyParser.urlencoded({
45 extended: false 45 extended: false
46 })); 46 }));
47 app.use(cookieParser()); 47 app.use(cookieParser());
  48 +
48 app.use(session({ 49 app.use(session({
49 proxy: true, 50 proxy: true,
50 resave: false, 51 resave: false,
  1 +/**
  2 + * 新潮教室
  3 + * @author: wsl<shuiling.wang@yoho.cn>
  4 + * @date: 2016/05/30
  5 + */
  6 +'use strict';
  7 +
  8 +const mRoot = '../models';
  9 +const library = '../../../library';
  10 +const _ = require('lodash');
  11 +const headerModel = require('../../../doraemon/models/header');
  12 +const starModel = require(`${mRoot}/star`);
  13 +const helpers = require(`${library}/helpers`);
  14 +
  15 +const headTab = [
  16 + {
  17 + url: '/guang/star',
  18 + name: '全部'
  19 + },
  20 + {
  21 + url: '/guang/star/special',
  22 + name: '星专题'
  23 + },
  24 + {
  25 + url: '/guang/star/collocation',
  26 + name: '星搭配'
  27 + }
  28 +];
  29 +
  30 +const processPublicData = (req, title, navBtn) => {
  31 + let channel = req.query.channel || req.cookies._Channel || 'boys';
  32 + let headerData = headerModel.setNavHeader(title, channel, '', '', navBtn);
  33 + let renderData = {
  34 + module: 'guang',
  35 + title: title,
  36 + pageHeader: headerData
  37 + };
  38 +
  39 + return renderData;
  40 +};
  41 +
  42 +/**
  43 + * 星潮教室首页
  44 + * @param {[object]} req
  45 + * @param {[object]} res
  46 + * @return {[type]}
  47 + */
  48 +exports.index = (req, res) => {
  49 + const pageHeadTab = _.cloneDeep(headTab);
  50 +
  51 + pageHeadTab[0].cur = true;
  52 + res.render('star/index', _.assign({
  53 + page: 'star',
  54 + isStarIndexPage: true,
  55 + headTab: pageHeadTab
  56 + }, processPublicData(req, '星潮教室')));
  57 +};
  58 +
  59 +exports.getIndexHtml = (req, res) => {
  60 + starModel.getIndexData().then((result) => {
  61 + res.render('star/index-html', _.assign({
  62 + layout: false,
  63 + content: {
  64 + focus: true,
  65 + data: result.ads
  66 + },
  67 + starAvatar: result.starAvatar,
  68 + articles: result.articles
  69 + }));
  70 + });
  71 +};
  72 +
  73 +/**
  74 + * 星专题
  75 + * @param {[object]} req
  76 + * @param {[object]} res
  77 + * @return {[type]}
  78 + */
  79 +exports.special = (req, res) => {
  80 + starModel.getSpecialData().then((result) => {
  81 + const pageHeadTab = _.cloneDeep(headTab);
  82 +
  83 + pageHeadTab[1].cur = true;
  84 + res.render('star/special', _.assign({
  85 + page: 'special'
  86 + }, processPublicData(req, '星潮教室'), {
  87 + resources: result,
  88 + headTab: pageHeadTab
  89 + }));
  90 + });
  91 +};
  92 +
  93 +
  94 +/**
  95 + * 星搭配
  96 + * @param {[object]} req
  97 + * @param {[object]} res
  98 + * @return {[type]}
  99 + */
  100 +exports.collocation = (req, res) => {
  101 + const pageHeadTab = _.cloneDeep(headTab);
  102 +
  103 + pageHeadTab[2].cur = true;
  104 + res.render('star/collocation', _.assign({
  105 + isStarDetailPage: true,
  106 + page: 'collocation'
  107 + }, processPublicData(req, '星潮教室'), {
  108 + headTab: pageHeadTab
  109 + }));
  110 +};
  111 +
  112 +/**
  113 + * 星搭配文章请求
  114 + * @param {[object]} req
  115 + * @param {[object]} res
  116 + * @return {[type]}
  117 + */
  118 +exports.collocationList = (req, res) => {
  119 + let params = req.query;
  120 + let uid = req.user.uid || 0;
  121 +
  122 + starModel.getCollocationListData(params, uid).then((result) => {
  123 + res.render('star/list', _.assign({
  124 + layout: false,
  125 + params: params,
  126 + list: result,
  127 + isApp: req.query.appVersion || false
  128 + }));
  129 + });
  130 +};
  131 +
  132 +/**
  133 + * 收藏文章
  134 + * @param {[type]} req [description]
  135 + * @param {[type]} res [description]
  136 + * @return {[type]}
  137 + */
  138 +exports.setFavorite = (req, res) => {
  139 + let params = req.body;
  140 + let uid = req.user.uid || 0;
  141 + let isApp = req.query.appVersion || false;
  142 + let url = '/guang/star/collocation';
  143 + let urlEncode = '';
  144 +
  145 + starModel.setFavorite(params, uid).then((result) => {
  146 + if (result.code === 401) {
  147 + if (!isApp) {
  148 + result.data = helpers.urlFormat('/signin.html', {
  149 + refer: req.get('Referer') || url
  150 + });
  151 + } else {
  152 + urlEncode = '\\/guang\\/star\\/collocation';
  153 + result.data = `${url}?openby:yohobuy={"action":"go.weblogin","params":{"jumpurl":{"url":"${urlEncode}","param":{"from":"app"}},"requesturl":{"url":"","param":{}},"priority":"N"}}`; // eslint-disable-line
  154 + }
  155 + }
  156 + res.json(result);
  157 + });
  158 +};
  159 +
  160 +/**
  161 + * 明星文章专区
  162 + * @param {[object]} req
  163 + * @param {[object]} res
  164 + * @return {[type]}
  165 + */
  166 +exports.detail = (req, res) => {
  167 + res.render('star/detail', _.assign({
  168 + isStarDetailPage: true,
  169 + page: 'detail-list'
  170 + }, processPublicData(req, req.query.tag, false)));
  171 +};
  172 +
  173 +/**
  174 + * 明星专题文章请求
  175 + * @param {[object]} req
  176 + * @param {[object]} res
  177 + * @return {[type]}
  178 + */
  179 +exports.detailList = (req, res) => {
  180 + let params = req.query;
  181 +
  182 + starModel.getDetailData(params).then((result) => {
  183 + res.render('star/list', _.assign({
  184 + layout: false,
  185 + params: params,
  186 + list: result,
  187 + isApp: req.query.appVersion || false
  188 + }));
  189 + });
  190 +};
  1 +/**
  2 + * sub app guang
  3 + * @author: Bi Kai<kai.bi@yoho.cn>
  4 + * @date: 2016/05/09
  5 + */
  6 +
  7 +var express = require('express'),
  8 + path = require('path'),
  9 + hbs = require('express-handlebars');
  10 +
  11 +var app = express();
  12 +
  13 +// set view engin
  14 +var doraemon = path.join(__dirname, '../../doraemon/views'); // parent view root
  15 +
  16 +app.on('mount', function(parent) {
  17 + delete parent.locals.settings; // 不继承父 App 的设置
  18 + Object.assign(app.locals, parent.locals);
  19 +});
  20 +
  21 +app.set('views', path.join(__dirname, 'views/action'));
  22 +app.engine('.hbs', hbs({
  23 + extname: '.hbs',
  24 + defaultLayout: 'layout',
  25 + layoutsDir: doraemon,
  26 + partialsDir: [path.join(__dirname, 'views/partial'), `${doraemon}/partial`],
  27 + helpers: require(`${global.library}/helpers`)
  28 +}));
  29 +
  30 +// router
  31 +app.use(require('./router'));
  32 +
  33 +module.exports = app;
  1 +/**
  2 + * 新潮教室
  3 + * @author: wsl<shuiling.wang@yoho.cn>
  4 + * @date: 2016/05/30
  5 + */
  6 +'use strict';
  7 +const library = '../../../library';
  8 +const utils = '../../../utils';
  9 +const resourcesProcess = require(`${utils}/resources-process`);
  10 +const ServiceAPI = require(`${library}/api`).ServiceAPI;
  11 +const API = require(`${library}/api`).API;
  12 +const sign = require(`${library}/sign`);
  13 +const logger = require(`${library}/logger`);
  14 +const camelCase = require(`${library}/camel-case`);
  15 +const helpers = require(`${library}/helpers`);
  16 +const _ = require('lodash');
  17 +const serviceAPI = new ServiceAPI();
  18 +const api = new API();
  19 +
  20 +const contentCode = {
  21 + special: '89cc20483ee2cbc8a716dcfe2b6c7603'
  22 +};
  23 +
  24 +class Star {
  25 + /**
  26 + * 获取资源位数据
  27 + * @param {[string]} page
  28 + * @return {[array]}
  29 + */
  30 + static getResources(page) {
  31 + return serviceAPI.get('operations/api/v5/resource/get', sign.apiSign({
  32 + content_code: contentCode[page]
  33 + })).then((result) => {
  34 + if (result && result.code === 200) {
  35 + return resourcesProcess(result.data);
  36 + } else {
  37 + logger.error('星潮教室页面资源位返回 code 不是 200');
  38 + return [];
  39 + }
  40 + });
  41 + }
  42 +
  43 + /**
  44 + * 星潮教室首页数据处理
  45 + * @param {[array]} list
  46 + * @return {[array]}
  47 + */
  48 + static processIndexData(list) {
  49 + const formatData = {
  50 + ads: [],
  51 + starAvatar: [],
  52 + articles: []
  53 + };
  54 +
  55 + list = list || {};
  56 + list = camelCase(list);
  57 +
  58 + // 首页资源位数据处理
  59 + _.forEach(list.ads.data, (data) => {
  60 + formatData.ads.push({
  61 + src: data.src,
  62 + url: data.url
  63 + });
  64 + });
  65 +
  66 + // 首页明星文章数据处理
  67 + _.forEach(list.list, (data) => {
  68 + const avatar = {
  69 + tags: []
  70 + };
  71 +
  72 + if (data.ext.tags.length > 1) {
  73 + avatar.isSwiper = true;
  74 + }
  75 +
  76 + _.forEach(data.ext.tags, (tags) => {
  77 + avatar.tags.push({
  78 + avatarUrl: `/guang/star/detail?tag=${tags.tagName}`,
  79 + cover: tags.cover,
  80 + tagName: tags.tagName
  81 + });
  82 + });
  83 +
  84 + formatData.articles.push(_.merge({
  85 + id: data.id,
  86 + url: data.url,
  87 + title: data.title,
  88 + articeTxt: data.intro,
  89 + src: data.src,
  90 + publishTime: helpers.dateFormat('MM月DD日 hh:mm', data.publishTime),
  91 + viewsNum: data.viewsNum
  92 + }, avatar));
  93 + });
  94 +
  95 + // 首页明星头像数据处理
  96 + _.forEach(list.tags, (data) => {
  97 + let url = `/guang/star/detail?tag=${data.tagName}`;
  98 +
  99 + formatData.starAvatar.push({
  100 + url: url,
  101 + cover: data.cover
  102 + });
  103 + });
  104 +
  105 + return formatData;
  106 + }
  107 +
  108 + static processShareUrl(post) {
  109 + return `${post.share.url}&openby:yohobuy={"action":"go.share","params":{"pic":"${helpers.image(post.src, 640, 640)}","title":"${post.title}","url":"${post.share.url}","content":"潮流资讯,新鲜贩售,YOHO!Buy有货【逛】不停"}}`; // eslint-disable-line
  110 + }
  111 +
  112 + /**
  113 + * 明星专题列表数据处理
  114 + * @param {[array]} list
  115 + * @return {[array]}
  116 + */
  117 + static processDetailData(list) {
  118 + const formatData = [];
  119 +
  120 + list = list || [];
  121 + list = camelCase(list);
  122 +
  123 + _.forEach(list, (data) => {
  124 + data.publishTime = helpers.dateFormat('MM月DD日 hh:mm', data.publishTime);
  125 + if (data.share && data.share.url) {
  126 + data.share.url = Star.processShareUrl(data);
  127 + }
  128 + formatData.push(data);
  129 + });
  130 +
  131 + return formatData;
  132 + }
  133 +
  134 +
  135 + /**
  136 + * 星搭配文章列表数据处理
  137 + */
  138 + static processCollocationData(list) {
  139 + const formatData = [];
  140 +
  141 + list = list || [];
  142 + list = camelCase(list);
  143 +
  144 + _.forEach(list, (data) => {
  145 + if (data.isFavor === 'N') {
  146 + data.isCollected = false;
  147 + } else {
  148 + data.isCollected = true;
  149 + }
  150 + formatData.push(data);
  151 + });
  152 +
  153 + return formatData;
  154 + }
  155 +
  156 + /**
  157 + * 星潮首页
  158 + */
  159 + static getIndexData() {
  160 + return api.get('', sign.apiSign({
  161 + method: 'app.starClass.index',
  162 + code: '8adc27fcf5676f356602889afcfd2a8e'
  163 + })).then((result) => {
  164 + if (result && result.code === 200) {
  165 + return Star.processIndexData(result.data);
  166 + } else {
  167 + logger.error('星潮教室首页数据返回 code 不是 200');
  168 + return {};
  169 + }
  170 + });
  171 + }
  172 +
  173 + /**
  174 + * 明星专题
  175 + */
  176 + static getDetailData(params) {
  177 + return api.get('', sign.apiSign({
  178 + method: 'app.starClass.lastTagArticle',
  179 + tag: params.tag,
  180 + page: params.page || 1,
  181 + size: 10
  182 + })).then((result) => {
  183 + if (result && result.code === 200) {
  184 + if (params.page > result.data.totalPage) {
  185 + return '';
  186 + } else {
  187 + return Star.processDetailData(result.data.list);
  188 + }
  189 + } else {
  190 + logger.error('明星专题文章数据返回 code 不是 200');
  191 + return [];
  192 + }
  193 + });
  194 + }
  195 +
  196 +
  197 + /**
  198 + * 星专题
  199 + */
  200 + static getSpecialData() {
  201 + return Star.getResources('special');
  202 + }
  203 +
  204 + /**
  205 + * 星搭配
  206 + */
  207 + static getCollocationListData(params, uid) {
  208 +
  209 + return serviceAPI.get('guang/api/v5/article/getStarClassroomArticleList', sign.apiSign(Object.assign({
  210 + limit: '20',
  211 + uid: uid
  212 + }, params))).then((result) => {
  213 + if (result && result.code === 200) {
  214 + return Star.processCollocationData(result.data.list.artList);
  215 + } else {
  216 + logger.error('获取星搭配文章列表返回 code 不是 200');
  217 + return [];
  218 + }
  219 + });
  220 + }
  221 +
  222 + static setFavorite(params, uid) {
  223 + if (!uid) {
  224 + return Promise.resolve({
  225 + code: 401,
  226 + message: '未登录'
  227 + });
  228 + }
  229 +
  230 + return api.get('', sign.apiSign({
  231 + method: params.type === 'del' ? 'app.sns.cancelFavorBackCount' : 'app.sns.setFavorBackCount',
  232 + client_type: 'h5',
  233 + article_id: params.articleId,
  234 + uid: uid
  235 + }));
  236 + }
  237 +}
  238 +
  239 +module.exports = Star;
  1 +/**
  2 + * router of sub app channel
  3 + * @author: Bi Kai<kai.bi@yoho.cn>
  4 + * @date: 2016/05/09
  5 + */
  6 +
  7 +'use strict';
  8 +
  9 +const express = require('express');
  10 +const cRoot = './controllers';
  11 +const star = require(cRoot + '/star');
  12 +
  13 +const router = express.Router(); // eslint-disable-line
  14 +
  15 +router.get('/star', star.index); // 星潮教室首页
  16 +router.get('/star/getIndexHtml', star.getIndexHtml); // 星潮教室首页
  17 +router.get('/star/detail', star.detail); // 明星文章专区
  18 +router.get('/star/detailList', star.detailList); // 明星文章专区文章Ajax请求
  19 +router.get('/star/special', star.special); // 星潮教室星专题
  20 +router.get('/star/collocation', star.collocation); // 星潮教室星搭配
  21 +router.get('/star/collocation/list', star.collocationList); // 星潮教室星搭配文章请求
  22 +
  23 +router.post('/star/setFavorite', star.setFavorite); // 收藏文章
  24 +
  25 +module.exports = router;
  1 +<div class="star-page yoho-page">
  2 + {{> star/head-tab}}
  3 + <ul class="collocation-list"></ul>
  4 +</div>
  1 +<div class="star-page yoho-page">
  2 + <ul class="detail-list" data-name="{{title}}">
  3 + {{> star/list}}
  4 + </ul>
  5 +</div>
  1 +<div class="loading-tip">松手开始刷新...</div>
  2 +<div class="star-wrap">
  3 + <div class="star-content">
  4 + {{#content}}
  5 + {{#if focus}}
  6 + {{> resources/banner-top}}
  7 + {{/if}}
  8 + {{/content}}
  9 +
  10 + <div class="avatar-wrap">
  11 + <div class="avatar-swiper avatar">
  12 + <ul class="clearfix swiper-wrapper">
  13 + {{# starAvatar}}
  14 + <li class="swiper-slide">
  15 + <span class="rank-avatar" data-url="{{url}}" data-avatar="{{image cover 180 180}}"></span>
  16 + </li>
  17 + {{/ starAvatar}}
  18 + </ul>
  19 + </div>
  20 + </div>
  21 +
  22 + <ul class="star-info clearfix">
  23 + {{#each articles}}
  24 + <li data-id="{{id}}">
  25 + <div class="star-avatar">
  26 + {{#if isSwiper}}
  27 + <div class="article-avatar-swiper">
  28 + <ul class="clearfix swiper-wrapper">
  29 + {{#each tags}}
  30 + <li class="swiper-slide">
  31 + <a href="{{avatarUrl}}">
  32 + <div data-avatar="{{image cover 100 100}}" class="rank-avatar" ></div>
  33 + <p class="name">{{tagName}}</p>
  34 + </a>
  35 + </li>
  36 + {{/each}}
  37 + </ul>
  38 + </div>
  39 + {{else}}
  40 + {{# tags}}
  41 + <a href="{{avatarUrl}}">
  42 + <div data-avatar="{{image cover 100 100}}" class="rank-avatar" ></div>
  43 + <p class="name">{{tagName}}</p>
  44 + </a>
  45 + {{/ tags}}
  46 + {{/if}}
  47 + </div>
  48 + <div class="star-article">
  49 + <i class="article-arrow"></i>
  50 + <a href="{{url}}"><h2 class="article-title">{{title}}</h2></a>
  51 + <div class="artice-cont">
  52 + <a href="{{url}}"><p>{{articeTxt}}</p></a>
  53 + <div class="artice-imgs-area">
  54 + <img src="{{image src 266 266}}" />
  55 +
  56 + {{!-- <ul class="artice-imgs">
  57 + {{#each articeImg}}
  58 + <li><img src="{{image . 640 640}}" /></li>
  59 + {{/each}}
  60 + </ul> --}}
  61 +
  62 + </div>
  63 + </div>
  64 + <div class="artice-o">
  65 + <span class="time"><i class="iconfont time-ico">&#xe603;</i>{{publishTime}}</span>
  66 + <span class="see"><i class="iconfont see-ico">&#xe602;</i>{{viewsNum}}</span>
  67 + </div>
  68 + </div>
  69 + </li>
  70 + <li data-id="{{id}}">
  71 + <div class="star-avatar">
  72 + {{#if isSwiper}}
  73 + <div class="article-avatar-swiper">
  74 + <ul class="clearfix swiper-wrapper">
  75 + {{#each tags}}
  76 + <li class="swiper-slide">
  77 + <a href="{{avatarUrl}}">
  78 + <div data-avatar="{{image cover 100 100}}" class="rank-avatar" ></div>
  79 + <p class="name">{{tagName}}</p>
  80 + </a>
  81 + </li>
  82 + {{/each}}
  83 + </ul>
  84 + </div>
  85 + {{else}}
  86 + {{# tags}}
  87 + <a href="{{avatarUrl}}">
  88 + <div data-avatar="{{image cover 100 100}}" class="rank-avatar" ></div>
  89 + <p class="name">{{tagName}}</p>
  90 + </a>
  91 + {{/ tags}}
  92 + {{/if}}
  93 + </div>
  94 + <div class="star-article">
  95 + <i class="article-arrow"></i>
  96 + <a href="{{url}}"><h2 class="article-title">{{title}}</h2></a>
  97 + <div class="artice-cont">
  98 + <a href="{{url}}"><p>{{articeTxt}}</p></a>
  99 + <div class="artice-imgs-area">
  100 + <img src="{{image src 266 266}}" />
  101 +
  102 + {{!-- <ul class="artice-imgs">
  103 + {{#each articeImg}}
  104 + <li><img src="{{image . 640 640}}" /></li>
  105 + {{/each}}
  106 + </ul> --}}
  107 +
  108 + </div>
  109 + </div>
  110 + <div class="artice-o">
  111 + <span class="time"><i class="iconfont time-ico">&#xe603;</i>{{publishTime}}</span>
  112 + <span class="see"><i class="iconfont see-ico">&#xe602;</i>{{viewsNum}}</span>
  113 + </div>
  114 + </div>
  115 + </li>
  116 + {{/each}}
  117 + </ul>
  118 + </div>
  119 +</div>
  120 +
  121 +{{!-- <div class="view-img">
  122 + <div class="mask-bg"></div>
  123 + <div class="view-area">
  124 + <div class="swiper-view">
  125 + <ul class="clearfix swiper-wrapper"></ul>
  126 + </div>
  127 + </div>
  128 +</div> --}}
  1 +<div class="star-page yoho-page">
  2 + {{> star/head-tab}}
  3 + <div class="swiper-num"></div>
  4 + <div class="star-main"></div>
  5 +</div>
  1 +<div class="star-page yoho-page">
  2 + {{> star/head-tab}}
  3 + <ul class="special-list">
  4 + {{#each resources}}
  5 + {{# data}}
  6 + <li data-bp-id="guang_subjectList_{{title}}_false" class="buriedpoint">
  7 + <a href="{{url}}">
  8 + <img class="lazy" data-original="{{image src 640 310}}" alt="{{alt}}"/>
  9 + <p>{{title}}</p>
  10 + </a>
  11 + </li>
  12 + {{/ data}}
  13 + {{/each}}
  14 + </ul>
  15 +</div>
  1 +<ul class="head-tab">
  2 + {{#each headTab}}
  3 + <li {{#if cur}} class="cur" {{/if}} ><a href="{{ url }}" data-bp-id="guang_tab_{{name}}_false">{{ name }}</a></li>
  4 + {{/each}}
  5 +</ul>
  1 +{{#each list}}
  2 + <li articleId="{{id}}" data-bp-id="guang_collocationList_{{title}}_false" class="buriedpoint">
  3 +
  4 + {{#if src}}
  5 + <a href="{{url}}"><img class="lazy" src ="" data-original="{{image src 640 310}}" /></a>
  6 + {{/if}}
  7 +
  8 + <div class="cont-area ">
  9 + <a href="{{url}}"><h2 class="title">{{title}}</h2></a>
  10 + <p class="cont-txt">{{intro}}</p>
  11 + <div class="count-area">
  12 + <span class="time"><i class="iconfont time-ico">&#xe603;</i>{{publishTime}}</span>
  13 + <span class="see"><i class="iconfont see-ico">&#xe602;</i>{{viewsNum}}</span>
  14 + {{#if ../isApp}}
  15 + {{#if share.url}}
  16 + <a href="{{share.url}}" class="iconfont forward">&#xe600;</a>
  17 + {{/if}}
  18 + {{/if}}
  19 + <span class="collection"><i class="iconfont collected-ico {{#isCollected}} collected {{/isCollected}}">&#xe605;</i></span>
  20 + </div>
  21 + </div>
  22 + </li>
  23 +{{/each}}
@@ -177,7 +177,7 @@ exports.search = (req, res) => { @@ -177,7 +177,7 @@ exports.search = (req, res) => {
177 let params = Object.assign({}, req.query); 177 let params = Object.assign({}, req.query);
178 178
179 // uid = 9239279 179 // uid = 9239279
180 - let uid = req.user.uid || 0; 180 + let uid = 9239279 || req.user.uid || 0;
181 181
182 saleModel.getSearchData(params, uid).then((result) => { 182 saleModel.getSearchData(params, uid).then((result) => {
183 let vipLevel = result[1].curLevel; 183 let vipLevel = result[1].curLevel;
@@ -187,10 +187,7 @@ exports.search = (req, res) => { @@ -187,10 +187,7 @@ exports.search = (req, res) => {
187 vipObj = Object.assign({ 187 vipObj = Object.assign({
188 saleVip: (req.query.saleType === '2' && (!uid || vipLevel === '0')), 188 saleVip: (req.query.saleType === '2' && (!uid || vipLevel === '0')),
189 vipLevel: vipLevel, 189 vipLevel: vipLevel,
190 - saleViplogin: vipLevel >= 1 ? true : false,  
191 - vipPrice1: vipLevel === '1',  
192 - vipPrice2: vipLevel === '2',  
193 - vipPrice3: vipLevel === '3' 190 + saleViplogin: vipLevel >= 1 ? true : false
194 }, vipObj); 191 }, vipObj);
195 } 192 }
196 193
@@ -13,6 +13,7 @@ module.exports = app => { @@ -13,6 +13,7 @@ module.exports = app => {
13 13
14 // 业务模块 14 // 业务模块
15 app.use('/product', require('./apps/product')); 15 app.use('/product', require('./apps/product'));
  16 + app.use('/guang', require('./apps/guang'));
16 app.use('/passport', require('./apps/passport')); 17 app.use('/passport', require('./apps/passport'));
17 app.use('/coupon', require('./apps/coupon')); 18 app.use('/coupon', require('./apps/coupon'));
18 }; 19 };
@@ -26,7 +26,7 @@ @@ -26,7 +26,7 @@
26 <link rel="apple-touch-startup-image" sizes="640x920" href="http://static.yohobuy.com/m/v1/img/startup/startup-retina.png" media="screen and (max-device-width: 480px) and (-webkit-min-device-pixel-ratio: 2)"> 26 <link rel="apple-touch-startup-image" sizes="640x920" href="http://static.yohobuy.com/m/v1/img/startup/startup-retina.png" media="screen and (max-device-width: 480px) and (-webkit-min-device-pixel-ratio: 2)">
27 <link rel="apple-touch-startup-image" sizes="320x460" href="http://static.yohobuy.com/m/v1/img/startup/startup.png" media="screen and (max-device-width: 320)"> 27 <link rel="apple-touch-startup-image" sizes="320x460" href="http://static.yohobuy.com/m/v1/img/startup/startup.png" media="screen and (max-device-width: 320)">
28 </head> 28 </head>
29 - <body {{#if isPassportPage}}class=passport-body{{/if}}> 29 + <body {{#if isPassportPage}}class=passport-body{{/if}} {{#if isStarIndexPage}} class="star-index-bg"{{/if}} {{#if isStarDetailPage}}class="star-class-body"{{/if}}>
30 <div class="main-wrap"> 30 <div class="main-wrap">
31 {{#if systemUpdate}} 31 {{#if systemUpdate}}
32 {{> updata}} 32 {{> updata}}
@@ -33,11 +33,11 @@ @@ -33,11 +33,11 @@
33 "dependencies": { 33 "dependencies": {
34 "bluebird": "^3.4.0", 34 "bluebird": "^3.4.0",
35 "body-parser": "^1.15.0", 35 "body-parser": "^1.15.0",
36 - "cookie-parser": "^1.4.1", 36 + "cookie-parser": "^1.4.3",
37 "express": "^4.13.1", 37 "express": "^4.13.1",
38 "express-handlebars": "^3.0.0", 38 "express-handlebars": "^3.0.0",
39 "influxdb-winston": "^1.0.1", 39 "influxdb-winston": "^1.0.1",
40 - "lodash": "^4.12.0", 40 + "lodash": "^4.13.1",
41 "md5": "^2.1.0", 41 "md5": "^2.1.0",
42 "memcached": "^2.2.1", 42 "memcached": "^2.2.1",
43 "moment": "^2.13.0", 43 "moment": "^2.13.0",
@@ -49,16 +49,16 @@ @@ -49,16 +49,16 @@
49 "serve-favicon": "^2.3.0", 49 "serve-favicon": "^2.3.0",
50 "uuid": "^2.0.2", 50 "uuid": "^2.0.2",
51 "winston": "^2.2.0", 51 "winston": "^2.2.0",
52 - "winston-daily-rotate-file": "^1.0.1", 52 + "winston-daily-rotate-file": "^1.1.3",
53 "yoho-connect-memcached": "^1.0.3", 53 "yoho-connect-memcached": "^1.0.3",
54 "yoho-express-session": "^1.0.3" 54 "yoho-express-session": "^1.0.3"
55 }, 55 },
56 "devDependencies": { 56 "devDependencies": {
57 "autoprefixer": "^6.3.6", 57 "autoprefixer": "^6.3.6",
58 - "ava": "^0.14.0", 58 + "ava": "^0.15.2",
59 "babel-preset-es2015": "^6.9.0", 59 "babel-preset-es2015": "^6.9.0",
60 "babel-register": "^6.9.0", 60 "babel-register": "^6.9.0",
61 - "eslint": "^2.10.2", 61 + "eslint": "^2.12.0",
62 "eslint-config-yoho": "^1.0.1", 62 "eslint-config-yoho": "^1.0.1",
63 "gulp": "^3.9.1", 63 "gulp": "^3.9.1",
64 "gulp-cssnano": "^2.1.2", 64 "gulp-cssnano": "^2.1.2",
@@ -68,15 +68,15 @@ @@ -68,15 +68,15 @@
68 "gulp-util": "^3.0.7", 68 "gulp-util": "^3.0.7",
69 "husky": "^0.11.4", 69 "husky": "^0.11.4",
70 "nodemon": "1.9.2", 70 "nodemon": "1.9.2",
71 - "nyc": "^6.4.3", 71 + "nyc": "^6.4.4",
72 "postcss-assets": "^4.0.1", 72 "postcss-assets": "^4.0.1",
73 - "postcss-cachebuster": "^0.1.2", 73 + "postcss-cachebuster": "^0.1.3",
74 "postcss-calc": "^5.2.1", 74 "postcss-calc": "^5.2.1",
75 "postcss-center": "^1.0.0", 75 "postcss-center": "^1.0.0",
76 "postcss-clearfix": "^1.0.0", 76 "postcss-clearfix": "^1.0.0",
77 "postcss-crip": "^2.0.0", 77 "postcss-crip": "^2.0.0",
78 "postcss-opacity": "^3.0.0", 78 "postcss-opacity": "^3.0.0",
79 - "postcss-position": "^0.4.0", 79 + "postcss-position": "^0.5.0",
80 "postcss-pxtorem": "^3.3.1", 80 "postcss-pxtorem": "^3.3.1",
81 "postcss-short": "^1.4.0", 81 "postcss-short": "^1.4.0",
82 "postcss-sprites": "^3.1.2", 82 "postcss-sprites": "^3.1.2",
@@ -84,17 +84,18 @@ @@ -84,17 +84,18 @@
84 "precss": "^1.4.0", 84 "precss": "^1.4.0",
85 "rewire": "^2.5.1", 85 "rewire": "^2.5.1",
86 "shelljs": "^0.7.0", 86 "shelljs": "^0.7.0",
87 - "stylelint": "^6.4.1", 87 + "stylelint": "^6.5.1",
88 "stylelint-config-yoho": "^1.2.3", 88 "stylelint-config-yoho": "^1.2.3",
89 - "webpack": "^1.13.0", 89 + "webpack": "^1.13.1",
90 "webpack-dev-server": "^1.14.1", 90 "webpack-dev-server": "^1.14.1",
91 "webpack-stream": "^3.1.0", 91 "webpack-stream": "^3.1.0",
92 "yoho-fastclick": "^1.0.6", 92 "yoho-fastclick": "^1.0.6",
93 "yoho-hammer": "^2.0.7", 93 "yoho-hammer": "^2.0.7",
94 "yoho-handlebars": "^4.0.5", 94 "yoho-handlebars": "^4.0.5",
  95 + "yoho-iscroll": "^5.2.0",
95 "yoho-jquery": "^2.2.4", 96 "yoho-jquery": "^2.2.4",
96 "yoho-jquery-lazyload": "^1.9.7", 97 "yoho-jquery-lazyload": "^1.9.7",
97 - "yoho-mlellipsis": "0.0.2", 98 + "yoho-mlellipsis": "0.0.3",
98 "yoho-swiper": "^3.3.1" 99 "yoho-swiper": "^3.3.1"
99 } 100 }
100 } 101 }
@@ -266,21 +266,23 @@ $('.nav-home').on('touchstart', function() { @@ -266,21 +266,23 @@ $('.nav-home').on('touchstart', function() {
266 window.cancelAnimationFrame = cancelAnimationFrame; 266 window.cancelAnimationFrame = cancelAnimationFrame;
267 }()); 267 }());
268 268
  269 +function queryString() {
  270 + var vars = [],
  271 + hash,
  272 + i;
  273 + var hashes = window.location.search.slice(1).split('&');
  274 +
  275 + for (i = 0; i < hashes.length; i++) {
  276 + hash = hashes[i].split('=');
  277 + vars.push(hash[0]);
  278 + vars[hash[0]] = hash[1];
  279 + }
  280 + return vars;
  281 +}
  282 +
269 // 给jQuery 扩展 queryString函数 283 // 给jQuery 扩展 queryString函数
270 $.extend({ 284 $.extend({
271 - queryString: function() {  
272 - var vars = [],  
273 - hash,  
274 - i;  
275 - var hashes = window.location.href.slice(window.location.href.indexOf('?') + 1).split('&');  
276 -  
277 - for (i = 0; i < hashes.length; i++) {  
278 - hash = hashes[i].split('=');  
279 - vars.push(hash[0]);  
280 - vars[hash[0]] = hash[1];  
281 - }  
282 - return vars;  
283 - } 285 + queryString: queryString
284 }); 286 });
285 287
286 // 临时修改 footer 288 // 临时修改 footer
@@ -308,3 +310,5 @@ window.getShoppingKey = getShoppingKey; @@ -308,3 +310,5 @@ window.getShoppingKey = getShoppingKey;
308 window.rePosFooter = rePosFooter; 310 window.rePosFooter = rePosFooter;
309 311
310 window.reMarginFooter = reMarginFooter; 312 window.reMarginFooter = reMarginFooter;
  313 +
  314 +window.queryString = queryString();
  1 +/**
  2 + * 星潮教室-星搭配分页加载
  3 + * @author: wsl<shuiling.wang@yoho.cn>
  4 + * @date: 2016/4/12
  5 + */
  6 +
  7 +var $ = require('yoho-jquery'),
  8 + tip = require('../plugin/tip'),
  9 + loading = require('../plugin/loading'),
  10 + lazyLoad = require('yoho-jquery-lazyload'),
  11 + ellipsis = require('yoho-mlellipsis');
  12 +
  13 +var stopLoading = false,
  14 + page = 1;
  15 +
  16 +require('./list-common');
  17 +
  18 +ellipsis.init();
  19 +
  20 +function massageAJAX(pageData) {
  21 + var $this, $title, $cont;
  22 +
  23 + loading.showLoadingMask();
  24 + $.ajax({
  25 + type: 'GET',
  26 + url: '/guang/star/collocation/list',
  27 + data: {
  28 + page: pageData,
  29 + appVersion: window.queryString.app_version
  30 + },
  31 + dataType: 'html',
  32 + success: function(data) {
  33 + stopLoading = false;
  34 +
  35 + if (data === '') {
  36 + stopLoading = true;
  37 + tip.show('没有更多内容了');
  38 + }
  39 +
  40 + $('.collocation-list').append(data);
  41 +
  42 + // 限制标题字数
  43 + $('.cont-area').each(function() {
  44 + $this = $(this);
  45 + $title = $this.find('.title');
  46 + $cont = $this.find('.cont-txt');
  47 +
  48 + $title[0].mlellipsis(2);
  49 + $cont[0].mlellipsis(2);
  50 + });
  51 +
  52 + loading.hideLoadingMask();
  53 + lazyLoad($('img.lazy'));
  54 + },
  55 + error: function() {
  56 + tip.show('网络断开连接了~');
  57 + }
  58 + });
  59 +}
  60 +
  61 +function scrollHandler() {
  62 + if (!stopLoading && ($(window).scrollTop() + $(window).height() > $('body').height() - 100)) {
  63 + stopLoading = true;
  64 + page++;
  65 + massageAJAX(page);
  66 + }
  67 +}
  68 +
  69 +$(window).scroll(function() {
  70 + scrollHandler();
  71 +});
  72 +
  73 +if ($('.collocation-list').find('li').length === 0) {
  74 + massageAJAX(1);
  75 +}
  1 +/**
  2 + * 星潮教室-明星专题列表
  3 + * @author: wsl<shuiling.wang@yoho.cn>
  4 + * @date: 2016/6/7
  5 + */
  6 +var $ = require('yoho-jquery'),
  7 + tip = require('../plugin/tip'),
  8 + loading = require('../plugin/loading'),
  9 + lazyLoad = require('yoho-jquery-lazyload'),
  10 + ellipsis = require('yoho-mlellipsis');
  11 +
  12 +var $detailList = $('.detail-list'),
  13 + stopLoading = false,
  14 + page = 1;
  15 +
  16 +require('./list-common');
  17 +
  18 +ellipsis.init();
  19 +
  20 +// 翻页
  21 +function massageAJAX(pageData) {
  22 + var $this, $title, $cont;
  23 +
  24 + loading.showLoadingMask();
  25 + $.ajax({
  26 + type: 'GET',
  27 + url: '/guang/star/detailList',
  28 + data: {
  29 + page: pageData,
  30 + tag: $('.detail-list').data('name')
  31 + },
  32 + dataType: 'html',
  33 + success: function(data) {
  34 + stopLoading = false;
  35 +
  36 + if (data === '') {
  37 + stopLoading = true;
  38 + tip.show('没有更多内容了');
  39 + }
  40 +
  41 + $('.detail-list').append(data);
  42 +
  43 + // 限制标题字数
  44 + $('.cont-area').each(function() {
  45 + $this = $(this);
  46 + $title = $this.find('.title');
  47 + $cont = $this.find('.cont-txt');
  48 +
  49 + $title[0].mlellipsis(2);
  50 + $cont[0].mlellipsis(2);
  51 + });
  52 +
  53 + lazyLoad($('img.lazy'));
  54 + loading.hideLoadingMask();
  55 + },
  56 + error: function() {
  57 + tip.show('网络断开连接了~');
  58 + }
  59 + });
  60 +}
  61 +
  62 +function scrollHandler() {
  63 + if (!stopLoading && ($(window).scrollTop() + $(window).height() > $('body').height() - 100)) {
  64 + stopLoading = true;
  65 + page++;
  66 + massageAJAX(page);
  67 + }
  68 +}
  69 +
  70 +$(window).scroll(function() {
  71 + scrollHandler();
  72 +});
  73 +
  74 +if ($detailList.find('li').length === 0) {
  75 + massageAJAX(1);
  76 +}
  1 +/**
  2 + * 星潮教室-列表公共部分
  3 + * @author: wsl<shuiling.wang@yoho.cn>
  4 + * @date: 2016/6/7
  5 +*/
  6 +
  7 +var $ = require('yoho-jquery'),
  8 + tip = require('../plugin/tip');
  9 +
  10 +require('../common');
  11 +
  12 +// 星搭配收藏请求
  13 +$(document).on('click', '.collection', function() {
  14 + var $that = $(this),
  15 + $icon = $that.find('.collected-ico');
  16 +
  17 + var type;
  18 +
  19 + if ($icon.hasClass('collected')) {
  20 + type = 'del';
  21 + } else {
  22 + type = 'fav';
  23 + }
  24 +
  25 +
  26 + $.ajax({
  27 + type: 'POST',
  28 + url: '/guang/star/setFavorite',
  29 + data: {
  30 + articleId: $that.parents('li').attr('articleId'),
  31 + type: type
  32 + },
  33 + success: function(data) {
  34 + var code = data.code;
  35 +
  36 + if (code === 200) {
  37 + if ($icon.hasClass('collected')) {
  38 + $icon.removeClass('collected');
  39 + } else {
  40 + $icon.addClass('collected');
  41 + }
  42 +
  43 + }
  44 +
  45 + if (code === 401) {
  46 + if ($('#collocation-link').length <= 0) {
  47 + $('body').append('<a href=\'' + data.data + '\' style="display:none;" id="collocation-link">' +
  48 + '<span class="collocation-link"></span></a>');
  49 + }
  50 +
  51 + $('.collocation-link').click();
  52 + }
  53 + },
  54 + error: function() {
  55 + tip.show('网络断开连接了~');
  56 + }
  57 + });
  58 +});
  59 +
  60 +// 分享成功
  61 +window.successShare = function() {
  62 + $.ajax({
  63 + type: 'POST',
  64 + url: '/guang/starclass/forward',
  65 + success: function(data) {
  66 + var code = data.code;
  67 +
  68 + if (code === 200 && data.data > 0) {
  69 + tip.show('分享成功,亲密度+10');
  70 + }
  71 + },
  72 + error: function() {
  73 + tip.show('网络断开连接了~');
  74 + }
  75 + });
  76 +};
  1 +/**
  2 + * 星专题
  3 + * @author: wsl<shuiling.wang@yoho.cn>
  4 + * @date: 2016/6/7
  5 + */
  6 +
  7 +var $ = require('yoho-jquery'),
  8 + lazyLoad = require('yoho-jquery-lazyload');
  9 +
  10 +require('../common');
  11 +
  12 +lazyLoad($('img.lazy'));
  1 +/**
  2 + * 星潮教室首页
  3 + * @author: wsl<shuiling.wang@yoho.cn>
  4 + * @date: 2016/5/31
  5 + */
  6 +
  7 +var $ = require('yoho-jquery'),
  8 + Swiper = require('yoho-swiper'),
  9 + tip = require('../plugin/tip'),
  10 + lazyLoad = require('yoho-jquery-lazyload'),
  11 + ellipsis = require('yoho-mlellipsis'),
  12 + loading = require('../plugin/loading'),
  13 + PullRefresh = require('../plugin/pull-refresh');
  14 +
  15 +var $window = $(window),
  16 + $starArticle = $('.star-article'),
  17 + $headTab = $('.head-tab'),
  18 + stopLoading = false,
  19 + avatarSwiper,
  20 + avatarSwiperClone,
  21 + getIndexHtml;
  22 +
  23 +/*
  24 + $swiperView = $('.swiper-view'),
  25 + $viewImg = $('.view-img'),
  26 + $body = $('body'),
  27 + imgs = [],
  28 + allImgs = {};
  29 +
  30 +var mySwiper;
  31 +*/
  32 +
  33 +var avatarKey, bannerLen;
  34 +
  35 +require('../common');
  36 +
  37 +lazyLoad($('img.lazy'));
  38 +ellipsis.init();
  39 +
  40 +$window.on('mousewheel', false);
  41 +
  42 +// 限制标题字数
  43 +function txtLimit(dom, item1, item2) {
  44 + var $title = dom.find(item1),
  45 + $cont = dom.find(item2);
  46 +
  47 + $title[0].mlellipsis(2);
  48 + $cont[0].mlellipsis(3);
  49 +}
  50 +
  51 +// 设置默认头像
  52 +function setAvatar($userAvatar) {
  53 + var myImage = new Image(),
  54 + avatar = '';
  55 +
  56 + // 部分老用户没有头像,显示默认头像
  57 + avatar = $userAvatar.data('avatar');
  58 +
  59 + if (avatar) {
  60 + myImage.src = avatar;
  61 + }
  62 +
  63 + myImage.onload = function() {
  64 + $userAvatar.css('background-image', 'url(' + avatar + ')');
  65 + };
  66 +}
  67 +
  68 +function setIndexAction() {
  69 + var starIScroll;
  70 +
  71 + var commonHeaderTop = $('#yoho-header').outerHeight(),
  72 + $loadingTip = $('.loading-tip'),
  73 + $avatarWrap = $('.avatar-wrap'),
  74 + avatarHeight = $('.avatar').height(),
  75 + infoTop = $('.star-info').css('margin-top');
  76 +
  77 + // 下拉刷新,上拉加载
  78 + starIScroll = new PullRefresh('.star-wrap', {
  79 + height: $(window).height() - commonHeaderTop - avatarHeight - parseInt(infoTop) * 2,
  80 + pullDown: function() {
  81 + if (!stopLoading) {
  82 + stopLoading = true;
  83 +
  84 + if (avatarSwiperClone) {
  85 + avatarSwiperClone.destroy(true, true);
  86 + avatarSwiperClone = '';
  87 + }
  88 + getIndexHtml();
  89 + }
  90 + }
  91 + });
  92 +
  93 + starIScroll.iScroll.on('scrollStart', function() {
  94 + // 下拉
  95 + if (this.directionY === -1) {
  96 + $headTab.slideDown();
  97 + $loadingTip.slideDown();
  98 + }
  99 + });
  100 +
  101 + starIScroll.iScroll.on('scroll', function() {
  102 + if (commonHeaderTop > $avatarWrap.offset().top) {
  103 + $('.avatar-clone').show();
  104 +
  105 + if (!avatarSwiperClone) {
  106 + avatarSwiperClone = new Swiper('.avatar-0', {
  107 + loop: true,
  108 + initialSlide: $('.avatar-1').find('.swiper-slide-active').index(),
  109 + centeredSlides: true,
  110 + slidesPerView: 'auto',
  111 + loopedSlides: bannerLen,
  112 + spaceBetween: 10,
  113 + slidesOffsetBefore: -($('.swiper-num').width()),
  114 + watchSlidesProgress: true,
  115 + watchSlidesVisibility: true
  116 + });
  117 +
  118 + avatarSwiperClone.params.control = avatarSwiper;
  119 + avatarSwiper.params.control = avatarSwiperClone;
  120 + }
  121 + }
  122 +
  123 + if (Math.abs(this.startY) < $('.banner-top').height() + avatarHeight + $('.head-tab').height()) {
  124 + $('.avatar-clone').hide();
  125 + }
  126 + });
  127 +
  128 + starIScroll.iScroll.on('scrollEnd', function() {
  129 + // 上滑
  130 + if (this.directionY === 1) {
  131 + $headTab.slideUp(1000);
  132 + }
  133 +
  134 + $loadingTip.slideUp();
  135 + });
  136 +
  137 + // 明星动态文章图片相关操作
  138 + /*
  139 + function articleImgAction(dom, key) {
  140 + var $articeImgs = dom.find('.artice-imgs'),
  141 + $li = $articeImgs.find('li'),
  142 + imgLen = $articeImgs.find('img').length,
  143 + addFlagDom = $li.eq(2);
  144 +
  145 + var i;
  146 +
  147 + imgs = [];
  148 +
  149 + $li.each(function() {
  150 + imgs.push($(this).find('img').attr('src'));
  151 + });
  152 +
  153 + allImgs[key] = imgs;
  154 +
  155 + $li.on('click', function() {
  156 + for (i = 0; i < imgLen; i++) {
  157 + $swiperView.find('ul').append('<li class="swiper-slide">' +
  158 + '<img class="swiper-lazy" data-src="' + allImgs[key][i] + '">' +
  159 + '<div class="swiper-lazy-preloader"></div></li>');
  160 + }
  161 + setTimeout(function() {
  162 + mySwiper = new Swiper('.swiper-view', {
  163 + lazyLoading: true,
  164 + lazyLoadingInPrevNext: true,
  165 + slideElement: 'li'
  166 + });
  167 +
  168 + $('.swiper-view li').on('click', function(e) {
  169 + if (e.target.nodeName === 'IMG') {
  170 + return;
  171 + }
  172 + $viewImg.hide();
  173 + $body.css({
  174 + overflow: 'auto'
  175 + });
  176 + $viewImg.find('li').remove();
  177 + mySwiper.destroy(false);
  178 + });
  179 + }, 100);
  180 +
  181 + $viewImg.show();
  182 +
  183 + $body.css({
  184 + overflow: 'hidden'
  185 + });
  186 + });
  187 +
  188 + if (imgLen > 3 && addFlagDom.find('.img-size').length < 1) {
  189 + addFlagDom.append('<div class="img-size"><i class="pic-icon"></i>' + imgLen + '</div>');
  190 + }
  191 + }
  192 + */
  193 +
  194 + $('.avatar').each(function(key, item) {
  195 + $(item).addClass('avatar-' + key);
  196 + });
  197 +
  198 + // banner swiper 初始化
  199 + if ($('.banner-swiper').find('li').length > 1) {
  200 + new Swiper('.banner-swiper', {
  201 + lazyLoading: true,
  202 + lazyLoadingInPrevNext: true,
  203 + loop: true,
  204 + autoplay: 3000,
  205 + autoplayDisableOnInteraction: false,
  206 + paginationClickable: true,
  207 + slideElement: 'li',
  208 + pagination: '.banner-top .pagination-inner'
  209 + });
  210 + }
  211 +
  212 + // 明星头像 swiper 初始化
  213 + if (bannerLen > 1) {
  214 + avatarSwiper = new Swiper('.avatar-1', {
  215 + loop: true,
  216 + centeredSlides: true,
  217 + slidesPerView: 'auto',
  218 + loopedSlides: bannerLen,
  219 + spaceBetween: 10,
  220 + slidesOffsetBefore: -($('.swiper-num').width()),
  221 + watchSlidesProgress: true,
  222 + watchSlidesVisibility: true
  223 + });
  224 + }
  225 +
  226 + // 明星动态头像左右滑动
  227 + if ($('.article-avatar-swiper').find('li').length > 1) {
  228 + new Swiper('.article-avatar-swiper', {
  229 + initialSlide: 0,
  230 + lazyLoading: true,
  231 + lazyLoadingInPrevNext: true,
  232 + loop: true,
  233 + autoplay: 5000
  234 + });
  235 + }
  236 +
  237 +
  238 + if ($('.star-info').find('li').length > 0) {
  239 + $starArticle.each(function(key, item) {
  240 + txtLimit($(item), '.article-title', 'p');
  241 +
  242 + // articleImgAction($(item), key);
  243 + });
  244 + }
  245 +
  246 + // 明星头像点击居中显示或跳转
  247 + $('.avatar-swiper li').on('click', function() {
  248 + if ($(this).hasClass('swiper-slide-active')) {
  249 + location.href = $(this).find('span').data('url');
  250 + } else {
  251 + avatarKey = $(this).index();
  252 +
  253 + if (avatarKey >= (2 * bannerLen + 1)) {
  254 + avatarSwiperClone && avatarSwiperClone.slideTo(bannerLen + 1, 0);
  255 + avatarSwiper.slideTo(bannerLen + 1, 0);
  256 + } else if (avatarKey <= (bannerLen - 1)) {
  257 + avatarSwiperClone && avatarSwiperClone.slideTo(2 * bannerLen - 1, 0);
  258 + avatarSwiper.slideTo(2 * bannerLen - 1, 0);
  259 + } else {
  260 + avatarSwiperClone && avatarSwiperClone.slideTo(avatarKey, 0);
  261 + avatarSwiper.slideTo(avatarKey, 0);
  262 + }
  263 + }
  264 + });
  265 +
  266 + $('.rank-avatar').each(function(key, item) {
  267 + if ($(item).attr('data-avatar') !== '') {
  268 + setAvatar($(item));
  269 + }
  270 + });
  271 +
  272 +}
  273 +
  274 +getIndexHtml = function() {
  275 + var $starMain = $('.star-main');
  276 +
  277 + loading.showLoadingMask();
  278 + $.ajax({
  279 + url: '/guang/star/getIndexHtml',
  280 + dataType: 'html',
  281 + success: function(data) {
  282 + stopLoading = false;
  283 +
  284 + if (!data) {
  285 + stopLoading = true;
  286 + tip.show('没有更多内容了');
  287 + }
  288 +
  289 + $starMain.html(data);
  290 + bannerLen = $('.avatar .swiper-slide').length;
  291 +
  292 + if ($('.avatar-clone')) {
  293 + $('.avatar-clone').remove();
  294 + }
  295 +
  296 + $('.avatar li').each(function() {
  297 + setAvatar($(this).find('span'));
  298 + });
  299 +
  300 + $starMain.before($('.avatar-swiper').clone().addClass('avatar-clone').hide());
  301 +
  302 + // 限制标题字数
  303 + $('.cont-area').each(function() {
  304 + txtLimit($(this), '.title', '.cont-txt');
  305 + });
  306 +
  307 + loading.hideLoadingMask();
  308 + lazyLoad($('img.lazy'));
  309 +
  310 + setTimeout(function() {
  311 + setIndexAction();
  312 + }, 100);
  313 +
  314 + },
  315 + error: function() {
  316 + tip.show('网络断开连接了~');
  317 + }
  318 + });
  319 +};
  320 +
  321 +getIndexHtml();
@@ -48,3 +48,5 @@ function hideLoadingMask() { @@ -48,3 +48,5 @@ function hideLoadingMask() {
48 exports.init = init; 48 exports.init = init;
49 exports.showLoadingMask = showLoadingMask; 49 exports.showLoadingMask = showLoadingMask;
50 exports.hideLoadingMask = hideLoadingMask; 50 exports.hideLoadingMask = hideLoadingMask;
  51 +exports.show = showLoadingMask;
  52 +exports.hide = hideLoadingMask;
  1 +var $ = require('yoho-jquery'),
  2 + IScroll = require('yoho-iscroll/build/iscroll-probe');
  3 +
  4 +// 下拉刷新,上滑加载插件
  5 +// 参数一选择器,参数二选项
  6 +// height:容器高度
  7 +// pullDown:下拉回调
  8 +// pullUp:上滑回调
  9 +// 示例代码:
  10 +// new PullRefresh('.star-wrap', {
  11 +// height: $(window).height() - $('#yoho-header').height() - $('.head-tab').height(),
  12 +// pullDown: function() {
  13 +// console.log('下拉了');
  14 +// },
  15 +// pullUp: function() {
  16 +// console.log('上滑了');
  17 +// }
  18 +// });
  19 +
  20 +function PullRefresh(seclector, options) {
  21 + var $window = $(window),
  22 + $em,
  23 + pullFormTop = false,
  24 + pullStart,
  25 + topOffset;
  26 +
  27 + $em = $(seclector);
  28 +
  29 + if (!$em.length) {
  30 + return;
  31 + }
  32 +
  33 + if (options.height) {
  34 + $em.height(options.height);
  35 + }
  36 +
  37 + topOffset = -$em.outerHeight();
  38 +
  39 + this.iScroll = new IScroll($em.get(0), {
  40 + click: true,
  41 + probeType: 3
  42 + });
  43 +
  44 + this.iScroll.on('scrollStart', function() {
  45 + if (this.y >= topOffset) {
  46 + pullFormTop = true;
  47 + }
  48 +
  49 + pullStart = this.y;
  50 + $window.trigger('scroll');
  51 + });
  52 +
  53 + this.iScroll.on('scrollEnd', function() {
  54 + if (pullFormTop && this.directionY === -1) {
  55 + options.pullDown && options.pullDown();
  56 + }
  57 + pullFormTop = false;
  58 +
  59 + if (pullStart === this.y && this.directionY === 1) {
  60 + options.pullUp && options.pullUp();
  61 + }
  62 +
  63 + $window.trigger('scroll');
  64 + });
  65 +}
  66 +
  67 +module.exports = PullRefresh;
  1 +@import "star/index";
  1 +.star-page {
  2 + .collocation-list,
  3 + .detail-list {
  4 + width: 100%;
  5 + float: left;
  6 +
  7 + li {
  8 + float: left;
  9 + width: 100%;
  10 + margin-top: 30px;
  11 + background: #000;
  12 +
  13 + .cont-area {
  14 + width: 100%;
  15 + box-sizing: border-box;
  16 + padding: 30px;
  17 + }
  18 +
  19 + .cont-txt {
  20 + font-size: 28px;
  21 + line-height: 46px;
  22 + color: #b0b0b0;
  23 + margin-top: 10px;
  24 + }
  25 +
  26 + img {
  27 + width: 100%;
  28 + }
  29 +
  30 + .title {
  31 + font-size: 40px;
  32 + line-height: 48px;
  33 + color: #fff;
  34 + width: 100%;
  35 + }
  36 + }
  37 + }
  38 +
  39 + .count-area {
  40 + position: relative;
  41 + width: 100%;
  42 + height: 32px;
  43 +
  44 + span {
  45 + font-size: 24px;
  46 + color: #b0b0b0;
  47 + height: 32px;
  48 + line-height: 32px;
  49 +
  50 + i {
  51 + display: inline-block;
  52 + margin-right: 5px;
  53 + font-size: 24px;
  54 + position: relative;
  55 + top: -2px;
  56 + }
  57 + }
  58 +
  59 + .time {
  60 + float: left;
  61 + }
  62 +
  63 + .see {
  64 + float: left;
  65 + margin-left: 20px;
  66 + }
  67 +
  68 + .time-ico {
  69 + width: 24px;
  70 + height: 24px;
  71 + }
  72 +
  73 + .see-ico {
  74 + width: 31px;
  75 + height: 24px;
  76 + }
  77 +
  78 + .collection {
  79 + float: right;
  80 + }
  81 +
  82 + .collected-ico {
  83 + width: 34px;
  84 + height: 32px;
  85 + vertical-align: text-bottom;
  86 + }
  87 +
  88 + .collected {
  89 + color: #d62927;
  90 + }
  91 +
  92 + .forward {
  93 + width: 40px;
  94 + height: 28px;
  95 + float: right;
  96 + margin-left: 45px;
  97 + font-size: 24px;
  98 + color: #b0b0b0;
  99 + height: 32px;
  100 + line-height: 32px;
  101 + }
  102 + }
  103 +}
  104 +
  105 +.star-class-body {
  106 + background: #333;
  107 + width: 100%;
  108 + font: 12px/1.5 Arial, '黑体';
  109 + float: left;
  110 +}
  1 +@import "star";
  2 +@import "special";
  3 +@import "collocation";
  1 +.star-page {
  2 + .special-list {
  3 + width: 100%;
  4 + height: auto;
  5 + overflow: hidden;
  6 +
  7 + li {
  8 + width: 100%;
  9 + float: left;
  10 + background: #000;
  11 + margin-top: 30px;
  12 +
  13 + img {
  14 + width: 100%;
  15 + }
  16 +
  17 + p {
  18 + width: 100%;
  19 + height: 88px;
  20 + box-sizing: border-box;
  21 + overflow: hidden;
  22 + white-space: nowrap;
  23 + text-overflow: ellipsis;
  24 + padding: 0 34px;
  25 + font-size: 34px;
  26 + line-height: 88px;
  27 + }
  28 +
  29 + a {
  30 + color: #fff;
  31 + }
  32 + }
  33 + }
  34 +}
  1 +.star-page {
  2 + background: #333;
  3 +
  4 + a {
  5 + text-decoration: none;
  6 + outline: none;
  7 + color: #000;
  8 +
  9 + &:link,
  10 + &:visited,
  11 + &:hover,
  12 + &:actived {
  13 + color: #000;
  14 + }
  15 + }
  16 +
  17 + *:focus {
  18 + outline: none;
  19 + }
  20 +
  21 + .font-bold {
  22 + font-weight: bold;
  23 + }
  24 +
  25 + .head-tab {
  26 + position: relative;
  27 + width: 100%;
  28 + height: 88px;
  29 + background: #000;
  30 + z-index: 1;
  31 + transform-origin: top;
  32 + transform: scale(1, 1);
  33 + transition: transform 400ms;
  34 +
  35 + &.hide-tab {
  36 + transform: scale(1, 0);
  37 + }
  38 +
  39 + li {
  40 + width: 33.3%;
  41 + text-align: center;
  42 + float: left;
  43 + line-height: 88px;
  44 + font-size: 30px;
  45 +
  46 + a {
  47 + color: #b0b0b0;
  48 + display: inline-block;
  49 + }
  50 +
  51 + &.cur a {
  52 + color: #fff;
  53 + }
  54 + }
  55 + }
  56 +
  57 + .banner-top {
  58 + width: 100%;
  59 + height: auto;
  60 + position: relative;
  61 +
  62 + .banner-swiper {
  63 + width: 100%;
  64 + height: auto;
  65 + overflow: hidden;
  66 + position: relative;
  67 +
  68 + ul {
  69 + position: relative;
  70 + height: auto;
  71 +
  72 + li {
  73 + float: left;
  74 + width: 100%;
  75 + height: auto;
  76 + }
  77 +
  78 + img {
  79 + width: 100%;
  80 + height: 100%;
  81 + }
  82 + }
  83 + }
  84 +
  85 + .swiper-pagination {
  86 + position: absolute;
  87 + left: 0;
  88 + right: 0;
  89 + bottom: 20px;
  90 + text-align: center;
  91 + z-index: 1;
  92 +
  93 + .pagination-inner {
  94 + display: inline-block;
  95 + }
  96 +
  97 + span {
  98 + display: inline-block;
  99 + width: 14px;
  100 + height: 14px;
  101 + background: #fff;
  102 + opacity: 0.5;
  103 + margin: 0 10px;
  104 + border-radius: 50%;
  105 + }
  106 +
  107 + .swiper-pagination-bullet-active {
  108 + background: #fff;
  109 + opacity: 1;
  110 + }
  111 + }
  112 + }
  113 +
  114 + .avatar-swiper {
  115 + overflow: hidden;
  116 + margin-top: 30px;
  117 + background: #000;
  118 +
  119 + &.avatar-clone {
  120 + margin-top: 0;
  121 + position: relative;
  122 + padding: 5px 0;
  123 + z-index: 9;
  124 + background: #000;
  125 + }
  126 +
  127 + li {
  128 + float: left;
  129 + width: auto;
  130 + width: 110px;
  131 + height: 110px;
  132 + margin-top: 34px;
  133 + background: #282828;
  134 +
  135 + span {
  136 + display: block;
  137 + width: 100%;
  138 + height: 100%;
  139 + }
  140 + }
  141 +
  142 + .swiper-slide-active {
  143 + width: 180px;
  144 + height: 180px;
  145 + margin-top: 0;
  146 + }
  147 +
  148 + .swiper-slide-prev,
  149 + .swiper-slide-next {
  150 + width: 130px;
  151 + height: 130px;
  152 + margin-top: 27px;
  153 + }
  154 + }
  155 +
  156 + .star-info {
  157 + margin-top: 30px;
  158 + background: #000;
  159 +
  160 + li {
  161 + float: left;
  162 + margin-bottom: 30px;
  163 + }
  164 + }
  165 +
  166 + .star-avatar {
  167 + width: 134px;
  168 + padding-left: 30px;
  169 + box-sizing: border-box;
  170 + float: left;
  171 + overflow: hidden;
  172 +
  173 + .article-avatar-swiper {
  174 + width: 104px;
  175 + overflow: hidden;
  176 + }
  177 +
  178 + .rank-avatar {
  179 + width: 104px;
  180 + height: 104px;
  181 + border-radius: 50%;
  182 + float: left;
  183 + }
  184 +
  185 + .name {
  186 + font-size: 24px;
  187 + width: 100%;
  188 + text-overflow: ellipsis;
  189 + overflow: hidden;
  190 + white-space: nowrap;
  191 + color: #fff;
  192 + margin-top: 8px;
  193 + float: left;
  194 + text-align: center;
  195 + }
  196 + }
  197 +
  198 + .star-article {
  199 + width: 472px;
  200 + position: relative;
  201 + border-radius: 8px;
  202 + background: #282828;
  203 + float: left;
  204 + padding: 20px 30px;
  205 + box-sizing: border-box;
  206 + margin-left: 18px;
  207 +
  208 + .article-arrow {
  209 + position: absolute;
  210 + left: -13px;
  211 + width: 0;
  212 + height: 0;
  213 + border-top: 10px solid transparent;
  214 + border-bottom: 10px solid transparent;
  215 + border-right: 13px solid #282828;
  216 + }
  217 +
  218 + .article-title {
  219 + font-size: 28px;
  220 + line-height: 38px;
  221 + color: #fff;
  222 + }
  223 +
  224 + .artice-cont {
  225 + margin-top: 10px;
  226 +
  227 + p {
  228 + font-size: 18px;
  229 + line-height: 29px;
  230 + color: #969696;
  231 + }
  232 + }
  233 +
  234 + .artice-imgs-area {
  235 + width: 100%;
  236 + overflow: hidden;
  237 +
  238 + img {
  239 + width: 266px;
  240 + float: left;
  241 + margin: 25px 0;
  242 + }
  243 + }
  244 +
  245 + .artice-imgs {
  246 + margin: 25px 0 0;
  247 + width: 2500px;
  248 + float: left;
  249 + overflow: hidden;
  250 +
  251 + li {
  252 + display: inline-block;
  253 + margin-left: 6px;
  254 + position: relative;
  255 + }
  256 +
  257 + li:first {
  258 + margin-left: 0;
  259 + }
  260 +
  261 + img {
  262 + width: 130px;
  263 + border-radius: 4px;
  264 + }
  265 +
  266 + .img-size {
  267 + width: 50px;
  268 + height: 26px;
  269 + line-height: 28px;
  270 + border-radius: 13px;
  271 + background-color: rgba(0, 0, 0, 0.4);
  272 + color: #fff;
  273 + position: absolute;
  274 + right: 10px;
  275 + bottom: 10px;
  276 + font-size: 18px;
  277 + }
  278 +
  279 + .pic-icon {
  280 + width: 19px;
  281 + height: 15px;
  282 + background: url('/guang/star/img.png') no-repeat;
  283 + background-size: contain;
  284 + display: inline-block;
  285 + margin: 6px 4px 0 8px;
  286 + vertical-align: top;
  287 + }
  288 + }
  289 +
  290 + .artice-o {
  291 + width: 100%;
  292 + float: left;
  293 + border-top: 1px solid #b0b0b0;
  294 + padding-top: 20px;
  295 +
  296 + span {
  297 + font-size: 18px;
  298 + color: #b0b0b0;
  299 + height: 22px;
  300 + line-height: 22px;
  301 +
  302 + i {
  303 + display: inline-block;
  304 + margin-right: 5px;
  305 + font-size: 22px;
  306 + vertical-align: text-bottom;
  307 + }
  308 + }
  309 +
  310 + .time {
  311 + float: left;
  312 + }
  313 +
  314 + .see {
  315 + float: left;
  316 + margin-left: 30px;
  317 + }
  318 +
  319 + .time-ico {
  320 + width: 24px;
  321 + height: 24px;
  322 + }
  323 +
  324 + .see-ico {
  325 + width: 31px;
  326 + height: 24px;
  327 + }
  328 + }
  329 + }
  330 +
  331 + .view-area {
  332 + height: 100%;
  333 + position: relative;
  334 + }
  335 +
  336 + .swiper-view {
  337 + height: 100%;
  338 + background: rgba(0, 0, 0, 0.5);
  339 + }
  340 +
  341 + .view-img {
  342 + position: fixed;
  343 + left: 0;
  344 + right: 0;
  345 + top: 0;
  346 + bottom: 0;
  347 + display: none;
  348 + z-index: 9;
  349 +
  350 + li {
  351 + float: left;
  352 +
  353 + img {
  354 + width: 90%;
  355 + transform: translate(-50%, -50%);
  356 + position: absolute;
  357 + top: 50%;
  358 + left: 50%;
  359 + }
  360 + }
  361 + }
  362 +
  363 + .rank-avatar {
  364 + background-image: resolve("guang/star/user-avatar.png");
  365 + background-repeat: no-repeat;
  366 + background-size: contain;
  367 + }
  368 +
  369 + .loading-tip {
  370 + display: none;
  371 + text-align: center;
  372 + color: #ccc;
  373 + font-size: 12px;
  374 + margin: 30px 0;
  375 + }
  376 +
  377 + .swiper-num {
  378 + width: 55px;
  379 + display: none;
  380 + }
  381 +}
  382 +
  383 +.star-index-bg {
  384 + background: #000;
  385 +
  386 + .star-page {
  387 + background: #000;
  388 + }
  389 +}
@@ -10,3 +10,4 @@ @@ -10,3 +10,4 @@
10 @import "common/index"; 10 @import "common/index";
11 @import "cart/chose-panel"; 11 @import "cart/chose-panel";
12 @import "coupon/index"; 12 @import "coupon/index";
  13 +@import "guang/index";
1 .loading-mask { 1 .loading-mask {
  2 + position: fixed;
  3 + top: 0;
  4 + right: 0;
  5 + bottom: 0;
  6 + left: 0;
  7 + background: rgba(0, 0, 0, 0.1);
  8 +
2 @keyframes scale { 9 @keyframes scale {
3 0% { 10 0% {
4 - opacity: 1;  
5 transform: scale(1); 11 transform: scale(1);
  12 + opacity: 1;
6 } 13 }
7 14
8 45% { 15 45% {
9 - opacity: 0.7;  
10 transform: scale(0.1); 16 transform: scale(0.1);
  17 + opacity: 0.7;
11 } 18 }
12 19
13 80% { 20 80% {
14 - opacity: 1;  
15 transform: scale(1); 21 transform: scale(1);
  22 + opacity: 1;
16 } 23 }
17 } 24 }
18 - position: fixed;  
19 - top: 0;  
20 - right: 0;  
21 - bottom: 0;  
22 - left: 0;  
23 - background: rgba(0, 0, 0, 0.1);  
24 25
25 .loading { 26 .loading {
26 position: absolute; 27 position: absolute;
@@ -35,12 +36,13 @@ @@ -35,12 +36,13 @@
35 $init: 0.12; 36 $init: 0.12;
36 37
37 @for $i from 1 to 3 { 38 @for $i from 1 to 3 {
38 - $init: ($i + 1) * 0.12;  
39 -  
40 &:nth-child($i) { 39 &:nth-child($i) {
41 animation: scale 0.75s $(init)s infinite cubic-bezier(0.2, 0.68, 0.18, 1.08); 40 animation: scale 0.75s $(init)s infinite cubic-bezier(0.2, 0.68, 0.18, 1.08);
42 } 41 }
  42 +
  43 + $init: calc(($i + 1) * 0.12);
43 } 44 }
  45 +
44 display: inline-block; 46 display: inline-block;
45 margin: 4px; 47 margin: 4px;
46 width: 30px; 48 width: 30px;