resource-box.vue 6.04 KB
<template>
    <div class="resource-box">
        <slot></slot>
    </div>
</template>

<script>
import {REPORT_YAS} from 'store/yoho/types';
import _ from 'lodash';
import {mapState} from 'vuex';
import {throttle} from 'common/utils';

export default {
    name: 'ResourceBox',
    data() {
        return {
            componentStatus: {},
            waiting: [],
            pageNameMap: {
                'channel.home': 'FP_BLK_Home_h5',
                'channel.channelHome.channelMen': 'FP_BLK_MenHome_h5',
                'channel.channelHome.channelWomen': 'FP_BLK_WomenHome_h5',
            }
        };
    },
    computed: {
        ...mapState(['yoho'])
    },
    watch: {
        ['yoho.pageVisible'](visible) {
            if (visible === 'true' || visible === true) {
                this.checkReport(void 0, true);
            }
        },
        ['yoho.visible'](visible) {
            if (visible && this.$yoho && this.$yoho.isiOS) {
                this.checkReport(void 0, true);
            }
        }
    },
    mounted() {
        this.scrollEvent = throttle(50, this.checkReport);
        if (_.get(this.$parent, '$options.name') === 'Scroller') {
            this.$scrollEl = this.$parent.$el;
        } else {
            this.$scrollEl = document.querySelector('.layout-content');
        }
        if (this.$scrollEl) {
            this.$scrollEl.addEventListener('scroll', this.scrollEvent);
            this.checkReport(void 0, true);
        }

        // 每隔三秒钟上报一次数据
        setInterval(() => {
            if (this.waiting.length) {
                this.report(this.waiting);
                this.waiting = [];
            }
        }, 3000);
    },
    destroyed() {
        if (this.$scrollEl) {
            this.$scrollEl.removeEventListener('scroll', this.scrollEvent);
        }
    },
    methods: {
        report(param) {
            _.each(param, item => {
                if (this.pageNameMap[item.P_NAME]) {
                    item.P_NAME = this.pageNameMap[item.P_NAME];
                }
            });

            this.$store.dispatch(REPORT_YAS, {
                params: {
                    appop: 'YB_SHOW_EVENT',
                    param
                }
            });
        },
        checkReport(evt, isInit) {
            _.each(this.$children, (component, index) => {
                const visible = this.isVisible(component.$el, this.$scrollEl);

                if (visible && (this.componentStatus[index] !== visible || isInit)) {
                    this.record(component, index + 1, isInit);
                }
                this.componentStatus[index] = visible;
            });
        },
        record(component, index, isInit) {
            const reportData = _.get(component, '$options.propsData.value');

            // 区分不通组件记录以楼层内item为单位、而不是以整个楼层为单位组织数据上报
            let param;
            if (reportData) {
                switch (reportData.template_name) {
                    case 'twoPicture':
                        param = [];
                        _.each(reportData.data.list, item => {
                            param.push({
                                P_NAME: this.$route.name,
                                F_NAME: reportData.template_name,
                                F_ID: reportData.template_id,
                                F_INDEX: index,
                                ACTION_URL: item.url
                            });
                        });
                        break;

                    case 'focus':
                        // 由于focus自动轮播的特殊性、上报数据由focus直接调用父组件方法
                        // 修改waiting数组所以这里不做数据监测
                        break;

                    case 'tfGoodsList':
                        // 楼层内存在多个item, 交给子组件各自检测
                        let visible = component.checkReqFromParent(isInit);
                        if (visible.length) {
                            param = [];
                            _.each(visible, item => {
                                param.push(Object.assign(item, {
                                    P_NAME: this.$route.name,
                                    F_NAME: reportData.template_name,
                                    F_ID: reportData.template_id,
                                    F_INDEX: index,
                                }));
                            });
                        }
                        break;

                    case 'newSingleImage':
                        param = {
                            P_NAME: this.$route.name,
                            F_NAME: reportData.template_name,
                            F_ID: reportData.template_id,
                            F_INDEX: index,
                            ACTION_URL: reportData.data.list[0].url
                        };
                        break;
                    default:
                        break;
                }

                if (param) {
                    _.isArray(param) ? (this.waiting = this.waiting.concat(param)) : this.waiting.push(param);
                }
            }
        },
        isVisible($el, $parent) {
            const rect = $el.getBoundingClientRect();
            const parentRect = $parent.getBoundingClientRect();

            return ((parentRect.top >= rect.top && parentRect.top <= (rect.top + rect.height)) ||
            ((parentRect.top + parentRect.height) >= rect.top && (parentRect.top + parentRect.height) <= (rect.top + rect.height)) ||
            (rect.top >= parentRect.top && (rect.top + rect.height) <= (parentRect.top + parentRect.height)));
        },
        checkReqFromChild(index) {
            // 重置子组件显示状态方可重新记录
            this.componentStatus[index] = false;
            this.checkReport();
        },
        focusComponentDataRecord(index, param) {
            if (this.componentStatus[index]) {
                this.waiting.push(param);
            }
        }
    }
};
</script>