Authored by 毕凯

Merge branch 'feature/newsKeywords' into 'gray'

Feature/news keywords



See merge request !1092
... ... @@ -7,6 +7,7 @@
const serviceAPI = global.yoho.ServiceAPI;
const _ = require('lodash');
const helpers = global.yoho.helpers;
const redis = require('../../../utils/redis');
const URI_PACKAGE_ARTICLE = 'guang/service/v2/article/';
const URI_PACKAGE_AUTHOR = 'guang/service/v1/author/';
... ... @@ -204,6 +205,21 @@ class DetailModel extends global.yoho.BaseModel {
});
}
// 获取逛文章分词内容
_getGuangArticleKeyword(id) {
return redis.all([
['get', `global:yoho:guang:detail:${id}`]
]).then(redisData => {
redisData = JSON.parse(redisData[0] || '{}');
if (!redisData.data) {
return this._getArticleContent(id);
}
return redisData;
});
}
/**
* [逛资讯详情页数据封装]
* @param {[int]} id [内容ID]
... ... @@ -229,7 +245,7 @@ class DetailModel extends global.yoho.BaseModel {
let article = result.getArticle = data && data.data || {};
let promises = [
this._getAuthor(article.author_id),
this._getArticleContent(id),
this._getGuangArticleKeyword(id),
this._getBrand(id)
];
... ...
... ... @@ -7,6 +7,9 @@
{{type}}
</li>
{{/ navs}}
<li class="guang-nav-item news-jump" data-type=-1>
<a href='//m.yohobuy.com/guang/news' title='资讯'>资讯</a>
</li>
</ul>
<div id="info-list" class="info-list-container">
... ...
... ... @@ -19,9 +19,9 @@ exports.index = (req, res, next) => {
}
return res.render('news-index', Object.assign({
title: '新闻 | ' + (res.locals.title || ''),
title: '资讯 | ' + (res.locals.title || ''),
pageHeader: headerModel.setNav({
navTitle: '新闻'
navTitle: '资讯'
}),
module: 'news',
localCss: true,
... ... @@ -51,7 +51,7 @@ exports.detail = (req, res, next) => {
req.ctx(newsService).detail(channel, query).then(result => {
return res.render('news-detail', Object.assign({
pageHeader: headerModel.setNav({
navTitle: result.header && result.header.title || '新闻详情页'
navTitle: result.header && result.header.title || '资讯详情页'
}),
module: 'news',
localCss: true,
... ...
... ... @@ -2,8 +2,10 @@
const _ = require('lodash');
const helpers = global.yoho.helpers;
const utils = '../../../utils';
const redis = require(`${utils}/redis`);
const NewsAPi = require('./news-api');
const utils = require('./utils');
const newsUtils = require('./utils');
const moment = require('moment');
const ATYPE = 'yohobuy4008899646,yohogroup,YOHO_GIRL,mars-app';
... ... @@ -24,7 +26,7 @@ module.exports = class extends global.yoho.BaseModel {
lresult = {
id: articleData.id,
url: helpers.urlFormat(`/news/${articleData.id}_${articleData.cid}.html`),
url: helpers.urlFormat(`/guang/news/${articleData.id}_${articleData.cid}.html`),
img: helpers.image(articleData.image, width, height, 1),
title: articleData.title,
publishTime: articleData.update_time && moment(articleData.update_time * 1000).format('MM月DD HH:mm'),
... ... @@ -80,15 +82,21 @@ module.exports = class extends global.yoho.BaseModel {
title: contents.title,
summary: contents.summary,
tag: contents.tag,
syncTypeName: contents.syncTypeName || 'YOHO潮流志',
publishTime: contents.update_time && moment(contents.update_time * 1000).format('MM月DD HH:mm'),
};
let content = utils.filterPhtml(contents.content, [
'阅读原文',
'点击这里',
'点这里'
]);
return {header: header, content: utils.filterAhtml(content)};
let content = newsUtils.filterPhtml(
contents.content.replace(/www.yohobuy.com\/chanpin\//ig, 'm.yohobuy.com/chanpin/'),
[
'阅读原文',
'点击这里',
'点这里'
]
);
content = newsUtils.filterAhtml(content);
return {header: header, content: newsUtils.imgAlt(content, contents.title, 5)};
}
detail(channel, param) {
... ... @@ -96,16 +104,25 @@ module.exports = class extends global.yoho.BaseModel {
id: param.id,
cid: param.cid
};
let newsAPi = new NewsAPi(this.ctx);
return newsAPi.getContentDetail(params).then(result => {
return redis.all([
['get', `global:yoho:news:detail:${params.id}-${params.cid}`]
]).then(redisData => {
redisData = JSON.parse(redisData[0] || '{}');
if (!redisData.data) {
return new NewsAPi(this.ctx).getContentDetail(params);
}
return redisData;
}).then(result => {
let responseData = {};
// 详情页数据
Object.assign(responseData, this._formatDetail(result, params));
// seo
let title = _.get(responseData, 'header.title', '新闻详情页');
let title = _.get(responseData, 'header.title', '资讯详情页');
let keywords = [];
let tags = _.compact(_.get(responseData, 'header.tag', []).map(el => {
return el.tag_name;
... ...
... ... @@ -23,7 +23,10 @@ const util = {
});
return $.html();
html = $.html();
$ = '';
return html;
},
// 过滤 a标签连接和删除html标签中的script和link脚本
... ... @@ -34,9 +37,33 @@ const util = {
let $ = cheerio.load(html, {decodeEntities: false});
$('a').attr('href', 'javascript:void(0);').css({cursor: 'text'});// eslint-disable-line
$('a').removeAttr('style').not('.a-anchor').attr('href', 'javascript:void(0);').css({cursor: 'text'});// eslint-disable-line
$('script,link').remove();
return $.html();
html = $.html();
$ = '';
return html;
},
// 过滤 a标签连接和删除html标签中的script和link脚本
imgAlt: (html, alt, num) => {
if (!html) {
return html;
}
let $ = cheerio.load(html, {decodeEntities: false});
_.each($('img').slice(0, num), item => {
let $dom = $(item);
$dom.attr('alt', $dom.attr('alt') || alt);
});
html = $.html();
$ = '';
return html;
}
};
... ...
... ... @@ -2,7 +2,7 @@
<div class="detail" data-id="{{id}}">
{{# header}}
<div class="post-title">
<p class="title">{{title}}</p>
<h1 class="title">{{title}}</h1>
{{> news-index/tvls}}
</div>
{{/header}}
... ...
<div class="time-view-like-share clearfix">
<i class="iconfont">&#xe603;</i>
{{publishTime}}&nbsp;&nbsp;&nbsp;&nbsp;
{{#if pageView}}
<i class="iconfont">&#xe602;</i>
<span class="page-view">{{pageView}}</span>
{{#if syncTypeName}}
<span class="page-view">来源于微信公众号:{{syncTypeName}}</span>
{{/if}}
<div class="like-share-container">
<i class="iconfont">&#xe603;</i>
{{publishTime}}&nbsp;&nbsp;&nbsp;&nbsp;
{{#if pageView}}
<i class="iconfont">&#xe602;</i>
<span class="page-view">{{pageView}}</span>
{{/if}}
{{#like}}
<i class="iconfont like-btn{{#isLiked}} like{{/isLiked}}">&#xe601;</i>
<span class="like-count">{{count}}</span>
... ...
... ... @@ -15,8 +15,8 @@ module.exports = app => {
// 业务模块
app.use('/product', require('./apps/product'));
app.use('/guang/news', require('./apps/news'));// seo-潮流资讯页
app.use('/guang', require('./apps/guang'));
app.use('/news', require('./apps/news'));
app.use('/activity', require('./apps/activity'));
app.use('/cart', require('./apps/cart'));
... ...
... ... @@ -63,6 +63,10 @@ $nav.bind('contextmenu', function() {
});
$nav.on('touchend touchcancel', function(e) {
if ($(e.target).closest('.news-jump').length > 0) {
return true;
}
let $this = $(e.target).closest('.guang-nav-item'),
$content,
index;
... ...
... ... @@ -62,7 +62,7 @@ export class IndexView extends View {
this.indexModel.loadMoreAjax({
type: 'GET',
url: '/news/index/page',
url: '/guang/news/index/page',
dataType: 'html',
data: that.navState[index]
}).then(rdata => {
... ...
... ... @@ -873,6 +873,11 @@ $focus-size: 42px;
overflow: visible;
}
}
.a-anchor {
color: #93b4c5;
text-decoration: underline;
}
}
.guang-detail-page.menu-open {
... ...
... ... @@ -75,6 +75,10 @@
&.focus {
color: #000;
}
&.news-jump a {
color: inherit;
}
}
.bytouch {
... ...
... ... @@ -87,6 +87,9 @@ $focus-size: 42px;
img {
height: auto;
width: auto;
max-width: 100%;
color: #fff;
}
}
... ... @@ -877,6 +880,11 @@ $focus-size: 42px;
overflow: visible;
}
}
.a-anchor {
color: #93b4c5;
text-decoration: underline;
}
}
.news-detail-page.menu-open {
... ...
... ... @@ -246,7 +246,7 @@ const processArticleDetail = (articleContent, isApp, gender, isWeixin, isqq, isW
newText = value.text.data.text;
}
finalDetail.push({
text: newText
text: newText.replace(/www.yohobuy.com\/chanpin\//ig, 'm.yohobuy.com/chanpin/')
});
}
... ...