shop.vue 12.7 KB
<template>
    <div class="stat-shop">
        <layout-body>
            <Card class="shop-card">
                <p slot="title">店铺看板</p>
                <layout-filter class="box-filter" :inline="true" :col="1">
                    <filter-item label="时间">
                        <Date-picker
                            type="daterange"
                            v-model="dateRange"
                            format="yyyy-MM-dd"
                            placeholder="选择开始结束日期"></Date-picker>
                        <div class="quick">
                            <a href="javascript:;" @click="() => {changeLimit(7)}">近7天</a>
                            <a href="javascript:;" @click="() => {changeLimit(30)}">近30天</a>
                        </div>
                        <Poptip trigger="hover" placement="bottom-end">
                            <div slot="content">
                                * 仅支持导出历史数据,时间跨度不得超过30天
                            </div>
                            <Button type="primary" @click="exportFile">导出</Button>
                            <p style="display: inline-block;font-size: 10px;color: #c90;">* 当日数据不支持导出</p>
                        </Poptip>
                    </filter-item>
                </layout-filter>
                <Row style="marginTop: 20px; marginBottom: 30px;">
                    <Col span="6">
                        <div class="box-item bg-red" >
                            <Icon type="person"></Icon>
                            <span class="box-item-label">{{filters.targetColumns[0].title}}</span>
                            <span class="box-item-value">{{this.overviewData.uv}}</span>
                        </div>
                        <div class="box-item bg-yellow">
                            <Icon type="eye"></Icon>
                            <span class="box-item-label">{{filters.targetColumns[1].title}}</span>
                            <span class="box-item-value">{{this.overviewData.pv}}</span>
                        </div>
                    </Col>
                    <Col span="6">
                        <div class="box-item bg-aqua">
                            <Icon type="android-cart"></Icon>
                            <span class="box-item-label">{{filters.targetColumns[2].title}}</span>
                            <span class="box-item-value">{{this.overviewData.orderCount}}</span>
                        </div>
                        <div class="box-item bg-blue">
                            <Icon type="social-yen"></Icon>
                            <span class="box-item-label">{{filters.targetColumns[3].title}}</span>
                            <span class="box-item-value">{{this.overviewData.orderAmount}}</span>
                        </div>
                    </Col>
                    <Col span="6">
                        <div class="box-item bg-light-blue">
                            <Icon type="clipboard"></Icon>
                            <span class="box-item-label">{{filters.targetColumns[4].title}}</span>
                            <span class="box-item-value">{{this.overviewData.shipmentOrderCount}}</span>
                        </div>
                        <div class="box-item bg-green">
                            <Icon type="social-yen"></Icon>
                            <span class="box-item-label">{{filters.targetColumns[5].title}}</span>
                            <span class="box-item-value">{{this.overviewData.shipmentOrderAmount}}</span>
                        </div>
                    </Col>
                    <Col  span="6">
                    <div class="box-item bg-purple">
                        <Icon type="loop"></Icon>
                        <span class="box-item-label">{{filters.targetColumns[6].title}}</span>
                        <span class="box-item-value">{{this.overviewData.uvOrderRate}}</span>
                    </div>
                    </Col>
                </Row>
            </Card>
            <Card class="shop-card">
                <p slot="title">最近30天运营趋势</p>
                <div class="tabs-col">
                    <Tabs size="small" v-model="curTarget">
                        <Tab-pane v-for="item in targetList" :label="item.label" :key="item.name" :name="item.name">
                            <EChart v-if="item.chatOpt.series" :className="item.name" :echartParams="item.chatOpt"></EChart>
                            <Spin fix size="large" v-else></Spin>
                        </Tab-pane>
                    </Tabs>
                </div>
            </Card>
        </layout-body>
    </div>
</template>

