Showing 49 changed files with 2442 additions and 78 deletions
... ... @@ -9,70 +9,286 @@
// const _ = require('lodash');
const channelModel = require('../models/index');
const headerModel = require('../../../doraemon/models/header');
const cookie = global.yoho.cookie;
const ghelper = require('../models/guang-helper');
// const HeaderModel = require('../../../doraemon/models/header');
/**
* 首页文章列表 类型列表
*/
exports.index = (req, res, next) => {
let channel = req.yoho.channel;
let page = req.query.page || 1;
let limit = req.query.limit || 20;
let pageSize = req.query.pageSize || 20;
let type = req.query.type || 0;
let pathNav = channelModel.getIndexNav(channel);
let pathNav = channelModel.getPathNav(channel);
let uid = cookie.getUid(req);
let udid = ghelper.getUdid(req);
let gender = ghelper.getGenderByCookie(req);
Object.assign(res.locals, {
page: 'guang'
});
Promise.all([
channelModel.getBanner(),
channelModel.getCategory(),
channelModel.getList(),
// page
channelModel.getHotTags(),
channelModel.getAds(),
channelModel.getExcellectRecos()
channelModel.getBanner(channel),
channelModel.getCategory(type),
channelModel.getArticleList(gender, type, uid, udid, page, '', '', pageSize),
channelModel.getHotTags(page, pageSize),
channelModel.getAds(channel),
channelModel.getExcellectRecos(gender, 1, 10),
headerModel.requestHeaderData(channel)
]).then(ret => {
res.render('index', {
guang: {
slider: ret[0],
msgTypes: ret[1],
msgs: ret[2],
hotTags: ret[6],
ads: ret[3],
msgs: (ret[2] && ret[2].msgs) || ret[2],
hotTags: ret[3],
ads: ret[4],
exRecos: ret[5],
msgPager: null,
guangIndexPage: true,
limit: limit,
pageSize: pageSize,
type: type,
pathNav: pathNav,
page: page
}
page: page,
total : (ret[2] && ret[2].total) || 0
},
headerData : ret[6]['headerData'] || ret[6]
});
}).catch(next);
/* return res.render('index', {
pageName: 'guang-index',
world: {
aaa: 'AAA'
}
});*/
};
exports.detail = (req, res) => {
return res.render('detail', {
detailId: req.params.id
});
};
/**
* 制定 tag 的文章列表
*/
exports.tags = (req, res, next) => {
let query = req.query.query;
let page = req.query.page || 1;
let pageSize = req.query.pageSize || 20;
let type = req.query.type || 0;
let uid = cookie.getUid(req);
let udid = ghelper.getUdid(req);
let gender = ghelper.getGenderByCookie(req);
let channel = req.yoho.channel;
let pathNav = channelModel.getPathNav(channel, query);
exports.tags = (req, res) => {
return res.render('index', {
// $this->setWebNavHeader();
//$this->setTitle($query, true);
});
Promise.all([
channelModel.getBanner(channel),
//channelModel.getCategory(type),
channelModel.getArticleList(gender, 0, uid, udid, page, query, '', pageSize),
channelModel.getHotTags(1, 20),
channelModel.getAds(channel),
channelModel.getExcellectRecos(gender, 1, 10),
headerModel.requestHeaderData(channel)
]).then(ret => {
res.render('tag', {
guang: {
slider: ret[0],
//msgTypes: ret[1],
msgs: (ret[1] && ret[1].msgs) || ret[1],
hotTags: ret[2],
ads: ret[3],
exRecos: ret[4],
tag : query,
guangIndexPage: true,
pageSize: pageSize,
type: type,
pathNav: pathNav,
page: page,
total : (ret[1] && ret[1].total) || 0
},
headerData : ret[5]['headerData'] || ret[5]
});
}).catch(next);
};
exports.editor = (req, res) => {
return res.render('index', {
/**
* 作者文章列表
*/
exports.editor = (req, res, next) => {
let authorId = req.query.author_id;
let channel = req.yoho.channel;
let gender = ghelper.getGenderByCookie(req);
let uid = cookie.getUid(req);
let udid = ghelper.getUdid(req);
let pathNav = channelModel.getPathNav(channel);
Object.assign(res.locals, {
page: 'editor'
});
//$this->setWebNavHeader();
// 设置标签页标题
//$authorName = $author['data']['name'];
//$this->setTitle($authorName, true, '');
let page = req.query.page || 1;
let pageSize = req.query.pageSize || 20;
Promise.all([
channelModel.getAuthor(authorId),
channelModel.getArticleList(gender, null, uid, udid, page, '', authorId, pageSize),
channelModel.getHotTags(1, 20),
channelModel.getAds(channel),
channelModel.getExcellectRecos(gender, 1, 10),
headerModel.requestHeaderData(channel)
]).then(ret => {
res.render('editor', {
guang: {
editor : {
avatar : ret[0] && ret[0]['avatar'],
name : ret[0] && ret[0]['name'],
intro : ret[0] && ret[0]['author_desc'],
info : '设计理念:时尚,线条流畅'
},
msgs: (ret[1] && ret[1].msgs) || ret[1],
hotTags: ret[2],
ads: ret[3],
exRecos: ret[4],
gender : gender,
pageSize: pageSize,
pathNav: pathNav,
page: page,
total : (ret[1] && ret[1].total) || 0
},
guangList : true,
guangListPage : true,
headerData : ret[5]['headerData'] || ret[5]
});
}).catch(next);
};
/**
* 文章详情
*/
exports.detail = (req, res, next) => {
let id = req.params.id || req.query.id;
let page = req.query.page || 1;
let pageSize = req.query.pageSize || 20;
let col = req.query.col || 0;
let pjax = req.query._pjax;
let uid = cookie.getUid(req);
let udid = ghelper.getUdid(req);
let gender = ghelper.getGenderByCookie(req);
let channel = req.yoho.channel;
if (!_.isNumber(id)) {
return next(new Error('文章不存在!'));
}
// $id = $this->param('id','');
// $id = 34374;
// if(empty($id)) {
// $id = $this->get('id');
// }
// $page = $this->get('page', 1);//评论分页
// $col = $this->get('col', 0);//收藏
// $pjax = $this->get("_pjax");
// $limit = 20; //评论每页显示条数
/*if(pjax) {
return channelModel.getComment(id, page, pageSize).then(res => {
return res.render('comment', {
});
});
}
// if ($pjax) {
// $this->_view->display('comment', InfoModel::commentList($id, $page, $limit));
// exit;
// }
// $uid = $this->getUid();
// $udid = $this->getUdid();
//登陆后自动收藏
if (col == 1 && uid > 0) {
InfoData::setFavorite($id, $uid);
}
// $gender = Helpers::getGenderByCookie();
// $channel = Helpers::getChannelNameByCookie();
let info = InfoModel::articleInfo($id, $uid, $udid, $page, $gender, $channel, $limit);
// 判断参数是否有效, 无效会跳转到错误页面
if (!info['header']) {
return next(new Error('文章不存在'));
}
$data = array(
'guangDetailPage' => true,
'pathNav' => $info['pathNav'],
'guang' => array(
'id' => $id,
'header' => isset($info['header']) ? $info['header']: array(),
'content' => isset($info['content']) ? $info['content'] : array(),
'brands' => isset($info['brands']) ? $info['brands'] : array(),
'userInfo' => isset($info['userInfo']) ? $info['userInfo'] : array(),
'tag' => isset($info['tag']) ? $info['tag'] : array(),
//分享
'shareImg' => $info['header']['shareImg'],
'sharedTitle' => $info['header']['title'],
'shareDesc' => $info['header']['desc'],
'weixinUrl' => $info['header']['weixinUrl'],
'relatedPost' => isset($info['relatedPost']) ? $info['relatedPost'] : array(),
'commentInfo' => $this->getSession('comment_'.$udid),
'comment' => isset($info['comment']) ? $info['comment'] : array(),
'exRecos' => isset($info['exRecos']) ? $info['exRecos'] : array(),
'hotTags' => isset($info['hotTags']) ? $info['hotTags'] : array(),
'ads' => IndexModel::getAds($channel),
)
);
$this->setTitle($info['header']['title'].' | YOHO!BUY有货 | 年轻人潮流购物中心,中国潮流购物风向标,官方授权正品保证');
$this->setKeywords('Yoho! 有货,潮流,时尚,流行,购物,B2C,正品,购物网站,网上购物,货到付款,品牌服饰,男士护肤,黑框眼镜,匡威,板鞋,i.t,izzue,5cm,eastpak,vans,lylescott,g-shock,new balance,lacoste,melissa,casio,卡西欧手表,舒雅,jasonwood,odm,AAAA,香港购物,日本潮流');
$this->setDescription('潮流商品搜索,上衣,衬衫,TEE,卫衣,冲锋衣,风衣,羽绒服,裤子,休闲鞋,板鞋,配饰,复古眼镜');
$this->setWebNavHeader($channel);
$this->_view->display('info', $data);
Promise.all([
channelModel.getAuthor(authorId),
channelModel.getArticle(id, uid, udid, page, gender, channel, pageSize),
channelModel.getHotTags(1, 20),
channelModel.getAds(channel),
channelModel.getExcellectRecos(gender, 1, 10),
headerModel.requestHeaderData(channel)
]).then(ret => {
res.render('editor', {
guang: {
editor : {
avatar : ret[0] && ret[0]['avatar'],
name : ret[0] && ret[0]['name'],
intro : ret[0] && ret[0]['author_desc'],
info : '设计理念:时尚,线条流畅'
},
msgs: (ret[1] && ret[1].msgs) || ret[1],
hotTags: ret[2],
ads: ret[3],
exRecos: ret[4],
gender : gender,
pageSize: pageSize,
pathNav: pathNav,
page: page,
total : (ret[1] && ret[1].total) || 0
},
guangList : true,
guangListPage : true,
headerData : ret[5]['headerData'] || ret[5]
});
}).catch(next);*/
};
\ No newline at end of file
... ...
... ... @@ -21,7 +21,7 @@ let ALL_TYPES = {
ellipsis: 'p-pe-n'
};
Handlebars.registerHelper('page', function() {
Handlebars.registerHelper('pager', function() {
let options = arguments[arguments.length - 1];
let baseUrl = (arguments.length > 1 ? arguments[0] : null) || options.hash.baseUrl || '',
page = (options.hash.page || 1) * 1,
... ... @@ -144,12 +144,12 @@ Handlebars.registerHelper('page', function() {
break;
case 'p' :
if (page > 1) {
ret += `<a href="${base}` + (page - 1) + '" title="上一页">上一页</a>';
ret += `<a href="${base}` + (page - 1) + '" title="上一页"><span class="iconfont">&#xe60e;</span>上一页</a>';
}
break;
case 'n' :
if (page < totalPages) {
ret += `<a href="${base}` + (page + 1) + '" title="下一页">下一页</a>';
ret += `<a href="${base}` + (page + 1) + '" title="下一页">下一页<span class="iconfont">&#xe60c;</span></a>';
}
break;
case 'l' :
... ...
... ... @@ -3,6 +3,7 @@
* @author: lcy<chuanyang.liu@yoho.cn>
* @date: 2016/08/31
*/
'use strict';
var express = require('express'),
path = require('path'),
... ... @@ -22,16 +23,22 @@ app.on('mount', function(parent) {
Object.assign(app.locals, parent.locals);
});
let mhbs = hbs.create({
// let mhbs = hbs.create({
// extname: '.hbs',
// defaultLayout: 'layout',
// layoutsDir: doraemon,
// partialsDir: [`${partials}/partial`, `${doraemon}/partial`],
// helpers: global.yoho.helpers
// });
app.set('views', path.join(__dirname, 'views/action'));
app.engine('.hbs', hbs({
extname: '.hbs',
defaultLayout: 'layout',
layoutsDir: doraemon,
partialsDir: [`${partials}/partial`, `${doraemon}/partial`],
helpers: global.yoho.helpers
});
app.set('views', path.join(__dirname, 'views/action'));
app.engine('.hbs', mhbs.engine);
}));
// register helper
// var helpersDir = path.join(__dirname, 'helpers');
... ...
/**
* 逛 model
* @author: lcy<chuanyang.liu@yoho.cn>
* @date: 2016/09/06
*/
'use strict';
const moment = require('moment');
/* COOKIE标识访问的是男生频道 */
const COOKIE_NAME_BOYS = 'boys';
const COOKIE_DOMAIN = '.yohobuy.com';
const getGenderByCookie = (req) => {
let gender = null;
let channel = req.cookies._Channel || 'boys';
switch (channel) {
case 'boys':
{
gender = '1,3';
break;
}
case 'girls':
{
gender = '2,3';
break;
}
default:
{
gender = '1,2,3';
}
}
return gender;
};
/**
* 获取客户端唯一标识
*
* @return string
*/
const getUdid = (req) => {
let udid = req.cookies.suid;
let realIp;
/*if (!udid) {
$realIP = $this->_request->getServer('HTTP_X_REAL_IP');
if ($realIP) {
$udid = md5($realIP);
}
else {
$realIP = $this->_request->getServer('REMOTE_ADDR', '');
$udid = md5($realIP);
}
}*/
return udid;
}
module.exports = {
getGenderByCookie,
getUdid
};
... ...
... ... @@ -12,12 +12,30 @@ const _ = require('lodash');
const helpers = global.yoho.helpers;
const serviceApi = global.yoho.ServiceAPI;
const cache = global.yoho.cache;
// const searchApi = global.yoho.SearchAPI;
const KEY_WEB_GUANG_BANNER_DATA = 'key_web_guang_banner_data';//逛的首页banner
const KEY_WEB_GUANG_ADS_DATA = 'key_web_guang_ads_data';//逛的首页ads
const URL_OPERATIONS_RESOURCE_GET = 'operations/api/v5/resource/get';
// const headerModel = require('../../../doraemon/models/header');
//guang banner code
const BANNER_CODE = {
'boys': '15a288635c2ed9f6c807417be90f5d2d',
'girls': 'e14e12e35af8626650979f7af8a0de2b',
'lifestyle': '1d398e899f759c6d88971be680521a6f',
'kids': 'ad14ee01ad048ce308aa3ca416133d2a'
}
//逛 ads code
const ADS_CODE = {
'boys': '41777aa7ac86347692c5aa0d394b2f59',
'girls': '722253573823ebb994e313e71b0a4fb9',
'lifestyle': '02568b6042510e4be739cc688dc7d6ae',
'kids': '1ffdd6ea22c58af52ee6408cd353c2d5'
}
/**
* 获取首页频道nav
... ... @@ -60,25 +78,225 @@ const getHomeChannelNav = (channel) => {
};
};
const getIndexNav = (channelType) => {
const getPathNav = (channelType, query) => {
_.concat(
let path = _.concat(
getHomeChannelNav(channelType),
[{
name: '逛',
pathTitle: '逛',
href: helpers.urlFormat('guang', '', 'guang')
href: helpers.urlFormat('', '', 'guang')
}]
);
};
return query ? _.concat(path, [{ name : query, pathTitle : query}]) : path;
}
const _formatTag = (tagData, isApp, uid) => {
return {
tag : tagData['name'],
url : helpers.urlFormat('/tags/index', { query : tagData['name']}, 'guang') //urlencode(tagData['name'])
}
}
/**
* 格式化资讯文章
*
* @param array $articleData 需要格式化的资讯数据
* @param bool $showTag 是否显示左上角标签
* @param mixed $isApp 是否显示分享,在APP客户端里嵌入需要传url链接
* @param bool $showAuthor 控制是否显示作者信息
* @param int $uid 当前登录的用户ID
* @return array | false
*/
const _formatArticle = (articleData, showTag, isApp, showAuthor, uid) => {
if(showTag !== false) {
showTag = true;
}
if(showAuthor !== false) {
showAuthor = true;
}
// 资讯ID不存在,则不显示
if (!articleData || !articleData.id) {
return false;
}
let width, height, isSquareImage = true, tags = [];
width = height = 360;
if(articleData['conver_image_type'] === 2) {
width = 360;
height = 240;
isSquareImage = false;
}
let result = {
id : articleData.id,
classification :articleData.category_name,
isReco : articleData.is_recommended ? true : false,
url : isApp ? articleData.url : helpers.urlFormat(`/${articleData.id}.html`, null, 'guang'),
img : helpers.image(articleData.src, width, height, 1),
isSquareImg : isSquareImage,
title : articleData.title,
pTime : articleData['publish_time'],
pView : articleData['views_num'],
content : articleData['intro'],
showTags : showTag,
comment : articleData['comment_num']
}
if(!articleData['author']){
articleData['author'] = {
name : '',
avatar : ''
}
}
result['author'] = articleData.author.name;
if (articleData['author']['author_id']) {
let author_id = articleData['author']['author_id'];
result['editorUrl'] = helpers.urlFormat('/Index/editor', {'author_id' : author_id}, 'guang');
}
if (articleData['tags']) {
for(let tag of articleData['tags']) {
tags.push(_formatTag(tag, isApp));
}
}
result['tags'] = tags;
// 收藏
if (isApp) {
result['collect'] = {
isCollected : articleData['isFavor'] && articleData['isFavor'] === 'Y',
url : uid ? 'javascript:;' : articleData['url'].replace('"islogin":"N"', '"islogin":"Y"')
}
} else { // 点赞
result['like'] = articleData['praise_num'];
result['liked'] = articleData['isPraise'] && articleData['isPraise'] === 'Y';
}
// 分享链接
result['share'] = isApp && articleData['share']['url'] ? articleData['share']['url'] : false;
// 判断是否显示作者信息
if (showAuthor && articleData['author']) {
if (!isApp) {
articleData['author']['url'] = articleData['author']['url'];//Helpers::getFilterUrl($articleData['author']['url']);
}
result['author'] = articleData['author'];
}
// 模板中需要的标签标识
if (showTag && articleData['category_id']) {
let categoryId = '' + articleData['category_id'];
switch (categoryId) {
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 '5': // 小贴士
result['isTip'] = true;
break;
}
}
return result;
}
const _formatAd = (adData, isApp, uid ) => {
return {
img : helpers.image(adData['src'], 640, 640),
url : isApp ? adData['url'] : helpers.urlFormat('/info/index', { 'id' : adData['id'] }, 'guang'),
title : adData['title'],
bgColor : adData['bgColor']
}
}
/**
* 获取页文章数据
* @param {String} channelType 传入频道页类型,值可以是: boys, girls, kids, lifestyle
* @return {Object}
*/
const getList = channelType => {
return channelType;
const getArticleList = (gender, sortId, uid, udid, page, tag, authorId, limit, useCache) => {
uid = uid || 0;
udid = udid || '';
page = page || 1;
useCache = useCache || false;
let param = {
gender : gender,
page : page,
uid : uid,
udid : udid,
client_type : "web"
}
// $param['private_key'] = Yohobuy::$privateKeyList['web'];
//param['client_secret'] =
if(sortId) {
param.sort_id = sortId;
}
if (tag) {
param.tag = tag;
}
if(_.isNumber(authorId)) {
param.author_id = authorId;
}
if(limit) {
param.limit = limit;
}
let cache = useCache ? 300 : false;
return serviceApi.get('guang/api/v2/article/getList', param, {
cache : cache
}).then(res => {
if(res && res.data) {
let artList, adsList, total = 0;
if(res.data.total) {
total = _.parseInt(res.data.total);
}
if(res.data.list) {
let list = res.data.list;
if(list.artList) {
artList = _.map(list.artList, it => {
return _formatArticle(it, true, false, false, uid);
});
}
if(list.adlist) {
adsList = _.map(list.artList, it => {
return _formatAd(it, true, false, false, uid);
});
}
}
return {
msgs : artList,
ads : adsList,
total : total
}
}
})
};
/**
... ... @@ -102,7 +320,7 @@ const getHotTags = (page, limit) => {
return _.map(tags, it => {
return {
tagName: it.tag_name,
url: helpers.urlFormat('/tags/', it.tag_name, 'guang')
url: helpers.urlFormat('/tags/index', { query : it.tag_name}, 'guang')
};
});
});
... ... @@ -114,7 +332,37 @@ const getHotTags = (page, limit) => {
* @return {Object}
*/
const getAds = channelType => {
return channelType;
let contentCode = ADS_CODE[channelType] || ADS_CODE.boys;
let ckey = KEY_WEB_GUANG_ADS_DATA + '_' + contentCode;
//$data = Cache::get($key);
//if(empty($data)) {
//$resource = IndexData::getResourceData($contentCode);
return serviceApi.get(URL_OPERATIONS_RESOURCE_GET, {
content_code : contentCode
}).then(res => {
let list = [];
if(res && res['code'] === 200 && res['data'] && res['data'][0] && res['data'][0]['data']) {
list = _.map(res['data'][0]['data'], (it) => {
return {
img : helpers.image(it.src, 640, 640, 1), //Images::getImageUrl($val['src'], 830, 327, 1),
url : it.url //Helpers::getUrlSafe($val['url']));
}
});
}
//格式化数据
//Cache::set($key, $data, 1800);
return list.length > 5 ? list.slice(0, 4) : list;
});
//}
//master没有数据,资源位没有数据, 取二层缓存
// if(empty($data)) {
// $data = Cache::get($key, 'slave');
// }
};
/**
... ... @@ -123,28 +371,114 @@ const getAds = channelType => {
* @return {Object}
*/
const getBanner = channelType => {
return channelType;
};
const getCategory = channelType => {
return channelType;
let contentCode = BANNER_CODE[channelType] || BANNER_CODE.boys;
let ckey = KEY_WEB_GUANG_BANNER_DATA + '_' + contentCode;
//return cache.get(ckey).then((data) => {
// if(!data) {
return serviceApi.get(URL_OPERATIONS_RESOURCE_GET, {
content_code : contentCode
}).then(res => {
let list = [];
if(res && res['code'] === 200 && res['data'] && res['data'][0] && res['data'][0]['data']) {
list = _.map(res['data'][0]['data'], (it) => {
return {
img : helpers.image(it.src, 830, 327, 1), //Images::getImageUrl($val['src'], 830, 327, 1),
url : it.url //Helpers::getUrlSafe($val['url']));
}
});
//cache.set(); //Cache::set($key, $data, 3600);
}
return list;
})
// }
// return data;
//});
};
const getExcellectRecos = (channelType, start, limit) => {
return {
channelType: channelType,
start: start,
limit: limit
};
const getCategory = currentSortId => {
currentSortId = currentSortId || 0;
return serviceApi.get('guang/api/v1/category/get', {}).then(res => {
let list = [];
if(res && res.code === 200 && res.data) {
for(let cat of res.data) {
if(cat.name === '专题') {
continue;
}
list.push({
typeId : cat.id,
type : cat.name,
isActive : cat.id == currentSortId,
navUrl : helpers.urlFormat('/index/index', { type : cat.id }, 'guang')
});
}
}
return list;
});
};
const getExcellectRecos = (gender, page, limit) => {
return serviceApi.get('guang/api/v2/article/getArticleByViewsNum', {
gender : gender,
page : page,
limit : limit
}).then(res => {
let list = [];
if(res && res['data']) {
for(let it of res['data']) {
let reco = {
url : helpers.urlFormat(`/${it.id}.html`, {}, 'guang'), // Helpers::url('/'.$article['id'].'.html', '', 'guang'),
title : it['title']
};
if(it['src']) {
reco['img'] = helpers.image(it.src, 90, 60, 1);//Images::getImageUrl($article['src'], 90, 60, 1);
}
list.push(reco);
}
}
return list;
});
}
const getAuthor = authorId => {
return serviceApi.get('guang/service/v1/author/getAuthor', {
author_id : authorId
}, {
cache : 3600
}).then(res => {
if(res && res['data']) {
return {
avatar : res['data']['avatar'],
name : res['data']['name'],
intro : res['data']['author_desc']
}
}
});
}
module.exports = {
getList: getList,
getArticleList: getArticleList,
getHotTags: getHotTags,
getAds: getAds,
getBanner: getBanner,
getCategory: getCategory,
getExcellectRecos: getExcellectRecos,
getIndexNav: getIndexNav
getExcellectRecos: getExcellectRecos,
getPathNav: getPathNav,
getAuthor : getAuthor
};
... ...
... ... @@ -12,7 +12,8 @@ const cRoot = './controllers';
const guangController = require(`${cRoot}/index`);
router.get('/', guangController.index);
router.get('/detail/:id', guangController.detail);
router.get('/index/index', guangController.index);
router.get('/detail/:id', guangController.detail); //guang/info/index
router.get('/tags/index', guangController.tags);
router.get('/Index/editor', guangController.editor);
... ...
<div class="guang-editor-page guang-page yoho-page clearfix">
{{# guang}}
{{> common/path-nav}}
{{# editor}}
<div class="editor-info clearfix">
<div class="author-avatar">
<img src="{{avatar}}" alt="">
</div>
<div class="author-info">
<p class="author-name">{{name}}</p>
<p class="author-introduce">{{intro}}</p>
</div>
</div>
{{/ editor}}
<div class="left-side">
<div id="msg-list" class="msg-list">
{{# msgs}}
{{> msg}}
{{/ msgs}}
</div>
<div class="msg-pager pager">
{{{msgPager}}}
</div>
</div>
<div class="right-side">
{{> right-side}}
</div>
{{/ guang}}
</div>
\ No newline at end of file
... ...
<div class="home-page yoho-page {{pageType}}" data-page="{{pageType}}">
hello, <br/>
{{world.aaa}}
{{json world}}
{{page '/good' totalRecords=1000 page=6 type="ellipsis" }}
{{lowerCase 'GGGGG'}}
<div class="guang-index-page guang-page yoho-page clearfix">
{{# guang}}
{{> common/path-nav}}
<div class="left-side">
<div id="slider" class="slider">
<ul class="slide-wrapper">
{{#each slider}}
<li>
<a href="{{url}}" target="_blank">
{{#if @first}}
<img src="{{img}}">
{{^}}
<img class="lazy" data-original="{{img}}">
{{/if}}
</a>
</li>
{{/each}}
</ul>
</div>
<div id="pjax-container" class="msg">
<ul class="msg-nav">
{{# msgTypes}}
<li data-type="{{typeId}}" {{#if isActive}}class="actived"{{/if}}>
<a class="pjax-link" href="{{navUrl}}">{{type}}</a>
</li>
{{/ msgTypes}}
</ul>
<div id="msg-list" class="msg-list">
{{# msgs}}
{{> msg}}
{{/ msgs}}
</div>
{{pager totalRecords=total page=page type="ellipsis" theme="msg-pager"}}
</div>
</div>
<div class="right-side">
{{> right-side}}
</div>
{{/ guang}}
</div>
\ No newline at end of file
... ...
<div class="guang-list-page guang-page yoho-page clearfix">
{{# guang}}
{{> common/path-nav}}
<div class="left-side">
<div class="tag-header">
<span>{{tag}}</span>
关联的文章
</div>
<div id="msg-list" class="msg-list">
{{# msgs}}
{{> msg}}
{{/ msgs}}
</div>
{{pager totalRecords=total page=page type="ellipsis" theme="msg-pager"}}
</div>
<div class="right-side">
{{> right-side}}
</div>
{{/ guang}}
</div>
\ No newline at end of file
... ...
{{# comment}}
<h4>
<span class="comment-num">{{commentNum}}</span>
条评论 <i></i>
</h4>
<p class="comments-empty">还没有评论,快抢沙发吧</p>
<div class="commnets-resultwrapper">
<ul class="comments-list">
{{# list}}
<li class="clearfix">
<div class="avatar">
<img class="comment-user-avatar" src="{{avatar}}" alt=""></div>
<div class="comment-info">
<p class="comment-user-name">{{name}}</p>
<p class="comment-content">{{content}}</p>
<p class="comment-time">{{time}}</p>
</div>
</li>
{{/ list}}
</ul>
<div class="comment-pager pager">{{{commentPager}}}</div>
</div>
{{/ comment}}
... ...
<div class="msg-content clearfix" data-id="{{id}}">
<div class="msg-img">
<div class="classification">
{{classification}}
</div>
{{#if isReco}}
<div class="reco"></div>
{{/if}}
<a href="{{url}}" target="_blank">
<img class="lazy{{#if isSquareImg}} square{{/if}}" data-original="{{img}}">
</a>
</div>
<div class="msg-info">
<a class="msg-title" href="{{url}}" target="_blank">{{title}}</a>
<p class="msg-app">
<a href="{{editorUrl}}" target="_blank">
<span class="author">{{author}}</span>
</a>
<span class="publish-time">
<i class="iconfont">&#xe625;</i>
{{pTime}}
</span>
<span class="page-view">
<i class="iconfont">&#xe627;</i>
{{pView}}
</span>
</p>
<p class="content">{{content}}</p>
<div class="footer">
<div class="tags">
{{# tags}}
<a class="msg-tag" href="{{url}}" target="_blank">{{tag}}</a>
{{/ tags}}
</div>
<div class="like-comment">
<span class="like">
<i class="iconfont like-icon{{#if liked}} liked{{/if}}">&#xe626;</i>
{{#if like}}<b class="like-num">(<em class="num">{{like}}</em>)</b>{{/if}}
</span>
<span class="comment">
<i class="iconfont">&#xe624;</i>
{{# comment}}
({{.}})
{{/ comment}}
</span>
</div>
</div>
</div>
</div>
\ No newline at end of file
... ...
<div class="ex-reco">
<h1 class="ex-reco-title">精彩推荐</h1>
<div id="ex-reco-list" class="ex-reco-list">
{{# exRecos}}
<div class="ex-reco-item clearfix">
<a class="ex-reco-img" href="{{url}}" target="_blank">
<span class="bg-img" style="background-image:url({{img}})"></span>
</a>
<a href="{{url}}" target="_blank">
<p class="ex-reco-context">{{title}}</p>
</a>
</div>
{{/ exRecos}}
</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}}
</div>
</div>
<div class="ads">
{{# ads}}
<a class="ad" href="{{url}}" target="_blank">
<img class="lazy" data-original="{{img}}">
</a>
{{/ ads}}
</div>
\ No newline at end of file
... ...
@font-face {font-family: "iconfont";
src: url('iconfont.eot?t=1473148446'); /* IE9*/
src: url('iconfont.eot?t=1473148446#iefix') format('embedded-opentype'), /* IE6-IE8 */
url('iconfont.woff?t=1473148446') format('woff'), /* chrome, firefox */
url('iconfont.ttf?t=1473148446') format('truetype'), /* chrome, firefox, opera, Safari, Android, iOS 4.2+*/
url('iconfont.svg?t=1473148446#iconfont') format('svg'); /* iOS 4.1- */
}
.iconfont {
font-family:"iconfont" !important;
font-size:16px;
font-style:normal;
-webkit-font-smoothing: antialiased;
-webkit-text-stroke-width: 0.2px;
-moz-osx-font-smoothing: grayscale;
}
.icon-pinglun:before { content: "\e624"; }
.icon-zuosanjiao:before { content: "\e618"; }
.icon-yousanjiao:before { content: "\e619"; }
.icon-chevron-down:before { content: "\e60b"; }
.icon-chevron-right:before { content: "\e60c"; }
.icon-duihao:before { content: "\e605"; }
.icon-gouwuche:before { content: "\e61b"; }
.icon-cha:before { content: "\e60d"; }
.icon-forbid:before { content: "\e61c"; }
.icon-left:before { content: "\e60e"; }
.icon-sort:before { content: "\e614"; }
.icon-iconsj:before { content: "\e625"; }
.icon-search:before { content: "\e60f"; }
.icon-sanjiao2:before { content: "\e615"; }
.icon-sanjiao1:before { content: "\e610"; }
.icon-xiangyou:before { content: "\e608"; }
.icon-xiangzuo:before { content: "\e609"; }
.icon-wenhao:before { content: "\e620"; }
.icon-xiangxia:before { content: "\e61d"; }
.icon-dianhua:before { content: "\e621"; }
.icon-time:before { content: "\e60a"; }
.icon-zan:before { content: "\e626"; }
.icon-up:before { content: "\e607"; }
.icon-heart:before { content: "\e611"; }
.icon-logincheckbutton1:before { content: "\e616"; }
.icon-aaa:before { content: "\e601"; }
.icon-pinglun1:before { content: "\e61e"; }
.icon-zhengque:before { content: "\e622"; }
.icon-circle:before { content: "\e606"; }
.icon-eye:before { content: "\e627"; }
.icon-03tanhao:before { content: "\e61f"; }
.icon-home:before { content: "\e61a"; }
.icon-shoppingcard:before { content: "\e600"; }
.icon-checkboxchecked:before { content: "\e617"; }
.icon-wujiaoxing:before { content: "\e623"; }
.icon-zhengchang:before { content: "\e612"; }
.icon-weibiaoti7:before { content: "\e613"; }
.icon-say1:before { content: "\e602"; }
.icon-7t11:before { content: "\e603"; }
.icon-z:before { content: "\e604"; }
... ...
No preview for this file type
... ... @@ -2,7 +2,7 @@
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd" >
<svg xmlns="http://www.w3.org/2000/svg">
<metadata>
Created by FontForge 20120731 at Wed Aug 10 19:10:35 2016
Created by FontForge 20120731 at Tue Sep 6 15:54:06 2016
By admin
</metadata>
<defs>
... ... @@ -19,7 +19,7 @@ Created by FontForge 20120731 at Wed Aug 10 19:10:35 2016
bbox="0 -212 1158 896"
underline-thickness="50"
underline-position="-100"
unicode-range="U+0078-E623"
unicode-range="U+0078-E627"
/>
<missing-glyph horiz-adv-x="374"
d="M34 0v682h272v-682h-272zM68 34h204v614h-204v-614z" />
... ... @@ -129,5 +129,17 @@ t-35.5 -173.5t35.5 -173.5t95.5 -142.5t142.5 -95t173 -35t173.5 35t142.5 95t95 142
" />
<glyph glyph-name="uniE623" unicode="&#xe623;"
d="M512 63l-316 -166l60 352l-256 250l354 51l158 321l158 -321l354 -51l-256 -250l60 -352z" />
<glyph glyph-name="uniE624" unicode="&#xe624;" horiz-adv-x="1000"
d="M744 598h-488q-38 0 -64.5 -26.5t-26.5 -64.5v-290q0 -38 26.5 -64.5t64.5 -26.5h227l200 -138v138h61q38 0 64.5 26.5t26.5 64.5v290q0 38 -26.5 64.5t-64.5 26.5zM744 358z" />
<glyph glyph-name="uniE625" unicode="&#xe625;"
d="M511 832q-91 0 -173.5 -35.5t-142 -95t-95 -142t-35.5 -173.5t35.5 -173.5t95 -142t142 -95t173.5 -35.5t173.5 35.5t142.5 95t95 142t35 173.5t-35 173.5t-95 142t-142.5 95t-173.5 35.5zM734 337h-237q-7 0 -14 3q-22 9 -22 33v237q0 15 10.5 26t26 11t26 -11t10.5 -26
v-200h200q15 0 26 -10.5t11 -26t-11 -26t-26 -10.5zM734 337z" />
<glyph glyph-name="uniE626" unicode="&#xe626;" horiz-adv-x="1025"
d="M994 163q-18 9 -16 30.5t27 46.5q24 27 17.5 54.5t-33.5 40.5q-17 8 -24.5 17.5t-2 20t26.5 19.5q30 11 29.5 55.5t-31.5 80.5q-34 39 -278 23l-23 -1q3 2 3 145q0 101 -28 139t-84 36q-18 0 -28.5 -5t-17 -13t-11 -26.5t-7.5 -38t-10 -56.5t-16 -74q-12 -47 -38 -94
t-54 -80t-55 -59t-44 -39l-18 -13v-386q10 -14 27 -25.5t31 -17t31 -11.5t21 -8q9 -4 65 -10.5t105.5 -11t51.5 -4.5q4 0 11 0.5t30 2.5t45 4.5t52 6.5t56.5 8t53.5 9.5t47 11t33.5 13t15.5 14.5q8 24 3 39t-2 27t23 20q27 10 34.5 34.5t0.5 46t-19 28.5zM0 379v-380
q0 -28 20 -48.5t49 -20.5h137v518h-137q-29 0 -49 -20.5t-20 -48.5zM0 379z" />
<glyph glyph-name="uniE627" unicode="&#xe627;" horiz-adv-x="1025"
d="M512 719q-167 0 -304.5 -89.5t-205.5 -236.5q-4 -9 0 -18q68 -147 205.5 -236.5t304.5 -89.5t304.5 89.5t205.5 236.5q4 9 0 18q-68 147 -205.5 236.5t-304.5 89.5zM512 153q-96 0 -163.5 67.5t-67.5 163.5t67.5 163.5t163.5 67.5t163.5 -67.5t67.5 -163.5t-67.5 -163.5
t-163.5 -67.5zM512 384zM364 384q0 61 43.5 104.5t104.5 43.5t104.5 -43.5t43.5 -104.5t-43.5 -104.5t-104.5 -43.5t-104.5 43.5t-43.5 104.5z" />
</font>
</defs></svg>
... ...
No preview for this file type
No preview for this file type
/**
* 分享
* @author: xuqi<qi.xu@yoho.cn>
* @date: 2016/3/1
*/
var $ = require('yoho-jquery');
function shareBase(options) {
var openUrl = '';
var defOption = {
title: '',
url: window.location.href,
weixinUrl: '',
image: '',
desc: '',
channel: ''
};
var shareChannels = ['weibo', 'tweibo', 'qzone', 'renren', 'qq', 'douban','weixin'];
var sharebox;
var shareCon = '<em><i></i></em>';
defOption = $.extend(defOption, options);
if (defOption.image && defOption.image.substr(0, 2) === '//') {
defOption.image = 'http:' + defOption.image;
}
if (defOption.weixinUrl && defOption.weixinUrl.substr(0, 2) === '//') {
defOption.weixinUrl = 'http:' + defOption.weixinUrl;
}
if (defOption.url && defOption.url.substr(0, 2) === '//') {
defOption.url = 'http:' + defOption.url;
}
if ($.inArray(defOption.channel, shareChannels) === -1) {
alert('不存在的分享平台!');
return false;
}
switch (defOption.channel) {
case 'weibo':
openUrl = 'http://service.weibo.com/share/share.php?url=' + defOption.url + '&title=' +
defOption.title + '&appkey=3739328910&searchPic=true&pic=' + defOption.image;
break;
case 'tweibo':
openUrl = 'http://share.v.t.qq.com/index.php?c=share&a=index&url=' + defOption.url + '&title=' +
defOption.title + '&appkey=c0af9c29e0900813028c2ccb42021792&pic=' + defOption.image;
break;
case 'qzone':
openUrl = 'http://sns.qzone.qq.com/cgi-bin/qzshare/cgi_qzshare_onekey?url=' + defOption.url + '&title=' +
defOption.title + '&desc=&summary=' + defOption.desc + '&site=YOHO!BUY 有货&pics=' + defOption.image;
break;
case 'renren':
openUrl = 'http://widget.renren.com/dialog/share?resourceUrl=' + defOption.url + '&srcUrl=' +
defOption.url + '&desc=' + defOption.desc + '&title=' + defOption.title + '&description=' +
defOption.desc + '&pic=' + defOption.image;
break;
case 'qq':
openUrl = 'http://connect.qq.com/widget/shareqq/index.html?url=' + defOption.url + '&desc=' +
defOption.desc + '&title=' + defOption.title.replace('%', '') + '&desc=&summary=' +
defOption.desc + '&site=YOHO!BUY 有货&pics=' + defOption.image;
break;
case 'weixin':
openUrl = 'http://s.jiathis.com/qrcode.php?url=' + defOption.weixinUrl + '&desc=' +
defOption.desc + '&title=' + defOption.title + '&description=' +
defOption.desc + '&pic=' + defOption.image;
break;
case 'douban':
openUrl = '//www.douban.com/share/service?href=' + defOption.url + '&text=' +
defOption.desc + '&image=' + defOption.image + '&title=' + defOption.title + '&comment=';
break;
}
if (defOption.channel === 'weixin') {
if (!defOption.self) {
return;
}
sharebox = defOption.self.closest('.share-to').find('.weixin-share-box');
if (sharebox.length > 0) {
shareCon += '<div class="con"><h2>分享到微信朋友圈</h2><p class="pic">' +
'<img src="' + openUrl + '" /></p><p class="w">打开微信,点击底部得“发现”,使用<br/>“扫一扫“即可将网页分享到我的朋友圈。</p>' +
'<a href="javascript:void(0)" class="close">x</a></div>';
sharebox.find('div').length > 0 ? sharebox.show() : sharebox.html(shareCon).show();
sharebox.find('.close').click(function() {
$(this).closest('.weixin-share-box').hide();
});
}
} else {
window.open(encodeURI(openUrl));
}
}
function share(channel, self) {
var title = document.title.replace(/(^\s*)|(\s*$)/g, '');
var desc = $('#share-desc').val();
var image = $('#share-img').val();
var weixinUrl = $('#weixin-url').val();
if (channel === 'weibo' || channel === 'tqq') {
shareBase({
channel: channel,
title: title,
image: image
});
} else {
shareBase({
channel: channel,
title: title,
desc: desc,
image: image,
self: self,
weixinUrl: weixinUrl
});
}
}
$('.share-wrapper').on('click', 'i', function() {
var $el = $(this),
type = $el.data('type'),
$weixinShareBox = $('.weixin-share-box');
if (type === 'weixin') {
share(type, $el);
} else {
$weixinShareBox.hide();
share(type);
}
});
... ...
/**
* 逛详情页
* @author: liuyue<yue.liu@yoho.cn>
* @date: 2015/12/16
*/
var $ = require('yoho-jquery'),
lazyLoad = require('yoho-jquery-lazyload'),
$commentArea = $('#comment-area'),
articleId = $('.detail-body').data('id');
var $commentList = $commentArea.find('.comments-wrap'),
$commentNum = $('#article-comment > .comment-num'),
commenting = false, //评论请求尚未返回变量
locating = false, //评论页面正在跳转
$commentBtn = $('#comment-btn'),
MAX_COMMENTS_WORDS = 100,
$wordCountTip = $('#word-count-tip');
require('./right-side');
require('./img-blink');
require('../common/share');
//Pjax
require('yoho-jquery-pjax');
lazyLoad({
failure_limit: 50
});
//点击评论滑到评论区
// $('#article-comment').click(function() {
// $('html, body').animate({
// scrollTop: $commentArea.offset().top - 20
// }, 800);
// });
//文章点赞与取消点赞
$('#prise-btn').click(function() {
var prising = false,
url,
$this = $(this);
if (prising) {
return;
}
$this.toggleClass('liked');
if ($this.hasClass('liked')) {
//点赞
url = '/guang/info/praise';
} else {
//取消点赞
url = '/guang/info/cancelPraise';
}
prising = true;
$.ajax({
type: 'GET',
url: url,
data: {
id: articleId
}
}).then(function(data) {
if (data.code === 200) {
$this.find('.like-num').html(data.data);
}
prising = false;
});
}).bind('mouseenter mouseleave', function() {
$(this).toggleClass('hover');
});
//文章收藏与取消收藏
$('#collect-btn').click(function() {
var collecting = false,
url,
col,
$this = $(this);
if (collecting) {
return;
}
if ($this.hasClass('collected')) {
//取消收藏
url = '/guang/info/cancelcollect';
col = 0;
} else {
//收藏
url = '/guang/info/collect';
col = 1;
}
collecting = true;
$.ajax({
type: 'GET',
url: url,
data: {
id: articleId
}
}).then(function(data) {
var hrefUrl;
switch (data.code) {
case 401:
//防止从已有col的页面再次进行跳转后出错的情况
if (/\?col=(1|0)/.test(location.href)) {
hrefUrl = location.href.replace(/\?col=(1|0)/, '?col=' + col);
} else {
hrefUrl = location.href + '?col=' + col;
}
location.href = '//www.yohobuy.com/signin.html?refer=' + encodeURI(hrefUrl);
break;
case 400:
// alert(data.message);
break;
case 200:
if (/\?col=(1|0)/.test(location.href)) {
//如果页面url中含有col,为了防止页面刷新时收藏或者取消收藏会根据col来的问题,进行页面跳转拿掉参数
location.href = location.href.replace(/\?col=(1|0)/, '');
} else {
$this.toggleClass('collected');
}
break;
}
collecting = false;
});
}).bind('mouseenter mouseleave', function() {
$(this).toggleClass('hover');
});
function showComment() {
var commonlist = $('.comments-list').find('li').length;
if (commonlist === 0) {
$('.commnets-resultwrapper').hide();
$('.comments-empty').show();
} else {
$('.commnets-resultwrapper').show();
$('.comments-empty').hide();
}
}
showComment();
//评论
function comment(id) {
var commentInfo = $('#comment-info').val();
if (commentInfo === '') {
alert('评论不能为空');
return false;
}
commenting = true;
$.ajax({
url: '/guang/info/comment',
data: {
id: id,
comment: commentInfo
},
type: 'post',
success: function(data) {
switch (data.code) {
case 401:
locating = true;
location.href = '//www.yohobuy.com/signin.html?refer=' +
window.escape(location.href + '#comment-info');
break;
case 400:
alert(data.message);
break;
case 200:
if (data.data) {
$commentList.html(data.data.content);
$commentNum.html(data.data.count);
showComment();
//clear comment-text
$('#comment-info').val('').keyup();
}
break;
}
commenting = false;
}
});
}
$commentBtn.click(function(e) {
//页面正在跳转或者正在AJAX请求时评论无效
if (locating || commenting) {
return false;
}
//字数不符合要求
if ($('#comment-info').val().length - MAX_COMMENTS_WORDS > 0) {
return;
}
e.preventDefault();
comment(articleId);
});
//comment pager pjax
$(document).pjax('.comment-pager a', '#pjax-container', {
timeout: 5000
});
//分页后移动到评论框的位置
$(document).on('pjax:end', function() {
showComment();
$('html,body').scrollTop($('#comment-info').offset().top);
});
$('#comment-info').keyup(function() {
var len = $(this).val().length,
showTxt;
if (len === 0) {
$wordCountTip.html('');
$commentBtn.addClass('disable');
} else {
if (len - MAX_COMMENTS_WORDS <= 0) {
showTxt = '还可以输入' + (MAX_COMMENTS_WORDS - len) + '字';
$commentBtn.removeClass('disable');
} else {
showTxt = '已超过<span class="exceed-count">' + (len - MAX_COMMENTS_WORDS) + '</span>字';
$commentBtn.addClass('disable');
}
}
$wordCountTip.html(showTxt);
});
//init
$('#comment-info').trigger('keyup');
... ...
/**
* 逛编辑页、列表页
* @author: xuqi<qi.xu@yoho.cn>
* @date: 2015/12/15
*/
require('./msg');
require('./img-blink');
require('./right-side');
\ No newline at end of file
... ...
/**
* 逛首页
* @author: xuqi<qi.xu@yoho.cn>
* @date: 2015/12/15
*/
var $ = require('yoho-jquery');
var msg = require('./msg');
require('yoho-jquery-pjax');
require('yoho-slider');
require('./img-blink');
require('./right-side');
$('#slider').slider(); //初始化slider
$(document).pjax('.pjax-link, .msg-pager a', '#pjax-container', {
timeout: 2000
});
$(document).on('pjax:end', function() {
msg.dotLazy();
});
\ No newline at end of file
... ...
/**
* 图片移入闪动效果JS
* @auhor: xuqi<qi.xu@yoho.cn>
* @date: 2015/7/29
*/
var $ = require('yoho-jquery');
$('.guang-page').on('mouseover', 'a img, a .bg-img', function(e) {
var $el = $(e.target);
//slider中的图片不做此效果
if ($el.closest('.slider').length > 0) {
return;
}
$el.addClass('blink');
setTimeout(function() {
$el.removeClass('blink');
}, 100);
});
... ...
var $ = require('yoho-jquery'),
lazyLoad = require('yoho-jquery-lazyload');
var prising;
require('yoho-jquery-dotdotdot');
//资讯文字截取和lazyload
function dotLazy() {
//文字截取
$('.msg-title, .msg-content .content').dotdotdot({
wrap: 'letter'
});
//Lazyload
lazyLoad($('#msg-list img.lazy'));
}
//资讯点赞
$('.guang-page').on('click', '.like-icon', function() {
var $this = $(this),
msgId = $this.closest('.msg-content').data('id'),
url;
//同一资讯多次点击归一处理
if (prising === msgId) {
return;
}
prising = msgId;
$this.toggleClass('liked');
//点赞或取消点赞
if ($this.hasClass('liked')) {
url = '/guang/info/praise';
} else {
url = '/guang/info/cancelPraise';
}
$.ajax({
type: 'GET',
url: url,
data: {
id: msgId,
time: new Date().getTime()
}
}).then(function(data) {
if (data.code === 200) {
if (data.data * 1 === 0) {
$this.next('b').addClass('num-0').children('.num').html('0'); //隐藏数字显示
} else {
$this.next('b').removeClass('num-0').children('.num').html(data.data);
}
}
prising = false;
});
}).on('mouseenter mouseleave', '.like-icon', function() {
$(this).closest('.like').toggleClass('hover');
});
dotLazy();
exports.dotLazy = dotLazy;
... ...
/**
* 右侧栏文字截取js
*/
var $ = require('yoho-jquery'),
lazyLoad = require('yoho-jquery-lazyload');
require('yoho-jquery-dotdotdot');
$('.ex-reco-context').dotdotdot({
wrap: 'letter'
});
lazyLoad($('.ads img.lazy'));
\ No newline at end of file
... ...
/**
* 逛编辑页、列表页
* @author: xuqi<qi.xu@yoho.cn>
* @date: 2015/12/15
*/
require('./msg');
require('./img-blink');
require('./right-side');
\ No newline at end of file
... ...
@use postcss-crip;
@use postcss-short;
.pager {
fz: 12px;
a {
h: 24px;
p: 0 9px;
lh: 24px;
d: inline-block;
ta: center;
mr: 8px;
c: #222;
&.cur {
c: #fff #222;
}
&:first-child .iconfont {
right: auto;
left: -5px;
}
}
.iconfont {
position: relative;
vertical-align: middle;
bottom: 1px;
right: -5px;
font-size: 14px;
}
}
\ No newline at end of file
... ...
.path-nav {
font-size: 12px;
padding: 15px 0;
height: 18px;
line-height: 18px;
/*border-bottom: 1px solid #eaeceb;*/
/*margin-bottom: 15px;*/
color: #666;
a {
color: #666;
}
.iconfont {
font-size: 12px;
}
.last {
font-weight: bold;
}
}
\ No newline at end of file
... ...
.guang-detail-page {
width: 1150px;
margin: 0 auto 95px;
b {
font-weight: bold;
}
i {
font-style: italic;
}
.block {
margin: 15px 0;
}
.excellent-recommendation-title {
margin-top: 4px;
}
.block-header {
position: relative;
border-bottom: 1px solid #c1c1c1;
font-size: 18px;
height: 38px;
line-height: 38px;
text-align: center;
margin-bottom: 24px;
color: #333;
.more-reco {
position: absolute;
right: 0;
color: #000;
font-size: 14px;
text-decoration: none;
}
}
/*830+22:兼容IE8不认识:nth-child导致brand换行的问题*/
.related-brand .brands {
width:852px;
}
.related-reco .recos {
width: 850px;
}
.detail-title {
font-size: 28px;
line-height: 64px;
border-bottom: 1px dotted #c1c1c1;
word-wrap:break-word;
}
.article-author {
float: left;
line-height: 64px;
.author-avatar {
clear: both;
width: 38px;
height: 64px;
img {
width: 38px;
height: 38px;
border-radius: 50%;
vertical-align: middle;
}
}
}
.author-info {
float: left;
margin-left: 10px;
font-size: 14px;
max-width: 447px;
.author-name {
display: block;
height: 64px;
line-height: 64px;
cursor: pointer;
color: #000;
&:hover {
color: #cc3300;
}
}
.author-introduce {
color: #999;
}
}
.article-status {
float: right;
height: 64px;
line-height: 64px;
color: #999;
font-size: 13px;
.article-click {
margin: 0 25px;
}
.article-comment {
color: #cc3300;
cursor: pointer;
}
}
.article-main {
img {
display: block;
max-width: 100%;
margin:0 auto;
}
.article-text {
margin: 2px 0 20px;
line-height: 28px;
font-size: 14px;
}
.article-small-pic {
text-align: center;
font-size: 0;
img {
display: inline-block;
max-width: 412px;
&:first-child {
margin: 0 6px 0 0;
}
}
}
.block:first-child {
margin-top: 10px;
}
}
/*user handle*/
.user-handle {
margin: 30px 0 0 0;
text-align: center;
ul {
display: inline-block;
li {
float: left;
margin: 0 15px;
cursor: pointer;
a {
position: relative;
display: block;
padding: 0 10px;
height: 36px;
line-height: 36px;
color: #535353;
font-size: 0;
background: #efefef;
text-align: left;
i, span{
display: inline-block;
font-style: normal;
font-size: 14px;
}
i {
margin: 0 5px 0 0;
font-size: 18px;
opacity: 0.5;
}
.cancel-collect {
display: none;
}
}
}
.like-status.liked i,
.like-status.hover i{
opacity: 1;
}
.like-statis.hover .like-num {
color: #000;
}
.sort-collect a {
i {
width: 21px;
}
}
.sort-collect.collected a {
i {
opacity: 1;
}
span {
display: none;
}
.cancel-collect {
display: inline;
}
}
.sort-collect.hover i {
opacity: 1;
}
.sort-collect.hover span {
color: #000;
}
}
}
.article-bottom-info {
margin: 44px 0 0 0;
padding: 0 0 10px;
border-bottom: 1px dotted #c1c1c1;
}
.article-tag {
float: left;
width: 588px;
.tag-icon {
float: left;
margin: 0 12px 0 0;
font-size: 20px;
font-style: normal;
}
ul {
float: left;
max-width: 555px;
li {
float: left;
margin: 0 10px 10px 0;
a {
display: block;
padding: 0 15px;
height: 20px;
line-height: 20px;
font-size: 12px;
color: #fff;
font-weight: bold;
background: #c1c1c1;
}
&:hover a {
background:#333;
}
}
li:first-child {
margin-left: 0;
}
}
}
.article-share {
float: right;
.title {
font-size: 12px;
}
}
.detail-related-posts {
margin: 14px 0 0 0;
li {
float: left;
width: 264px;
margin-left: 19px;
a {
display: block;
}
.bg-img {
display: block;
width: 100%;
height: 173px;
line-height: 173px;
text-align: center;
font-size: 0;
img {
max-width: 100%;
max-height: 100%;
vertical-align: middle;
}
}
.post-title {
margin: 8px 0 0 0;
h2 {
line-height: 16px;
font-size: 14px;
color: #000;
overflow: hidden;
white-space: nowrap;
text-overflow: ellipsis;
}
}
.post-title:hover h2 {
color: #cc3300 !important;
}
}
li:first-child {
margin-left: 0;
}
}
.comment-area {
margin: 58px 0 0 0;
.comment-publish {
height: 48px;
}
}
.comment-textarea {
textarea {
display: block;
width: 812px;
height: 86px;
padding: 12px 12px;
resize: none;
outline: none;
font-size: 14px;
line-height: 18px;
color: #535353;
font-family: "arial","helvetica","微软雅黑";
border: 1px solid #e7e7e7;
}
}
.word-count-tip {
display: inline-block;
height: 48px;
line-height: 48px;
font-size: 12px;
color: #c8c8c8;
.exceed-count {
color: #f00;
}
}
.publish-btn {
margin: 10px 0 0 0;
float: right;
width: 90px;
height: 33px;
line-height: 33px;
text-align: center;
color: #fff;
font-size: 14px;
background: #cb3a3e;
cursor: pointer;
&:hover {
background: #c03234;
}
&.disable {
background-color: #e79c9e;
}
}
.comments-wrap {
h4 {
position: relative;
line-height: 32px;
border-bottom: 1px solid #e7e7e7;
.comment-num {
margin-right: 5px;
color: #c11e00;
}
i {
position: absolute;
width: 13px;
height: 7px;
left: 30px;
bottom: -7px;
background: resolve('guang/comment-icon.png') no-repeat;
}
}
.comment-pager {
float: right;
margin: 20px 0;
}
}
.comments-empty {
display: none;
color: #ccc;
margin: 20px 0;
font-size: 12px;
line-height: 12px;
text-align: center;
}
.commnets-resultwrapper {
display: none;
}
.comments-list{
li{
margin: 14px 0 0;
padding: 0 0 15px;
border-bottom: 1px dotted #e7e7e7;
.avatar{
float: left;
width: 40px;
height: 40px;
overflow: hidden;
img{
display: block;
width: 100%;
height: 100%;
border-radius: 50%;
}
}
.comment-info{
float: left;
width: 774px;
margin: 0 0 0 16px;
.comment-user-name{
color: #c11e00;
font-size: 15px;
line-height: 15px;
}
.comment-content{
margin-top: 10px;
line-height: 16px;
font-size: 12px;
word-wrap:break-word;
}
.comment-time{
margin: 10px 0 0 0;
color: #c8c8c8;
font-size: 12px;
line-height: 12px;
clear: both;
}
}
}
}
.brand {
margin-right: 22px;
margin-bottom: 20px;
float: left;
.thumb {
display: table-cell;
border: 1px solid #f5f5f5;
height: 120px;
width: 120px;
box-sizing: border-box;
text-align: center;
vertical-align: middle;
img {
display: block;
max-width: 120px;
max-height: 120px;
margin: 0 auto;
}
}
.brand-name {
width: 120px;
font-size: 13px;
line-height: 20px;
overflow: hidden;
white-space: nowrap;
text-overflow: ellipsis;
text-align: center;
color: #333;
}
}
$commodityWidth: 192px;
.tag-container,
.few-tag {
display: none;
}
.good-info {
width: $commodityWidth;
margin-right: 20px;
margin-bottom: 12px;
.good-detail-img {
height: auto;
.good-thumb,
img.lazy {
height: 257px;
}
}
.good-detail-text > a {
margin-top: 0;
line-height: 36px;
}
.good-detail-text > .price {
margin-top: 0;
}
}
}
... ...
.guang-index-page {
.msg-nav {
border-bottom: 1px solid #000;
margin-top: 24px;
height: 30px;
li {
float: left;
height: 30px;
line-height: 30px;
text-align: center;
font-size: 18px;
padding: 0 28px;
a {
display: block;
height: 100%;
width: 100%;
color: #333;
}
&.actived {
background-color: #111;
a {
color: #fff;
}
}
}
}
.msg-pager {
float: right;
margin: 20px 0;
}
}
\ No newline at end of file
... ...
.guang-page {
width: 1150px;
margin: 0 auto;
.left-side {
float: left;
width: 830px;
}
.right-side {
float: left;
width: 290px;
margin-left: 30px;
}
img.blink,
.bg-img.blink {
opacity: 0.8;
}
/*精彩推荐*/
.ex-reco-title {
color: #333;
line-height: 24px;
padding-bottom: 10px;
border-bottom: 1px solid #ccc;
font-size: 20px;
font-weight: bold;
}
.ex-reco-list {
margin-top: 14px;
}
.ex-reco-item {
box-sizing: border-box;
height: 60px;
margin-bottom: 14px;
&:last-child {
margin-bottom: 0;
}
}
.ex-reco-img {
display: block;
float: left;
width: 90px;
height: 60px;
span {
display: block;
height: 100%;
width: 100%;
background-size:cover;
background-position: center;
img {
width: 100%;
height: 100%;
}
}
margin-right: 5px;
}
.ex-reco-context {
float: left;
max-width: 195px;
height: 40px;
line-height: 20px;
font-size: 13px;
color: #666;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
&:hover {
color: #cc3300;
}
}
/*热门标签*/
.hot {
margin-top: 40px;
.hot-title {
color: #333;
line-height: 24px;
padding-bottom: 10px;
border-bottom: 1px solid #ccc;
font-weight: bold;
font-size: 20px;
}
.hot-tag-list {
margin-top: 14px;
max-height: 150px;
overflow: hidden;
}
.hot-tag {
display: inline-block;
float: left;
padding: 5px;
font-size: 12px;
background-color: #ccc;
border: none;
margin-right: 10px;
margin-bottom: 10px;
color: white;
font-weight: bold;
&:hover {
background-color: #333;
}
}
}
/*广告位*/
.ads {
margin-top: 30px;
.ad {
display: block;
box-sizing: border-box;
margin-bottom: 24px;
width: 290px;
img {
display: block;
width: 100%;
}
}
}
/*资讯*/
.msg-content {
padding: 24px 0;
border-bottom: 1px solid #ccc;
position: relative;
.content {
height: 80px;
line-height: 24px;
}
.iconfont {
color: #ccc;
}
.msg-img {
position: relative;
float: left;
margin-right: 26px;
img {
display: block;
width: 360px;
height: 240px;
}
img.square {
height: 360px;
}
}
.classification {
position: absolute;
background-color: #000;
color: #fff;
text-align: center;
width: 80px;
height: 32px;
line-height: 32px;
font-size: 13px;
opacity: 0.9;
z-index: 99;
}
.reco {
position: absolute;
top: 0;
left: 66px;
height: 32px;
width: 32px;
background: resolve("guang/msg-reco.png");
background-size: 100% 100%;
z-index: 100;
}
.msg-info {
float: left;
width: 440px;
}
.msg-title {
display: block;
font-size: 22px;
color: #333;
line-height: 30px;
max-height: 64px;
&:hover {
color: #CC3300;
}
}
.content {
font-size: 14px;
color: #666;
}
.msg-app {
line-height: 34px;
color: #999;
font-size: 13px;
}
.author {
display: block;
float: left;
color: #333;
margin-right: 22px;
max-width: 180px;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
&:hover {
color: #CC3300;
}
}
.publish-time, .page-view {
color: #999;
}
.publish-time {
margin-right: 30px;
}
.tags, .like-comment {
position: absolute;
bottom: 24px;
font-size: 12px;
&.tags {
left: 386px;
max-width: 350px;
height: 20px;
overflow: hidden;
}
&.like-comment {
right: 0;
color: #999;
}
.like {
margin-right: 10px;
&:hover * {
color: #000;
}
}
.like-icon {
cursor: pointer;
&.liked {
color: #000;
}
}
}
.msg-tag {
display: inline-block;
text-align: center;
height: 20px;
line-height: 20px;
padding: 0 10px;
margin-right: 10px;
background-color: #ccc;
color: #fff;
&:last-child {
margin-right: 0;
}
&:hover {
background-color: #333;
}
}
}
.pager {
font-size: 12px;
a {
height: 24px;
padding: 0 9px;
line-height: 24px;
display: inline-block;
text-align: center;
margin-right: 8px;
color: #222;
&.cur {
background-color: #222;
color: #fff;
}
}
}
}
@import "home";
@import "detail";
@import "list";
... ...
.guang-editor-page,
.guang-list-page {
.tag-header {
height: 45px;
line-height: 45px;
color: #333;
font-size: 14px;
font-weight: bold;
border-bottom: 1px solid #ccc;
> span {
font-size: 20px;
}
}
.msg-pager {
float: right;
margin: 20px 0;
}
}
.guang-editor-page .right-side {
margin-top: 20px;
}
.guang-list-page .right-side {
margin-top: 11px;
}
.guang-editor-page .editor-info {
padding: 10px 10px;
background: #fafafa;
.author-avatar {
float: left;
width: 80px;
height: 100%;
img {
width: 80px;
height: 80px;
vertical-align: middle;
border-radius: 50%;
}
}
.author-info {
float: left;
margin: 0 0 0 10px;
max-width: 1060px;
}
.author-name {
margin-top: 11px;
font-size: 20px;
height: 30px !important;
line-height: 30px !important;
}
.author-introduce {
line-height: 24px;
font-size: 14px;
color: #999;
}
.intro-content {
margin: 15px 0 0 0;
line-height: 18px;
font-size: 14px;
color: #999;
}
}
\ No newline at end of file
... ...
... ... @@ -4,6 +4,8 @@
@import "common/index";
@import "plugin/index";
@import "common/dialog";
@import "pager";
@import "path-nav";
/* 模块 */
@import "channel/index";
... ... @@ -11,3 +13,4 @@
@import "passport/index";
@import "share";
@import 'home/index';
@import 'guang/index'
\ No newline at end of file
... ...
... ... @@ -23,7 +23,9 @@ shelljs.ls(path.join(__dirname, '/js/**/*.page.js')).forEach((f) => {
'yoho-handlebars',
'yoho-jquery',
'yoho-jquery-lazyload',
'yoho-slider'
'yoho-slider',
'yoho-jquery-pjax',
'yoho-jquery-dotdotdot'
];
});
... ...