890 lines
31 KiB
Vue
890 lines
31 KiB
Vue
<template>
|
||
<ai-list class="list" v-loading="isLoading" element-loading-text="拼命加载中" element-loading-spinner="el-icon-loading">
|
||
<ai-title
|
||
slot="title"
|
||
title="销售统计"
|
||
tips="最多只能统计近60天的销售数据"
|
||
isShowBottomBorder>
|
||
<template #rightBtn>
|
||
<div class="title-right">
|
||
<div>
|
||
<label style="width:90px">时间范围:</label>
|
||
<el-date-picker
|
||
v-model="dateRange"
|
||
type="daterange"
|
||
start-placeholder="开始日期"
|
||
end-placeholder="结束日期"
|
||
format="yyyy-MM-dd"
|
||
value-format="yyyy-MM-dd">
|
||
</el-date-picker>
|
||
</div>
|
||
<div>
|
||
<label style="width:90px">店铺:</label>
|
||
<el-select v-model="mallId" placeholder="请选择" size="small">
|
||
<el-option
|
||
v-for="item in $store.state.mallList"
|
||
:key="item.mallId"
|
||
:label="item.mallName"
|
||
:value="item.mallId">
|
||
</el-option>
|
||
</el-select>
|
||
</div>
|
||
<el-button type="button" :class="'el-button el-button--primary'" @click="toBeginStat">开始统计</el-button>
|
||
<el-button type="primary" icon="el-icon-download" @click="downloadPicture">下载图片</el-button>
|
||
<json-excel
|
||
:data="skcList"
|
||
:fields="skcJsonFields"
|
||
name="SKC销售统计.xls"
|
||
worksheet="SKC销售统计">
|
||
<el-button type="primary" icon="el-icon-download">下载SKC统计</el-button>
|
||
</json-excel>
|
||
<json-excel
|
||
:data="skuList"
|
||
:fields="skuJsonFields"
|
||
name="SKU销售统计.xls"
|
||
worksheet="SKU销售统计">
|
||
<el-button type="primary" icon="el-icon-download">下载SKU统计</el-button>
|
||
</json-excel>
|
||
</div>
|
||
</template>
|
||
</ai-title>
|
||
<template slot="content">
|
||
<div id="app-content">
|
||
<ai-card title="数据概览" style="padding-bottom: 40px;">
|
||
<div>
|
||
<el-row :gutter="20">
|
||
<el-col :span="5">
|
||
<div>
|
||
<el-statistic
|
||
group-separator=","
|
||
:precision="2"
|
||
:value="saleAmount"
|
||
title="销售额"
|
||
>
|
||
</el-statistic>
|
||
</div>
|
||
</el-col>
|
||
<el-col :span="5">
|
||
<div>
|
||
<el-statistic
|
||
group-separator=","
|
||
:value="saleCount"
|
||
title="单量"
|
||
>
|
||
</el-statistic>
|
||
</div>
|
||
</el-col>
|
||
<el-col :span="5">
|
||
<div>
|
||
<el-statistic
|
||
group-separator=","
|
||
:precision="2"
|
||
:value="costAmount"
|
||
title="成本"
|
||
></el-statistic>
|
||
</div>
|
||
</el-col>
|
||
<el-col :span="5">
|
||
<div>
|
||
<el-statistic
|
||
group-separator=","
|
||
:precision="2"
|
||
:value="profitAmount"
|
||
title="利润"
|
||
></el-statistic>
|
||
</div>
|
||
</el-col>
|
||
<el-col :span="4">
|
||
<div>
|
||
<el-statistic
|
||
group-separator=","
|
||
:precision="2"
|
||
:value="profitPercent"
|
||
title="利润率"
|
||
>
|
||
<template slot="suffix">%</template>
|
||
</el-statistic>
|
||
</div>
|
||
</el-col>
|
||
</el-row>
|
||
</div>
|
||
</ai-card>
|
||
<ai-card title="趋势分析" style="padding-bottom: 40px;">
|
||
<div>
|
||
<div id="chart1"></div>
|
||
</div>
|
||
</ai-card>
|
||
<div>
|
||
<el-row :gutter="20">
|
||
<el-col :span="12">
|
||
<ai-card title="SKC销售额TOP10排行">
|
||
<ai-table
|
||
ref="table0"
|
||
:isShowPagination="false"
|
||
:tableData="topSaleAmountSkcList"
|
||
:col-configs="skcColConfigs"
|
||
style="margin-top: 8px;">
|
||
<el-table-column slot="saleAmount" label="销售额">
|
||
<template slot-scope="scope">
|
||
<div style="color: red">{{ scope.row.saleAmount }}</div>
|
||
</template>
|
||
</el-table-column>
|
||
<el-table-column slot="profitAmount" label="利润">
|
||
<template slot-scope="scope">
|
||
<div>{{ scope.row.profitAmount }}</div>
|
||
</template>
|
||
</el-table-column>
|
||
<el-table-column slot="saleCount" label="单量">
|
||
<template slot-scope="scope">
|
||
<div>{{ scope.row.saleCount }}</div>
|
||
</template>
|
||
</el-table-column>
|
||
</ai-table>
|
||
</ai-card>
|
||
</el-col>
|
||
<el-col :span="12">
|
||
<ai-card title="SKC利润TOP10排行">
|
||
<ai-table
|
||
ref="table1"
|
||
:isShowPagination="false"
|
||
:tableData="topSaleProfitSkcList"
|
||
:col-configs="skcColConfigs"
|
||
style="margin-top: 8px;">
|
||
<el-table-column slot="saleAmount" label="销售额">
|
||
<template slot-scope="scope">
|
||
<div>{{ scope.row.saleAmount }}</div>
|
||
</template>
|
||
</el-table-column>
|
||
<el-table-column slot="profitAmount" label="利润">
|
||
<template slot-scope="scope">
|
||
<div style="color: red">{{ scope.row.profitAmount }}</div>
|
||
</template>
|
||
</el-table-column>
|
||
<el-table-column slot="saleCount" label="单量">
|
||
<template slot-scope="scope">
|
||
<div>{{ scope.row.saleCount }}</div>
|
||
</template>
|
||
</el-table-column>
|
||
</ai-table>
|
||
</ai-card>
|
||
</el-col>
|
||
</el-row>
|
||
<el-row :gutter="20">
|
||
<el-col :span="12">
|
||
<ai-card title="SKC单量TOP10排行">
|
||
<ai-table
|
||
ref="table2"
|
||
:isShowPagination="false"
|
||
:tableData="topSaleCountSkcList"
|
||
:col-configs="skcColConfigs"
|
||
style="margin-top: 8px;">
|
||
<el-table-column slot="saleAmount" label="销售额">
|
||
<template slot-scope="scope">
|
||
<div>{{ scope.row.saleAmount }}</div>
|
||
</template>
|
||
</el-table-column>
|
||
<el-table-column slot="profitAmount" label="利润">
|
||
<template slot-scope="scope">
|
||
<div>{{ scope.row.profitAmount }}</div>
|
||
</template>
|
||
</el-table-column>
|
||
<el-table-column slot="saleCount" label="单量">
|
||
<template slot-scope="scope">
|
||
<div style="color: red">{{ scope.row.saleCount }}</div>
|
||
</template>
|
||
</el-table-column>
|
||
</ai-table>
|
||
</ai-card>
|
||
</el-col>
|
||
<el-col :span="12">
|
||
<ai-card title="SKU销售额TOP10排行">
|
||
<ai-table
|
||
ref="table3"
|
||
:isShowPagination="false"
|
||
:tableData="topSaleAmountSkuList"
|
||
:col-configs="skuColConfigs"
|
||
style="margin-top: 8px;">
|
||
<el-table-column slot="skuExtCode" label="SKC属性/SKU属性" width="250px" :show-overflow-tooltip="true">
|
||
<template slot-scope="scope">
|
||
<div>{{ scope.row.skcExtCode + '/' + scope.row.skuExtCode }}</div>
|
||
</template>
|
||
</el-table-column>
|
||
<el-table-column slot="saleAmount" label="销售额">
|
||
<template slot-scope="scope">
|
||
<div style="color: red">{{ scope.row.saleAmount }}</div>
|
||
</template>
|
||
</el-table-column>
|
||
<el-table-column slot="profitAmount" label="利润">
|
||
<template slot-scope="scope">
|
||
<div>{{ scope.row.profitAmount }}</div>
|
||
</template>
|
||
</el-table-column>
|
||
<el-table-column slot="saleCount" label="单量">
|
||
<template slot-scope="scope">
|
||
<div>{{ scope.row.saleCount }}</div>
|
||
</template>
|
||
</el-table-column>
|
||
</ai-table>
|
||
</ai-card>
|
||
</el-col>
|
||
</el-row>
|
||
<el-row :gutter="20">
|
||
<el-col :span="12">
|
||
<ai-card title="SKU利润TOP10排行">
|
||
<ai-table
|
||
ref="table4"
|
||
:isShowPagination="false"
|
||
:tableData="topSaleProfitSkuList"
|
||
:col-configs="skuColConfigs"
|
||
style="margin-top: 8px;">
|
||
<el-table-column slot="skuExtCode" label="SKC属性/SKU属性" width="250px" :show-overflow-tooltip="true">
|
||
<template slot-scope="scope">
|
||
<div>{{ scope.row.skcExtCode + '/' + scope.row.skuExtCode }}</div>
|
||
</template>
|
||
</el-table-column>
|
||
<el-table-column slot="saleAmount" label="销售额">
|
||
<template slot-scope="scope">
|
||
<div>{{ scope.row.saleAmount }}</div>
|
||
</template>
|
||
</el-table-column>
|
||
<el-table-column slot="profitAmount" label="利润">
|
||
<template slot-scope="scope">
|
||
<div style="color: red">{{ scope.row.profitAmount }}</div>
|
||
</template>
|
||
</el-table-column>
|
||
<el-table-column slot="saleCount" label="单量">
|
||
<template slot-scope="scope">
|
||
<div>{{ scope.row.saleCount }}</div>
|
||
</template>
|
||
</el-table-column>
|
||
</ai-table>
|
||
</ai-card>
|
||
</el-col>
|
||
<el-col :span="12">
|
||
<ai-card title="SKU单量TOP10排行">
|
||
<ai-table
|
||
ref="table5"
|
||
:isShowPagination="false"
|
||
:tableData="topSaleCountSkuList"
|
||
:col-configs="skuColConfigs"
|
||
style="margin-top: 8px;">
|
||
<el-table-column slot="skuExtCode" label="SKC属性/SKU属性" width="250px" :show-overflow-tooltip="true">
|
||
<template slot-scope="scope">
|
||
<div>{{ scope.row.skcExtCode + '/' + scope.row.skuExtCode }}</div>
|
||
</template>
|
||
</el-table-column>
|
||
<el-table-column slot="saleAmount" label="销售额">
|
||
<template slot-scope="scope">
|
||
<div>{{ scope.row.saleAmount }}</div>
|
||
</template>
|
||
</el-table-column>
|
||
<el-table-column slot="profitAmount" label="利润">
|
||
<template slot-scope="scope">
|
||
<div>{{ scope.row.profitAmount }}</div>
|
||
</template>
|
||
</el-table-column>
|
||
<el-table-column slot="saleCount" label="单量">
|
||
<template slot-scope="scope">
|
||
<div style="color: red">{{ scope.row.saleCount }}</div>
|
||
</template>
|
||
</el-table-column>
|
||
</ai-table>
|
||
</ai-card>
|
||
</el-col>
|
||
</el-row>
|
||
</div>
|
||
</div>
|
||
</template>
|
||
|
||
|
||
</ai-list>
|
||
</template>
|
||
|
||
<script>
|
||
import {sendChromeAPIMessage } from '@/api/chromeApi'
|
||
import JsonExcel from 'vue-json-excel'
|
||
import { Message } from 'element-ui'
|
||
import {formatDate} from '@/utils/date'
|
||
import html2canvas from 'html2canvas'
|
||
import { DualAxes } from '@antv/g2plot'
|
||
|
||
export default {
|
||
name: 'ExportSaleStatTemu',
|
||
|
||
data () {
|
||
return {
|
||
mallId: null,
|
||
storeCode: '',
|
||
|
||
dateRange: null,
|
||
|
||
currentPage: 1,
|
||
pageSize: 50,
|
||
productList: [],
|
||
productCostList: [],
|
||
saleAmount: 0.0,
|
||
saleCount: 0,
|
||
costAmount: 0.0,
|
||
profitAmount: 0.0,
|
||
profitPercent: 0.0,
|
||
deductionAmount: 0.0,
|
||
skcList: [],
|
||
skuList: [],
|
||
|
||
leftChartData: [],
|
||
rightChartData: [],
|
||
|
||
isLoading: false,
|
||
|
||
skcColConfigs: [
|
||
{ prop: 'skcExtCode', label: 'SKC货号', width: '250px' },
|
||
{ slot: 'saleAmount', label: '销售额', align: 'center' },
|
||
{ slot: 'saleCount', label: '单量', align: 'center' },
|
||
{ prop: 'costAmount', label: '成本', align: 'center'},
|
||
{ slot: 'profitAmount', label: '利润', align: 'center' }
|
||
],
|
||
skcJsonFields: {
|
||
"SKC": "productSkcId",
|
||
"SKC货号": "skcExtCode",
|
||
"销售额": "saleAmount",
|
||
"单量": "saleCount",
|
||
"成本": "costAmount",
|
||
"利润": "profitAmount"
|
||
},
|
||
skuColConfigs: [
|
||
{ slot: 'skuExtCode', label: 'SKC货号/SKU货号' },
|
||
{ slot: 'saleAmount', label: '销售额', align: 'center' },
|
||
{ slot: 'saleCount', label: '单量', align: 'center' },
|
||
{ prop: 'costAmount', label: '成本', align: 'center'},
|
||
{ slot: 'profitAmount', label: '利润', align: 'center' }
|
||
],
|
||
skuJsonFields: {
|
||
"SKC": "productSkcId",
|
||
"SKU": "productSkuId",
|
||
"SKC货号": "skcExtCode",
|
||
"SKU货号": "skuExtCode",
|
||
"销售额": "saleAmount",
|
||
"单量": "saleCount",
|
||
"成本": "costAmount",
|
||
"利润": "profitAmount"
|
||
},
|
||
|
||
chartObj: null
|
||
}
|
||
},
|
||
|
||
computed: {
|
||
topSaleAmountSkcList() {
|
||
const list = Object.assign([], this.skcList)
|
||
list.sort((a, b) => b.saleAmount - a.saleAmount)
|
||
return list.slice(0, 10)
|
||
},
|
||
topSaleProfitSkcList() {
|
||
const list = Object.assign([], this.skcList)
|
||
list.sort((a, b) => b.profitAmount - a.profitAmount)
|
||
return list.slice(0, 10)
|
||
},
|
||
topSaleCountSkcList() {
|
||
const list = Object.assign([], this.skcList)
|
||
list.sort((a, b) => b.saleCount - a.saleCount)
|
||
return list.slice(0, 10)
|
||
},
|
||
topSaleAmountSkuList() {
|
||
const list = Object.assign([], this.skuList)
|
||
list.sort((a, b) => b.saleAmount - a.saleAmount)
|
||
return list.slice(0, 10)
|
||
},
|
||
topSaleProfitSkuList() {
|
||
const list = Object.assign([], this.skuList)
|
||
list.sort((a, b) => b.profitAmount - a.profitAmount)
|
||
return list.slice(0, 10)
|
||
},
|
||
topSaleCountSkuList() {
|
||
const list = Object.assign([], this.skuList)
|
||
list.sort((a, b) => b.saleCount - a.saleCount)
|
||
return list.slice(0, 10)
|
||
}
|
||
},
|
||
|
||
components: {
|
||
JsonExcel
|
||
},
|
||
mounted () {
|
||
this.initChart1()
|
||
},
|
||
methods: {
|
||
initChart1 () {
|
||
this.chartObj = new DualAxes('chart1', {
|
||
data: [this.leftChartData, this.rightChartData],
|
||
xField: 'day',
|
||
yField: ['value', 'value1'],
|
||
yAxis: {
|
||
value: {
|
||
title: {
|
||
text: '金额'
|
||
},
|
||
label: {
|
||
formatter: (value) => {
|
||
return `${value}元`;
|
||
}
|
||
}
|
||
},
|
||
value1: {
|
||
max: 100,
|
||
title: {
|
||
text: '利润率'
|
||
},
|
||
label: {
|
||
formatter: (value) => {
|
||
return `${value}%`;
|
||
}
|
||
}
|
||
}
|
||
},
|
||
geometryOptions: [
|
||
{
|
||
geometry: 'line',
|
||
color: ['#FF9A49', '#7A8AA1', '#1EEB73', '#C947AE' ],
|
||
isGroup: true,
|
||
smooth: true, // 是否平滑
|
||
seriesField: 'type'
|
||
},
|
||
{
|
||
geometry: 'line',
|
||
color: ['red' ],
|
||
lineStyle: {
|
||
fill: 'red',
|
||
fillOpacity: 0.5,
|
||
stroke: 'red',
|
||
lineWidth: 4,
|
||
strokeOpacity: 0.7,
|
||
shadowColor: 'black',
|
||
shadowBlur: 10,
|
||
shadowOffsetX: 5,
|
||
shadowOffsetY: 5,
|
||
cursor: 'pointer'
|
||
},
|
||
isStack: true,
|
||
smooth: true, // 是否平滑
|
||
seriesField: 'type', // 指定使用第二个Y轴字段
|
||
}],
|
||
});
|
||
|
||
this.chartObj.render();
|
||
},
|
||
toBeginStat() {
|
||
if (!this.dateRange) {
|
||
Message.error("请选择统计时间范围")
|
||
return
|
||
}
|
||
if (!this.mallId) {
|
||
Message.error("请选择店铺")
|
||
return
|
||
}
|
||
this.$userCheck(this.mallId).then(() => {
|
||
this.beginStat()
|
||
}).catch((err) => {
|
||
this.mallId = ''
|
||
this.isLoading = false
|
||
})
|
||
},
|
||
async beginStat() {
|
||
this.currentPage = 1
|
||
this.isLoading = true
|
||
this.saleAmount = 0.0
|
||
this.saleCount = 0
|
||
this.costAmount = 0.0
|
||
this.profitAmount = 0.0
|
||
this.profitPercent = 0.0
|
||
this.productList = []
|
||
this.productCostList = []
|
||
this.skcList = []
|
||
this.skuList = []
|
||
this.leftChartData = []
|
||
this.rightChartData = []
|
||
this.chartObj.changeData([this.leftChartData, this.rightChartData])
|
||
await this.getProductList()
|
||
await this.getSkuCostList()
|
||
await this.getSkuSaleNumber(0)
|
||
this.leftChartData.sort((a, b) => {
|
||
let leftDate = new Date(a.day)
|
||
let rightDate = new Date(b.day)
|
||
return leftDate.getTime() - rightDate.getTime()
|
||
})
|
||
this.leftChartData.map(item => {
|
||
if (item.type == '销售额' || item.type == '成本' || item.type == '利润') {
|
||
item.value = Math.round(item.value * 100) / 100
|
||
}
|
||
|
||
if (item.type == '销售额') {
|
||
this.leftChartData.map(item1 => {
|
||
if (item1.type == '成本' && item1.day == item.day) {
|
||
this.rightChartData.push({
|
||
day: item1.day,
|
||
value1: Math.round((item.value - item1.value) / item.value * 10000) / 100,
|
||
type: '利润率'
|
||
})
|
||
}
|
||
})
|
||
}
|
||
})
|
||
this.rightChartData.sort((a, b) => {
|
||
let leftDate = new Date(a.day)
|
||
let rightDate = new Date(b.day)
|
||
return leftDate.getTime() - rightDate.getTime()
|
||
})
|
||
this.skuList = this.skuList.filter(item => {
|
||
return item.saleCount > 0
|
||
})
|
||
|
||
this.skuList.map(item => {
|
||
item.saleAmount = Math.round(item.saleAmount * 100) / 100
|
||
item.costAmount = Math.round(item.costAmount * 100) / 100
|
||
item.profitAmount = Math.round(item.profitAmount * 100) / 100
|
||
})
|
||
this.skuList.map(item => {
|
||
let flag = false
|
||
for (let i = 0; i < this.skcList.length; i++) {
|
||
if (item.productSkcId == this.skcList[i].productSkcId) {
|
||
this.skcList[i].saleAmount = this.skcList[i].saleAmount + item.saleAmount
|
||
this.skcList[i].costAmount = this.skcList[i].costAmount + item.costAmount
|
||
this.skcList[i].saleCount = this.skcList[i].saleCount + item.saleCount
|
||
this.skcList[i].profitAmount = this.skcList[i].profitAmount + item.profitAmount
|
||
flag = true
|
||
break
|
||
}
|
||
}
|
||
if (!flag) {
|
||
this.skcList.push({
|
||
productSkcId: item.productSkcId,
|
||
skcExtCode: item.skcExtCode,
|
||
saleAmount: item.saleAmount,
|
||
saleCount: item.saleCount,
|
||
costAmount: item.costAmount,
|
||
profitAmount: item.profitAmount,
|
||
profitPercent: item.profitPercent
|
||
})
|
||
}
|
||
})
|
||
|
||
this.skcList.map(item => {
|
||
item.saleAmount = Math.round(item.saleAmount * 100) / 100
|
||
item.costAmount = Math.round(item.costAmount * 100) / 100
|
||
item.profitAmount = Math.round(item.profitAmount * 100) / 100
|
||
})
|
||
this.leftChartData.map(item => {
|
||
if (item.type == '销售额') {
|
||
this.saleAmount = this.saleAmount + item.value
|
||
}
|
||
if (item.type == '成本') {
|
||
this.costAmount = this.costAmount + item.value
|
||
}
|
||
if (item.type == '利润') {
|
||
this.profitAmount = this.profitAmount + item.value
|
||
}
|
||
if (item.type == '单量') {
|
||
this.saleCount = this.saleCount + item.value
|
||
}
|
||
})
|
||
this.saleAmount = Math.round(this.saleAmount * 100) / 100
|
||
this.costAmount = Math.round(this.costAmount * 100) / 100
|
||
this.profitAmount = Math.round(this.profitAmount * 100) / 100
|
||
this.profitPercent = Math.round((this.saleAmount - this.costAmount) / this.saleAmount * 10000) / 100
|
||
this.chartObj.changeData([this.leftChartData, this.rightChartData])
|
||
this.isLoading = false
|
||
},
|
||
getPorductList() {
|
||
this.$http.post(`/api/skuCost/listAll`, null, {
|
||
params: {
|
||
mallId: this.storeCode
|
||
}
|
||
}).then(res => {
|
||
if (res.code == 0) {
|
||
this.productList = res.data
|
||
}
|
||
})
|
||
},
|
||
async getProductList() {
|
||
let res = await sendChromeAPIMessage({
|
||
url: 'marvel-mms/cn/api/kiana/venom/sales/management/listWarehouse',
|
||
needMallId: true,
|
||
mallId: this.mallId,
|
||
data: {
|
||
pageNo: this.currentPage,
|
||
pageSize: this.pageSize,
|
||
isLack: 0,
|
||
priceAdjustRecentDays: 7
|
||
}})
|
||
|
||
if (res.errorCode == 1000000) {
|
||
for(let i = 0;i < res.result.subOrderList.length; i++) {
|
||
let item = res.result.subOrderList[i]
|
||
let data = {}
|
||
data.productName = item.productName
|
||
data.productId = item.productId
|
||
data.productSkcId = item.productSkcId
|
||
data.skcExtCode = item.skcExtCode
|
||
for(let j = 0;j < item.skuQuantityDetailList.length; j++) {
|
||
data = {...data,
|
||
skuExtCode: item.skuQuantityDetailList[j].skuExtCode,
|
||
supplierPrice: item.skuQuantityDetailList[j].supplierPrice / 100,
|
||
productSkuId: item.skuQuantityDetailList[j].productSkuId,
|
||
className: item.skuQuantityDetailList[j].className
|
||
}
|
||
this.productList.push(data)
|
||
}
|
||
}
|
||
|
||
if ((this.currentPage * this.pageSize) < res.result.total) {
|
||
this.currentPage ++
|
||
await this.getProductList()
|
||
}
|
||
} else {
|
||
await this.getProductList()
|
||
}
|
||
},
|
||
async getSkuSaleNumber (page) {
|
||
let tempSkuId = []
|
||
let i = page * 500
|
||
let j = 0
|
||
for (; i < this.productList.length; i++) {
|
||
tempSkuId.push(this.productList[i].productSkuId)
|
||
j ++
|
||
if (j == 500) break
|
||
}
|
||
if (tempSkuId.length == 0) return
|
||
let res = await sendChromeAPIMessage({
|
||
url: 'oms/bg/venom/api/supplier/sales/management/querySkuSalesNumber',
|
||
needMallId: true,
|
||
mallId: this.mallId,
|
||
data: {
|
||
productSkuIds: tempSkuId,
|
||
startDate: this.dateRange[0],
|
||
endDate: this.dateRange[1]
|
||
}})
|
||
if (res.errorCode == 1000000) {
|
||
for (let i = 0; i < res.result.length; i++) {
|
||
let cost = this.getCost(res.result[i].prodSkuId)
|
||
|
||
let flag = false
|
||
// 计算每日销售额
|
||
let skuObj = 0
|
||
for (let k = 0; k < this.productList.length; k++) {
|
||
if (this.productList[k].productSkuId == res.result[i].prodSkuId) {
|
||
skuObj = this.productList[k]
|
||
break
|
||
}
|
||
}
|
||
for (let j = 0; j < this.leftChartData.length; j++) {
|
||
if (this.leftChartData[j].type == '销售额' && this.leftChartData[j].day == res.result[i].date) {
|
||
this.leftChartData[j].value = this.leftChartData[j].value + skuObj.supplierPrice * res.result[i].salesNumber
|
||
flag = true
|
||
break
|
||
}
|
||
}
|
||
if (!flag) {
|
||
this.leftChartData.push({
|
||
type: '销售额',
|
||
value: skuObj.supplierPrice * res.result[i].salesNumber,
|
||
day: res.result[i].date
|
||
})
|
||
}
|
||
|
||
// 计算每日销量
|
||
flag = false
|
||
for (let j = 0; j < this.leftChartData.length; j++) {
|
||
if (this.leftChartData[j].type == '单量' && this.leftChartData[j].day == res.result[i].date) {
|
||
this.leftChartData[j].value = this.leftChartData[j].value + res.result[i].salesNumber
|
||
flag = true
|
||
break
|
||
}
|
||
}
|
||
if (!flag) {
|
||
this.leftChartData.push({
|
||
type: '单量',
|
||
value: res.result[i].salesNumber,
|
||
day: res.result[i].date
|
||
})
|
||
}
|
||
|
||
// 计算每日成本
|
||
flag = false
|
||
for (let j = 0; j < this.leftChartData.length; j++) {
|
||
if (this.leftChartData[j].type == '成本' && this.leftChartData[j].day == res.result[i].date) {
|
||
this.leftChartData[j].value = this.leftChartData[j].value + cost * res.result[i].salesNumber
|
||
flag = true
|
||
break
|
||
}
|
||
}
|
||
if (!flag) {
|
||
this.leftChartData.push({
|
||
type: '成本',
|
||
value: cost * res.result[i].salesNumber,
|
||
day: res.result[i].date
|
||
})
|
||
}
|
||
|
||
// 计算每日利润
|
||
flag = false
|
||
for (let j = 0; j < this.leftChartData.length; j++) {
|
||
if (this.leftChartData[j].type == '利润' && this.leftChartData[j].day == res.result[i].date) {
|
||
this.leftChartData[j].value = this.leftChartData[j].value + (skuObj.supplierPrice - cost) * res.result[i].salesNumber
|
||
flag = true
|
||
break
|
||
}
|
||
}
|
||
if (!flag) {
|
||
this.leftChartData.push({
|
||
type: '利润',
|
||
value: (skuObj.supplierPrice - cost) * res.result[i].salesNumber,
|
||
day: res.result[i].date
|
||
})
|
||
}
|
||
|
||
// 计算SKU维度销售额
|
||
flag = false
|
||
for (let j = 0; j < this.skuList.length; j++) {
|
||
if (this.skuList[j].productSkuId == res.result[i].prodSkuId) {
|
||
this.skuList[j].saleAmount = this.skuList[j].saleAmount + skuObj.supplierPrice * res.result[i].salesNumber
|
||
this.skuList[j].costAmount = this.skuList[j].costAmount + cost * res.result[i].salesNumber
|
||
this.skuList[j].saleCount = this.skuList[j].saleCount + res.result[i].salesNumber
|
||
this.skuList[j].profitAmount = this.skuList[j].profitAmount + (skuObj.supplierPrice - cost) * res.result[i].salesNumber
|
||
flag = true
|
||
break
|
||
}
|
||
}
|
||
if (!flag) {
|
||
this.skuList.push({
|
||
productSkcId: skuObj.productSkcId,
|
||
productSkuId: skuObj.productSkuId,
|
||
skcExtCode: skuObj.skcExtCode,
|
||
skuExtCode: skuObj.skuExtCode,
|
||
saleAmount: skuObj.supplierPrice * res.result[i].salesNumber,
|
||
costAmount: cost * res.result[i].salesNumber,
|
||
profitAmount: (skuObj.supplierPrice - cost) * res.result[i].salesNumber,
|
||
saleCount: res.result[i].salesNumber,
|
||
profitPercent: Math.round((skuObj.supplierPrice - cost) / skuObj.supplierPrice * 10000) / 100
|
||
})
|
||
}
|
||
}
|
||
await this.getSkuSaleNumber(page + 1)
|
||
} else {
|
||
await this.getSkuSaleNumber(page)
|
||
}
|
||
},
|
||
async getSkuCostList() {
|
||
let res = await this.$http.post(`/api/skuCost/listAll`, null, {
|
||
params: {
|
||
mallId: this.mallId
|
||
}
|
||
})
|
||
if (res.code == 0) {
|
||
this.productCostList = res.data
|
||
}
|
||
},
|
||
getCost(sku) {
|
||
for (let i = 0; i < this.productCostList.length; i++) {
|
||
if (sku == this.productCostList[i].sku) {
|
||
return this.productCostList[i].costPrice
|
||
}
|
||
}
|
||
return 0
|
||
},
|
||
sleepSync(milliseconds) {
|
||
return new Promise(resolve => setTimeout(resolve, milliseconds));
|
||
},
|
||
async downloadPicture() {
|
||
try {
|
||
const element = document.getElementById('app-content');
|
||
const canvas = await html2canvas(element);
|
||
// 创建一个图片元素
|
||
const img = new Image();
|
||
img.src = canvas.toDataURL('image/png');
|
||
// 添加到body中以便下载
|
||
document.body.appendChild(img);
|
||
// 触发下载
|
||
const a = document.createElement('a');
|
||
a.style.display = 'none'
|
||
a.href = img.src;
|
||
a.download = '销售统计.png';
|
||
a.click();
|
||
document.body.removeChild(img);
|
||
} catch (error) {
|
||
console.error('Error saving image:', error);
|
||
}
|
||
}
|
||
}
|
||
}
|
||
</script>
|
||
|
||
<style scoped lang="scss">
|
||
.list {
|
||
.title-right {
|
||
display: flex;
|
||
align-items: center;
|
||
|
||
& > div:first-child {
|
||
margin-right: 20px;
|
||
}
|
||
}
|
||
::v-deep.ai-list {
|
||
.ai-list__content--right-wrapper {
|
||
background: transparent;
|
||
box-shadow: none;
|
||
padding: 0!important;
|
||
}
|
||
}
|
||
|
||
.top {
|
||
display: flex;
|
||
justify-content: space-between;
|
||
margin-bottom: 24px;
|
||
|
||
.item {
|
||
flex: 1;
|
||
margin-right: 20px;
|
||
padding: 16px 24px;
|
||
background: #FFF;
|
||
box-shadow: 0px 4px 6px -2px rgba(15, 15, 21, 0.15);
|
||
border-radius: 4px;
|
||
|
||
&:last-child {
|
||
margin-right: 0;
|
||
}
|
||
|
||
&:nth-of-type(1) {
|
||
color: #2266ff;
|
||
}
|
||
|
||
&:nth-of-type(2) {
|
||
color: #f8b426;
|
||
}
|
||
&:nth-of-type(3) {
|
||
color: #21aa99;
|
||
}
|
||
&:nth-of-type(4) {
|
||
color: #F46;
|
||
}
|
||
&:nth-of-type(5) {
|
||
color: #11A265;
|
||
}
|
||
h2 {
|
||
margin-bottom: 30px;
|
||
font-size: 16px;
|
||
color: #999;
|
||
}
|
||
|
||
p {
|
||
font-weight: 600;
|
||
font-size: 28px;
|
||
}
|
||
}
|
||
}
|
||
}
|
||
.like {
|
||
cursor: pointer;
|
||
font-size: 25px;
|
||
display: inline-block;
|
||
}
|
||
</style>
|