index.js 4.55 KB
const cheerio = require('cheerio');
const superAgent = require('superagent');
const NO_MAGAZINE_ID = '无效的电子刊编号'; // 没有杂志id
const READ_MAGAZINE_URL_ERROR = '电子刊内容读取失败,请重试'; // superagent抓取页面内容失败
const NO_HYPE_CONTAINER_ID = '电子刊格式错误!'; // 找不到hype_container的id
const NO_HYPE_SCRIPT = '无效的电子刊内容!'; // 找不到hype_script
const WRONG_INVIROMENT = '电子刊获取失败!'; // 不在有货app也不在小程序中打开的时候提示
const ERROR_MSG = {
    4001: '您未购买该电子刊',
    4002: '未获取到电子刊信息',
    4003: '该电子刊已被删除',
    4004: '阅读码未兑换'
};

const headerModel = require('../../../doraemon/models/header');
const indexModel = require('../models/index');

/**
 * 获取到杂志的url之后使用superAgent读取html内容并进行处理后输出
 * @param req
 * @param res
 * @param next
 */
const index = async function(req, res, next) {
    let {e_id, token = ''} = req.query;
    let isApp = req.yoho.isApp;
    let userAgent = req.get('User-Agent');

    let isYohobuy = /yohobuy/i.test(userAgent);
    let isMiniprogram = /miniprogram/i.test(userAgent);

    /**
     * 用于渲染错误结果页面
     * @param result
     * @returns {*}
     */
    function renderErroPage(result) {
        return res.render('index/error', {
            pageHeader: headerModel.setNav({
                navTitle: false,
                navBtn: false
            }),
            module: 'magazine',
            page: 'error',
            title: '错误提示',
            localCss: true,
            result: result
        });
    }



    // 如果不在小程序或app中打开则返回
    if (!isApp || (!isYohobuy && !isMiniprogram)) {
        return renderErroPage({msg: WRONG_INVIROMENT});
    }

    // 没有杂志id,返回
    if (!e_id) {
        return renderErroPage({msg: NO_MAGAZINE_ID});
    }

    // 查看session中是否有登录信息


    if (!req.user.uid || !req.user.uid.toString() || !req.user.uid.sessionKey) {
        return res.redirect(`//m.yohobuy.com/magazine/${e_id}.html`);
    }

    // 通过接口获取到杂志对应的实际的url,并进行处理
    let magazineInfo = await req.ctx(indexModel).getMagazineInfo(req.user.uid, e_id, token).catch(next);

    // console.log(req.user, magazineInfo);

    if (magazineInfo && magazineInfo.code === 200 && magazineInfo.data) {
        let code = magazineInfo.data.code;

        // 4000:获取成功 4001: 未购买该电子刊 4002:未获取到电子刊 4003:电子刊已删除

        if (code === 4000) {
            let url = magazineInfo.data.link;

            if (!url) {
                return renderErroPage({msg: '杂志地址获取失败'});
            }

            let resourceUrl = url.substring(0, url.lastIndexOf('/') + 1);

            superAgent.get(url).end(function(err, response) {
                if (err) {
                    return renderErroPage({msg: READ_MAGAZINE_URL_ERROR});
                }

                let $ = cheerio.load(response.text);
                let idMatch = response.text.match(/id="(.*)_hype_container"/);

                // HYPE生成的html有其固定格式的div id,此处获取的也是这个hype创建时的名称,此名称对应插入的js
                if (idMatch && idMatch.length >= 2) {
                    let name = idMatch[1];
                    let id = `${name}_hype_container`;
                    let script = $(`#${id}`).html();

                    let scriptSrc = script.match(/src="(.*)"/);

                    // 获取到对应div里面的script的src,并替换成带有域名的地址,可以让所有图片地址指向js对应的域名
                    if (scriptSrc && scriptSrc.length >= 2) {
                        let src = scriptSrc[1];
                        let newScript = '<script type="text/javascript" charset="utf-8" src="' +
                            resourceUrl + src + '">';

                        $(`#${id}`).html(newScript);

                        return res.send($.html()); // 输出修改过的html
                    } else {
                        return renderErroPage({msg: NO_HYPE_SCRIPT});
                    }
                } else {
                    return renderErroPage({msg: NO_HYPE_CONTAINER_ID});
                }
            });
        } else {
            return renderErroPage({msg: ERROR_MSG[code] || '购买信息校验失败'});
        }
    } else {
        return res.redirect(`//m.yohobuy.com/magazine/${e_id}.html`);
    }
};

module.exports = {
    index
};