259 lines
7.4 KiB
Vue
259 lines
7.4 KiB
Vue
<template>
|
||
<div class="app-container">
|
||
<el-form :model="queryParams" ref="queryForm" size="small" :inline="true" v-show="showSearch" label-width="96px">
|
||
<el-form-item label="统计日期">
|
||
<el-date-picker
|
||
v-model="dateRange"
|
||
type="daterange"
|
||
unlink-panels
|
||
value-format="yyyy-MM-dd"
|
||
range-separator="至"
|
||
start-placeholder="开始日期"
|
||
end-placeholder="结束日期"
|
||
style="width: 280px"
|
||
/>
|
||
</el-form-item>
|
||
<el-form-item>
|
||
<el-button type="primary" icon="el-icon-search" size="mini" @click="handleQuery">搜索</el-button>
|
||
<el-button icon="el-icon-refresh" size="mini" @click="resetQuery">重置</el-button>
|
||
<el-button
|
||
type="warning"
|
||
plain
|
||
icon="el-icon-download"
|
||
size="mini"
|
||
@click="handleExport"
|
||
v-hasPermi="['subteam:consume:export']"
|
||
>导出</el-button>
|
||
<right-toolbar :showSearch.sync="showSearch" @queryTable="getList"></right-toolbar>
|
||
</el-form-item>
|
||
</el-form>
|
||
|
||
<p class="summary-line">
|
||
<template v-if="summaryState.mode === 'loading'">
|
||
<span> </span>
|
||
<span class="summary-prefix">汇总:</span><span class="summary-muted">加载中…</span>
|
||
</template>
|
||
<template v-else-if="summaryState.mode === 'empty'">
|
||
<span> </span>
|
||
<span class="summary-prefix">汇总:</span><span class="summary-muted">—</span>
|
||
</template>
|
||
<template v-else>
|
||
<span> </span>
|
||
<span class="summary-prefix">汇总:</span>
|
||
<span class="summary-label">总计</span>
|
||
<span class="summary-num">{{ summaryState.totalStr }}</span>
|
||
<span class="summary-label">条记录,实际充值积分</span>
|
||
<span class="summary-num">{{ summaryState.recharge }}</span>
|
||
<span class="summary-unit">分</span>
|
||
<span class="summary-label">,消耗积分</span>
|
||
<span class="summary-num">{{ summaryState.score }}</span>
|
||
<span class="summary-unit">分</span>
|
||
<span class="summary-label">,实际订单数量(成功)</span>
|
||
<span class="summary-num">{{ summaryState.orders }}</span>
|
||
<span class="summary-unit">单</span>
|
||
<span class="summary-label">,三方消耗tokens数量</span>
|
||
<span class="summary-num">{{ summaryState.tokens }}</span>
|
||
<span class="summary-unit">。</span>
|
||
</template>
|
||
</p>
|
||
|
||
<el-table v-loading="loading" :data="dataList">
|
||
<el-table-column label="日期" align="center" prop="dateKey" min-width="110" />
|
||
<el-table-column
|
||
label="实际充值积分(充值-退款)"
|
||
align="center"
|
||
prop="rechargeScore"
|
||
min-width="200"
|
||
:formatter="formatWesternNumber"
|
||
/>
|
||
<el-table-column label="消耗积分" align="center" prop="score" width="120" :formatter="formatWesternNumber" />
|
||
<el-table-column
|
||
label="实际订单数量(成功)"
|
||
align="center"
|
||
prop="orderCount"
|
||
width="160"
|
||
:formatter="formatWesternNumber"
|
||
/>
|
||
<el-table-column
|
||
label="三方消耗tokens数量"
|
||
align="center"
|
||
prop="useTokens"
|
||
width="170"
|
||
:formatter="formatWesternNumber"
|
||
/>
|
||
</el-table>
|
||
|
||
<pagination
|
||
v-show="total>0"
|
||
:total="total"
|
||
:page.sync="queryParams.pageNum"
|
||
:limit.sync="queryParams.pageSize"
|
||
@pagination="getList"
|
||
/>
|
||
</div>
|
||
</template>
|
||
|
||
<script>
|
||
import { listSubteamConsumeStat, subteamConsumeStatExportUrl } from '@/api/subteam'
|
||
|
||
export default {
|
||
name: 'SubteamConsumeStat',
|
||
data() {
|
||
return {
|
||
loading: false,
|
||
showSearch: true,
|
||
total: 0,
|
||
dataList: [],
|
||
aggregate: null,
|
||
dateRange: [],
|
||
queryParams: {
|
||
pageNum: 1,
|
||
pageSize: 10,
|
||
startDate: null,
|
||
endDate: null
|
||
}
|
||
}
|
||
},
|
||
created() {
|
||
this.initDefaultDateRange()
|
||
this.syncDateRangeToQuery()
|
||
this.getList()
|
||
},
|
||
computed: {
|
||
summaryState() {
|
||
if (this.loading) {
|
||
return { mode: 'loading' }
|
||
}
|
||
const a = this.aggregate
|
||
if (!a) {
|
||
return { mode: 'empty' }
|
||
}
|
||
const fmt = (v) => this.formatWesternNumberValue(v)
|
||
const n = a.totalRows != null ? Number(a.totalRows) : 0
|
||
const totalStr = Number.isNaN(n) ? '0' : n.toLocaleString('en-US')
|
||
return {
|
||
mode: 'ok',
|
||
totalStr,
|
||
recharge: fmt(a.sumRechargeScore),
|
||
score: fmt(a.sumScore),
|
||
orders: fmt(a.sumOrderCount),
|
||
tokens: fmt(a.sumUseTokens)
|
||
}
|
||
}
|
||
},
|
||
methods: {
|
||
formatWesternNumberValue(cellValue) {
|
||
if (cellValue === null || cellValue === undefined || cellValue === '') {
|
||
return (0).toLocaleString('en-US')
|
||
}
|
||
const n = Number(cellValue)
|
||
if (Number.isNaN(n)) {
|
||
return (0).toLocaleString('en-US')
|
||
}
|
||
return n.toLocaleString('en-US')
|
||
},
|
||
formatWesternNumber(row, column, cellValue) {
|
||
return this.formatWesternNumberValue(cellValue)
|
||
},
|
||
buildLastMonthDateRange() {
|
||
const end = new Date()
|
||
const start = new Date(end.getTime())
|
||
start.setMonth(start.getMonth() - 1)
|
||
return [this.formatYmd(start), this.formatYmd(end)]
|
||
},
|
||
formatYmd(d) {
|
||
const y = d.getFullYear()
|
||
const m = String(d.getMonth() + 1).padStart(2, '0')
|
||
const day = String(d.getDate()).padStart(2, '0')
|
||
return `${y}-${m}-${day}`
|
||
},
|
||
initDefaultDateRange() {
|
||
this.dateRange = this.buildLastMonthDateRange()
|
||
},
|
||
syncDateRangeToQuery() {
|
||
if (Array.isArray(this.dateRange) && this.dateRange.length === 2) {
|
||
this.queryParams.startDate = this.dateRange[0]
|
||
this.queryParams.endDate = this.dateRange[1]
|
||
} else {
|
||
this.queryParams.startDate = null
|
||
this.queryParams.endDate = null
|
||
}
|
||
},
|
||
getList() {
|
||
this.syncDateRangeToQuery()
|
||
this.loading = true
|
||
listSubteamConsumeStat(this.queryParams)
|
||
.then(response => {
|
||
this.dataList = response.rows || []
|
||
this.total = response.total != null ? response.total : 0
|
||
this.aggregate =
|
||
response.param && response.param.aggregate != null ? response.param.aggregate : null
|
||
})
|
||
.finally(() => {
|
||
this.loading = false
|
||
})
|
||
},
|
||
handleQuery() {
|
||
this.queryParams.pageNum = 1
|
||
this.getList()
|
||
},
|
||
resetQuery() {
|
||
this.initDefaultDateRange()
|
||
this.resetForm('queryForm')
|
||
this.queryParams.pageNum = 1
|
||
this.syncDateRangeToQuery()
|
||
this.getList()
|
||
},
|
||
handleExport() {
|
||
this.syncDateRangeToQuery()
|
||
this.download(
|
||
subteamConsumeStatExportUrl,
|
||
{
|
||
startDate: this.queryParams.startDate,
|
||
endDate: this.queryParams.endDate
|
||
},
|
||
`team_consume_${new Date().getTime()}.xlsx`
|
||
)
|
||
}
|
||
}
|
||
}
|
||
</script>
|
||
|
||
<style scoped>
|
||
.summary-line {
|
||
color: #606266;
|
||
font-size: 13px;
|
||
margin: 0 0 12px 0;
|
||
padding-left: 8px;
|
||
line-height: 1.75;
|
||
}
|
||
|
||
.summary-prefix {
|
||
color: #909399;
|
||
font-weight: 600;
|
||
margin-right: 2px;
|
||
}
|
||
|
||
.summary-muted {
|
||
color: #c0c4cc;
|
||
}
|
||
|
||
.summary-label {
|
||
color: #606266;
|
||
}
|
||
|
||
.summary-unit {
|
||
color: #909399;
|
||
font-size: 12px;
|
||
margin-left: 1px;
|
||
margin-right: 1px;
|
||
}
|
||
|
||
.summary-num {
|
||
color: #409eff;
|
||
font-weight: 600;
|
||
font-variant-numeric: tabular-nums;
|
||
margin: 0 2px;
|
||
}
|
||
</style>
|