You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
846 lines
25 KiB
846 lines
25 KiB
<template>
|
|
<div class="graph">
|
|
<el-card style="width:100%;" class="graph-card">
|
|
<div>
|
|
<el-tabs v-model="activeTab" @tab-change="handleTabChange">
|
|
<el-tab-pane :label="t('workbench.coinRecharge')" name="recharge"></el-tab-pane>
|
|
<el-tab-pane :label="t('workbench.coinConsume')" name="consume"></el-tab-pane>
|
|
</el-tabs>
|
|
</div>
|
|
<div class="condition">
|
|
<div class="stats">
|
|
<div v-if="activeTab === 'consume'">{{ t('workbench.total') }} {{ sumConsume / 100 }}</div>
|
|
{{ t('workbench.permanentGold') }}:{{ activeTab === 'recharge' ? sumRechargePermanent / 100 : sumConsumePermanent / 100 }}
|
|
{{ t('workbench.freeGold') }}:{{ activeTab === 'recharge' ? sumRechargeFree / 100 : sumConsumeFree / 100 }}
|
|
{{ t('workbench.taskGold') }}:{{ activeTab === 'recharge' ? sumRechargeTask / 100 : sumConsumeTask / 100 }}
|
|
</div>
|
|
<div style="display: flex">
|
|
<el-button
|
|
:style="{ backgroundColor: activeTimeRange === 'yes' ? '#2741DE' : '#E5EBFE', color: activeTimeRange === 'yes' ? 'white' : '#666' }"
|
|
@click="getYes()" size="default">{{ t('workbench.yesterday') }}
|
|
</el-button>
|
|
<el-button
|
|
:style="{ backgroundColor: activeTimeRange === 'today' ? '#2741DE' : '#E5EBFE', color: activeTimeRange === 'today' ? 'white' : '#666' }"
|
|
@click="getToday()" size="default">{{ t('workbench.today') }}
|
|
</el-button>
|
|
<el-button
|
|
:style="{ backgroundColor: activeTimeRange === 'week' ? '#2741DE' : '#E5EBFE', color: activeTimeRange === 'week' ? 'white' : '#666' }"
|
|
@click="getWeek()" size="default">{{ t('workbench.thisWeek') }}
|
|
</el-button>
|
|
<el-button
|
|
:style="{ backgroundColor: activeTimeRange === 'month' ? '#2741DE' : '#E5EBFE', color: activeTimeRange === 'month' ? 'white' : '#666' }"
|
|
@click="getMonth()" size="default">{{ t('workbench.thisMonth') }}
|
|
</el-button>
|
|
<el-button
|
|
:style="{ backgroundColor: activeTimeRange === 'year' ? '#2741DE' : '#E5EBFE', color: activeTimeRange === 'year' ? 'white' : '#666' }"
|
|
@click="getYear()" size="default">{{ t('workbench.thisYear') }}
|
|
</el-button>
|
|
</div>
|
|
<div style="display: flex">
|
|
<el-date-picker size="small" v-model="dateRange" type="datetimerange" range-separator="→"
|
|
:start-placeholder="t('workbench.startTime')" :end-placeholder="t('workbench.endTime')" format="YYYY-MM-DD HH:mm:ss"
|
|
style="width:20vw;margin-left:0.5vw;" value-format="YYYY-MM-DD HH:mm:ss"
|
|
:default-time="defaultTime"
|
|
:disabled-date="disabledDate" @change="handleDatePickerChange"/>
|
|
<el-button type="primary" size="small" style="margin-left: 0.5vw" @click="getChartData">{{ t('workbench.query') }}</el-button>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="graph-content">
|
|
<div ref="chartRef" class="left"
|
|
v-loading="loading"
|
|
element-loading-background="rgba(122, 122, 122, 0)">
|
|
<!-- 加上loading动画 图表有点慢-->
|
|
</div>
|
|
<div class="right">
|
|
<el-card class="graph-card-list">
|
|
<div class="card-large">{{ t('workbench.gold') }}{{ activeTab === 'recharge' ? t('workbench.recharge') : t('workbench.consume') }}{{ t('workbench.rank') }}</div>
|
|
<el-select popper-class="mySelectStyle" class="card-select" v-model="selectedType"
|
|
style="width: 100%; margin-bottom: 15px">
|
|
<el-option :label="t('workbench.allTypes')" value="all"></el-option>
|
|
<el-option :label="t('workbench.permanentGold')" value="permanent"></el-option>
|
|
<el-option :label="t('workbench.freeGold')" value="free"></el-option>
|
|
<el-option :label="t('workbench.taskGold')" value="task"></el-option>
|
|
</el-select>
|
|
<el-table class="card-table" :data="tableData" height="320px">
|
|
<el-table-column prop="rank" :label="t('workbench.rank')" width="60" align="center"></el-table-column>
|
|
<el-table-column prop="market" :label="t('workbench.region')" align="center">
|
|
<template #default="scope">
|
|
<span>{{ marketMapping[scope.row.market] || scope.row.market }}</span>
|
|
</template>
|
|
</el-table-column>
|
|
<el-table-column prop="coinAmount" :label="t('workbench.goldCount')" align="center">
|
|
<template #default="{ row }">
|
|
{{ row.coinAmount.toLocaleString() }}
|
|
</template>
|
|
</el-table-column>
|
|
</el-table>
|
|
</el-card>
|
|
</div>
|
|
</div>
|
|
</el-card>
|
|
</div>
|
|
</template>
|
|
|
|
<script setup>
|
|
import * as echarts from 'echarts'
|
|
import {onMounted, onUnmounted, ref, watch} from 'vue'
|
|
import API from '@/util/http'
|
|
import {ElMessage} from 'element-plus'
|
|
import dayjs from 'dayjs';
|
|
import utc from 'dayjs-plugin-utc'
|
|
import {marketMapping} from "@/utils/marketMap.js";
|
|
import { useI18n } from 'vue-i18n'
|
|
|
|
const { t } = useI18n()
|
|
|
|
dayjs.extend(utc)
|
|
|
|
const defaultTime = [
|
|
new Date(2000, 1, 1, 0, 0, 0),
|
|
new Date(2000, 2, 1, 23, 59, 59),
|
|
]
|
|
// 加载状态
|
|
const loading = ref(true)
|
|
// 地区数据
|
|
const markets = ref([])
|
|
// 图表相关
|
|
const dateRange = ref([])
|
|
const activeTab = ref('recharge')
|
|
const selectedType = ref('all')
|
|
const tableData = ref([])
|
|
const chartRef = ref(null)
|
|
let chartInstance = null
|
|
// 图表合计数
|
|
const sumRechargePermanent = ref(0)
|
|
const sumRechargeFree = ref(0)
|
|
const sumRechargeTask = ref(0)
|
|
const sumConsumePermanent = ref(0)
|
|
const sumConsumeFree = ref(0)
|
|
const sumConsumeTask = ref(0)
|
|
const sumConsume = ref(0)
|
|
// 用户信息
|
|
const adminData = ref({})
|
|
// 卡片数据相关
|
|
const currentGold = ref(0)
|
|
const dailyChange = ref(0)
|
|
const currentPermanent = ref(0)
|
|
const currentFree = ref(0)
|
|
const currentFreeJune = ref(0)
|
|
const currentFreeDecember = ref(0)
|
|
const currentTask = ref(0)
|
|
const yearlyRecharge = ref(0)
|
|
const yearlyMoney = ref(0)
|
|
const recharge = ref(0)
|
|
const money = ref(0)
|
|
const yearlyReduce = ref(0)
|
|
const yearlyConsume = ref(0)
|
|
const yearlyRefund = ref(0)
|
|
const dailyReduce = ref(0)
|
|
const dailyConsume = ref(0)
|
|
const dailyRefund = ref(0)
|
|
const yearlyRechargeNum = ref(0)
|
|
const sumWow = ref(0)
|
|
const sumDaily = ref(0)
|
|
const rechargeNum = ref(0)
|
|
const ydayRechargeNum = ref(0)
|
|
const firstRecharge = ref(0)
|
|
const length = ref(0)
|
|
// 加载状态
|
|
const chartLoading = ref(true)
|
|
|
|
const handleResize = () => {
|
|
if (chartInstance.value) {
|
|
try {
|
|
chartInstance.value.resize()
|
|
console.log('resize一下')
|
|
} catch (error) {
|
|
console.error('图表resize失败:', error)
|
|
}
|
|
}
|
|
}
|
|
// 初始化图表
|
|
const initChart = () => {
|
|
if (!chartInstance && chartRef.value) {
|
|
chartInstance = echarts.init(chartRef.value)
|
|
window.addEventListener('resize', handleResize)
|
|
}
|
|
}
|
|
// 销毁图表
|
|
const destroyChart = () => {
|
|
if (chartInstance.value) {
|
|
try {
|
|
chartInstance.value.dispose()
|
|
} catch (error) {
|
|
console.error('图表销毁失败:', error)
|
|
}
|
|
chartInstance.value = null
|
|
}
|
|
window.removeEventListener('resize', handleResize)
|
|
}
|
|
const formatDate = function (date) {
|
|
const year = date.getFullYear();
|
|
const month = String(date.getMonth() + 1).padStart(2, '0');
|
|
const day = String(date.getDate()).padStart(2, '0');
|
|
const hours = String(date.getHours()).padStart(2, '0');
|
|
const minutes = String(date.getMinutes()).padStart(2, '0');
|
|
const seconds = String(date.getSeconds()).padStart(2, '0');
|
|
return `${year}-${month}-${day} ${hours}:${minutes}:${seconds}`;
|
|
}
|
|
// 昨天
|
|
const getYes = function () {
|
|
const yesterday = dayjs().subtract(1, 'day')
|
|
const startTime = yesterday.startOf('day').format('YYYY-MM-DD HH:mm:ss')
|
|
const endTime = yesterday.endOf('day').format('YYYY-MM-DD HH:mm:ss')
|
|
dateRange.value = [startTime, endTime]
|
|
console.log('看看dateRange', dateRange.value)
|
|
activeTimeRange.value = 'yes' // 标记当前激活状态
|
|
|
|
getChartData()
|
|
}
|
|
// 今天
|
|
const getToday = function () {
|
|
const today = dayjs()
|
|
const startTime = today.startOf('day').format('YYYY-MM-DD HH:mm:ss')
|
|
const endTime = today.endOf('day').format('YYYY-MM-DD HH:mm:ss')
|
|
// const endTime = today.add(1, 'day').startOf('day').format('YYYY-MM-DD HH:mm:ss')
|
|
dateRange.value = [startTime, endTime]
|
|
console.log('看看dateRange', dateRange.value)
|
|
activeTimeRange.value = 'today' // 标记当前激活状态
|
|
|
|
getChartData()
|
|
}
|
|
// 本周
|
|
const getWeek = function () {
|
|
const today = dayjs();
|
|
// 获取今天是星期几(0是周日,1是周一,...,6是周六)
|
|
const day = today.day();
|
|
|
|
// 计算本周一(如果今天是周一,就取今天;如果是周日,就减6天)
|
|
let monday = today.subtract(day === 0 ? 6 : day - 1, 'day');
|
|
// 计算本周日(如果今天是周日,就取今天;否则就加(7 - day)天)
|
|
let sunday = today.add(day === 0 ? 0 : 7 - day, 'day');
|
|
|
|
// 设置时间为起始和结束
|
|
const startTime = monday.startOf('day').format('YYYY-MM-DD HH:mm:ss');
|
|
const endTime = sunday.endOf('day').format('YYYY-MM-DD HH:mm:ss');
|
|
|
|
dateRange.value = [startTime, endTime];
|
|
console.log('本周时间范围(周一到周日):', dateRange.value);
|
|
activeTimeRange.value = 'week';
|
|
|
|
getChartData();
|
|
};
|
|
// 本月
|
|
const getMonth = function () {
|
|
const today = dayjs()
|
|
const startTime = today.startOf('month').format('YYYY-MM-DD HH:mm:ss')
|
|
// const endTime = today.add(1, 'month').startOf('month').format('YYYY-MM-DD HH:mm:ss')
|
|
const endTime = today.endOf('month').format('YYYY-MM-DD HH:mm:ss')
|
|
dateRange.value = [startTime, endTime]
|
|
console.log('看看dateRange', dateRange.value)
|
|
activeTimeRange.value = 'month' // 标记当前激活状态
|
|
|
|
getChartData()
|
|
}
|
|
// 本年
|
|
const getYear = function () {
|
|
const today = dayjs()
|
|
const startTime = today.startOf('year').format('YYYY-MM-DD HH:mm:ss')
|
|
const endTime = today.endOf('year').format('YYYY-MM-DD HH:mm:ss')
|
|
// const endTime = today.add(1, 'year').startOf('year').format('YYYY-MM-DD HH:mm:ss')
|
|
dateRange.value = [startTime, endTime]
|
|
console.log('看看dateRange', dateRange.value)
|
|
activeTimeRange.value = 'year' // 标记当前激活状态
|
|
|
|
getChartData()
|
|
}
|
|
|
|
// 要加上所有市场的,还有额外计算的(总数 = 永久 + 6月 + 12月 + 免费 + 任务)
|
|
const processData = (data) => {
|
|
const summary = {
|
|
currentGold: 0,
|
|
dailyChange: 0,
|
|
currentPermanent: 0,
|
|
currentFreeJune: 0,
|
|
currentFreeDecember: 0,
|
|
currentTask: 0,
|
|
currentFree: 0,
|
|
recharge: 0,
|
|
money: 0,
|
|
yearlyRecharge: 0,
|
|
yearlyMoney: 0,
|
|
consumePermanent: 0,
|
|
consumeFreeJune: 0,
|
|
consumeFreeDecember: 0,
|
|
consumeTask: 0,
|
|
refundPermanent: 0,
|
|
refundFreeJune: 0,
|
|
refundFreeDecember: 0,
|
|
refundTask: 0,
|
|
dailyReduce: 0,
|
|
yearlyConsume: 0,
|
|
yearlyRefund: 0,
|
|
yearlyReduce: 0,
|
|
rechargeNum: 0,
|
|
ydayRechargeNum: 0,
|
|
firstRecharge: 0,
|
|
sumWow: 0,
|
|
sumDaily: 0,
|
|
yearlyRechargeNum: 0
|
|
}
|
|
|
|
// 遍历市场
|
|
data.marketCards.forEach(market => {
|
|
for (const i in summary) {
|
|
if (market[i] !== undefined && market[i] !== null) { // 其实还应该卡一个number
|
|
summary[i] += market[i]
|
|
}
|
|
}
|
|
})
|
|
|
|
// wow和daily除一下
|
|
length.value = data.markets.length
|
|
console.log(length.value)
|
|
|
|
// 计算昨日新增消费和退款
|
|
const yesterdayConsume = summary.consumePermanent + summary.consumeFreeJune + summary.consumeFreeDecember + summary.consumeTask
|
|
const yesterdayRefund = summary.refundPermanent + summary.refundFreeJune + summary.refundFreeDecember + summary.refundTask
|
|
|
|
// 更新卡片数据
|
|
currentGold.value = summary.currentGold.toFixed(2)
|
|
dailyChange.value = summary.dailyChange.toFixed(2)
|
|
currentPermanent.value = summary.currentPermanent.toFixed(2)
|
|
currentFree.value = summary.currentFree.toFixed(2)
|
|
currentFreeJune.value = summary.currentFreeJune.toFixed(2)
|
|
currentFreeDecember.value = summary.currentFreeDecember.toFixed(2)
|
|
currentTask.value = summary.currentTask.toFixed(2)
|
|
|
|
yearlyRecharge.value = summary.yearlyRecharge.toFixed(2)
|
|
yearlyMoney.value = summary.yearlyMoney.toFixed(2)
|
|
recharge.value = summary.recharge.toFixed(2)
|
|
money.value = summary.money.toFixed(2)
|
|
|
|
yearlyReduce.value = summary.yearlyReduce.toFixed(2)
|
|
yearlyConsume.value = summary.yearlyConsume.toFixed(2)
|
|
yearlyRefund.value = summary.yearlyRefund.toFixed(2)
|
|
dailyReduce.value = summary.dailyReduce.toFixed(2)
|
|
dailyConsume.value = yesterdayConsume.toFixed(2)
|
|
dailyRefund.value = yesterdayRefund.toFixed(2)
|
|
|
|
yearlyRechargeNum.value = summary.yearlyRechargeNum
|
|
|
|
// // 周同比
|
|
// sumWow.value = (marketCards.sumWow / length.value).toFixed(2)
|
|
// // 日环比
|
|
// sumDaily.value = (marketCards.sumDaily / length.value).toFixed(2)
|
|
|
|
// rechargeNum.value = summary.rechargeNum
|
|
ydayRechargeNum.value = summary.ydayRechargeNum
|
|
firstRecharge.value = summary.firstRecharge
|
|
}
|
|
|
|
//无法选择的时间
|
|
const disabledDate = (time) => {
|
|
const limitDate = new Date(2025, 0, 1);
|
|
return time.getTime() < limitDate.getTime();
|
|
}
|
|
|
|
// 获取市场列表
|
|
const getMarkets = async () => {
|
|
console.log("adminData", adminData.value.account)
|
|
try {
|
|
const response = await API({
|
|
url: '/general/adminMarkets',
|
|
data: {
|
|
account: adminData.value.account
|
|
}
|
|
})
|
|
if (Array.isArray(response.data)) {
|
|
// markets.value = response.data.filter(data => data !== "1")
|
|
markets.value = response.data
|
|
console.log('市场列表获取成功:', markets.value)
|
|
} else {
|
|
console.error('获取市场列表失败', response)
|
|
ElMessage.error(t('elmessage.getMarketListFailed'))
|
|
}
|
|
} catch (error) {
|
|
console.error('获取市场列表失败:', error)
|
|
ElMessage.error(t('elmessage.getMarketListFailed'))
|
|
}
|
|
}
|
|
|
|
// 获取图表数据
|
|
const getChartData = async () => {
|
|
try {
|
|
// 校验市场数据到底有没有
|
|
if (!markets.value || markets.value.length === 0) {
|
|
await getMarkets()
|
|
}
|
|
// 本年
|
|
if (!dateRange.value || dateRange.value.length === 0) {
|
|
getYear()
|
|
}
|
|
const params = {
|
|
markets: markets.value,
|
|
startDate: dateRange.value[0],
|
|
endDate: dateRange.value[1]
|
|
};
|
|
|
|
|
|
const response = await API({
|
|
url: '/workbench/getGraph',
|
|
data: params
|
|
})
|
|
console.log('看看params', params)
|
|
if (Array.isArray(response.marketGraphs)) {
|
|
// const filteredGraphs = response.marketGraphs.filter(data => data.market !== "1");
|
|
// 处理图表数据
|
|
processChartData(response.marketGraphs)
|
|
// 处理排名数据
|
|
processRankingData(response.marketGraphs)
|
|
} else {
|
|
console.error('获取图表数据失败:', response)
|
|
ElMessage.error(t('elmessage.getChartDataFailed'))
|
|
}
|
|
} catch (error) {
|
|
console.error('获取图表数据失败:', error)
|
|
ElMessage.error(t('elmessage.getChartDataFailed'))
|
|
}
|
|
}
|
|
// 处理图表数据
|
|
const processChartData = (marketCards) => {
|
|
const chartData = {
|
|
rechargePermanent: [],
|
|
rechargeFree: [],
|
|
rechargeTask: [],
|
|
consumePermanent: [],
|
|
consumeFree: [],
|
|
consumeTask: [],
|
|
sumConsume: []
|
|
}
|
|
// 这是图表的合计数,怎样遍历?????
|
|
const sumRechargePermanent1 = ref(0)
|
|
const sumRechargeFree1 = ref(0)
|
|
const sumRechargeTask1 = ref(0)
|
|
const sumConsumePermanent1 = ref(0)
|
|
const sumConsumeFree1 = ref(0)
|
|
const sumConsumeTask1 = ref(0)
|
|
const sumConsume1 = ref(0)
|
|
|
|
|
|
marketCards.forEach(market => {
|
|
chartData.rechargePermanent.push(market.sumRechargePermanent / 100 || 0)
|
|
chartData.rechargeFree.push(market.sumRechargeFree / 100 || 0)
|
|
chartData.rechargeTask.push(market.sumRechargeTask / 100 || 0)
|
|
chartData.consumePermanent.push(market.sumConsumePermanent / 100 || 0)
|
|
chartData.consumeFree.push(market.sumConsumeFree / 100 || 0)
|
|
chartData.consumeTask.push(market.sumConsumeTask / 100 || 0)
|
|
chartData.sumConsume.push(market.sumConsume / 100 || 0)
|
|
|
|
// 合计数合计数合计数咋算
|
|
sumRechargePermanent1.value += (market.sumRechargePermanent || 0)
|
|
sumRechargeFree1.value += (market.sumRechargeFree || 0)
|
|
//sumRechargeTask1.value += (market.sumRechargeTask || 0)
|
|
sumConsumePermanent1.value += (market.sumConsumePermanent || 0)
|
|
sumConsumeFree1.value += (market.sumConsumeFree || 0)
|
|
sumConsumeTask1.value += (market.sumConsumeTask || 0)
|
|
sumConsume1.value += (market.sumConsume || 0)
|
|
})
|
|
sumRechargePermanent.value = sumRechargePermanent1.value
|
|
sumRechargeFree.value = sumRechargeFree1.value
|
|
sumRechargeTask.value = 0
|
|
sumConsumePermanent.value = sumConsumePermanent1.value
|
|
sumConsumeFree.value = sumConsumeFree1.value
|
|
sumConsumeTask.value = sumConsumeTask1.value
|
|
sumConsume.value = sumConsume1.value
|
|
|
|
updateChart(chartData)
|
|
}
|
|
|
|
const processRankingData = (marketCards) => {
|
|
// 每个市场的总金币数
|
|
const rankingData = marketCards.map(market => {
|
|
let coinAmount = 0;
|
|
if (activeTab.value === 'recharge') {
|
|
// 充值排名
|
|
switch (selectedType.value) {
|
|
case 'all':
|
|
coinAmount = (market.sumRechargePermanent / 100 || 0) + (market.sumRechargeFree / 100 || 0) + (market.sumRechargeTask / 100 || 0);
|
|
break;
|
|
case 'permanent':
|
|
coinAmount = market.sumRechargePermanent / 100 || 0;
|
|
break;
|
|
case 'free':
|
|
coinAmount = market.sumRechargeFree / 100 || 0;
|
|
break;
|
|
case 'task':
|
|
coinAmount = market.sumRechargeTask / 100 || 0;
|
|
break;
|
|
}
|
|
} else {
|
|
// 消费排名
|
|
switch (selectedType.value) {
|
|
case 'all':
|
|
coinAmount = (market.sumConsumePermanent / 100 || 0) + (market.sumConsumeFree / 100 || 0) + (market.sumConsumeTask / 100 || 0);
|
|
break;
|
|
case 'permanent':
|
|
coinAmount = market.sumConsumePermanent / 100 || 0;
|
|
break;
|
|
case 'free':
|
|
coinAmount = market.sumConsumeFree / 100 || 0;
|
|
break;
|
|
case 'task':
|
|
coinAmount = market.sumConsumeTask / 100 || 0;
|
|
break;
|
|
}
|
|
}
|
|
return {
|
|
market: market.market,
|
|
coinAmount: coinAmount
|
|
};
|
|
});
|
|
|
|
// 按金币数量排序
|
|
rankingData.sort((a, b) => b.coinAmount - a.coinAmount);
|
|
|
|
// 排名序号
|
|
tableData.value = rankingData.map((item, index) => ({
|
|
rank: index + 1,
|
|
...item
|
|
}));
|
|
}
|
|
|
|
watch(selectedType, () => {
|
|
getChartData();
|
|
});
|
|
// 更新图表
|
|
const updateChart = (chartData) => {
|
|
if (!chartInstance) {
|
|
initChart()
|
|
}
|
|
chartLoading.value = true
|
|
try {
|
|
let series = []
|
|
let legend = []
|
|
|
|
if (activeTab.value === 'recharge') {
|
|
series = [
|
|
{
|
|
name: t('workbench.permanentGold'),
|
|
type: 'bar',
|
|
stack: 'recharge',
|
|
data: chartData.rechargePermanent,
|
|
itemStyle: {color: '#5470c6'},
|
|
barWidth: 30
|
|
},
|
|
{
|
|
name: t('workbench.freeGold'),
|
|
type: 'bar',
|
|
stack: 'recharge',
|
|
data: chartData.rechargeFree,
|
|
itemStyle: {color: '#91cc75'},
|
|
barWidth: 30
|
|
},
|
|
{
|
|
name: t('workbench.taskGold'),
|
|
type: 'bar',
|
|
stack: 'recharge',
|
|
data: chartData.rechargeTask,
|
|
itemStyle: {color: '#fac858'},
|
|
barWidth: 30
|
|
}
|
|
]
|
|
legend = [t('workbench.permanentGold'), t('workbench.freeGold'), t('workbench.taskGold')]
|
|
} else {
|
|
series = [
|
|
{
|
|
name: t('workbench.permanentGold'),
|
|
type: 'bar',
|
|
stack: 'consume',
|
|
data: chartData.consumePermanent,
|
|
itemStyle: {color: '#5470c6'},
|
|
barWidth: 30
|
|
},
|
|
{
|
|
name: t('workbench.freeGold'),
|
|
type: 'bar',
|
|
stack: 'consume',
|
|
data: chartData.consumeFree,
|
|
itemStyle: {color: '#91cc75'},
|
|
barWidth: 30
|
|
},
|
|
{
|
|
name: t('workbench.taskGold'),
|
|
type: 'bar',
|
|
stack: 'consume',
|
|
data: chartData.consumeTask,
|
|
itemStyle: {color: '#fac858'},
|
|
barWidth: 30
|
|
}
|
|
]
|
|
legend = [t('workbench.permanentGold'), t('workbench.freeGold'), t('workbench.taskGold')]
|
|
}
|
|
|
|
const option = {
|
|
tooltip: {
|
|
trigger: 'axis',
|
|
axisPointer: {
|
|
type: 'shadow'
|
|
},
|
|
formatter: function (params) {
|
|
let result = params[0].name + '<br/>'
|
|
let total = 0;
|
|
params.forEach(param => {
|
|
result += `${param.seriesName}: ${param.value.toLocaleString()}<br/>`;
|
|
total += param.value;
|
|
})
|
|
result += `${t('workbench.all')}${activeTab.value === 'recharge' ? t('workbench.recharge') : t('workbench.consume')}: ${total.toLocaleString()}`;
|
|
return result
|
|
}
|
|
},
|
|
legend: {
|
|
data: legend,
|
|
bottom: 10
|
|
},
|
|
grid: {
|
|
left: '3%',
|
|
right: '4%',
|
|
bottom: '10%',
|
|
containLabel: true
|
|
},
|
|
xAxis: {
|
|
type: 'category',
|
|
data: markets.value,
|
|
axisLabel: {
|
|
interval: 0,
|
|
rotate: 0
|
|
}
|
|
},
|
|
yAxis: {
|
|
type: 'value',
|
|
splitLine: {
|
|
lineStyle: {
|
|
type: 'dashed',
|
|
width: 1,
|
|
color: '#000000'
|
|
}
|
|
},
|
|
axisLabel: {
|
|
formatter: function (value) {
|
|
return value.toLocaleString()
|
|
}
|
|
},
|
|
|
|
},
|
|
series: series,
|
|
// dataZoom: [
|
|
// {
|
|
// type: 'slider',
|
|
// show: true,
|
|
// start: 0,
|
|
// end: 100,
|
|
// maxSpan: 100,
|
|
// minSpan: 100,
|
|
//
|
|
// height: 2,
|
|
// },
|
|
// ]
|
|
}
|
|
|
|
chartInstance.setOption(option)
|
|
} catch (error) {
|
|
console.error('图表更新失败:', error)
|
|
ElMessage.error(t('elmessage.renderChartFailed'))
|
|
} finally {
|
|
setTimeout(() => {
|
|
chartLoading.value = false
|
|
}, 300)
|
|
}
|
|
}
|
|
|
|
// 处理标签切换
|
|
const handleTabChange = () => {
|
|
getChartData()
|
|
console.log('标签切换调用图表')
|
|
}
|
|
|
|
const getAdminData = async function () {
|
|
try {
|
|
const result = await API({url: '/admin/userinfo', data: {}})
|
|
adminData.value = result
|
|
console.log('用户信息', adminData.value)
|
|
} catch (error) {
|
|
console.log('请求失败', error)
|
|
}
|
|
}
|
|
|
|
|
|
// 标记当前激活的时间范围按钮
|
|
const activeTimeRange = ref('')
|
|
// 日期选择器变化时清除按钮激活状态
|
|
const handleDatePickerChange = () => {
|
|
activeTimeRange.value = ''
|
|
}
|
|
|
|
onMounted(async () => {
|
|
await getAdminData()
|
|
await getMarkets()
|
|
getYear()
|
|
window.addEventListener('resize', () => {
|
|
chartInstance.resize()
|
|
})
|
|
})
|
|
onUnmounted(() => {
|
|
destroyChart()
|
|
})
|
|
</script>
|
|
<style scoped lang="scss">
|
|
|
|
/* 整个柱状图的图表样式 */
|
|
.graph {
|
|
.condition {
|
|
width: 100%;
|
|
height: 1%;
|
|
display: flex;
|
|
align-items: center;
|
|
|
|
.stats {
|
|
display: flex;
|
|
align-items: center;
|
|
width: 35vw;
|
|
font-size: 15px;
|
|
}
|
|
}
|
|
|
|
.graph-content {
|
|
flex: 1;
|
|
height: auto;
|
|
display: flex;
|
|
|
|
.left {
|
|
width: 70%;
|
|
height: auto;
|
|
}
|
|
|
|
.right {
|
|
flex: 1;
|
|
padding: 0.5vw 2vh;
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
.card-item {
|
|
width: 25%;
|
|
height: 28vh;
|
|
display: flex;
|
|
flex-direction: column;
|
|
justify-content: center;
|
|
margin-right: 0.25vw;
|
|
}
|
|
|
|
.card-title {
|
|
font-weight: bold;
|
|
margin-bottom: 1vh;
|
|
display: flex;
|
|
justify-content: center;
|
|
align-items: center;
|
|
}
|
|
|
|
.card-large {
|
|
font-weight: bold;
|
|
font-size: 16px;
|
|
text-align: center;
|
|
margin-bottom: 15px;
|
|
|
|
}
|
|
|
|
@keyframes spin {
|
|
0% {
|
|
transform: rotate(0deg);
|
|
}
|
|
|
|
100% {
|
|
transform: rotate(360deg);
|
|
}
|
|
}
|
|
|
|
.graph-card {
|
|
background: #F3FAFF;
|
|
box-shadow: 0 0 8px 0 #00000040;
|
|
}
|
|
|
|
.graph-card-list {
|
|
background: #E7F4FD;
|
|
box-shadow: 0 0 8px 0 #00000040;
|
|
padding: 12px;
|
|
|
|
.card-select {
|
|
:deep(.el-select__wrapper) {
|
|
background-color: #E7F4FD !important;
|
|
box-shadow: 0 0 4px 0 rgba(0, 0, 0, 0.25) !important;
|
|
border: none !important;
|
|
}
|
|
|
|
:deep(.el-select-dropdown) {
|
|
background-color: #E7F4FD !important;
|
|
box-shadow: 0 0 4px 0 rgba(0, 0, 0, 0.25) !important;
|
|
border: none !important;
|
|
}
|
|
}
|
|
|
|
/* 表格整体背景:把表格容器设为卡片背景 */
|
|
:deep(.el-table) {
|
|
background-color: #E7F4FD !important;
|
|
box-shadow: none !important;
|
|
}
|
|
|
|
/* 表头/表体 wrapper 与 table body 单元格 */
|
|
:deep(.el-table__header-wrapper),
|
|
:deep(.el-table__body-wrapper),
|
|
:deep(.el-table__body tr),
|
|
:deep(.el-table__body td) {
|
|
background-color: transparent !important;
|
|
}
|
|
|
|
/* 表头 */
|
|
:deep(.el-table__header th) {
|
|
background-color: #E7F4FD !important;
|
|
}
|
|
|
|
/* 针对表格 body 中的单元格底部边框 */
|
|
:deep(.el-table__body .el-table__cell) {
|
|
border-bottom: 1px solid #BBC0C9 !important;
|
|
}
|
|
|
|
}
|
|
|
|
/* select 列表项 初始颜色 */
|
|
.el-select-dropdown__item {
|
|
background: #ffffff;
|
|
}
|
|
|
|
/* select hover状态*/
|
|
.el-select-dropdown__item:hover {
|
|
border-radius: 8px;
|
|
margin-left: 2px;
|
|
margin-right: 2px;
|
|
background: #E5EBFE;
|
|
height: 32px;
|
|
}
|
|
|
|
/* 选中状态(针对 is-selected 类) */
|
|
.el-select-dropdown__item.is-selected {
|
|
color: #2549E0;
|
|
border-radius: 8px;
|
|
}
|
|
|
|
/* tabs的样式 */
|
|
/* 选中 tab 的文字颜色 */
|
|
:deep(.el-tabs__item.is-active) {
|
|
color: #2741DE !important;
|
|
font-size: 18px;
|
|
font-weight: bold;
|
|
}
|
|
</style>
|