首页统计

master
czc 2 years ago
parent 5257ec80ec
commit 606a5a2758

@ -0,0 +1,32 @@
import request from '@/utils/request'
// 获取首页查询热卖商品TOP
export function goodsStatistics(query) {
return request({
url: '/dev/statistics/index/goodsStatistics',
method: 'get',
params: query
})
}
export function memberAndCartStatistics() {
return request({
url: '/dev/statistics/index/memberAndCart/statistics',
method: 'get'
})
}
export function orderAndAftersaleStatistics() {
return request({
url: '/dev/statistics/index/order/aftersale/statistics',
method: 'get'
})
}
// 获取订单信息
export function orderStatistics(query) {
return request({
url: '/dev/statistics/index/orderStatistics',
method: 'get',
params: query
})
}

@ -0,0 +1,95 @@
<template>
<div class="sales-top">
<el-card>
<div slot="header" class="clearfix">
<el-row>
<el-col :span="6">
<div style="font-size: large">
<el-radio-group v-model="params.statType" size="small" @change="getData">
<el-radio-button label="1">商品规格销量榜</el-radio-button>
<el-radio-button label="2">商品销量榜</el-radio-button>
</el-radio-group>
</div>
</el-col>
<el-col :span="18">
<div style="text-align: right">
<el-radio-group v-model="params.type" size="small" @change="getData">
<el-radio-button label="0">当日</el-radio-button>
<el-radio-button label="7">近七日</el-radio-button>
<el-radio-button label="30">近一个月</el-radio-button>
</el-radio-group>
</div>
</el-col>
</el-row>
</div>
<el-table v-loading="loading" :data="salesTopData" :border="false">
<el-table-column type="index" width="80"></el-table-column>
<el-table-column prop="productName" label="商品名称"></el-table-column>
<el-table-column prop="spData" label="规格" v-if="params.statType == 1">
<template v-slot="scope">
<div v-for="(value, key) in JSON.parse(scope.row.spData)">{{ key }}{{ value }}&nbsp;</div>
</template>
</el-table-column>
<el-table-column label="主图" align="center" prop="pic">
<template slot-scope="{ row }">
<el-image v-if="row.pic" :src="row.pic" :preview-src-list="[row.pic]" class="small-img circle-img"/>
</template>
</el-table-column>
<el-table-column prop="totalSales" label="销量" width="120">
<template #default="{ row }">
{{ row.totalSales }}
</template>
</el-table-column>
</el-table>
</el-card>
</div>
</template>
<script>
import {goodsStatistics} from "@/api/statistics";
import dateUtil from '@/utils/DateUtil';
export default {
name: 'TopProduct',
data() {
return {
salesTopData: [],
params: {
statType: 1,
type:0,
size: 10,
startDate: '2023-02-01',
endDate: '2023-06-01'
},
loading: false
};
},
created() {
this.getData()
},
methods: {
getData(){
this.loading = true
let range= Number(this.params.type)
this.params.startDate = dateUtil.getAfterDate(-range)
this.params.endDate = dateUtil.getAfterDate(0)
goodsStatistics(this.params).then(res => {
this.salesTopData = res
this.loading = false
})
},
},
};
</script>
<style>
.sales-top {
margin: 20px;
}
.export-btn {
float: right;
margin-right: 20px;
}
</style>

