sitemap-service.js 6.24 KB
const sm = require('sitemap');
const _ = require('lodash');

const sitemapConfig = require('./sitemap-config');
const sitemapStore = global.yoho.config.sitemap;

const ProductService = require('./product-service');
const ListService = require('./list-service');
const ShopService = require('./shop-service');
const GuangService = require('./guang-service');
const ChanpinService = require('./chanpin-service');
const HotService = require('./hot-service');

const logger = global.yoho.logger;

async function _createSiteMapIndex(host, opts) {
    const urls = [];

    opts.urls.forEach((url) => {
        if (!_.startsWith(url, 'https://')) {
            urls.push(host + url);
        }
    });

    opts.urls = urls;

    const xml = sm.buildSitemapIndex(opts);

    return xml;
}

function _createXml(host, urls, opts) {
    return new Promise((resolve, reject) => {
        sm.createSitemap({
            hostname: host,
            xmlNs: '',
            urls: _.map(urls, url => {
                return Object.assign({url}, opts)
            })
        }).toXML((err, xml) => {
            if (err) {
                return reject(err);
            }

            resolve(xml);
        });
    });
}

function _createXml2(host, urls) {
    return new Promise((resolve, reject) => {
        sm.createSitemap({
            hostname: host,
            xmlNs: '',
            urls
        }).toXML((err, xml) => {
            if (err) {
                return reject(err);
            }

            resolve(xml);
        });
    });
}

module.exports = class extends global.yoho.BaseModel {
    constructor(ctx) {
        super(ctx);

        this.host = sitemapStore.pc.host;
        this.props = sitemapStore.pc.props;
        this.type = sitemapStore.pc.type;

        this.listService = new ListService(ctx);
        this.shopService = new ShopService(ctx);
        this.productService = new ProductService(ctx);
        this.guangService = new GuangService(ctx);
        this.chanpinService = new ChanpinService(ctx);
        this.hotService = new HotService(ctx);

        this.config = sitemapConfig();
    }

    async indexXml() {
        const listIndex = await this.listService.getIndex(this.type);
        const productIndex = await this.productService.getIndex(this.type);
        const guangIndex = await this.guangService.getIndex(this.type);
        const shopIndex = await this.shopService.getIndex(this.type);
        const homeIndex = await this.getHomeIndex(this.type);
        const chanpinIndex = await this.chanpinService.getIndex(this.type);
        const hotIndex = await this.hotService.getIndex(this.type);

        this.config.index.urls = _.concat(this.config.index.urls, listIndex, productIndex, guangIndex, shopIndex, homeIndex, chanpinIndex, hotIndex);

        return _createSiteMapIndex(this.host, this.config.index);
    }

    async getHomeIndex(type) {
        return [`/sitemap_${type}/home_1.xml`];
    }

    async homeXml() {
        const home = this.config.www;

        const urls = Object.values(home).map(opts => {
            const opt = _.pick(opts, this.props);

            return opts.urls.map((url) => {
                return Object.assign({url}, opt);
            });
        });

        return _createXml2(this.host, _.flatten(urls));
    }

    async listXml(page) {
        logger.info(`list page ${page} start`);

        const listConfig = this.config.list;
        const opt = _.pick(this.config.list, this.props);

        let urls = await this.listService.getUrls(page);

        listConfig.urls = listConfig.urls.concat(urls);

        return _createXml(this.host, listConfig.urls, opt);
    }


    async shopXml() {
        const shopConfig = this.config.shop;
        const opt = _.pick(this.config.shop, this.props);
        let urls = await this.shopService.getUrls();

        shopConfig.urls = shopConfig.urls.concat(urls);

        return _createXml(this.host, shopConfig.urls, opt);
    }

    async productXml(page) {
        const productConfig = this.config.product;
        const opt = _.pick(this.config.product, this.props);
        let urls = await this.productService.getUrls(page);

        productConfig.urls = productConfig.urls.concat(urls);

        return _createXml(this.host, productConfig.urls, opt);
    }

    async guangXml(page) {
        let guangConfig = this.config.guang;
        let opt = _.pick(this.config.guang, this.props);
        let urls = await this.guangService.getUrls(page);

        if (_.has(guangConfig, 'mobileUrls') && this.type === 'h5') {
            urls = guangConfig.mobileUrls.concat(urls);
        } else {
            urls = guangConfig.urls.concat(urls);
        }

        return _createXml(this.host, urls, opt);
    }

    async chanpinXml(page) {
        let chanpinConfig = this.config.chanpin;
        let opt = _.pick(this.config.chanpin, this.props);
        let urls = await this.chanpinService.getUrls(page);

        chanpinConfig.urls = chanpinConfig.urls.concat(urls);

        return _createXml(this.host, chanpinConfig.urls, opt);
    }

    async hotXml(page) {
        let hotConfig = this.config.hot;
        let opt = _.pick(this.config.hot, this.props);
        let urls = await this.hotService.getUrls(page);

        hotConfig.urls = hotConfig.urls.concat(urls);

        return _createXml(this.host, hotConfig.urls, opt);
    }

    async indexJson() {
        const index = this.config.index;

        const listIndex = await this.listService.getIndex(this.type);

        const productIndex = await this.productService.getIndex(this.type);
        const guangIndex = await this.guangService.getIndex(this.type);
        const shopIndex = await this.shopService.getIndex(this.type);
        const homeIndex = await this.getHomeIndex(this.type);
        const chanpinIndex = await this.chanpinService.getIndex(this.type);
        const hotIndex = await this.hotService.getIndex(this.type);

        index.urls = _.concat(index.urls, listIndex, productIndex, guangIndex, shopIndex, homeIndex, chanpinIndex, hotIndex);

        return index.urls.map(url => this.host + url);
    }

    async productIndexXml() {
      const productIndex = await this.productService.getIndex(this.type);

      this.config.index.urls = _.concat(this.config.index.urls, productIndex)

      return _createSiteMapIndex(this.host, this.config.index);
    }
};