expandModel.js 5.28 KB
'use strict';

const _ = require('lodash');
const model = require('../../../lib/model');
const MysqlPromise = require('../../../lib/mysql-promise');
const Promise = require('bluebird');

const keywordsRedis = {
    'keywordsAllIds': `global:yoho:seo:keywords:allIds`,// 关键词表符合条件所有id
    'keywordsSortId': `global:yoho:seo:keywords:sortId`,// 分类下的所有关键词
    'keywordsId': `global:yoho:seo:keywords:id`,// 每条关键词关联其它12条关键词
    'keywordsIsRun': `global:yoho:seo:keywords:isRun`,// 判断是否正在执行中
};

class expandModel extends model {

    constructor(ctx) {
        super(ctx);

        this.mysql = new MysqlPromise();
        this.redis = ctx.redis;
    }

    getRanData() {
        return this.redis.setAsync(`${keywordsRedis.keywordsIsRun}`, 1).then(() => {// 设置正在运行的key
            return this.redis.expireAsync(`${keywordsRedis.keywordsIsRun}`, 10800);// 设置正在运行的key有效期
        }).then(() => {
            return this.sortIdInit();
        }).then(rdata => {
            return this.msortInit();
        }).then(() => {
            return this.allIdsExec(1);
        }).then(() => {
            return this.redis.delAsync(`${keywordsRedis.keywordsIsRun}`);
        }).then(() => {
            return true;
        });
    }

    //处理小分类function
    sortIdInit() {
        return this.mysql.query(`SELECT sort_id FROM seo_keywords WHERE status = 1 AND sort_id > 0 GROUP BY sort_id;`).then(rdata => {
            return Promise.each(rdata, (item) => this.sortIdExec(item.sort_id, 1));
        });
    }
    sortIdExec(sortId, page) {
        let pageSize = 1000;
        let pageStart = (page - 1) * pageSize;

        return this.sleep(5000).then(() => {
            return this.mysql.query(`SELECT id, keyword, root_id, brand_id, sort_id FROM seo_keywords WHERE status = 1 AND yoho_goods_num > 3 AND sort_id=${sortId} LIMIT ${pageStart}, ${pageSize};`);
        }).then(dsort => {
            if (dsort.length <= 0) {
                return false;
            }

            return this.execRandData(dsort).then(() => {
                return this.redis.setAsync(`${keywordsRedis.keywordsSortId}:${sortId}:page:${page}`, JSON.stringify(dsort));
            }).then(() => {
                dsort = [];
                return this.sortIdExec(sortId, ++page);
            });
        });
    }

    //处理小分类为0且大分类>=0的function
    msortInit() {
        return this.mysql.query(`SELECT msort FROM seo_keywords WHERE status = 1 AND sort_id = 0 GROUP BY msort;`).then(rdata => {
            return Promise.each(rdata, (item) => this.msortExec(item.msort, 1));
        });
    }
    msortExec(sortId, page) {
        let pageSize = 1000;
        let pageStart = (page - 1) * pageSize;
        return this.sleep(5000).then(() => {
            return this.mysql.query(`SELECT id, keyword, root_id, brand_id, sort_id FROM seo_keywords WHERE status = 1 AND sort_id = 0 AND yoho_goods_num > 3 AND msort=${sortId} LIMIT ${pageStart}, ${pageSize};`);
        }).then(dsort => {
            if (dsort.length <= 0) {
                return false;
            }

            /**
             * 1、小分类为0且大分类大于0,要随机关联12词
             * 2、小分类为0且大分类小于0,不要随机关联12个词。即大分类和小分类都为0的情况,data: [];
             */
            return this.execRandData(dsort).then(() => {
                dsort = [];
                return this.msortExec(sortId, ++page);
            });
        });
    }

    //随机关联12个关键词
    execRandData(dsort) {
        let len = dsort.length;
        let key;
        let tdata;

        if (len <= 0) {
            return Promise.resolve(false);
        }

        return Promise.each(dsort, (el, index) => {
            key = `${keywordsRedis.keywordsId}:${el.id}`;

            tdata = {
                name: el.keyword,
                data: _.compact(_.map(this.getRandom(dsort, index), (mval) => {
                    return dsort[mval];
                })) || []
            };

            console.log(`execRandData, index: ${index}, len: ${len}, id: ${el.id}, keywords: ${el.keyword}, key: ${key}`);
            return this.redis.setAsync(key, JSON.stringify(tdata));
        });
    }

    getRandom(dsort, index) {
        return _.shuffle(_.difference(_.keys(dsort), [`${index}`])).slice(0, 12);
    }

    //符合条件和关键词设置redis中
    allIdsExec(page) {
        let pageSize = 40000;
        let pageStart = (page - 1) * pageSize;

        return this.mysql.query(`SELECT id FROM seo_keywords WHERE status = 1 AND yoho_goods_num > 3 LIMIT ${pageStart}, ${pageSize};`).then(dsort => {
            if (dsort.length <= 0) {
                return false;
            }

            let ids = _.map(dsort, (sort) => {
                return sort.id;
            });

            return this.redis.setAsync(`${keywordsRedis.keywordsAllIds}:page:${page}`, JSON.stringify(ids)).then(() => {
                dsort = [];
                ids = [];
                return this.allIdsExec(++page);
            });
        });
    }

    sleep(time) {
        return new Promise((resolve, reject) => {
            setTimeout(() => {
                resolve();
            }, time);
        });
    }
}

module.exports = expandModel;