Authored by 陈峰

店铺统计样式调整

... ... @@ -4,6 +4,7 @@ import yohoPluginCore from './plugins/yoho-plugin-core';
import yohoPluginRouter from './plugins/yoho-plugin-router';
import yohoPluginAuth from './plugins/yoho-plugin-auth';
import yohoPluginCache from './plugins/yoho-plugin-cache';
import './statics/scss/base.scss';
import './filters';
import './directives';
... ...
<template>
<Date-picker
type="daterange"
:value="dateRange"
format="yyyy-MM-dd"
placeholder="选择开始结束日期"
:options="timeOptions"
@on-change="datePickChange"></Date-picker>
</template>
<script>
import moment from 'moment';
export default {
name: 'dateSlot',
props: ['value', 'timeOpt', 'timeLimit'],
methods: {
datePickChange(val) {
if (!this.timeLimit) {
let mean = new Date(val[1]).getTime() - new Date(val[0]).getTime();
this.dateRange = val;
if (Math.floor(mean / (24 * 3600 * 1000)) > 30) {
this.error();
return;
}
} else {
this.dateRange = val;
}
},
error() {
this.$Message.error('开始日期与结束日期的跨度为一个月');
}
},
data() {
return {
dateRange: this.value,
timeOptions: this.timeOpt ? this.timeOpt : {
disabledDate(date) {
return moment(date).isAfter(new Date(), 'day');
}
}
};
},
watch: {
value() {
this.dateRange = this.value;
},
dateRange(newValue) {
this.$emit('input', newValue);
}
}
};
</script>
<style lang="scss">
.ivu-date-picker {
width: 200px;
margin-left: 15px;
display: inline-block;
}
</style>
import DateSlot from './date-slot';
export {
DateSlot
};
... ... @@ -65,7 +65,6 @@
initChart() {
let yAxis = [], series = [], opt = {};
let data = [];
let self = this;
if (!this.myEchart && document.querySelector(`.${this.className}`)) {
this.myEchart = ECharts.init(document.querySelector(`.${this.className}`), 'macarons');
... ... @@ -170,43 +169,6 @@
}
};
// 类目店铺贡献top10
if (this.echartParams.shops) {
opt.xAxis[0].axisLabel = {
interval: 0
};
opt.tooltip = _.assign({
backgroundColor: 'rgba(255, 152, 0, 0.7)',
borderColor: '#ff9800',
borderWidth: 2,
formatter(params) {
let label = '';
_.each(self.echartParams.shops[params[0].dataIndex], item => {
label += `<br>${item.shopName}, 订单数(${item.orderCount}), 订单金额(${item.orderAmount})`;
});
return `<h4>${params[0].name}</h4>收订金额:${params[0].value}${label}`;
}
}, opt.tooltip);
}
// 全网分析
if (this.bigFlag) {
opt.dataZoom = [
{
type: 'slider',
show: true,
handleSize: 8
},
{
type: 'inside',
start: 94,
end: 100
}
];
}
this.myEchart.setOption(opt, true);
window.addEventListener('resize', () => {
... ...
... ... @@ -94,7 +94,7 @@ body {
right: 0;
bottom: 0;
display: flex;
min-width: 800px;
min-width: 1200px;
.print-hide {
display: none;
... ...
<template>
<Radio-group type="button" v-model="day" class="radio-clear">
<Radio :label="day.day" v-for="day in dayList" :key="day.name">{{day.name}}</Radio>
</Radio-group>
</template>
<script>
import moment from 'moment';
export default {
name: 'RadioDay',
props: ['value'],
data() {
return {
day: this.value,
dayList: [{
name: '近7天',
day: moment().add(-6, 'days').format('YYYY-MM-DD')
}, {
name: '近30天',
day: moment().add(-29, 'days').format('YYYY-MM-DD')
}]
};
},
created() {
},
watch: {
day(newValue) {
this.$emit('input', newValue);
},
value() {
this.day = this.value;
}
}
};
</script>
<style lang="scss">
.radio-clear {
&.ivu-radio-group-button {
.ivu-radio-wrapper {
border-color: transparent;
color: #2d8cf0;
text-decoration: underline;
&:hover {
text-decoration: none;
}
&:first-child {
border-left-color: transparent;
}
}
.ivu-radio-wrapper-checked {
box-shadow: none;
&:hover {
box-shadow: none;
}
}
}
}
</style>
<template>
<div class="layout-grey">
<div class="stat-shop">
<layout-body>
<div class="box">
<div class="box-title" style="marginTop: 20px;">
店铺看板
</div>
<layout-filter class="box-filter">
<Card class="shop-card">
<p slot="title">店铺看板</p>
<layout-filter class="box-filter" :inline="true" :col="1">
<filter-item label="时间">
<date-slot v-model="dateRange">
</date-slot>
</filter-item>
<filter-item label="快速查询">
<radio-day v-model="day" class="radio-day"></radio-day>
</filter-item>
<filter-item>
<Button type="primary" @click="exportFile">导出</Button>
<span class="notice">*仅支持导出历史数据,时间跨度不得超过30天</span>
<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>
</Poptip>
</filter-item>
</layout-filter>
<Row style="marginTop: 20px; marginBottom: 30px;">
<Col span="6">
<div class="box-item green" >
<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 green-light">
<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 blue">
<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 blue-light">
<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 purple">
<div class="box-item bg-light-blue">
<span class="box-item-label" style="marginLeft: 20px;">{{filters.targetColumns[4].title}}</span>
<span class="box-item-value">{{this.overviewData.shipmentOrderCount}}</span>
</div>
<div class="box-item purple-light">
<div class="box-item bg-green">
<span class="box-item-label" style="marginLeft: 20px;">{{filters.targetColumns[5].title}}</span>
<span class="box-item-value">{{this.overviewData.shipmentOrderAmount}}</span>
</div>
</Col>
<Col span="6">
<div class="box-item black">
<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>
</div>
<div class="box" style="marginTop: 50px;">
<div class="box-title" style="marginTop: 20px;">
最近30天运营趋势
</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>
<layout-tab>
<div class="tabs-col">
<Tabs :animated="false" size="small" v-model="curTarget">
<Tab-pane v-for="item in targetList" :label="item.label" :key="item.name" :name="item.name">
</Tab-pane>
<EChart :className="[overviewName]" :echartParams="overviewParams"></EChart>
</Tabs>
</div>
</layout-tab>
</div>
</Card>
</layout-body>
</div>
</template>
... ... @@ -86,10 +84,8 @@
<script>
import _ from 'lodash';
import moment from 'moment';
import RadioDay from './components/radio-day.vue';
import goodStore from './store';
import GoodService from 'services/statistics/shop-service';
import {DateSlot} from 'components/date';
export default {
data() {
... ... @@ -143,25 +139,16 @@
this.getOverviewData();
this.getOverviewTrend();
},
setOverviewParamsRank() {
// 日期为跨天的echart opt
this.overviewParams = {
title: '',
color: '#000',
legend: [_.find(this.targetList, {name: this.curTarget}).value],
xAxis: this.overviewChartData.xAxis,
yAxis: [''],
min: _.min(this.overviewChartData[this.curTarget]),
series: [
{
name: _.find(this.targetList, {name: this.curTarget}).value,
data: this.overviewChartData[this.curTarget]
}
]
};
changeLimit(limit) {
this.dateRange = [this[`day${limit}`], this.today];
},
getOverviewTrend() {
let target = _.find(this.targetList,
tar => tar.name === this.curTarget);
if (target.chatOpt.series) {
return;
}
this.goodService.getOverviewTrend({
type: this.curTarget,
... ... @@ -184,13 +171,20 @@
});
this.overviewChartData.xAxis = name;
this.overviewChartData.uv = sum;
this.overviewChartData.pv = sum;
this.overviewChartData.orderCount = sum;
this.overviewChartData.orderAmount = sum;
this.setOverviewParamsRank();
target.chatOpt = {
title: '',
color: '#000',
legend: [target.label],
xAxis: name,
yAxis: [''],
min: _.min(sum),
series: [
{
name: target.label,
data: sum
}
]
};
});
},
getOverviewData() {
... ... @@ -234,153 +228,104 @@
window.open(href, '_blank');
},
},
components: {
DateSlot,
RadioDay
}
};
</script>
<style lang="scss">
.layout-container {
min-height: 200px;
margin: 15px;
overflow: hidden;
background: #fff;
border-radius: 4px;
.layout-filter .line {
border-top: none;
margin-bottom: 0;
}
.stat-shop {
.ivu-tabs-tabpane {
height: 400px;
position: relative;
}
.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;
}
}
.layout-container {
min-height: 200px;
margin: 15px;
overflow: hidden;
background: #fff;
border-radius: 4px;
.layout-filter .line {
border-top: none;
margin-bottom: 0;
}
.box-item {
margin-left: 5%;
width: 90%;
height: 50px;
padding: 0 0 0 15px;
line-height: 50px;
font-size: 14px;
overflow: hidden;
border-radius: 5px;
color: #fff;
&.green {
background-color: rgb(19, 145, 79);
}
&.green-light {
background-color: rgba(19, 145, 79, 0.5);
}
&.blue {
background-color: rgb(19, 137, 150);
}
&.blue-light {
background-color: rgba(19, 137, 150, 0.5);
}
&.purple {
background-color: rgb(114, 105, 227);
}
&.purple-light {
background-color: rgba(114, 105, 227, 0.5);
}
&.black {
background-color: rgb(52, 52, 52);
}
.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;
}
&[class*="light"] {
margin-top: 20px;
}
}
.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;
}
.notice {
font-size: 10px;
color: #999;
.box-item-value {
font-size: 20px;
font-weight: 600;
}
.tabs-col {
.ivu-tabs-nav {
width: 100%;
border-left: rgb(225, 227, 229);
box-sizing: border-box;
.ivu-tabs-tab {
width: 25%;
text-align: center;
border-top: 1px solid rgb(225, 227, 229);
border-right: 1px solid rgb(225, 227, 229);
padding: 23px 70px;
background-color: rgb(235, 237, 239);
border-radius: 0;
margin-right: 0;
box-sizing: border-box;
&[class*="tab-active"] {
background-color: rgb(245, 247, 249);
border-top: 1px solid rgb(225, 227, 229);
}
}
}
i {
display: inline-block;
width: 20px;
height: 20px;
font-size: 22px;
text-align: center;
margin-top: -7px;
vertical-align: middle;
margin-right: 3px;
}
}
.ivu-tabs-ink-bar {
height: 4px;
background-color: #000;
top: 0;
}
.box-filter {
.ivu-date-picker {
margin-left: 0;
width: 220px !important;
}
.box-filter {
.ivu-date-picker {
margin-left: 0;
.quick {
display: inline-block;
margin-left: 20px;
margin-right: 50px;
a {
margin-right: 5px;
}
}
}
</style>
... ...
... ... @@ -27,19 +27,23 @@ export default function() {
targetList: [
{
label: '访客数(UV)',
name: 'uv'
name: 'uv',
chatOpt: {}
},
{
label: '浏览数(PV)',
name: 'pv'
name: 'pv',
chatOpt: {}
},
{
label: '下单数',
name: 'orderCount'
name: 'orderCount',
chatOpt: {}
},
{
label: '下单金额',
name: 'orderAmount'
name: 'orderAmount',
chatOpt: {}
}
],
filters: {
... ...
.bg-red {
background-color: #dd4b39 !important;
}
.bg-yellow {
background-color: #f39c12 !important;
}
.bg-aqua {
background-color: #00c0ef !important;
}
.bg-blue {
background-color: #0073b7 !important;
}
.bg-light-blue {
background-color: #3c8dbc !important;
}
.bg-green {
background-color: #00a65a !important;
}
.bg-navy {
background-color: #001f3f !important;
}
.bg-teal {
background-color: #39cccc !important;
}
.bg-olive {
background-color: #3d9970 !important;
}
.bg-lime {
background-color: #01ff70 !important;
}
.bg-orange {
background-color: #ff851b !important;
}
.bg-fuchsia {
background-color: #f012be !important;
}
.bg-purple {
background-color: #605ca8 !important;
}
.bg-maroon {
background-color: #d81b60 !important;
}
.bg-gray-active {
color: #000;
background-color: #b5bbc8 !important;
}
.bg-black-active {
background-color: #000 !important;
}
.bg-red-active {
background-color: #d33724 !important;
}
.bg-yellow-active {
background-color: #db8b0b !important;
}
.bg-aqua-active {
background-color: #00a7d0 !important;
}
.bg-blue-active {
background-color: #005384 !important;
}
.bg-light-blue-active {
background-color: #357ca5 !important;
}
.bg-green-active {
background-color: #008d4c !important;
}
.bg-navy-active {
background-color: #001a35 !important;
}
.bg-teal-active {
background-color: #30bbbb !important;
}
.bg-olive-active {
background-color: #368763 !important;
}
.bg-lime-active {
background-color: #00e765 !important;
}
.bg-orange-active {
background-color: #ff7701 !important;
}
.bg-fuchsia-active {
background-color: #db0ead !important;
}
.bg-purple-active {
background-color: #555299 !important;
}
.bg-maroon-active {
background-color: #ca195a !important;
}
... ...
This diff could not be displayed because it is too large.
... ... @@ -1185,7 +1185,7 @@ camelcase@^1.0.2, camelcase@^1.2.1:
version "1.2.1"
resolved "http://npm.yoho.cn/camelcase/-/camelcase-1.2.1.tgz#9bb5304d2e0b56698b2c758b08a3eaa9daa58a39"
camelcase@^2.0.0, camelcase@^2.0.1:
camelcase@^2.0.0:
version "2.1.1"
resolved "http://npm.yoho.cn/camelcase/-/camelcase-2.1.1.tgz#7c1d16d679a1bbe59ca02cacecfb011e201f5a1f"
... ... @@ -1329,7 +1329,7 @@ cliui@^2.1.0:
right-align "^0.1.1"
wordwrap "0.0.2"
cliui@^3.0.3, cliui@^3.2.0:
cliui@^3.2.0:
version "3.2.0"
resolved "http://npm.yoho.cn/cliui/-/cliui-3.2.0.tgz#120601537a916d29940f934da3b48d585a39213d"
dependencies:
... ... @@ -2100,6 +2100,12 @@ ecc-jsbn@~0.1.1:
dependencies:
jsbn "~0.1.0"
echarts@^3.6.1:
version "3.7.0"
resolved "http://npm.yoho.cn/echarts/-/echarts-3.7.0.tgz#79d21b2a7be18a43f6a3f19f8c0ec07c2cf4a3dc"
dependencies:
zrender "^3.6.0"
editorconfig@^0.13.2:
version "0.13.2"
resolved "http://npm.yoho.cn/editorconfig/-/editorconfig-0.13.2.tgz#8e57926d9ee69ab6cb999f027c2171467acceb35"
... ... @@ -7118,10 +7124,6 @@ window-size@0.1.0:
version "0.1.0"
resolved "http://npm.yoho.cn/window-size/-/window-size-0.1.0.tgz#5438cd2ea93b202efa3a19fe8887aee7c94f9c9d"
window-size@^0.1.4:
version "0.1.4"
resolved "http://npm.yoho.cn/window-size/-/window-size-0.1.4.tgz#f8e1aa1ee5a53ec5bf151ffa09742a6ad7697876"
winston-daily-rotate-file@^1.1.1:
version "1.4.6"
resolved "http://npm.yoho.cn/winston-daily-rotate-file/-/winston-daily-rotate-file-1.4.6.tgz#f204b6ada19a5386fdf52fe997d8e10e43ff7788"
... ... @@ -7223,7 +7225,7 @@ xss@^0.3.3:
version "4.0.1"
resolved "http://npm.yoho.cn/xtend/-/xtend-4.0.1.tgz#a5c6d532be656e23db820efb943a1f04998d63af"
y18n@^3.2.0, y18n@^3.2.1:
y18n@^3.2.1:
version "3.2.1"
resolved "http://npm.yoho.cn/y18n/-/y18n-3.2.1.tgz#6d15fba884c08679c0d77e88e7759e811e07fa41"
... ... @@ -7253,17 +7255,14 @@ yargs@^1.2.6:
version "1.3.3"
resolved "http://npm.yoho.cn/yargs/-/yargs-1.3.3.tgz#054de8b61f22eefdb7207059eaef9d6b83fb931a"
yargs@^3.5.4:
version "3.32.0"
resolved "http://npm.yoho.cn/yargs/-/yargs-3.32.0.tgz#03088e9ebf9e756b69751611d2a5ef591482c995"
yargs@^3.5.4, yargs@~3.10.0:
version "3.10.0"
resolved "http://npm.yoho.cn/yargs/-/yargs-3.10.0.tgz#f7ee7bd857dd7c1d2d38c0e74efbd681d1431fd1"
dependencies:
camelcase "^2.0.1"
cliui "^3.0.3"
decamelize "^1.1.1"
os-locale "^1.4.0"
string-width "^1.0.1"
window-size "^0.1.4"
y18n "^3.2.0"
camelcase "^1.0.2"
cliui "^2.1.0"
decamelize "^1.0.0"
window-size "0.1.0"
yargs@^6.0.0:
version "6.6.0"
... ... @@ -7319,15 +7318,6 @@ yargs@^8.0.2:
y18n "^3.2.1"
yargs-parser "^7.0.0"
yargs@~3.10.0:
version "3.10.0"
resolved "http://npm.yoho.cn/yargs/-/yargs-3.10.0.tgz#f7ee7bd857dd7c1d2d38c0e74efbd681d1431fd1"
dependencies:
camelcase "^1.0.2"
cliui "^2.1.0"
decamelize "^1.0.0"
window-size "0.1.0"
yoho-cookie@^1.2.0:
version "1.2.0"
resolved "http://npm.yoho.cn/yoho-cookie/-/yoho-cookie-1.2.0.tgz#e8600ff0fcf316e8a9f88d32cd263396dc7e5f22"
... ... @@ -7363,3 +7353,7 @@ yoho-node-lib@^0.2.18:
yoho-store@^1.3.20:
version "1.3.20"
resolved "http://npm.yoho.cn/yoho-store/-/yoho-store-1.3.20.tgz#bebf6c383720f12a527eab139cf6f8e6886ae721"
zrender@^3.6.0:
version "3.6.0"
resolved "http://npm.yoho.cn/zrender/-/zrender-3.6.0.tgz#b8f4de98200c2c90785b90695680a1f12b4c71ba"
... ...