<script>
    import _ from 'lodash';
    import moment from 'moment';
    import goodStore from './store';
    import GoodService from 'services/statistics/shop-service';

    export default {
        data() {
            return goodStore.call(this);
        },
        created() {
            this.goodService = new GoodService();
        },
        watch: {
            date() {
                this.loadData();
            },
            day(newDay) {
                let curDay = moment().format('YYYY-MM-DD');

                if (newDay === this.beginDate || !newDay) {

                    return;
                }

                this.dateRange = newDay !== this.curDay ? [newDay, curDay] : [newDay, newDay];

            },
            dateRange(newDate) {
                this.beginDate = moment(newDate[0]).format('YYYY-MM-DD');
                this.endDate = moment(newDate[1]).format('YYYY-MM-DD');
                this.day = this.beginDate === this.endDate === this.today ? '' : this.beginDate;
                this.curTarget = 'uv';
                this.getDataFlag = true;

                this.getOverviewData();

                _.each(this.targetList, tar => {
                    tar.chatOpt = {};
                });
                this.getOverviewTrend();
            },
            curTarget(value) {

                this.curTarget = value;

                this.getOverviewTrend(this.curTarget);

                return value;
            }
        },
        mounted() {
            this.loadData();
        },
        methods: {
            loadData() {
                this.getOverviewData();
                this.getOverviewTrend();
            },
            changeLimit(limit) {
                this.dateRange = [this[`day${limit}`], this.today];

                if (this.endDate !== this.today) {
                    _.each(this.targetList, tar => {
                        tar.chatOpt = {};
                    });
                    this.getOverviewTrend();
                }
            },
            getOverviewTrend() {
                let target = _.find(this.targetList,
                    tar => tar.name === this.curTarget);

                if (target.chatOpt.series) {
                    return;
                }

                this.goodService.getOverviewTrend({
                    type: this.curTarget,
                    begin: moment(this.endDate).subtract(30, 'days').format('YYYY-MM-DD'),
                    end: this.endDate,
                    platform: '1,2'
                }).then(ret => {

                    let data = ret.data;

                    this.overviewChartData.xAxis = _.map(data, 'date');
                    this.overviewChartData.uv = _.map(data, 'uv');
                    this.overviewChartData.pv = _.map(data, 'pv');
                    this.overviewChartData.orderCount = _.map(data, 'orderCount');
                    this.overviewChartData.orderAmount = _.map(data, 'orderAmount');
                    this.overviewChartData.paymentOrderCount = _.map(data, 'paymentOrderCount');
                    this.overviewChartData.paymentOrderAmount = _.map(data, 'paymentOrderAmount');

                    target.chatOpt = {
                        title: '',
                        color: '#000',
                        legend: [target.label],
                        xAxis: this.overviewChartData.xAxis,
                        yAxis: [''],
                        min: _.min(this.overviewChartData[this.curTarget]),
                        series: [
                            {name: [target.label], data: this.overviewChartData[this.curTarget]}
                        ]
                    };
                });
            },
            getOverviewData() {
                this.goodService.getData({
                    begin: this.beginDate,
                    end: this.endDate,
                    platform: '1,2'
                }).then(ret => {

                    if (!ret.data) {
                        this.overviewData.uv = 1;
                        this.overviewData.pv = 1;
                        this.overviewData.orderCount = 0;
                        this.overviewData.orderAmount = 0;
                        this.overviewData.shipmentOrderCount = 0;
                        this.overviewData.shipmentOrderAmount = 0;
                        this.overviewData.uvOrderRate = 0;
                        return;
                    }

                    this.overviewData = ret.data;

                    this.overviewData.uv = _.get(ret.data, 'uv') ? ret.data.uv : '——';
                    this.overviewData.pv = _.get(ret.data, 'pv') ? ret.data.pv : '——';
                    this.overviewData.orderCount = _.get(ret.data, 'orderCount') ? ret.data.orderCount : '——';
                    this.overviewData.orderAmount = _.get(ret.data, 'orderAmount') ? ret.data.orderAmount : '——';
                    this.overviewData.shipmentOrderCount = _.get(ret.data, 'paymentOrderCount') ? ret.data.paymentOrderCount : '——';
                    this.overviewData.shipmentOrderAmount = _.get(ret.data, 'paymentOrderAmount') ? ret.data.paymentOrderAmount : '——';
                    this.overviewData.uvOrderRate = ((_.get(ret.data, 'uvOrderRate') && (ret.data.uvOrderRate <= 1) ?
                        (ret.data.uvOrderRate * 100) : ret.data.uvOrderRate)).toFixed(2) + '%';

                    if (this.beginDate !== this.endDate) {
                        let formatData = _.slice(ret.data, 0, ret.data.length - 1);

                        this.overviewChartData.uv = _.get(ret, 'uv');
                        this.overviewChartData.pv = _.get(ret, 'pv');
                        this.overviewChartData.orderCount = _.get(ret, 'orderCount');
                        this.overviewChartData.orderAmount = _.get(ret, 'orderAmount');
                        this.overviewChartData.paymentOrderCount = _.get(ret, 'paymentOrderCount');
                        this.overviewChartData.paymentOrderAmount = _.get(ret, 'paymentOrderAmount');
                        this.overviewChartData.xAxis = _.map(formatData, 'date');
                    }
                });
            },
            exportFile() {
                let param = {};

                param.begin = this.beginDate;
                param.end = this.endDate;
                param.platform = '1,2';

                const href = '/Api/platform/exportOneShopOverview?queryConf=' +
                    JSON.stringify(param);

                window.open(href, '_blank');
            },
        }
};
</script>

<style lang="scss">
.stat-shop {
    .ivu-tabs-tabpane {
        height: 400px;
        position: relative;
    }
}

.layout-container {
    min-height: 200px;
    margin: 15px;
    overflow: hidden;
    background: #fff;
    border-radius: 4px;

    .layout-filter .line {
        border-top: none;
        margin-bottom: 0;
    }
}

.shop-card {
    margin-top: 10px;
    margin-bottom: 10px;
}

.box-title {
    font-weight: 700;
    color: #495060;
    font-size: 16px;
    line-height: 22px;
    margin: 5px;

    &:before {
        content: " ";
        display: inline-block;
        width: 5px;
        margin-right: 2px;
        height: 22px;
        vertical-align: top;
        background-color: #999;
    }
}

.box-item {
    width: 90%;
    height: 50px;
    padding: 0 0 0 15px;
    line-height: 50px;
    font-size: 14px;
    overflow: hidden;
    border-radius: 5px;
    color: #fff;
    margin-bottom: 10px;

    .box-item-label {
        display: inline-block;
        min-width: 75px;
        vertical-align: top;
        font-weight: normal;
    }

    .box-item-value {
        font-size: 20px;
        font-weight: 600;
    }

    i {
        display: inline-block;
        width: 20px;
        height: 20px;
        font-size: 22px;
        text-align: center;
        margin-top: -7px;
        vertical-align: middle;
        margin-right: 3px;
    }
}

.box-filter {
    .ivu-date-picker {
        margin-left: 0;
        width: 220px !important;
    }

    .quick {
        display: inline-block;
        margin-left: 20px;
        margin-right: 50px;

        a {
            margin-right: 5px;
        }
    }
}
</style>