@ -0,0 +1,263 @@
<template>
<el-card style="margin: 20px 20px; font-size: 14px;">
<div slot="header" class="clearfix">
<el-row>
<el-col :span="12">
<div style="text-align: left">
<el-radio-group v-model="params.type" size="small" @change="OnRadioChange">
<el-radio-button label="0">订单数</el-radio-button>
<el-radio-button label="30">支付金额</el-radio-button>
</el-radio-group>
</div>
</el-col>
<!-- <el-col :span="12">-->
<!-- <div style="border-left:1px solid #DCDFE6">-->
<!-- <el-date-picker v-model="orderCountDate" align="right" end-placeholder=""-->
<!-- :picker-options="pickerOptions" range-separator="至" size="small"-->
<!-- start-placeholder="开始日期" style="float: right;z-index: 1" type="daterange"-->
<!-- unlink-panels="unlink-panels" @change="handleDateChange"></el-date-picker>-->
<!-- </div>-->
<!-- </el-col>-->
</el-row>
</div>
<div :style="{minHeight:height,minWidth:width}">
<div ref="chart" class="chart" :style="{height:height,width:width}"/>
</div>
</el-card>
</template>
<script>
import {orderStatistics} from "@/api/statistics";
import echarts from 'echarts'
require('echarts/theme/macarons') // echarts theme
import resize from './mixins/resize'
export default {
mixins: [resize],
name: "OrderLineChart",
props: {
width: {
type: String,
default: '100%'
},
height: {
type: String,
default: '350px'
},
autoResize: {
type: Boolean,
default: true
},
},
data() {
return {
pickerOptions: {
shortcuts: [{
text: '最近一周',
onClick(picker) {
const end = new Date();
let start = new Date();
start.setFullYear(2018);
start.setMonth(10);
start.setDate(1);
end.setTime(start.getTime() + 3600 * 1000 * 24 * 7);
picker.$emit('pick', [start, end]);
}
}, {
text: '最近一月',
onClick(picker) {
const end = new Date();
let start = new Date();
start.setFullYear(2018);
start.setMonth(10);
start.setDate(1);
end.setTime(start.getTime() + 3600 * 1000 * 24 * 30);
picker.$emit('pick', [start, end]);
}
}]
},
orderCountDate: '',
params: {
type: 0
},
chartData: {},
}
},
mounted() {
this.$nextTick(() => {
this.initChart()
})
},
beforeDestroy() {
if (!this.chart) {
return
}
this.chart.dispose()
this.chart = null
},
created() {
orderStatistics().then(res => {
const orderAmount = res.map(it => {
return it.orderAmount
})
const orderCount = res.map(it => {
return it.orderCount
})
const dateList = res.map(it => {
return it.date
})
console.log(dateList, 'date')
this.chartData = {dateList, orderAmount, orderCount}
this.initChart()
})
},
methods: {
OnRadioChange(type) {
this.initChart(type)
},
initChart(type = 0) {
this.chart = echarts.init(this.$refs.chart, 'macarons')
if (type == 0) {
this.setOptions(this.chartData)
} else {
this.setAmountOptions(this.chartData)
}
},
setOptions({dateList, orderAmount, orderCount} = {}) {
this.chart.setOption({
xAxis: {
data: dateList,
type: 'category',
boundaryGap: false,
axisTick: {
show: false
}
},
grid: {
left: 10,
right: 10,
bottom: 20,
top: 30,
containLabel: true
},
tooltip: {
trigger: 'axis',
axisPointer: {
type: 'cross'
},
padding: [5, 10]
},
yAxis: {
axisTick: {
show: false
}
},
legend: {
data: ['订单数', '支付订单']
},
series: [
// {
// name: '', itemStyle: {
// normal: {
// color: '#FF005A',
// lineStyle: {
// color: '#FF005A',
// width: 2
// }
// }
// },
// smooth: true,
// type: 'line',
// data: orderAmount,
// animationDuration: 2800,
// animationEasing: 'cubicInOut'
// },
{
name: '支付订单',
smooth: true,
type: 'line',
itemStyle: {
normal: {
color: '#3888fa',
lineStyle: {
color: '#3888fa',
width: 2
},
areaStyle: {
color: '#f3f8ff'
}
}
},
data: orderCount,
animationDuration: 2800,
animationEasing: 'quadraticOut'
}]
})
}
, setAmountOptions({dateList, orderAmount, orderCount} = {}) {
this.chart.setOption({
xAxis: {
data: dateList,
type: 'category',
boundaryGap: false,
axisTick: {
show: false
}
},
grid: {
left: 10,
right: 10,
bottom: 20,
top: 30,
containLabel: true
},
tooltip: {
trigger: 'axis',
axisPointer: {
type: 'cross'
},
padding: [5, 10]
},
yAxis: {
axisTick: {
show: false
}
},
legend: {
data: ['支付金额']
},
series: [
{
name: '支付金额', itemStyle: {
normal: {
color: '#FF005A',
lineStyle: {
color: '#FF005A',
width: 2
}
}
},
smooth: true,
type: 'line',
data: orderAmount,
animationDuration: 2800,
animationEasing: 'cubicInOut'
},
]
})
},
handleDateChange() {
this.getData();
}
,
}
}
</script>
<style scoped lang="scss">
</style>

