seo.js 4.85 KB
'use strict';

const api = global.yoho.API;
const rp = require('request-promise');
const serviceApi = global.yoho.ServiceAPI;
const Promise = require('bluebird');
const co = Promise.coroutine;
const _ = require('lodash');
const logger = global.yoho.logger;
const helper = global.yoho.helpers;
const moment = require('moment');
const config = require('../config/config');
const staticUrl = require('../config/staticUrls');
const fs = require('fs');
const schedule = require('node-schedule');

const siteUrls = {
    pcProduct: {
        site: 'https://item.yohobuy.com',
        url: []
    },
    pcGuang: {
        site: 'https://guang.yohobuy.com',
        url: []
    },
    mProduct: {
        site: 'https://m.yohobuy.com',
        url: []
    },
    mGuang: {
        site: 'https://guang.m.yohobuy.com',
        url: []
    }

};


/**
 * 获取最新1000条商品详情链接和逛详情链接
 */
const getUrls = () => {
    let apiArr = [api.get('', {method: 'web.product.bdPromotion'}),
        serviceApi.get('/guang/api/v2/article/getLastArticleList', {limit: 100})];

    return api.all(apiArr).spread((productData, articleData) => {

        _.forEach(_.get(productData, 'data', {}), value => {
            siteUrls.pcProduct.url.push('https:' + helper.urlFormat(`/p${value.erpProductId}.html`, null, 'item'));
            siteUrls.mProduct.url.push('https:' + helper.urlFormat(`/product/${value.id}.html`, null, 'm'));
        });

        _.forEach(_.get(articleData, 'data.artList', {}), value => {
            siteUrls.pcGuang.url.push('https:' + helper.urlFormat(`/${value.articleId}.html`, null, 'guang'));
            siteUrls.mGuang.url.push('https:' + helper.urlFormat(`/guang/info/${value.articleId}.html`
, null, 'guang.m'));
        });

        return siteUrls;
    });
};

/**
 * 将链接推送到百度站长
 * @param site string 站点
 * @param urls array
 */
const sendUrlsToBaidu = (site, urls, token) => {
    logger.info(`${site}${urls.length}`);

    let options = {
        url: `http://data.zz.baidu.com/urls?site=${site}&token=${token || config.baiduToken}`,
        headers: {
            'Content-Type': 'text/plain'
        },
        method: 'post',
        form: urls.join('\n'),
        json: true,
        timeout: 3000,
        gzip: true
    };

    return rp(options).then(result => {
        return Object.assign(result, {site: site});
    });
};

/**
 * 获取最新商品详情和逛详情推送到相应的站点域名
 */
const sendUrls = () => {

    return co(function*() {
        // 获取pc/wap的商品详情和逛的链接
        let sendArr = [],
            urls = yield getUrls();

        _.forEach(urls, value => {
            sendArr.push(sendUrlsToBaidu(value.site, value.url));
        });

        // 推送url
        api.all(sendArr).then(result => {
            logger.info(result);
        });
    })();
};


const getXmlUrl = (maps) => {
    let xmlUrl = '';

    _.forEach(_.get(maps, 'loc'), (url) => {
        if (url) {
            xmlUrl += `
            <url>
                <loc>${url}</loc>
                <lastmod>${maps.lastmod}</lastmod>
                <changefreq>${maps.changefreq}</changefreq>
                <priority>${maps.priority}</priority>
            </url>`;
        }
    });
    return xmlUrl;
};

const generateSitemapXml = (site, maps, sitemapPath) => {
    sitemapPath = sitemapPath || config.sitemapPath;

    let content = '<?xml version="1.0" encoding="utf-8"?><urlset><url></url></urlset>';
    let fileName = `${sitemapPath}/${site}_sitemap.xml`;
    let urls = '';

    if (maps.hasOwnProperty('loc')) {
        urls += getXmlUrl(maps);
    } else {
        _.forEach(maps, (val)=>{
            urls += getXmlUrl(val);
        });
    }
    if (urls.length === 0) {
        return;
    }

    content = content.replace('<url></url>', urls);
    fs.open(fileName, 'r+', ()=>{
        fs.writeFile(fileName, content, function(err) {
            if (err) {
                logger.error(err);
            } else {
                let now = moment().format('YMD H:mm:ss');

                logger.info(`${now} ${fileName} completed`);
            }
        });
    });

};

/**
 * sitemap
 */
const sitemap = () => {

    co(function*() {
        // 获取pc/wap的商品详情和逛的链接
        let urls = yield getUrls();

        staticUrl.item.loc = _.concat(staticUrl.item.loc, urls.pcProduct.url);
        staticUrl.guang.loc = _.concat(staticUrl.guang.loc, urls.pcGuang.url);
        staticUrl.m.item.loc = _.concat(staticUrl.m.item.loc, urls.mProduct.url);
        staticUrl['guang.m'].loc = _.concat(staticUrl['guang.m'].loc, urls.mGuang.url);

        _.forEach(staticUrl, (val, key) => {
            generateSitemapXml(key, val);
        });
    })();
};

const start = () => {
    schedule.scheduleJob('1 * * *', function() {
        sendUrls();
        sitemap();
    });
};

module.exports = {
    sendUrls,
    sitemap,
    start
};