2024-09-19 21:28:59 +08:00
|
|
|
|
<template>
|
|
|
|
|
|
<ai-list class="list" v-loading="isLoading" element-loading-text="拼命加载中" element-loading-spinner="el-icon-loading">
|
|
|
|
|
|
<ai-title
|
|
|
|
|
|
slot="title"
|
|
|
|
|
|
title="物流统计"
|
2024-10-30 09:42:08 +08:00
|
|
|
|
tips="数据来源于“履约服务账单->明细->缴费记录”"
|
2024-09-19 21:28:59 +08:00
|
|
|
|
isShowBottomBorder>
|
|
|
|
|
|
</ai-title>
|
|
|
|
|
|
<template slot="content">
|
|
|
|
|
|
<div class="content">
|
|
|
|
|
|
<ai-search-bar>
|
|
|
|
|
|
<template #left>
|
|
|
|
|
|
<div class="search-item">
|
|
|
|
|
|
<label>缴费完成时间:</label>
|
|
|
|
|
|
<el-date-picker
|
|
|
|
|
|
v-model="searchDate"
|
|
|
|
|
|
type="daterange"
|
|
|
|
|
|
range-separator="至"
|
|
|
|
|
|
start-placeholder="开始时间"
|
|
|
|
|
|
end-placeholder="结束时间">
|
|
|
|
|
|
</el-date-picker>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
</template>
|
|
|
|
|
|
<template #right>
|
|
|
|
|
|
<el-button type="primary" @click="beforeGetList">加载</el-button>
|
|
|
|
|
|
</template>
|
|
|
|
|
|
</ai-search-bar>
|
|
|
|
|
|
<ai-card title="数据概览" style="padding-bottom: 40px;">
|
|
|
|
|
|
<div>
|
|
|
|
|
|
<el-row :gutter="20">
|
|
|
|
|
|
<el-col :span="6">
|
|
|
|
|
|
<div>
|
|
|
|
|
|
<el-statistic
|
|
|
|
|
|
group-separator=","
|
|
|
|
|
|
:precision="2"
|
|
|
|
|
|
:value="totalLogisticFee"
|
|
|
|
|
|
title="物流总费用"
|
|
|
|
|
|
>
|
|
|
|
|
|
</el-statistic>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
</el-col>
|
|
|
|
|
|
<el-col :span="6">
|
|
|
|
|
|
<div>
|
|
|
|
|
|
<el-statistic
|
|
|
|
|
|
title="备货单总数"
|
|
|
|
|
|
:value="totalOrders"
|
|
|
|
|
|
>
|
|
|
|
|
|
</el-statistic>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
</el-col>
|
|
|
|
|
|
<el-col :span="6">
|
|
|
|
|
|
<div>
|
|
|
|
|
|
<el-statistic
|
|
|
|
|
|
title="发货时填写总重量(KG)"
|
|
|
|
|
|
:value="totalWriteWeight"
|
|
|
|
|
|
>
|
|
|
|
|
|
</el-statistic>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
</el-col>
|
|
|
|
|
|
<el-col :span="6">
|
|
|
|
|
|
<div>
|
|
|
|
|
|
<el-statistic
|
|
|
|
|
|
title="最终计费总重量(KG)"
|
|
|
|
|
|
:value="totalFinalWeight"
|
|
|
|
|
|
>
|
|
|
|
|
|
</el-statistic>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
</el-col>
|
|
|
|
|
|
</el-row>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
</ai-card>
|
|
|
|
|
|
<ai-card title="店铺分布" style="padding-bottom: 40px;">
|
|
|
|
|
|
<ai-table
|
|
|
|
|
|
:isShowPagination="false"
|
|
|
|
|
|
:tableData="tableData"
|
|
|
|
|
|
:col-configs="colConfigs"
|
|
|
|
|
|
:total="tableData.length"
|
|
|
|
|
|
height="500"
|
|
|
|
|
|
style="margin-top: 8px;"
|
|
|
|
|
|
@getList="() => {}">
|
|
|
|
|
|
</ai-table>
|
|
|
|
|
|
</ai-card>
|
|
|
|
|
|
<ai-card title="运费分布" style="padding-bottom: 40px;">
|
|
|
|
|
|
<ai-table
|
|
|
|
|
|
:isShowPagination="false"
|
|
|
|
|
|
:tableData="logisticTableData"
|
|
|
|
|
|
:col-configs="logisticColConfigs"
|
|
|
|
|
|
:total="tableData.length"
|
|
|
|
|
|
height="500"
|
|
|
|
|
|
style="margin-top: 8px;"
|
|
|
|
|
|
@getList="() => {}">
|
|
|
|
|
|
</ai-table>
|
|
|
|
|
|
</ai-card>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
</template>
|
|
|
|
|
|
</ai-list>
|
|
|
|
|
|
</template>
|
|
|
|
|
|
|
|
|
|
|
|
<script>
|
|
|
|
|
|
import { Message } from 'element-ui'
|
|
|
|
|
|
import {sendChromeAPIMessage } from '@/api/chromeApi'
|
|
|
|
|
|
|
|
|
|
|
|
export default {
|
|
|
|
|
|
name: 'LogisticFee',
|
|
|
|
|
|
|
|
|
|
|
|
data () {
|
|
|
|
|
|
return {
|
|
|
|
|
|
searchDate: [],
|
|
|
|
|
|
reqData: {
|
|
|
|
|
|
pageNum: 1,
|
|
|
|
|
|
pageSize: 100
|
|
|
|
|
|
},
|
|
|
|
|
|
totalLogisticFee: 0.0,
|
|
|
|
|
|
totalOrders: 0,
|
|
|
|
|
|
totalWriteWeight: 0.0,
|
|
|
|
|
|
totalFinalWeight: 0.0,
|
|
|
|
|
|
colConfigs: [
|
|
|
|
|
|
{ prop: 'mallName', label: '店铺名称', align: 'left' },
|
|
|
|
|
|
{ prop: 'wayBillCount', label: '备货单数', align: 'left', sortable: true, 'sort-method': (a, b) => a.wayBillCount - b.wayBillCount },
|
|
|
|
|
|
{ prop: 'writeWeight', label: '填写重量(KG)', align: 'left', sortable: true, 'sort-method': (a, b) => a.writeWeight - b.writeWeight },
|
|
|
|
|
|
{ prop: 'weight', label: '实际重量(KG)', align: 'left', sortable: true, 'sort-method': (a, b) => a.weight - b.weight },
|
|
|
|
|
|
{ prop: 'amount', label: '物流费用', align: 'left', sortable: true, 'sort-method': (a, b) => a.amount - b.amount }
|
|
|
|
|
|
],
|
|
|
|
|
|
logisticColConfigs: [
|
|
|
|
|
|
{ prop: 'company', label: '物流公司', align: 'left' },
|
|
|
|
|
|
{ prop: 'writeWeight', label: '填写总重量(KG)', align: 'left', sortable: true, 'sort-method': (a, b) => a.writeWeight - b.writeWeight },
|
|
|
|
|
|
{ prop: 'weight', label: '实际总重量(KG)', align: 'left', sortable: true, 'sort-method': (a, b) => a.weight - b.weight },
|
|
|
|
|
|
{ prop: 'amount', label: '物流费用', align: 'left', sortable: true, 'sort-method': (a, b) => a.amount - b.amount }
|
|
|
|
|
|
],
|
|
|
|
|
|
isLoading: false,
|
|
|
|
|
|
tableData: [],
|
|
|
|
|
|
logisticTableData: [],
|
|
|
|
|
|
transList: [],
|
|
|
|
|
|
mallWayBillList: [],
|
|
|
|
|
|
logisticFeeList: []
|
|
|
|
|
|
}
|
|
|
|
|
|
},
|
|
|
|
|
|
methods: {
|
|
|
|
|
|
beforeGetList() {
|
|
|
|
|
|
this.$userCheck().then(() => {
|
|
|
|
|
|
this.toLoad()
|
|
|
|
|
|
}).catch((err) => {
|
|
|
|
|
|
})
|
|
|
|
|
|
},
|
|
|
|
|
|
async toLoad() {
|
|
|
|
|
|
if (!this.searchDate) {
|
|
|
|
|
|
Message.error("请选择时间范围")
|
|
|
|
|
|
return
|
|
|
|
|
|
}
|
|
|
|
|
|
this.reqData.pageNum = 1
|
|
|
|
|
|
this.tableData = []
|
|
|
|
|
|
this.logisticTableData = []
|
|
|
|
|
|
this.isLoading = true
|
|
|
|
|
|
this.totalLogisticFee = 0.0
|
|
|
|
|
|
this.totalOrders = 0
|
|
|
|
|
|
this.totalWriteWeight = 0.0
|
|
|
|
|
|
this.totalFinalWeight = 0.0
|
|
|
|
|
|
this.transList = []
|
|
|
|
|
|
this.mallWayBillList = []
|
|
|
|
|
|
this.logisticFeeList = []
|
|
|
|
|
|
|
|
|
|
|
|
let startTime = this.searchDate[0].getTime()
|
|
|
|
|
|
let endTime = this.searchDate[1].getTime() + 86400000 - 1
|
|
|
|
|
|
await this.getLogisticFee(startTime, endTime)
|
|
|
|
|
|
|
|
|
|
|
|
this.totalLogisticFee = Math.round(this.totalLogisticFee * 100)/100
|
|
|
|
|
|
this.totalFinalWeight = Math.round(this.totalFinalWeight * 100)/100
|
|
|
|
|
|
|
|
|
|
|
|
this.isLoading = false
|
|
|
|
|
|
|
|
|
|
|
|
},
|
|
|
|
|
|
async getLogisticFee(startTime, endTime) {
|
|
|
|
|
|
let res = await sendChromeAPIMessage({
|
|
|
|
|
|
url: `api/merchant/warehouse/express/pay/bill/list`,
|
|
|
|
|
|
needMallId: true,
|
|
|
|
|
|
mallId: this.$store.state.mallList[0].mallId,
|
|
|
|
|
|
data: {
|
|
|
|
|
|
...this.reqData,
|
|
|
|
|
|
sucTimeStart: startTime,
|
|
|
|
|
|
sucTimeEnd: endTime
|
|
|
|
|
|
}})
|
|
|
|
|
|
if (res.errorCode == 1000000) {
|
|
|
|
|
|
for (let i = 0; i < res.result.list.length; i++) {
|
|
|
|
|
|
let item = res.result.list[i]
|
|
|
|
|
|
this.totalLogisticFee += item.amount
|
|
|
|
|
|
|
2024-10-30 09:42:08 +08:00
|
|
|
|
this.transList.push({ptransId: item.ptransId, chargeType: item.chargeType} )
|
2024-09-19 21:28:59 +08:00
|
|
|
|
}
|
|
|
|
|
|
if ((this.reqData.pageSize * this.reqData.pageNum) < res.result.total) {
|
|
|
|
|
|
this.reqData.pageNum ++
|
|
|
|
|
|
await this.getLogisticFee(startTime, endTime)
|
|
|
|
|
|
} else {
|
|
|
|
|
|
await this.getLogisticDetail()
|
|
|
|
|
|
await this.getLogisticWeightDetail()
|
|
|
|
|
|
this.calcLogiticData()
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
},
|
|
|
|
|
|
async getLogisticDetail() {
|
|
|
|
|
|
for (let i = 0; i < this.transList.length; i++) {
|
|
|
|
|
|
let res = await sendChromeAPIMessage({
|
|
|
|
|
|
url: `api/merchant/warehouse/express/pay/bill/detail/list`,
|
|
|
|
|
|
needMallId: true,
|
|
|
|
|
|
mallId: this.$store.state.mallList[0].mallId,
|
|
|
|
|
|
data: {
|
2024-10-30 09:42:08 +08:00
|
|
|
|
chargeType: this.transList[i].chargeType,
|
2024-09-19 21:28:59 +08:00
|
|
|
|
pageSize: 100,
|
|
|
|
|
|
pageNum: 1,
|
2024-10-30 09:42:08 +08:00
|
|
|
|
ptransId: this.transList[i].ptransId
|
2024-09-19 21:28:59 +08:00
|
|
|
|
}})
|
|
|
|
|
|
if (res.errorCode == 1000000) {
|
|
|
|
|
|
for (let k = 0; k < res.result.list.length; k++) {
|
|
|
|
|
|
let item = res.result.list[k]
|
|
|
|
|
|
let flag = false
|
|
|
|
|
|
for (let j = 0; j < this.tableData.length; j++) {
|
|
|
|
|
|
if (this.tableData[j].mallId == item.mallId) {
|
|
|
|
|
|
flag = true
|
|
|
|
|
|
this.tableData[j].amount += item.amount
|
|
|
|
|
|
this.tableData[j].wayBillCount += item.wayBillCount
|
|
|
|
|
|
|
|
|
|
|
|
this.tableData[j].amount = Math.round(this.tableData[j].amount * 100)/100
|
|
|
|
|
|
|
|
|
|
|
|
this.totalOrders += item.wayBillCount
|
|
|
|
|
|
break
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if (!flag) {
|
|
|
|
|
|
this.tableData.push({
|
|
|
|
|
|
mallId: item.mallId,
|
|
|
|
|
|
mallName: item.mallName,
|
|
|
|
|
|
amount: item.amount,
|
|
|
|
|
|
wayBillCount: item.wayBillCount,
|
|
|
|
|
|
weight: 0.0,
|
|
|
|
|
|
writeWeight: 0.0
|
|
|
|
|
|
})
|
|
|
|
|
|
this.totalOrders += item.wayBillCount
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
await this.getWayBillList(item.transId, item.mallId)
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
},
|
|
|
|
|
|
async getWayBillList(transId, mallId) {
|
|
|
|
|
|
let pageNum = 1
|
|
|
|
|
|
let pageSize = 100
|
|
|
|
|
|
while(true) {
|
|
|
|
|
|
let res = await sendChromeAPIMessage({
|
|
|
|
|
|
url: `api/merchant/warehouse/express/bill/detail/list`,
|
|
|
|
|
|
needMallId: true,
|
|
|
|
|
|
mallId: this.$store.state.mallList[0].mallId,
|
|
|
|
|
|
data: {
|
|
|
|
|
|
pageNum: pageNum,
|
|
|
|
|
|
pageSize: pageSize,
|
|
|
|
|
|
billStatus: 2,
|
|
|
|
|
|
mallId: mallId,
|
|
|
|
|
|
transId: transId
|
|
|
|
|
|
}})
|
|
|
|
|
|
if (res.errorCode == 1000000) {
|
|
|
|
|
|
let flag = false
|
|
|
|
|
|
for (let i = 0; i < this.logisticFeeList.length; i++) {
|
|
|
|
|
|
if (this.logisticFeeList[i].mallId == mallId) {
|
|
|
|
|
|
flag = true
|
|
|
|
|
|
for (let j = 0; j < res.result.list.length; j++) {
|
|
|
|
|
|
this.logisticFeeList[i].billList.push({
|
|
|
|
|
|
sn: res.result.list[j].mainWayBillSn,
|
|
|
|
|
|
amount: res.result.list[j].amount,
|
|
|
|
|
|
company: null,
|
|
|
|
|
|
waight: 0.0
|
|
|
|
|
|
})
|
|
|
|
|
|
}
|
|
|
|
|
|
break
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if (!flag) {
|
|
|
|
|
|
let temp = {
|
|
|
|
|
|
mallId: mallId,
|
|
|
|
|
|
billList: []
|
|
|
|
|
|
}
|
|
|
|
|
|
for (let j = 0; j < res.result.list.length; j++) {
|
|
|
|
|
|
temp.billList.push({
|
|
|
|
|
|
sn: res.result.list[j].mainWayBillSn,
|
|
|
|
|
|
amount: res.result.list[j].amount,
|
|
|
|
|
|
company: null,
|
|
|
|
|
|
weight: 0.0,
|
|
|
|
|
|
writeWeight: 0.0
|
|
|
|
|
|
})
|
|
|
|
|
|
}
|
|
|
|
|
|
this.logisticFeeList.push(temp)
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if (pageNum * pageSize < res.result.total) {
|
|
|
|
|
|
pageNum ++
|
|
|
|
|
|
} else {
|
|
|
|
|
|
break
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
},
|
|
|
|
|
|
async getLogisticWeightDetail() {
|
|
|
|
|
|
for (let i = 0; i < this.logisticFeeList.length; i++) {
|
|
|
|
|
|
let page = 1
|
|
|
|
|
|
let weight = 0.0
|
|
|
|
|
|
let writeWeight = 0.0
|
|
|
|
|
|
while(true) {
|
|
|
|
|
|
let tempList = []
|
|
|
|
|
|
for (let j = (page-1)*20; j < this.logisticFeeList[i].billList.length; j++) {
|
|
|
|
|
|
tempList.push(this.logisticFeeList[i].billList[j].sn)
|
|
|
|
|
|
|
|
|
|
|
|
if (tempList.length % 20 == 0) {
|
|
|
|
|
|
break
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
if (tempList.length == 0) break
|
|
|
|
|
|
|
|
|
|
|
|
let res = await sendChromeAPIMessage({
|
|
|
|
|
|
url: `bgSongbird-api/supplier/delivery/feedback/queryWaitConfirmWeightExpressList`,
|
|
|
|
|
|
needMallId: true,
|
|
|
|
|
|
mallId: this.logisticFeeList[i].mallId,
|
|
|
|
|
|
anti: true,
|
|
|
|
|
|
data: {
|
|
|
|
|
|
pageNo: 1,
|
|
|
|
|
|
pageSize: 20,
|
|
|
|
|
|
platformExpressMainSnList: tempList,
|
|
|
|
|
|
displayStatus: 100
|
|
|
|
|
|
}})
|
|
|
|
|
|
if (res.errorCode == 1000000) {
|
|
|
|
|
|
for (let ii = 0; ii < res.result.list.length; ii++) {
|
|
|
|
|
|
for (let jj = 0; jj < this.logisticFeeList[i].billList.length; jj++) {
|
|
|
|
|
|
if (this.logisticFeeList[i].billList[jj].sn == res.result.list[ii].expressDeliverySn) {
|
|
|
|
|
|
this.logisticFeeList[i].billList[jj].company = res.result.list[ii].expressCompany
|
|
|
|
|
|
this.logisticFeeList[i].billList[jj].weight = res.result.list[ii].realExpressWeight / 1000
|
|
|
|
|
|
this.logisticFeeList[i].billList[jj].writeWeight = res.result.list[ii].predictTotalPackageWeight / 1000
|
|
|
|
|
|
|
|
|
|
|
|
this.totalFinalWeight += res.result.list[ii].realExpressWeight / 1000
|
|
|
|
|
|
this.totalWriteWeight += res.result.list[ii].predictTotalPackageWeight / 1000
|
|
|
|
|
|
|
|
|
|
|
|
writeWeight += res.result.list[ii].predictTotalPackageWeight / 1000
|
|
|
|
|
|
weight += res.result.list[ii].realExpressWeight / 1000
|
|
|
|
|
|
|
|
|
|
|
|
break
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
page++
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
for (let kk = 0; kk < this.tableData.length; kk++) {
|
|
|
|
|
|
if (this.tableData[kk].mallId == this.logisticFeeList[i].mallId) {
|
|
|
|
|
|
this.tableData[kk].weight = Math.round(weight * 100)/100
|
|
|
|
|
|
this.tableData[kk].writeWeight = Math.round(writeWeight * 100)/100
|
|
|
|
|
|
break
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
},
|
|
|
|
|
|
calcLogiticData() {
|
|
|
|
|
|
for (let i = 0; i < this.logisticFeeList.length; i++) {
|
|
|
|
|
|
for (let j = 0; j < this.logisticFeeList[i].billList.length; j++) {
|
|
|
|
|
|
let flag = false
|
|
|
|
|
|
for (let x = 0; x < this.logisticTableData.length; x++) {
|
|
|
|
|
|
if (this.logisticTableData[x].company == this.logisticFeeList[i].billList[j].company) {
|
|
|
|
|
|
flag = true
|
|
|
|
|
|
this.logisticTableData[x].writeWeight += this.logisticFeeList[i].billList[j].writeWeight
|
|
|
|
|
|
this.logisticTableData[x].weight += this.logisticFeeList[i].billList[j].weight
|
|
|
|
|
|
this.logisticTableData[x].amount += this.logisticFeeList[i].billList[j].amount
|
|
|
|
|
|
break
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
if (!flag) {
|
|
|
|
|
|
console.log(this.logisticFeeList[i].mallId, this.logisticFeeList[i].billList[j], this.logisticFeeList[i].billList[j].company)
|
|
|
|
|
|
this.logisticTableData.push({
|
|
|
|
|
|
company: this.logisticFeeList[i].billList[j].company,
|
|
|
|
|
|
writeWeight: this.logisticFeeList[i].billList[j].writeWeight,
|
|
|
|
|
|
weight: this.logisticFeeList[i].billList[j].weight,
|
|
|
|
|
|
amount: this.logisticFeeList[i].billList[j].amount,
|
|
|
|
|
|
weightPercent: 0.0,
|
|
|
|
|
|
amountPercent: 0.0
|
|
|
|
|
|
})
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
for (let j = 0; j < this.logisticTableData.length; j++) {
|
|
|
|
|
|
this.logisticTableData[j].weight = Math.round(this.logisticTableData[j].weight * 100)/100
|
|
|
|
|
|
this.logisticTableData[j].amount = Math.round(this.logisticTableData[j].amount * 100)/100
|
|
|
|
|
|
|
|
|
|
|
|
this.logisticTableData[j].company = this.logisticTableData[j].company || '退回服务费'
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
</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;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
</style>
|