Files
temu-plugin/src/view/ExportSaleData.vue
liushiwei f7749d1a94 调整
2023-08-25 00:56:56 +08:00

593 lines
18 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<template>
<ai-list class="list" v-loading="isLoading">
<ai-title
slot="title"
title="销售数据"
isShowBottomBorder>
<template #rightBtn>
<div class="title-right">
<div>
<label style="width:90px">统计类型</label>
<el-select v-model="type" @change="changeDataType" placeholder="请选择" size="small">
<el-option
key="0"
label="销售数据"
value="0">
</el-option>
<el-option
key="1"
label="近30天销售"
value="1">
</el-option>
</el-select>
</div>
<div>
<label style="width:90px">店铺</label>
<el-select v-model="mallId" @change="beforeGetList" 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>
</div>
</template>
</ai-title>
<template slot="content" v-if="type === '0'">
<div class="top">
<div class="item">
<h2>今日销量</h2>
<p>{{ todayTotal }}</p>
</div>
<div class="item">
<h2>今日销售额</h2>
<p>{{ todayMoney }}</p>
</div>
<div class="item">
<h2>库存总量</h2>
<p>{{ inventoryTotal }}</p>
</div>
<div class="item">
<h2>库存总额</h2>
<p>{{ inventoryMoeny }}</p>
</div>
<div class="item">
<h2>已收货总量</h2>
<p>{{ deliveryTotal }}</p>
</div>
<div class="item">
<h2>已收货总货值</h2>
<p>{{ deliveryMoeny }}</p>
</div>
</div>
<ai-card title="数据明细" style="padding-bottom: 40px;">
<template #right>
<json-excel
:data="list"
v-if="type === '0'"
:fields="jsonFields"
:before-generate = "startDownload"
name="销售数据.xls"
worksheet="销售统计">
<el-button type="primary">导出数据</el-button>
</json-excel>
</template>
<ai-table
:isShowPagination="false"
:tableData="list"
:col-configs="colConfigs"
:total="list.length"
style="margin-top: 8px;"
@getList="() => {}">
</ai-table>
</ai-card>
</template>
<template slot="content" v-if="type === '1'">
<ai-card title="数据明细" style="padding-bottom: 40px;">
<template #right>
<json-excel
v-if="type === '1'"
:data="last30Daylist"
:fields="last30DaysJsonFields"
:before-generate = "startDownload"
name="近30天销售数据.xls"
worksheet="近30天销售统计">
<el-button type="primary">导出数据</el-button>
</json-excel>
</template>
<ai-table
:isShowPagination="false"
:tableData="last30Daylist"
:col-configs="col30DaysConfigs"
:total="last30Daylist.length"
style="margin-top: 8px;"
@getList="() => {}">
</ai-table>
</ai-card>
</template>
</ai-list>
</template>
<script>
import {sendChromeAPIMessage} from '@/api/chromeApi'
import JsonExcel from 'vue-json-excel'
import {formatDate} from '@/utils/date'
import { Message } from 'element-ui'
export default {
name: 'ExportSaleData',
data () {
return {
list: [],
last30Daylist: [],
mallId: '',
type: '0',
isLoading: false,
pageSize: 10,
currentPage: 1,
todayTotal: 0,
todayMoney: 0.0,
inventoryTotal: 0,
inventoryMoeny: 0.0,
deliveryTotal: 0,
deliveryMoeny: 0.0,
allProductList: [],
startDate: '',
endDate: '',
jsonFields: {
"商品名称": "productName",
"SPU": "productId",
"SKC": "productSkcId",
"SKU ID": "productSkuId",
"SKU属性": "className",
"SKU货号": "skuExtCode",
"加入站点时长": "onSalesDurationOffline",
"图片链接": "productSkcPicture",
"申报价格(CNY)": {
"field": "supplierPrice",
callback: (value) => {
return value /100;
}
},
"开款核价状态": {
"field": "isVerifyPrice",
callback: (value) => {
return value ? '核价通过': '核价未通过 / 无法备货';
}
},
"缺货数量": "lackQuantity",
"建议备货量": "adviceQuantity",
"可售天数": "availableSaleDays",
"库存可售天数": "availableSaleDaysFromInventory",
"仓内库存可售天数": "warehouseAvailableSaleDays",
"近7日用户加购数量": "inCartNumber7d",
"用户累计加购数量": "inCardNumber",
"已订阅待提醒到货": "nomsgSubsCntCntSth",
"销售数据 - 今日": "todaySaleVolume",
"销售数据 - 近7日": "lastSevenDaysSaleVolume",
"销售数据 - 近30天": "lastThirtyDaysSaleVolume",
"库存数据 - 仓内可用库存": "inventoryNumInfo.warehouseInventoryNum",
"库存数据 - 仓内暂不可用库存": "inventoryNumInfo.unavailableWarehouseInventoryNum",
"库存数据 - 已发货库存": "inventoryNumInfo.waitReceiveNum",
"库存数据 - 已下单待发货库存": "inventoryNumInfo.waitDeliveryInventoryNum",
"库存数据 - 待审核备货库存": "inventoryNumInfo.waitApproveInventoryNum",
"VMI备货单数 - 待发货": "vmiOrderInfo.waitDeliveryNum",
"VMI备货单数 - 在途单数": "vmiOrderInfo.transportationNum",
"VMI备货单数 - 发货延迟": "vmiOrderInfo.deliveryDelayNum",
"VMI备货单数 - 到货延迟": "vmiOrderInfo.arrivalDelayNum",
"非VMI备货单数 - 待发货": "notVmiOrderInfo.waitDeliveryNum",
"非VMI备货单数 - 在途单数": "notVmiOrderInfo.transportationNum",
"非VMI备货单数 - 发货延迟": "notVmiOrderInfo.deliveryDelayNum",
"非VMI备货单数 - 到货延迟": "notVmiOrderInfo.arrivalDelayNum",
"备货逻辑": "purchaseConfig",
"库存货值(CNY)": "productTotalPrice",
}
}
},
computed: {
colConfigs () {
return [
{
prop: 'productName',
label: '商品名称',
"show-overflow-tooltip": true,
width: '280px',
align: 'left'
},
{
prop: 'productId',
label: 'SPU',
align: 'center'
},
{
prop: 'productSkcId',
label: 'SKC',
align: 'center'
},
{
prop: 'productSkuId',
label: 'SKU ID',
align: 'center'
},
{
prop: 'className',
label: 'SKU属性',
align: 'center'
},
{
prop: 'skuExtCode',
label: 'SKU货号',
align: 'center'
},
{
prop: 'onSalesDurationOffline',
label: '加入站点时长',
align: 'center'
},
{
prop: 'isVerifyPrice',
label: '开款核价状态',
align: 'center',
format: v => v ? '核价通过': '核价未通过 / 无法备货'
},
{
prop: 'supplierPrice',
label: '申报价格(CNY)',
align: 'center',
format: v => v / 100,
fixed: "right"
},
{
prop: 'warehouseInventoryNum',
label: '仓内可用库存',
align: 'center',
fixed: "right",
sortable: true,
'sort-method': (a, b) => {
return a.warehouseInventoryNum - b.warehouseInventoryNum
}
},
{
prop: 'productTotalPrice',
label: '库存货值(CNY)',
align: 'center',
fixed: "right",
sortable: true,
'sort-method': (a, b) => {
return a.productTotalPrice - b.productTotalPrice
}
},
]
},
col30DaysConfigs () {
let config = [
{
prop: 'productName',
label: '商品名称',
"show-overflow-tooltip": true,
width: '300px',
align: 'left',
fixed: 'left'
},
{
prop: 'productId',
label: 'SPU',
width: '120px',
align: 'center',
fixed: 'left'
},
{
prop: 'productSkcId',
label: 'SKC',
width: '120px',
align: 'center',
fixed: 'left'
},
{
prop: 'productSkuId',
label: 'SKU ID',
width: '120px',
align: 'center',
fixed: 'left'
}
]
let date = new Date()
date.setDate(date.getDate())
for (let i = 0; i < 30; i++) {
date.setDate(date.getDate() - 1)
let dateStr = formatDate(date)
config.push({
prop: dateStr,
label: dateStr,
width: '100px',
align: 'center',
sortable: true,
'sort-method': (a, b) => {
console.log('1、' + a[dateStr] + ' 2、' + b[dateStr])
return new Number(a[dateStr]) - new Number(b[dateStr])
}})
}
return config
},
last30DaysJsonFields () {
let jsonFields = {
"商品名称": "productName",
"SPU": "productId",
"SKC": "productSkcId",
"SKU ID": "productSkuId"
}
let date = new Date()
date.setDate(date.getDate() )
for (let i = 0; i < 30; i++) {
date.setDate(date.getDate() - 1)
let dateStr = formatDate(date)
jsonFields[dateStr] = dateStr
}
return jsonFields
}
},
components: {
JsonExcel
},
created () {
let date = new Date()
date.setDate(date.getDate() - 30)
this.startDate = formatDate(date)
date.setDate(date.getDate() + 29)
this.endDate = formatDate(date)
},
methods: {
changeDataType() {
},
beforeGetList() {
this.list = []
this.currentPage = 1
this.todayMoney = 0.0
this.todayTotal = 0
this.inventoryMoeny = 0.0
this.inventoryTotal = 0
this.deliveryTotal = 0
this.deliveryMoeny = 0.0
this.allProductList = []
if (!this.mallId) {
Message.error("请先选择店铺")
return
}
this.isLoading = true
this.$userCheck(this.mallId).then(() => {
this.getAllProductList()
this.getList()
}).catch((err) => {
console.log(err)
this.isLoading = false
})
},
getAllProductList() {
this.$http.post('/api/deliveryOrder/totalDelivery',null, {
params: {mallId: this.mallId}
}).then(res => {
if (res.code === 0) {
this.deliveryTotal = res.data
}
})
this.$http.post('/api/deliveryOrder/getAllProductList', null, {
params: {mallId: this.mallId}
}).then(res => {
if (res.code == 0) {
this.allProductList = res.data
}
})
},
getList () {
sendChromeAPIMessage({
url: 'marvel-mms/cn/api/kiana/venom/sales/management/list',
needMallId: true,
mallId: this.mallId,
data: {
pageNo: this.currentPage,
pageSize: this.pageSize,
isLack: 0,
priceAdjustRecentDays: 7
}}).then((res) => {
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.purchaseConfig = item.purchaseConfig;
if (item.onSalesDurationOffline == 0) {
data.onSalesDurationOffline = '-天'
} else {
data.onSalesDurationOffline = item.onSalesDurationOffline + '天'
}
data.productSkcPicture = item.productSkcPicture;
for(let j = 0;j < item.skuQuantityDetailList.length; j++) {
data = {...data, ...item.skuQuantityDetailList[j],
productTotalPrice: ((item.skuQuantityDetailList[j].supplierPrice / 100) * item.skuQuantityDetailList[j].inventoryNumInfo.warehouseInventoryNum).toFixed(2),
warehouseInventoryNum: item.skuQuantityDetailList[j].inventoryNumInfo.warehouseInventoryNum}
this.todayTotal += item.skuQuantityDetailList[j].todaySaleVolume
this.todayMoney += new Number(((item.skuQuantityDetailList[j].supplierPrice / 100) * item.skuQuantityDetailList[j].todaySaleVolume).toFixed(2))
this.todayMoney = new Number(this.todayMoney.toFixed(2))
this.inventoryTotal += item.skuQuantityDetailList[j].inventoryNumInfo.warehouseInventoryNum
this.inventoryMoeny += new Number(((item.skuQuantityDetailList[j].supplierPrice / 100) * item.skuQuantityDetailList[j].inventoryNumInfo.warehouseInventoryNum).toFixed(2))
this.inventoryMoeny = new Number(this.inventoryMoeny.toFixed(2))
this.list.push(data);
// 计算已发货货值
for(let k = 0; k < this.allProductList.length; k++) {
if (this.allProductList[k].product_sku_id == data.productSkuId) {
this.deliveryMoeny += (item.skuQuantityDetailList[j].supplierPrice / 100) * this.allProductList[k].product_sku_number
this.deliveryMoeny = new Number(this.deliveryMoeny.toFixed(2))
}
}
}
}
if (this.pageSize == res.result.subOrderList.length) {
this.currentPage ++
setTimeout(() => {
this.getList()
}, 1500)
} else {
this.isLoading = false
Message.success('销售数据加载完成,可进行导出')
this.last30Daylist = this.list.map(item => {
let temp = {
productName: item.productName,
productId: item.productId,
productSkcId: item.productSkcId,
productSkuId: item.productSkuId
}
let date = new Date()
date.setDate(date.getDate() - 31)
for (let i = 0; i < 30; i++) {
date.setDate(date.getDate() + 1)
let dateStr = formatDate(date)
temp[dateStr] = 0
}
return temp
})
this.getSkuDetailList()
}
} else {
setTimeout(() => {
this.getList()
}, 1500)
// Message.error("【拼多多】" + res.errorMsg + ", 请重新尝试加载")
}
}).catch(() => {
this.isLoading = false
})
},
getSkuDetailList () {
let skuIds = this.list.map(item => {
return item.productSkuId
})
sendChromeAPIMessage({
url: 'oms/bg/venom/api/supplier/sales/management/querySkuSalesNumber',
needMallId: true,
mallId: this.mallId,
data: {
"productSkuIds": skuIds,
"startDate": this.startDate,
"endDate": this.endDate
}}).then((res) => {
if (res.errorCode == 1000000) {
for (let i = 0; i < res.result.length; i++) {
for (let j = 0; j < this.last30Daylist.length; j++) {
if (this.last30Daylist[j].productSkuId == res.result[i].prodSkuId) {
this.last30Daylist[j][res.result[i].date] = res.result[i].salesNumber
break
}
}
}
}
})
},
startDownload() {
this.$http.post('/api/malluser/info').then(res => {
if (res.code == 0) {
this.$store.commit('setUserInfo', res.data)
if (res.data.flag != 1) {
Message.error('您的账号未激活或已失效,请激活后使用')
this.$store.commit('setActiveDlgShow', true)
return;
}
}
})
}
}
}
</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>