@ -9,10 +9,8 @@
<div class="first"> <div class="first">
<ul> <ul>
<li class="li" style="width: 33%">会员数 <li class="li" style="width: 33%">会员数
<el-popover class="ml5" content="功能开发中" placement="top" trigger="hover"><i class="el-icon-warning-outline" slot="reference"></i></el-popover>
</li> </li>
<li class="li" style="width: 33%">加购数 <li class="li" style="width: 33%">加购数
<el-popover class="ml5" content="功能开发中" placement="top" trigger="hover"><i class="el-icon-warning-outline" slot="reference"></i></el-popover>
</li> </li>
<li class="li" style="width: 33%">分销商数 <li class="li" style="width: 33%">分销商数
<el-popover class="ml5" content="功能开发中" placement="top" trigger="hover"><i class="el-icon-warning-outline" slot="reference"></i></el-popover> <el-popover class="ml5" content="功能开发中" placement="top" trigger="hover"><i class="el-icon-warning-outline" slot="reference"></i></el-popover>
@ -20,12 +18,11 @@
</ul> </ul>
<ul> <ul>
<li class="da" style="width: 33%"> <li class="da" style="width: 33%">
<!-- <router-link to="/index">2,910</router-link> --> <router-link to="/member/member">{{ memberAndCartStatisticsObj.memberCount }}</router-link>
2,910
</li> </li>
<li class="da" style="width: 33%"> <li class="da" style="width: 33%">
<!-- <router-link to="/index">56</router-link> --> <router-link to="/member/shoppingCart">{{ memberAndCartStatisticsObj.cartCount }}</router-link>
56
</li> </li>
<li class="da" style="width: 33%"> <li class="da" style="width: 33%">
<!-- <router-link to="/index">21,085</router-link> --> <!-- <router-link to="/index">21,085</router-link> -->
@ -40,18 +37,16 @@
<div slot="header"><span>售后</span></div> <div slot="header"><span>售后</span></div>
<ul> <ul>
<li class="li" style="width: 50%">待处理 <li class="li" style="width: 50%">待处理
<el-popover class="ml5" content="功能开发中" placement="top" trigger="hover"><i class="el-icon-warning-outline" slot="reference"></i></el-popover>
</li> </li>
<li class="li" style="width: 50%">处理中 <li class="li" style="width: 50%">处理中
<el-popover class="ml5" content="功能开发中" placement="top" trigger="hover"><i class="el-icon-warning-outline" slot="reference"></i></el-popover>
</li> </li>
</ul> </ul>
<ul> <ul>
<li class="da" style="width: 50%"> <li class="da" style="width: 50%">
<router-link to="/order/aftersale">2</router-link> <router-link :to="{path:'/order/aftersale', query:{status:0}}">{{ orderAndAftersaleStatisticsObj.pendingAftersaleCount }}</router-link>
</li> </li>
<li class="da" style="width: 50%"> <li class="da" style="width: 50%">
<router-link to="/order/aftersale">1</router-link> <router-link :to="{path:'/order/aftersale', query:{status:1}}">{{ orderAndAftersaleStatisticsObj.processingAftersaleCount }}</router-link>
</li> </li>
</ul> </ul>
</el-card> </el-card>
@ -62,33 +57,26 @@
<div> <div>
<ul> <ul>
<li class="li">未发订单数 <li class="li">未发订单数
<el-popover class="ml5" content="功能开发中" placement="top" trigger="hover"><i class="el-icon-warning-outline" slot="reference"></i></el-popover>
</li> </li>
<li class="li">今日订单数 <li class="li">今日订单数
<el-popover class="ml5" content="功能开发中" placement="top" trigger="hover"><i class="el-icon-warning-outline" slot="reference"></i></el-popover>
</li> </li>
<li class="li">今日成交额 <li class="li">今日成交额
<el-popover class="ml5" content="功能开发中" placement="top" trigger="hover"><i class="el-icon-warning-outline" slot="reference"></i></el-popover>
</li> </li>
<li class="li">今日发货数 <li class="li">今日发货数
<el-popover class="ml5" content="功能开发中" placement="top" trigger="hover"><i class="el-icon-warning-outline" slot="reference"></i></el-popover>
</li> </li>
</ul> </ul>
<ul> <ul>
<li class="da"> <li class="da">
<router-link to="/order/order">50</router-link> <router-link :to="{path:'/order/order',query:{status:1}}">{{ orderAndAftersaleStatisticsObj.waitDeliveredCount }}</router-link>
</li> </li>
<li class="da"> <li class="da">
<!-- <router-link to="/relation/supplier">0</router-link> --> <router-link :to="{path:'/order/order',query:{today:true}}">{{ orderAndAftersaleStatisticsObj.todayOrderCount }}</router-link>
0
</li> </li>
<li class="da"> <li class="da">
<!-- <router-link to="/relation/carrier">4</router-link> --> <router-link :to="{path:'/order/order',query:{today:true,status:1}}">{{ orderAndAftersaleStatisticsObj.todayTransactionAmount }}</router-link>
0
</li> </li>
<li class="da"> <li class="da">
<!-- <router-link to="/item">3</router-link> --> <router-link :to="{path:'/order/order',query:{today:true, status: 2}}">{{ orderAndAftersaleStatisticsObj.todayHasDeliveredCount }}</router-link>
3
</li> </li>
</ul> </ul>
</div> </div>
@ -97,44 +85,11 @@
</el-row> </el-row>
<el-row class="pl20 pr20" :gutter="10"> <el-row class="pl20 pr20" :gutter="10">
<el-col :span="16"> <el-col :span="16">
<el-card style="margin: 20px 20px; font-size: 14px"> <order-line-chart></order-line-chart>
<div slot="header"><span>订单统计</span></div> <div class="card transform">
<el-row> <top-product></top-product>
<el-col :span="4">
<div style="padding: 20px">
<div>
<div style="color: #909399;font-size: 14px">本月订单总数</div>
<div style="color: #606266;font-size: 24px;padding: 10px 0">10000</div>
<div><span class="color-success" style="font-size: 14px">+10%</span><span style="color: #C0C4CC;font-size: 14px">同比上月</span></div>
</div>
<div style="margin-top: 20px;">
<div style="color: #909399;font-size: 14px">本周订单总数</div>
<div style="color: #606266;font-size: 24px;padding: 10px 0">1000</div>
<div><span class="color-danger" style="font-size: 14px">-10%</span><span style="color: #C0C4CC;font-size: 14px">同比上周</span></div>
</div>
<div style="margin-top: 20px;">
<div style="color: #909399;font-size: 14px">本月销售总额</div>
<div style="color: #606266;font-size: 24px;padding: 10px 0">100000</div>
<div><span class="color-success" style="font-size: 14px">+10%</span><span style="color: #C0C4CC;font-size: 14px">同比上月</span></div>
</div>
<div style="margin-top: 20px;">
<div style="color: #909399;font-size: 14px">本周销售总额</div>
<div style="color: #606266;font-size: 24px;padding: 10px 0">50000</div>
<div><span class="color-danger" style="font-size: 14px">-10%</span><span style="color: #C0C4CC;font-size: 14px">同比上周</span></div>
</div>
</div> </div>
</el-col> </el-col>
<el-col :span="20">
<div style="padding: 10px;border-left:1px solid #DCDFE6">
<el-date-picker v-model="orderCountDate" align="right" end-placeholder="结束日期" :picker-options="pickerOptions" range-separator="至" size="small" start-placeholder="开始日期" style="float: right;z-index: 1" type="daterange" unlink-panels="unlink-panels" @change="handleDateChange"></el-date-picker>
<div>
<ve-line :data-empty="dataEmpty" :data="chartData" :legend-visible="false" :loading="loading" :settings="chartSettings"></ve-line>
</div>
</div>
</el-col>
</el-row>
</el-card>
</el-col>
<el-col :span="8"> <el-col :span="8">
<el-card style="margin: 20px 20px; font-size: 14px"> <el-card style="margin: 20px 20px; font-size: 14px">
<div slot="header"><span>发展历程</span></div> <div slot="header"><span>发展历程</span></div>
@ -174,6 +129,10 @@
import {str2Date} from '@/utils/date'; import {str2Date} from '@/utils/date';
import PanelGroup from '@/views/components/PanelGroup' import PanelGroup from '@/views/components/PanelGroup'
import { mapGetters } from 'vuex' import { mapGetters } from 'vuex'
import OrderLineChart from "@/views/dashboard/OrderLineChart.vue";
import TopProduct from "@/views/components/IndexOrderPanelGroup/TopProduct.vue";
import {memberAndCartStatistics, orderAndAftersaleStatistics} from "@/api/statistics";
const DATA_FROM_BACKEND = { const DATA_FROM_BACKEND = {
columns: ['date', 'orderCount','orderAmount'], columns: ['date', 'orderCount','orderAmount'],
rows: [ rows: [
@ -197,7 +156,9 @@ const DATA_FROM_BACKEND = {
export default { export default {
components: { components: {
PanelGroup PanelGroup,
OrderLineChart,
TopProduct
}, },
data() { data() {
return { return {
@ -239,7 +200,19 @@ export default {
loading: false, loading: false,
dataEmpty: false, dataEmpty: false,
nowTime: '', nowTime: '',
hello: '' hello: '',
memberAndCartStatisticsObj: {
memberCount: 0,
cartCount: 0
},
orderAndAftersaleStatisticsObj: {
pendingAftersaleCount: 0,
processingAftersaleCount: 0,
waitDeliveredCount: 0,
todayHasDeliveredCount: 0,
todayOrderCount: 0,
todayTransactionAmount: 0
}
} }
}, },
computed: { computed: {
@ -248,6 +221,8 @@ export default {
created() { created() {
this.showTimes() this.showTimes()
this.helloTimes() this.helloTimes()
this.memberAndCartStat()
this.orderAndAftersaleStat()
this.initOrderCountDate() this.initOrderCountDate()
this.getData() this.getData()
}, },
@ -329,6 +304,16 @@ export default {
} else { } else {
this.hello = '晚上好' this.hello = '晚上好'
} }
},
memberAndCartStat(){
memberAndCartStatistics().then((response) => {
this.memberAndCartStatisticsObj = response
})
},
orderAndAftersaleStat(){
orderAndAftersaleStatistics().then((response) => {
this.orderAndAftersaleStatisticsObj = response
})
} }
} }
} }

@ -110,8 +110,8 @@
<h4>{{ getLogEvent(item.orderStatus) }}</h4> <h4>{{ getLogEvent(item.orderStatus) }}</h4>
<br> <br>
<h4>操作人{{ item.operateMan }}</h4> <h4>操作人{{ item.operateMan }}</h4>
<br> <br v-if="item.note">
<h4>备注{{ item.note }}</h4> <h4 v-if="item.note">{{ item.note }}</h4>
</el-card> </el-card>
</el-timeline-item> </el-timeline-item>
</el-timeline> </el-timeline>
@ -185,6 +185,10 @@ export default {
}; };
}, },
created() { created() {
const { status } = this.$route.query
if (status){
this.queryParams.status = status
}
this.getList(); this.getList();
}, },
methods: { methods: {

@ -219,8 +219,8 @@
<h4>{{ getLogEvent(item.orderStatus) }}</h4> <h4>{{ getLogEvent(item.orderStatus) }}</h4>
<br> <br>
<h4>操作人{{ item.operateMan }}</h4> <h4>操作人{{ item.operateMan }}</h4>
<br> <br v-if="item.note">
<h4>备注{{ item.note }}</h4> <h4 v-if="item.note">{{ item.note }}</h4>
</el-card> </el-card>
</el-timeline-item> </el-timeline-item>
</el-timeline> </el-timeline>
@ -231,7 +231,7 @@
<script> <script>
import { listOmsOrder, getOmsOrder, delOmsOrder, addOmsOrder, updateOmsOrder, exportOmsOrder, saveMerchantNote, deliverProduct, viewLog } from "@/api/oms/order"; import { listOmsOrder, getOmsOrder, delOmsOrder, addOmsOrder, updateOmsOrder, exportOmsOrder, saveMerchantNote, deliverProduct, viewLog } from "@/api/oms/order";
import AddressSelector from "@/views/components/AddressSelector/index.vue"; import AddressSelector from "@/views/components/AddressSelector/index.vue";
import dateUtil from '@/utils/DateUtil'; import dateUtil, {dateFormat} from '@/utils/DateUtil';
import fa from "element-ui/src/locale/lang/fa"; import fa from "element-ui/src/locale/lang/fa";
export default { export default {
@ -331,13 +331,25 @@ export default {
}; };
}, },
created() { created() {
const { phone } = this.$route.query const { phone,status,today } = this.$route.query
if (phone){ if (phone){
this.queryParams.userPhone = phone this.queryParams.userPhone = phone
} }
if (status){
this.queryParams.status = status
}
if (today){
this.setToday()
}
this.getList(); this.getList();
}, },
methods: { methods: {
/** 日期组件设置为今天 */
setToday(){
const temp = new Date();
this.queryParams.Time[0] = dateFormat(new Date(temp.setHours(0, 0, 0, 0)), "yyyy-MM-dd hh:mm:ss")
this.queryParams.Time[1] = dateFormat(new Date(temp.setHours(23, 59, 59, 0)), "yyyy-MM-dd hh:mm:ss")
},
/** 查询订单表列表 */ /** 查询订单表列表 */
getList() { getList() {
if (this.queryParams.Time) { if (this.queryParams.Time) {

@ -1,6 +1,6 @@
<template> <template>
<div> <div>
<div class="user-info-head" @click="editCropper()"><img v-bind:src="options.img" title="点击上传头像" class="img-circle img-lg" /></div> <div class="user-info-head"><img v-bind:src="options.img" title="点击上传头像" class="img-circle img-lg" /></div>
<el-dialog :title="title" :visible.sync="open" width="800px" append-to-body @opened="modalOpened" @close="closeDialog"> <el-dialog :title="title" :visible.sync="open" width="800px" append-to-body @opened="modalOpened" @close="closeDialog">
<el-row> <el-row>
<el-col :xs="24" :md="12" :style="{height: '350px'}"> <el-col :xs="24" :md="12" :style="{height: '350px'}">

Loading…
Cancel
Save