feat(dashboard): add daily and monthly recharge rankings
This commit is contained in:
parent
8e2e3feaca
commit
62632adc7e
@ -80,6 +80,15 @@ export function listDailyUserRechargeTop(dateNumber) {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 用户日/月充值排行榜(服务端分页)
|
||||||
|
export function pageUserRechargeRank(params) {
|
||||||
|
return request({
|
||||||
|
url: '/count/currency/user-recharge-rank/page',
|
||||||
|
method: 'get',
|
||||||
|
params
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
// 最新平台内购情况
|
// 最新平台内购情况
|
||||||
export function latestPurchaseAmountPlatform(areaCode) {
|
export function latestPurchaseAmountPlatform(areaCode) {
|
||||||
return request({
|
return request({
|
||||||
|
|||||||
@ -4199,7 +4199,7 @@ export default {
|
|||||||
dailyGoldAnalysis: 'Daily Gold Analysis',
|
dailyGoldAnalysis: 'Daily Gold Analysis',
|
||||||
dailyGoldSourceTop: 'Daily Gold Source Top',
|
dailyGoldSourceTop: 'Daily Gold Source Top',
|
||||||
userGoldTop: 'User Gold Top 50',
|
userGoldTop: 'User Gold Top 50',
|
||||||
dailyRechargeTop: 'Daily Recharge Top 50'
|
dailyRechargeTop: 'Recharge Ranking'
|
||||||
},
|
},
|
||||||
account: {
|
account: {
|
||||||
accountLabel: 'Account'
|
accountLabel: 'Account'
|
||||||
@ -4332,8 +4332,14 @@ export default {
|
|||||||
},
|
},
|
||||||
rechargeTop: {
|
rechargeTop: {
|
||||||
datePlaceholder: 'Select date',
|
datePlaceholder: 'Select date',
|
||||||
title: 'Recharge Top 50 ({sysOriginName})',
|
monthPlaceholder: 'Select month',
|
||||||
description: 'Same-day total recharge amount, including refunds',
|
platformPlaceholder: 'Select platform',
|
||||||
|
title: 'Recharge Ranking ({sysOriginName})',
|
||||||
|
descriptionDaily: 'Recharge total from 08:00 on the selected day to 08:00 the next day, including refunds',
|
||||||
|
descriptionMonthly: 'Net recharge total for the selected month, with refunds deducted',
|
||||||
|
daily: 'Daily',
|
||||||
|
monthly: 'Monthly',
|
||||||
|
rank: 'Rank',
|
||||||
user: 'User',
|
user: 'User',
|
||||||
amount: 'Amount'
|
amount: 'Amount'
|
||||||
},
|
},
|
||||||
|
|||||||
@ -4196,7 +4196,7 @@ export default {
|
|||||||
dailyGoldAnalysis: '每日金币(分析)',
|
dailyGoldAnalysis: '每日金币(分析)',
|
||||||
dailyGoldSourceTop: '每日金币(来源榜)',
|
dailyGoldSourceTop: '每日金币(来源榜)',
|
||||||
userGoldTop: '用户金币(Top50)',
|
userGoldTop: '用户金币(Top50)',
|
||||||
dailyRechargeTop: '每日充值(Top50)'
|
dailyRechargeTop: '充值排行榜'
|
||||||
},
|
},
|
||||||
account: {
|
account: {
|
||||||
accountLabel: '账号'
|
accountLabel: '账号'
|
||||||
@ -4329,8 +4329,14 @@ export default {
|
|||||||
},
|
},
|
||||||
rechargeTop: {
|
rechargeTop: {
|
||||||
datePlaceholder: '选择日期',
|
datePlaceholder: '选择日期',
|
||||||
title: '充值Top50({sysOriginName})',
|
monthPlaceholder: '选择月份',
|
||||||
description: '当日充值总额,包含退款',
|
platformPlaceholder: '选择平台',
|
||||||
|
title: '充值排行榜({sysOriginName})',
|
||||||
|
descriptionDaily: '所选统计日08:00至次日08:00的充值总额,包含退款',
|
||||||
|
descriptionMonthly: '所选月份的净充值总额,退款金额会扣除',
|
||||||
|
daily: '日榜',
|
||||||
|
monthly: '月榜',
|
||||||
|
rank: '排名',
|
||||||
user: '用户',
|
user: '用户',
|
||||||
amount: '金额'
|
amount: '金额'
|
||||||
},
|
},
|
||||||
|
|||||||
@ -1,134 +1,196 @@
|
|||||||
<template>
|
<template>
|
||||||
<div v-loading="loading" class="dily-register-user" :data-language="language">
|
<div v-loading="loading" class="user-recharge-rank" :data-language="language">
|
||||||
|
<div class="query-bar">
|
||||||
|
<el-radio-group v-model="listQuery.periodType" size="mini" @change="changePeriodType">
|
||||||
|
<el-radio-button label="DAILY">{{ $t('pages.dashboard.rechargeTop.daily') }}</el-radio-button>
|
||||||
|
<el-radio-button label="MONTHLY">{{ $t('pages.dashboard.rechargeTop.monthly') }}</el-radio-button>
|
||||||
|
</el-radio-group>
|
||||||
|
|
||||||
|
<el-select
|
||||||
|
v-model="listQuery.sysOrigin"
|
||||||
|
size="mini"
|
||||||
|
:placeholder="$t('pages.dashboard.rechargeTop.platformPlaceholder')"
|
||||||
|
@change="handleSearch"
|
||||||
|
>
|
||||||
|
<el-option
|
||||||
|
v-for="item in permissionsSysOriginPlatformAlls"
|
||||||
|
:key="item.value"
|
||||||
|
:label="item.name"
|
||||||
|
:value="item.value"
|
||||||
|
/>
|
||||||
|
</el-select>
|
||||||
|
|
||||||
<el-date-picker
|
<el-date-picker
|
||||||
v-model="dateNumber"
|
v-if="listQuery.periodType === 'DAILY'"
|
||||||
style="margin-bottom: 10px;"
|
v-model="listQuery.periodNumber"
|
||||||
type="date"
|
type="date"
|
||||||
:placeholder="$t('pages.dashboard.rechargeTop.datePlaceholder')"
|
|
||||||
value-format="yyyyMMdd"
|
value-format="yyyyMMdd"
|
||||||
size="mini"
|
size="mini"
|
||||||
:picker-options="pickerOptions"
|
|
||||||
:clearable="false"
|
:clearable="false"
|
||||||
@change="changeDateNumber"
|
:picker-options="dailyPickerOptions"
|
||||||
|
:placeholder="$t('pages.dashboard.rechargeTop.datePlaceholder')"
|
||||||
|
@change="handleSearch"
|
||||||
|
/>
|
||||||
|
<el-date-picker
|
||||||
|
v-else
|
||||||
|
v-model="listQuery.periodNumber"
|
||||||
|
type="month"
|
||||||
|
value-format="yyyyMM"
|
||||||
|
size="mini"
|
||||||
|
:clearable="false"
|
||||||
|
:picker-options="monthlyPickerOptions"
|
||||||
|
:placeholder="$t('pages.dashboard.rechargeTop.monthPlaceholder')"
|
||||||
|
@change="handleSearch"
|
||||||
/>
|
/>
|
||||||
<div v-for="(item, index) in list" :key="index">
|
|
||||||
<el-card v-if="sysOriginPlatforms.includes(item.sysOrigin)" class="box-card">
|
|
||||||
<div slot="header" class="clearfix">
|
|
||||||
<span>{{ $t('pages.dashboard.rechargeTop.title', { sysOriginName: item.sysOriginName }) }}</span>
|
|
||||||
</div>
|
</div>
|
||||||
<div class="content">
|
|
||||||
<div style="font-size: 12px;color: #666;margin-bottom: 10px;">{{ $t('pages.dashboard.rechargeTop.description') }}</div>
|
<el-card class="box-card">
|
||||||
<el-table
|
<div slot="header" class="clearfix">
|
||||||
:data="item.items"
|
<span>{{ $t('pages.dashboard.rechargeTop.title', { sysOriginName: selectedOriginName }) }}</span>
|
||||||
element-loading-text="Loading"
|
</div>
|
||||||
fit
|
<div class="description">
|
||||||
highlight-current-row
|
{{ listQuery.periodType === 'DAILY'
|
||||||
>
|
? $t('pages.dashboard.rechargeTop.descriptionDaily')
|
||||||
<el-table-column label="No" width="50" align="center">
|
: $t('pages.dashboard.rechargeTop.descriptionMonthly') }}
|
||||||
<template slot-scope="scope">{{ scope.$index + 1 }}</template>
|
</div>
|
||||||
</el-table-column>
|
<el-table :data="list" element-loading-text="Loading" fit highlight-current-row>
|
||||||
<el-table-column :label="$t('pages.dashboard.rechargeTop.user')" prop="roomProfile.roomName" align="center" min-width="200">
|
<el-table-column :label="$t('pages.dashboard.rechargeTop.rank')" width="90" align="center">
|
||||||
<template slot-scope="scope">
|
<template slot-scope="scope">
|
||||||
<user-table-exhibit :user-profile="scope.row.userProfile" :query-details="true" />
|
{{ (listQuery.cursor - 1) * listQuery.limit + scope.$index + 1 }}
|
||||||
</template>
|
</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
<el-table-column :label="$t('pages.dashboard.rechargeTop.amount')" min-width="100" align="center">
|
<el-table-column :label="$t('pages.dashboard.rechargeTop.user')" align="center" min-width="220">
|
||||||
<template slot-scope="scope">
|
<template slot-scope="scope">
|
||||||
<div>{{ scope.row.quantity || 0 }}</div>
|
<user-table-exhibit
|
||||||
|
v-if="scope.row.userProfile"
|
||||||
|
:user-profile="scope.row.userProfile"
|
||||||
|
:query-details="true"
|
||||||
|
/>
|
||||||
|
<span v-else>{{ scope.row.userId }}</span>
|
||||||
</template>
|
</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
|
<el-table-column :label="$t('pages.dashboard.rechargeTop.amount')" min-width="120" align="center">
|
||||||
|
<template slot-scope="scope">{{ scope.row.quantity || 0 }}</template>
|
||||||
|
</el-table-column>
|
||||||
</el-table>
|
</el-table>
|
||||||
</div>
|
|
||||||
|
<pagination
|
||||||
|
v-show="total > 0"
|
||||||
|
:total="total"
|
||||||
|
:page.sync="listQuery.cursor"
|
||||||
|
:limit.sync="listQuery.limit"
|
||||||
|
@pagination="loadRank"
|
||||||
|
/>
|
||||||
</el-card>
|
</el-card>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import { listDailyUserRechargeTop } from '@/api/statistics'
|
import { pageUserRechargeRank } from '@/api/statistics'
|
||||||
import { currencyOrigins } from '@/constant/type'
|
import Pagination from '@/components/Pagination'
|
||||||
import { mapGetters } from 'vuex'
|
import { mapGetters } from 'vuex'
|
||||||
import { formatDate, beforeDateObject } from '@/utils'
|
import { formatDate, beforeDateObject } from '@/utils'
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: 'DilyRegisterUser',
|
name: 'UserRechargeRank',
|
||||||
|
components: { Pagination },
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
pickerOptions: {
|
loading: false,
|
||||||
|
list: [],
|
||||||
|
total: 0,
|
||||||
|
dailyPeriodNumber: formatDate(beforeDateObject(1), 'yyyyMMdd'),
|
||||||
|
monthlyPeriodNumber: formatDate(new Date(), 'yyyyMM'),
|
||||||
|
dailyPickerOptions: {
|
||||||
disabledDate(date) {
|
disabledDate(date) {
|
||||||
return date.getTime() > beforeDateObject(1).getTime()
|
return date.getTime() > beforeDateObject(1).getTime()
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
dateNumber: formatDate(beforeDateObject(new Date().getHours() >= 8 ? 1 : 2), 'yyyyMMdd'),
|
monthlyPickerOptions: {
|
||||||
loading: false,
|
disabledDate(date) {
|
||||||
list: [],
|
const now = new Date()
|
||||||
queryDetailsRow: {},
|
return date.getFullYear() > now.getFullYear() ||
|
||||||
selectOrigin: currencyOrigins[0].value,
|
(date.getFullYear() === now.getFullYear() && date.getMonth() > now.getMonth())
|
||||||
selectOriginName: currencyOrigins[0].name
|
}
|
||||||
|
},
|
||||||
|
listQuery: {
|
||||||
|
cursor: 1,
|
||||||
|
limit: 20,
|
||||||
|
sysOrigin: '',
|
||||||
|
periodType: 'DAILY',
|
||||||
|
periodNumber: ''
|
||||||
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
...mapGetters(['permissionsSysOriginPlatformAlls', 'language']),
|
...mapGetters(['permissionsSysOriginPlatformAlls', 'language']),
|
||||||
sysOriginPlatforms() {
|
selectedOriginName() {
|
||||||
if (!this.permissionsSysOriginPlatformAlls || this.permissionsSysOriginPlatformAlls.length <= 0) {
|
const selected = (this.permissionsSysOriginPlatformAlls || [])
|
||||||
return []
|
.find(item => item.value === this.listQuery.sysOrigin)
|
||||||
}
|
return selected ? selected.name : this.listQuery.sysOrigin
|
||||||
return this.permissionsSysOriginPlatformAlls.map(item => item.value)
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
created() {
|
created() {
|
||||||
this.loadOrigin()
|
const firstOrigin = (this.permissionsSysOriginPlatformAlls || [])[0]
|
||||||
|
if (!firstOrigin) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
this.listQuery.sysOrigin = firstOrigin.value
|
||||||
|
this.listQuery.periodNumber = this.dailyPeriodNumber
|
||||||
|
this.loadRank()
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
loadOrigin() {
|
changePeriodType(periodType) {
|
||||||
|
// 分别保留日榜和月榜的选择值,切换周期时不会把 yyyyMMdd 错当成 yyyyMM 提交。
|
||||||
|
this.listQuery.periodNumber = periodType === 'DAILY'
|
||||||
|
? this.dailyPeriodNumber
|
||||||
|
: this.monthlyPeriodNumber
|
||||||
|
this.handleSearch()
|
||||||
|
},
|
||||||
|
handleSearch() {
|
||||||
|
if (this.listQuery.periodType === 'DAILY') {
|
||||||
|
this.dailyPeriodNumber = this.listQuery.periodNumber
|
||||||
|
} else {
|
||||||
|
this.monthlyPeriodNumber = this.listQuery.periodNumber
|
||||||
|
}
|
||||||
|
this.listQuery.cursor = 1
|
||||||
|
this.loadRank()
|
||||||
|
},
|
||||||
|
loadRank() {
|
||||||
|
if (!this.listQuery.sysOrigin || !this.listQuery.periodNumber) {
|
||||||
|
return
|
||||||
|
}
|
||||||
this.loading = true
|
this.loading = true
|
||||||
listDailyUserRechargeTop(this.dateNumber).then(res => {
|
pageUserRechargeRank(this.listQuery).then(res => {
|
||||||
|
const body = res.body || {}
|
||||||
|
this.list = body.records || []
|
||||||
|
this.total = Number(body.total || 0)
|
||||||
this.loading = false
|
this.loading = false
|
||||||
const { body } = res
|
|
||||||
const list = body || []
|
|
||||||
this.list = list.filter(item => !item.sysOrigin || this.permissionsSysOriginPlatformAlls.some(sys => sys.value === item.sysOrigin))
|
|
||||||
}).catch(() => {
|
}).catch(() => {
|
||||||
this.loading = false
|
this.loading = false
|
||||||
})
|
})
|
||||||
},
|
|
||||||
querySearch(queryString, cb) {
|
|
||||||
const restaurants = currencyOrigins
|
|
||||||
const results = queryString ? restaurants.filter(this.createFilter(queryString)) : restaurants
|
|
||||||
cb(results)
|
|
||||||
},
|
|
||||||
createFilter(queryString) {
|
|
||||||
return restaurant => {
|
|
||||||
return restaurant.value.toLowerCase().indexOf(queryString.toLowerCase()) >= 0 ||
|
|
||||||
restaurant.name.toLowerCase().indexOf(queryString.toLowerCase()) >= 0
|
|
||||||
}
|
|
||||||
},
|
|
||||||
handleSelect(item) {
|
|
||||||
const selectedItem = item || currencyOrigins[0]
|
|
||||||
this.selectOrigin = selectedItem.value
|
|
||||||
this.selectOriginName = selectedItem.name
|
|
||||||
this.loadOrigin()
|
|
||||||
},
|
|
||||||
changeDateNumber() {
|
|
||||||
this.loadOrigin()
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style scoped lang="scss">
|
<style scoped lang="scss">
|
||||||
|
.user-recharge-rank {
|
||||||
|
.query-bar {
|
||||||
|
display: flex;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
gap: 10px;
|
||||||
|
margin-bottom: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
.box-card {
|
.box-card {
|
||||||
margin-bottom: 10px;
|
|
||||||
padding: 10px;
|
padding: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
.card-col {
|
.description {
|
||||||
margin-bottom: 10px;
|
margin-bottom: 10px;
|
||||||
}
|
color: #666;
|
||||||
}
|
font-size: 12px;
|
||||||
|
|
||||||
.register-logout-count {
|
|
||||||
.date {
|
|
||||||
font-weight: bold;
|
|
||||||
line-height: 30px;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user