ai_images/admin-ui/src/views/subteam/consumeStat/index.vue

259 lines
7.4 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>
<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>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span>
<span class="summary-prefix">汇总:</span><span class="summary-muted">加载中…</span>
</template>
<template v-else-if="summaryState.mode === 'empty'">
<span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span>
<span class="summary-prefix">汇总:</span><span class="summary-muted">—</span>
</template>
<template v-else>
<span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</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>