|
|
<script setup> import * as echarts from 'echarts' import { ref, onMounted, reactive, computed } from 'vue' import { VscInfo } from 'vue-icons-plus/vsc' import * as bs from 'vue-icons-plus/bs' import axios, { all } from 'axios' import API from '@/util/http' import moment from 'moment' import * as math from 'mathjs' import { getTime } from 'element-plus/es/components/countdown/src/utils.mjs'
// 变量
// 加载对象
const loading = ref(true) const areaRankLoading = ref(true) // 总览对象
const getSumCoin = ref({}) const statistics = ref({}) // const getYearConsumeCoin = ref({});
// const getDayConsumeCoin = ref({});
// 中间统计图搜索参数
const changeTimeRatio = ref('allDays') const searchTime = ref([])
// 月份柱状图
const getMiddleBarObj = ref({ updateType: 0 }) const getMiddleBarData = ref({}) const middleTotalRecharge = ref(0) const middleTotalFree = ref(0) const middleTotalTask = ref(0) const middleCategory = ref([]) const middleRecharge = ref([]) const middleFree = ref([]) const middleTask = ref([])
// 地区排名
const getAreaRankObj = ref({ updateType: 0 }) const getMediumArea = ref([]) const areaRank = ref([])
// 金币概览
const option3Data = ref([]) const option4Data = ref([]) const option5Data = ref([]) // 四大学科类别占比
const platformData = ref([]) const allData = ref([]) const ERPData = ref([]) const HCData = ref([]) const LinkData = ref([]) const goldData = ref([])
// 重构工作台,第一个方框类别
const oneData = ref([]) const twoData = ref([]) const threeData = ref([])
// 搜索对象
const goldType = ref('全部类型') const platform = ref('全部平台') //默认高亮标签页
const activeName = ref('recharge') // 金币分类选项
const gold = [ { value: '全部类型', label: '全部类型' }, { value: '充值金币', label: '永久金币' }, { value: '免费金币', label: '免费金币' }, { value: '任务金币', label: '任务金币' } ]
const list = ref([]) const token = localStorage.getItem('token') let rechargeBar = null // 方法
// 搜索方法
const get = async function () { try { getAreaRank() getMiddleBar() // 发送POST请求
// const result1 = await API.post(
// "http://54.251.137.151:10702/statistics/getSumCoin",
// {}
// );
const result2 = await API({ url: '/statistics/a', data: {} }) // const result3 = await API.post(
// "http://54.251.137.151:10702/statistics/getYearConsumeCoin",
// {}
// );
// const result4 = await API.post(
// "http://54.251.137.151:10702/statistics/getDayConsumeCoin",
// {}
// );
// const result5 = await API.post(
// "http://192.168.8.93:10010/statistics/getMediumAreaPay",
// {}
// );
// const result6 = await API.post(
// "http://192.168.8.93:10010/statistics/getMediumAreaConsume",
// {}
// );
// const result7 = await API.post(
// "http://192.168.8.93:10010/statistics/getMediuPayCoin",
// {}
// );
// const result8 = await API.post(
// "http://192.168.8.93:10010/statistics/getMediuConsumeCoin",
// {}
// );
const result9 = await API({ url: '/statistics/b', data: {} }) // 重构的工作台
const result10 = await API({ url: '/One/getOne', data: { token: token } }) const result11 = await API({ url: '/One/getTwo', data: { token: token } }) const result12 = await API({ url: '/One/getThree', data: { token: token } }) oneData.value = result10 twoData.value = result11 threeData.value = result12 console.log('oneData', oneData.value)
// 将响应结果存储到响应式数据中
// getSumCoin.value = result1.data;
statistics.value = result2.data // getYearConsumeCoin.value = result3.data;
// getDayConsumeCoin.value = result4.data;
platformData.value = result9.data
// console.log("getSumCoin", getSumCoin.value);
console.log('statistics', statistics.value) // console.log("getYearConsumeCoin", getYearConsumeCoin.value);
// console.log("getDayConsumeCoin", getDayConsumeCoin.value);
console.log('platformData', platformData.value)
option3Data.value = [ { value: Math.abs(twoData.value.rechargegold), name: '永久金币' + ' | ' + formatNum(twoData.value.rechargegold / 100) }, { value: Math.abs(twoData.value.freegold), name: '免费金币' + ' | ' + formatNum(twoData.value.freegold / 100) }, { value: Math.abs(twoData.value.taskgold), name: '任务金币' + ' | ' + formatNum(twoData.value.taskgold / 100) } ]
option4Data.value = [ { value: Math.abs(threeData.value.rechargegold), name: '永久金币' + ' | ' + formatNum(Math.abs(threeData.value.rechargegold / 100)) }, { value: Math.abs(threeData.value.freegold), name: '免费金币' + ' | ' + formatNum(Math.abs(threeData.value.freegold / 100)) }, { value: Math.abs(threeData.value.taskgold), name: '任务金币' + ' | ' + formatNum(Math.abs(threeData.value.taskgold / 100)) } ] console.log('option4Data', option4Data.value)
option5Data.value = [ { value: Math.abs(oneData.value.rechargegold), name: '永久金币' + ' | ' + formatNum(oneData.value.rechargegold / 100) }, { value: Math.abs(oneData.value.freegold), name: '免费金币' + ' | ' + formatNum(oneData.value.freegold / 100) }, { value: Math.abs(oneData.value.taskgold), name: '任务金币' + ' | ' + formatNum(oneData.value.taskgold / 100) } ] console.log('option5Data', option5Data.value) // 平台数据处理
ERPData.value = [ platformData.value.erpsum .filter((item) => item.subject == '第一学科') .map((item) => Math.abs(item.totalERPSum)), platformData.value.erpsum .filter((item) => item.subject == '第二学科') .map((item) => Math.abs(item.totalERPSum)), platformData.value.erpsum .filter((item) => item.subject == '第三学科') .map((item) => Math.abs(item.totalERPSum)), platformData.value.erpsum .filter((item) => item.subject == '第四学科') .map((item) => Math.abs(item.totalERPSum)) ] ERPData.value.forEach((item, index) => item == '' ? (ERPData.value[index] = { value: 0, name: '第' + (index + 1) + '学科' + 0 }) : (ERPData.value[index] = { value: item[0], name: '第' + (index + 1) + '学科' + item[0] }) ) console.log('ERPData', ERPData.value) HCData.value = [ platformData.value.homilyChartSum .filter((item) => item.subject == '第一学科') .map((item) => Math.abs(item.totalHomilyChartSum)), platformData.value.homilyChartSum .filter((item) => item.subject == '第二学科') .map((item) => Math.abs(item.totalHomilyChartSum)), platformData.value.homilyChartSum .filter((item) => item.subject == '第三学科') .map((item) => Math.abs(item.totalHomilyChartSum)), platformData.value.homilyChartSum .filter((item) => item.subject == '第四学科') .map((item) => Math.abs(item.totalHomilyChartSum)) ] HCData.value.forEach((item, index) => item == '' ? (HCData.value[index] = { value: 0, name: '第' + (index + 1) + '学科' + 0 }) : (HCData.value[index] = { value: item[0], name: '第' + (index + 1) + '学科' + item[0] }) ) console.log('HCData', HCData.value) LinkData.value = [ platformData.value.homilyLinkSum .filter((item) => item.subject == '第一学科') .map((item) => Math.abs(item.totalHomilyLinkSum)), platformData.value.homilyLinkSum .filter((item) => item.subject == '第二学科') .map((item) => Math.abs(item.totalHomilyLinkSum)), platformData.value.homilyLinkSum .filter((item) => item.subject == '第三学科') .map((item) => Math.abs(item.totalHomilyLinkSum)), platformData.value.homilyLinkSum .filter((item) => item.subject == '第四学科') .map((item) => Math.abs(item.totalHomilyLinkSum)) ] LinkData.value.forEach((item, index) => item == '' ? (LinkData.value[index] = { value: 0, name: '第' + (index + 1) + '学科' + 0 }) : (LinkData.value[index] = { value: item[0], name: '第' + (index + 1) + '学科' + item[0] }) ) console.log('LinkData', LinkData.value) goldData.value = [ platformData.value.coinSystemSum .filter((item) => item.subject == '第一学科') .map((item) => Math.abs(item.totalCoinSystemSum)), platformData.value.coinSystemSum .filter((item) => item.subject == '第二学科') .map((item) => Math.abs(item.totalCoinSystemSum)), platformData.value.coinSystemSum .filter((item) => item.subject == '第三学科') .map((item) => Math.abs(item.totalCoinSystemSum)), platformData.value.coinSystemSum .filter((item) => item.subject == '第四学科') .map((item) => Math.abs(item.totalCoinSystemSum)) ] goldData.value.forEach((item, index) => item == '' ? (goldData.value[index] = { value: 0, name: '第' + (index + 1) + '学科' + 0 }) : (goldData.value[index] = { value: item[0], name: '第' + (index + 1) + '学科' + item[0] }) ) console.log('goldData', goldData.value) allData.value = [ { value: Number(ERPData.value[0].value) + Number(HCData.value[0].value) + Number(LinkData.value[0].value) + Number(goldData.value[0].value), name: '第一学科' + (Number(ERPData.value[0].value) + Number(HCData.value[0].value) + Number(LinkData.value[0].value) + Number(goldData.value[0].value)) }, { value: Number(ERPData.value[1].value) + Number(HCData.value[1].value) + Number(LinkData.value[1].value) + Number(goldData.value[1].value), name: '第二学科' + (Number(ERPData.value[1].value) + Number(HCData.value[1].value) + Number(LinkData.value[1].value) + Number(goldData.value[1].value)) }, { value: Number(ERPData.value[2].value) + Number(HCData.value[2].value) + Number(LinkData.value[2].value) + Number(goldData.value[2].value), name: '第三学科' + (Number(ERPData.value[2].value) + Number(HCData.value[2].value) + Number(LinkData.value[2].value) + Number(goldData.value[2].value)) }, { value: Number(ERPData.value[3].value) + Number(HCData.value[3].value) + Number(LinkData.value[3].value) + Number(goldData.value[3].value), name: '第四学科' + (Number(ERPData.value[3].value) + Number(HCData.value[3].value) + Number(LinkData.value[3].value) + Number(goldData.value[3].value)) } ]
loading.value = false
console.log('allData', allData.value) } catch (error) { console.log('请求失败', error) loading.value = false // 在这里可以处理错误逻辑,比如显示错误提示等
} } // 获取中间柱状图数据
const getMiddleBar = async function () { const result = await API({ url: '/statistics/getCoinTime', data: getMiddleBarObj.value })
getMiddleBarData.value = result.data console.log('getMiddleBarData', getMiddleBarData.value)
// 柱状图数据处理
middleCategory.value = getMiddleBarData.value.map((item) => item.day == null ? item.month : item.day.substring(5, 10) ) middleRecharge.value = getMiddleBarData.value.map((item) => Math.abs(item.rechargeSumCoin) ) middleFree.value = getMiddleBarData.value.map((item) => Math.abs(item.freeSumCoin) ) middleTask.value = getMiddleBarData.value.map((item) => Math.abs(item.taskSumCoin) ) middleTotalRecharge.value = 0 middleTotalFree.value = 0 middleTotalTask.value = 0 middleRecharge.value.forEach((number) => { middleTotalRecharge.value = math.add( math.bignumber(middleTotalRecharge.value), math.bignumber(number) ) }) middleFree.value.forEach((number) => { middleTotalFree.value = math.add( math.bignumber(middleTotalFree.value), math.bignumber(number) ) }) middleTask.value.forEach((number) => { middleTotalTask.value = math.add( math.bignumber(middleTotalTask.value), math.bignumber(number) ) })
console.log('middleCategory', middleCategory.value) console.log('middleRecharge', middleRecharge.value) console.log('middleFree', middleFree.value) console.log('middleTask', middleTask.value) console.log('middleTotalRecharge', middleTotalRecharge.value) console.log('middleTotalFree', middleTotalFree.value) console.log('middleTotalTask', middleTotalTask.value)
if (getMiddleBarObj.value.updateType == 0) { // 基于准备好的dom,初始化echarts实例
updateChart() // var recharge = echarts.init(document.getElementById('recharge'))
// const option = {
// tooltip: {
// trigger: 'axis',
// axisPointer: {
// type: 'shadow'
// },
// formatter: function (params) {
// let total = 0
// let content = `${params[0].name}<br/>`
// params.forEach((param) => {
// content += `${param.seriesName}: ${param.value}<br/>`
// total += param.value
// })
// content += `总和: ${total}`
// return content
// }
// },
// legend: {
// right: '-5%',
// orient: 'vertical'
// },
// grid: {
// left: '3%',
// right: '4%',
// bottom: '3%',
// containLabel: true
// },
// xAxis: {
// type: 'category',
// data: middleCategory.value
// },
// yAxis: {
// type: 'value'
// },
// series: [
// {
// name: '永久金币',
// color: '#35e383',
// type: 'bar',
// stack: 'total',
// label: {
// show: false
// },
// emphasis: {
// focus: 'series'
// },
// data: middleRecharge.value
// },
// {
// name: '免费金币',
// color: '#5f8ff5',
// type: 'bar',
// stack: 'total',
// label: {
// show: false
// },
// emphasis: {
// focus: 'series'
// },
// data: middleFree.value
// },
// {
// name: '任务金币',
// color: '#ffe733',
// type: 'bar',
// stack: 'total',
// label: {
// show: false
// },
// emphasis: {
// focus: 'series'
// },
// data: middleTask.value
// }
// ]
// }
// // 使用刚指定的配置项和数据显示图表。
// recharge.setOption(option)
} else { // 基于准备好的dom,初始化echarts实例
var consume = echarts.init(document.getElementById('consume')) const option = { tooltip: { trigger: 'axis', axisPointer: { type: 'shadow' }, formatter: function (params) { let total = 0 let content = `${params[0].name}<br/>` params.forEach((param) => { content += `${param.seriesName}: ${param.value}<br/>` total += param.value }) content += `总和: ${total}` return content } }, legend: { right: '-5%', orient: 'vertical' }, grid: { left: '3%', right: '4%', bottom: '3%', containLabel: true }, xAxis: { type: 'category', data: middleCategory.value }, yAxis: { type: 'value' }, series: [ { name: '永久金币', color: '#35e383', type: 'bar', stack: 'total', label: { show: false }, emphasis: { focus: 'series' }, data: middleRecharge.value }, { name: '免费金币', color: '#5f8ff5', type: 'bar', stack: 'total', label: { show: false }, emphasis: { focus: 'series' }, data: middleFree.value }, { name: '任务金币', color: '#ffe733', type: 'bar', stack: 'total', label: { show: false }, emphasis: { focus: 'series' }, data: middleTask.value } ] } // 使用刚指定的配置项和数据显示图表。
consume.setOption(option) } }
// 获取门店排名
const getAreaRank = async function () { const result = await API({ url: '/statistics/getMee', data: getAreaRankObj.value })
getMediumArea.value = result.data
console.log('getMediumArea', getMediumArea.value)
if (getAreaRankObj.value.type == '充值金币') { areaRank.value = getMediumArea.value.map((item) => ({ value: Math.abs(item.rechargeSumCoin).toFixed(2), name: item.area })) } else if (getAreaRankObj.value.type == '免费金币') { areaRank.value = getMediumArea.value.map((item) => ({ value: Math.abs(item.freeSumCoin).toFixed(2), name: item.area })) } else if (getAreaRankObj.value.type == '任务金币') { areaRank.value = getMediumArea.value.map((item) => ({ value: Math.abs(item.taskSumCoin).toFixed(2), name: item.area })) } else { areaRank.value = getMediumArea.value.map((item) => ({ value: Math.abs(item.totalRechargeSum).toFixed(2), name: item.area })) } areaRank.value.sort((a, b) => b.value - a.value) areaRankLoading.value = false console.log('areaRank', areaRank.value) }
// 金币类型
const findBsComponent = function (index) { let iconName if (index < 3) { iconName = `bs.Bs${index + 1}CircleFill` // 根据index拼接图标名称
} else { iconName = `bs.Bs${index + 1}Circle` // 根据index拼接图标名称
} return eval(iconName) // 动态执行图标名称,返回图标组件
} // 门店排名下拉框
const changeGoldType = function () { console.log('changeGoldType', goldType.value) if (goldType.value == '全部类型') { getAreaRankObj.value.type = '' } else if (goldType.value == '充值金币') { getAreaRankObj.value.type = '充值金币' } else if (goldType.value == '免费金币') { getAreaRankObj.value.type = '免费金币' } else if (goldType.value == '任务金币') { getAreaRankObj.value.type = '任务金币' } areaRankLoading.value = true getAreaRank() } // 点击标签页初始化
const handleChange = function () { if (activeName.value == 'recharge') { getMiddleBarObj.value.updateType = 0 getAreaRankObj.value.updateType = 0 } else { getMiddleBarObj.value.updateType = 1 getAreaRankObj.value.updateType = 1 } getAreaRankObj.value.type = '' goldType.value = '全部类型' getMiddleBar() areaRankLoading.value = true getAreaRank() } // 时间范围控制
const disabledDate = function (date) { const currentDate = new Date() const startDate = new Date( currentDate.getFullYear(), currentDate.getMonth() - 1, 1 ) const endDate = new Date( currentDate.getFullYear(), currentDate.getMonth() + 1, 0 ) if (date >= startDate && date <= endDate) { return false } return true } // 本日
const today = function () { const current = new Date() const startDate = new Date( current.getFullYear(), current.getMonth(), current.getDate() ) const endDate = new Date( current.getFullYear(), current.getMonth(), current.getDate() ) searchTime.value = [startDate, endDate] search() // console.log("searchTime", moment(searchTime.value[0]).format("YYYY-MM-DD") + "至" + moment(searchTime.value[1]).format("YYYY-MM-DD"))
} // 本周
const thisWeek = function () { const current = new Date() const dayOfWeek = current.getDay() // 获取今天是星期几(0 表示周日,1 表示周一,以此类推)
const diff = current.getDate() - dayOfWeek + (dayOfWeek === 0 ? -6 : 1) // 计算本周第一天的日期差值
const startDate = new Date(current.getFullYear(), current.getMonth(), diff) const endDate = new Date() searchTime.value = [startDate, endDate] search() // console.log("searchTime", moment(searchTime.value[0]).format("YYYY-MM-DD") + "至" + moment(searchTime.value[1]).format("YYYY-MM-DD"))
} // 本月
const thisMonth = function () { const current = new Date() const startDate = new Date(current.getFullYear(), current.getMonth(), 1) const endDate = new Date() searchTime.value = [startDate, endDate] search() // console.log("searchTime", moment(searchTime.value[0]).format("YYYY-MM-DD") + "至" + moment(searchTime.value[1]).format("YYYY-MM-DD"))
} // 本年
const thisYear = function () { const current = new Date() const startDate = new Date(current.getFullYear(), 0, 1) const endDate = new Date(current.getFullYear(), current.getMonth() + 1, 0) const year = 1 searchTime.value = [startDate, endDate, year] search() // console.log("searchTime", moment(searchTime.value[0]).format("YYYY-MM-DD") + "至" + moment(searchTime.value[1]).format("YYYY-MM-DD"))
} // 全部
const allTime = function () { searchTime.value = ['', ''] search() } // 时间选择器
const changeTime = function () { console.log('changeTimeRatio', changeTimeRatio.value) if (changeTimeRatio.value == 'allDays') { allTime() } else if (changeTimeRatio.value == 'week') { thisWeek() } else if (changeTimeRatio.value == 'month') { thisMonth() } else if (changeTimeRatio.value == 'year') { thisYear() } else if (changeTimeRatio.value == 'day') { today() } }
// 根据时间搜索
const search = function () { console.log( 'searchTime', moment(searchTime.value[0]).format('YYYY-MM-DD') + '至' + moment(searchTime.value[1]).format('YYYY-MM-DD') )
getMiddleBarObj.value.searchStartTime = moment(searchTime.value[0]).format( 'YYYY-MM-DD' ) getMiddleBarObj.value.searchEndTime = moment(searchTime.value[1]).format( 'YYYY-MM-DD' ) if (getMiddleBarObj.value.searchStartTime == 'Invalid date') { delete getMiddleBarObj.value.searchStartTime } if (getMiddleBarObj.value.searchEndTime == 'Invalid date') { delete getMiddleBarObj.value.searchEndTime } console.log('getMiddleBarObj', getMiddleBarObj.value)
getAreaRankObj.value.searchStartTime = moment(searchTime.value[0]).format( 'YYYY-MM-DD' ) getAreaRankObj.value.searchEndTime = moment(searchTime.value[1]).format( 'YYYY-MM-DD' ) if (getAreaRankObj.value.searchStartTime == 'Invalid date') { delete getAreaRankObj.value.searchStartTime } if (getAreaRankObj.value.searchEndTime == 'Invalid date') { delete getAreaRankObj.value.searchEndTime } console.log('getAreaRankObj', getAreaRankObj.value)
if (searchTime.value[2] == 1) { getMiddleBarObj.value.year = searchTime.value[2] } else { delete getMiddleBarObj.value.year } getMiddleBar() areaRankLoading.value = true getAreaRank() }
// 切换平台
const changePlatform = function () { console.log('changePlatform', platform.value) if (platform.value == '全部平台') { // 基于准备好的dom,初始化echarts实例
var all = echarts.init(document.getElementById('all')) const option6 = { tooltip: { trigger: 'item' }, series: [ { name: '四大学科类别占比', type: 'pie', radius: ['40%', '60%'], avoidLabelOverlap: false, data: allData.value } ] } // 使用刚指定的配置项和数据显示图表。
all.setOption(option6) } else if (platform.value == 'ERP') { // 基于准备好的dom,初始化echarts实例
var ERP = echarts.init(document.getElementById('ERP')) const option7 = { tooltip: { trigger: 'item' }, series: [ { name: '四大学科类别占比', type: 'pie', radius: ['40%', '60%'], avoidLabelOverlap: false, data: ERPData.value } ] } // 使用刚指定的配置项和数据显示图表。
ERP.setOption(option7) } else if (platform.value == 'HC') { // 第4-3个饼状图 基于准备好的dom,初始化echarts实例
var HC = echarts.init(document.getElementById('HC')) const option8 = { tooltip: { trigger: 'item' }, series: [ { name: '四大学科类别占比', type: 'pie', radius: ['40%', '60%'], avoidLabelOverlap: false, data: HCData.value } ] } // 使用刚指定的配置项和数据显示图表。
HC.setOption(option8) } else if (platform.value == 'Link') { // 第4-4个饼状图 基于准备好的dom,初始化echarts实例
var Link = echarts.init(document.getElementById('Link')) const option9 = { tooltip: { trigger: 'item' }, series: [ { name: '四大学科类别占比', type: 'pie', radius: ['40%', '60%'], avoidLabelOverlap: false, data: LinkData.value } ] } // 使用刚指定的配置项和数据显示图表。
Link.setOption(option9) } else if (platform.value == '金币系统') { // 第4-5个饼状图 基于准备好的dom,初始化echarts实例
var gold = echarts.init(document.getElementById('gold')) const option10 = { tooltip: { trigger: 'item' }, series: [ { name: '四大学科类别占比', type: 'pie', radius: ['40%', '60%'], avoidLabelOverlap: false, data: goldData.value } ] } // 使用刚指定的配置项和数据显示图表。
gold.setOption(option10) } }
// 计算属性
// 格式化数字 这是一个方法
const formatNum = function (val) { if (val === undefined) { return '' } const num = parseFloat(val) // 判断是否为整数
if (Number.isInteger(num)) { return num.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ',') } else { // 四舍五入保留两位小数
const roundedVal = num.toFixed(2) return roundedVal.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ',') } }
function updateChart() { // 第一个柱状图 基于准备好的dom,初始化echarts实例
rechargeBar = echarts.init(document.getElementById('recharge')) const option1 = { tooltip: { trigger: 'axis', axisPointer: { // Use axis to trigger tooltip
type: 'shadow' // 'shadow' as default; can also be 'line' or 'shadow'
} }, legend: { right: 0, orient: 'vertical' }, grid: { left: '3%', right: '4%', bottom: '3%', containLabel: true }, xAxis: { type: 'category', data: middleCategory.value }, yAxis: { type: 'value' }, series: [ { name: '永久金币', color: '#35e383', type: 'bar', stack: 'total', label: { show: false }, emphasis: { focus: 'series' }, data: middleRecharge.value }, { name: '免费金币', color: '#5f8ff5', type: 'bar', stack: 'total', label: { show: false }, emphasis: { focus: 'series' }, data: middleFree.value }, { name: '任务金币', color: '#ffe733', type: 'bar', stack: 'total', label: { show: false }, emphasis: { focus: 'series' }, data: middleTask.value } ] } // 使用刚指定的配置项和数据显示图表。
rechargeBar.setOption(option1) } onMounted(async function () { await get() updateChart()
// 第一个饼状图 基于准备好的dom,初始化echarts实例
var yearRechargePie = echarts.init(document.getElementById('yearRecharge')) const option3 = { tooltip: { trigger: 'item', position: ['15%', '-3%'], formatter: function (params) { return params.seriesName + '<br/>' + params.name } }, legend: { bottom: '-1%', left: 'center', orient: 'vertical' }, series: [ { name: '全年累计金币数(个)\n' + formatNum(Math.abs(twoData.value.totalgold / 100)), type: 'pie', radius: ['60%', '80%'], avoidLabelOverlap: false, label: { show: true, position: 'center', formatter: '{a}', fontSize: 15, fontWeight: 'bold' }, labelLine: { show: false }, data: option3Data.value, color: ['#57a5ff', '#7f29ff', '#f2d113'] } ] } // 使用刚指定的配置项和数据显示图表。
yearRechargePie.setOption(option3)
// 第二个饼状图 基于准备好的dom,初始化echarts实例
var yearConsumePie = echarts.init(document.getElementById('yearConsume')) const option4 = { tooltip: { trigger: 'item', position: ['15%', '-3%'], formatter: function (params) { return params.seriesName + '<br/>' + params.name } }, legend: { bottom: '-1%', left: 'center', orient: 'vertical' }, grid: { top: '0%' // 设置图表距离容器顶部的距离为10%,使饼图上移
}, series: [ { name: '全年累计消耗金币数(个)\n' + formatNum(Math.abs(threeData.value.consumeGold / 100)), type: 'pie', radius: ['60%', '80%'], avoidLabelOverlap: false, label: { show: true, position: 'center', formatter: '{a}', fontSize: 15, fontWeight: 'bold' }, labelLine: { show: false }, data: option4Data.value, color: ['#57a5ff', '#7f29ff', '#f2d113'] } ] } // 使用刚指定的配置项和数据显示图表。
yearConsumePie.setOption(option4)
// 第三个饼状图 基于准备好的dom,初始化echarts实例
var nowGoldPie = echarts.init(document.getElementById('nowGold')) const option5 = { tooltip: { trigger: 'item', position: ['15%', '-3%'], formatter: function (params) { return ( params.seriesName + '<br/>' + params.name + (params.value == oneData.value.freegold ? '</br>6月到期 | ' + oneData.value.sfreegold / 100 + ' ; 12月到期 | ' + oneData.value.dfreegold / 100 : '') ) } }, legend: { bottom: '-1%', left: 'center', orient: 'vertical' }, grid: { top: '10%' // 设置图表距离容器顶部的距离为10%,使饼图上移
}, series: [ { name: '当前金币余量(个)\n' + formatNum(Math.abs(oneData.value.sumgold / 100)), type: 'pie', radius: ['60%', '80%'], avoidLabelOverlap: false, label: { show: true, position: 'center', formatter: '{a}', fontSize: 15, fontWeight: 'bold' }, labelLine: { show: false }, data: option5Data.value, color: ['#57a5ff', '#7f29ff', '#f2d113'] } ] } // 使用刚指定的配置项和数据显示图表。
nowGoldPie.setOption(option5)
// 第4-1个饼状图 基于准备好的dom,初始化echarts实例
var all = echarts.init(document.getElementById('all')) const option6 = { tooltip: { trigger: 'item' }, series: [ { name: '四大学科类别占比', type: 'pie', radius: ['40%', '60%'], avoidLabelOverlap: false, data: allData.value } ] } // 使用刚指定的配置项和数据显示图表。
all.setOption(option6) }) </script>
<template> <div v-loading="loading"> <el-row :gutter="20"> <el-col :span="6"> <el-card style="height: 260px"> <p>当前金币余量</p> <p class="head-mid-font"> {{ formatNum(oneData.sumgold / 100) }} </p> <p> <span v-if="oneData.differr > 0"> <div class="comparedWithYesterday"> <span>较前一天 {{ formatNum(oneData.differr / 100) }}</span> <span class="red-triangle" style="margin: 6px 0px 0px 7px" ></span> </div> </span> <span v-if="oneData.differr < 0"> <div class="comparedWithYesterday"> <span>较前一天 {{ formatNum(oneData.differr / 100) }}</span> <span class="green-triangle" style="margin: 6px 0px 0px 7px" ></span> </div> </span> <span v-if="oneData.differr == 0"> <div class="comparedWithYesterday"> <span>较前一天 {{ formatNum(oneData.differr / 100) }}</span> <span class="grey-triangle" style="margin: 6px 0px 0px 7px" ></span> </div> </span> </p> <template #footer> <span style="font-size: 15px" >永久{{ formatNum(oneData.rechargegold / 100) }} 免费{{ formatNum(oneData.freegold / 100) }} 任务{{ formatNum(oneData.taskgold / 100) }} </span> <p style="font-size: 12px"> 免费金币:6月到期 | {{ formatNum(oneData.sfreegold / 100) }} ; 12月到期 | {{ formatNum(oneData.dfreegold / 100) }} </p> </template> </el-card> </el-col> <el-col :span="6"> <el-card style="height: 260px"> <p>全年累计金币数</p> <p class="head-mid-font"> {{ formatNum(Math.abs(twoData.totalgold / 100)) }} </p> <p> 折合新币累计金额 {{ formatNum(Math.abs(twoData.totalcoin / 100)) }} </p> <template #footer >昨日新增 {{ formatNum(Math.abs(twoData.yesterdaytotal / 100)) }} ,其中充值{{ formatNum(Math.abs(twoData.yesterdayrecharge / 100)) }}</template > </el-card> </el-col> <el-col :span="6"> <el-card style="height: 260px"> <p>全年累计消耗金币数</p> <p class="head-mid-font"> {{ formatNum( Math.abs((threeData.consumeGold + threeData.refundCoin) / 100) ) }} </p> <p> 消费 {{ formatNum(Math.abs(threeData.consumeGold / 100)) }}; 退款 {{ formatNum(Math.abs(threeData.refundCoin / 100)) }} </p> <template #footer >昨日新增消耗{{ formatNum( Math.abs( threeData.yesterdayGold + threeData.yesterdayrefund !== undefined && threeData.yesterdayGold + threeData.yesterdayrefund !== null ? (threeData.yesterdayGold + threeData.yesterdayrefund) / 100 : 0 ) ) }} ; 消费{{ formatNum( Math.abs( threeData.yesterdayGold !== undefined && threeData.yesterdayGold !== null ? threeData.yesterdayGold / 100 : 0 ) ) }} ; 退款{{ formatNum( Math.abs( threeData.yesterdayrefund !== undefined && threeData.yesterdayrefund !== null ? threeData.yesterdayrefund / 100 : 0 ) ) }}</template > </el-card> </el-col> <el-col :span="6"> <el-card style="height: 260px"> <p>全年累计充值人数</p> <p class="head-mid-font"> {{ formatNum(Math.abs(statistics.rechargeCount)) }} </p> <p style="display: flex"> <span v-if="statistics.weekOverWeekRate > 0"> <div class="comparedWithYesterday"> <span>周同比 {{ statistics.weekOverWeekRate }}%</span> <span class="red-triangle" style="margin: 6px 0px 0px 7px" ></span> </div> </span> <span v-if="statistics.weekOverWeekRate < 0"> <div class="comparedWithYesterday"> <span>周同比 {{ statistics.weekOverWeekRate }}%</span> <span class="green-triangle" style="margin: 6px 0px 0px 7px" ></span> </div> </span> <span v-if="statistics.weekOverWeekRate == 0"> <div class="comparedWithYesterday"> <span>周同比 {{ statistics.weekOverWeekRate }}%</span> <span class="grey-triangle" style="margin: 6px 0px 0px 7px" ></span> </div> </span> <span> </span> <span v-if="statistics.dayOverDayRate > 0"> <div class="comparedWithYesterday"> <span> 日环比{{ statistics.dayOverDayRate }}%</span> <span class="red-triangle" style="margin: 6px 0px 0px 7px" ></span> </div> </span> <span v-if="statistics.dayOverDayRate < 0"> <div class="comparedWithYesterday"> <span> 日环比{{ statistics.dayOverDayRate }}%</span> <span class="green-triangle" style="margin: 6px 0px 0px 7px" ></span> </div> </span> <span v-if="statistics.dayOverDayRate == 0"> <div class="comparedWithYesterday"> <span> 日环比{{ statistics.dayOverDayRate }}%</span> <span class="grey-triangle" style="margin: 6px 0px 0px 7px" ></span> </div> </span> </p> <template #footer >昨日充值人数{{ formatNum(Math.abs(statistics.rechargeCountYesterday)) }} ,其中首充{{ formatNum(Math.abs(statistics.firstRechargeCountYesterday)) }}人</template > </el-card> </el-col> </el-row> <el-row :gutter="20"> <el-col> <el-card> <div style="margin-right: auto; text-align: right"> <el-radio-group v-model="changeTimeRatio" style="margin-right: 10px" @change="changeTime()" > <el-radio-button label="全部" value="allDays" style="border-color: white" /> <el-radio-button label="本日" value="day" style="border-color: white" /> <el-radio-button label="本周" value="week" style="border-color: white" /> <el-radio-button label="本月" value="month" style="border-color: white" /> <el-radio-button label="本年" value="year" style="border-color: white" /> </el-radio-group> <!-- <el-button text @click="allTime()" dark=true>全部</el-button> <el-button text @click="today()">今日</el-button> <el-button text @click="thisWeek()">本周</el-button> <el-button text @click="thisMonth()">本月</el-button> <el-button text @click="thisYear()">本年</el-button> --> <el-date-picker v-model="searchTime" type="daterange" range-separator="→" start-placeholder="开始时间" end-placeholder="结束时间" style="width: 200px" :disabled-date="disabledDate" @change="search" /> </div>
<el-tabs v-model="activeName" class="demo-tabs" @tab-change="handleChange" > <el-tab-pane label="金币充值" name="recharge"> <div> 合计:永久金币: <span class="mid-head-font">{{ formatNum(middleTotalRecharge) }}</span> ,免费金币: <span class="mid-head-font">{{ formatNum(middleTotalFree) }}</span> ,任务金币: <span class="mid-head-font">{{ formatNum(middleTotalTask) }}</span> </div> <div class="bar"> <div id="recharge" style="width: 100%; height: 400px"></div> <div style="width: 140px"> <div class="goldCategory"> <span>永久金币</span> </div> <div class="goldCategory"> <span>免费金币</span> </div> <div class="goldCategory"> <span>任务金币</span> </div> </div> <div style="width: 30%"> <div class="ranking-header"> <span style="width: 150px">地区金币充值排名</span> <el-select v-model="goldType" placeholder="请选择金币类型" size="small" style="margin-left: auto; width: 25%" @change="changeGoldType" > <el-option v-for="item in gold" :key="item.value" :label="item.label" :value="item.value" /> </el-select> </div> <div v-loading="areaRankLoading"> <el-scrollbar height="360px"> <div v-for="(item, index) in areaRank" :key="item" class="ranking-item" > <!-- <component :is="findBsComponent(index)" /> --> <span style="width: 15px; text-align: center">{{ index + 1 }}</span> <span style="margin-left: 10px">{{ item.name }}</span> <span style="margin-left: auto; margin-right: 10px">{{ formatNum(item.value) }}</span> </div> </el-scrollbar> </div> </div> </div> </el-tab-pane> <el-tab-pane label="金币消费" name="consume"> <div> 合计:永久金币: <span class="mid-head-font">{{ formatNum(middleTotalRecharge) }}</span> ,免费金币: <span class="mid-head-font">{{ formatNum(middleTotalFree) }}</span> ,任务金币: <span class="mid-head-font">{{ formatNum(middleTotalTask) }}</span> </div> <div class="bar"> <div id="consume" style="width: 100%; height: 400px"></div> <div style="width: 140px"> <div class="goldCategory"> <span>永久金币</span> </div> <div class="goldCategory"> <span>免费金币</span> </div> <div class="goldCategory"> <span>任务金币</span> </div> </div> <div style="width: 310px"> <div class="ranking-header"> <span style="margin-right: 90px; width: 150px" >地区金币消费排名</span > <el-select v-model="goldType" placeholder="请选择金币类型" size="small" style="width: 90px" @change="changeGoldType" > <el-option v-for="item in gold" :key="item.value" :label="item.label" :value="item.value" /> </el-select> </div> <div v-loading="areaRankLoading"> <el-scrollbar height="360px"> <div v-for="(item, index) in areaRank" :key="item" class="ranking-item" > <!-- <component :is="findBsComponent(index)" /> --> <span style="width: 15px; text-align: center">{{ index + 1 }}</span> <span style="margin-left: 10px">{{ item.name }}</span> <span style="margin-left: auto; margin-right: 10px">{{ formatNum(item.value) }}</span> </div> </el-scrollbar> </div> </div> </div> </el-tab-pane> </el-tabs> </el-card> </el-col> </el-row> <el-row :gutter="20"> <el-col :span="16"> <el-card> <template #header> <div class="card-header"> <span class="tail-head">金币概览</span> </div> </template> <div class="pie"> <div id="yearRecharge" style="width: 400px; height: 450px"></div> <div id="yearConsume" style="width: 400px; height: 450px"></div> <div id="nowGold" style="width: 400px; height: 450px"></div> </div> </el-card> </el-col> <!-- <el-col :span="8"> <el-card> <template #header> <div class="card-header" style="display: flex"> <span class="tail-head">四大学科类别占比</span> <el-radio-group v-model="platform" fill="#ffffff" text-color="#409eff" size="small" @change="changePlatform" style="margin-left: auto" > <el-radio-button label="全部平台" value="全部平台" /> <el-radio-button label="ERP" value="ERP" /> <el-radio-button label="HC" value="HC" /> <el-radio-button label="Link" value="Link" /> <el-radio-button label="金币系统" value="金币系统" /> </el-radio-group> </div> </template> <span v-if="platform == '全部平台'"> <div id="all" style="width: 500px; height: 450px"></div> </span> <span v-if="platform == 'ERP'"> <div id="ERP" style="width: 500px; height: 450px"></div> </span> <span v-if="platform == 'HC'"> <div id="HC" style="width: 500px; height: 450px"></div> </span> <span v-if="platform == 'Link'"> <div id="Link" style="width: 500px; height: 450px"></div> </span> <span v-if="platform == '金币系统'"> <div id="gold" style="width: 500px; height: 400px"></div> </span> </el-card> </el-col> --> </el-row> </div> </template>
<style scoped> .medium-button { display: flex; }
.head-mid-font { font-size: 20px; font-weight: bold; }
.mid-head-font { font-weight: bold; color: #5eb7ff; }
.tail-head { font-weight: bold; }
.comparedWithYesterday { display: flex; }
.ranking-item { margin-bottom: 10px; display: flex; }
.ranking-header { margin-bottom: 10px; display: flex; }
.goldCategory { margin-bottom: 4px; margin-right: 20px; display: flex; }
.bar { display: flex; }
.pie { display: flex; }
.el-row { margin-bottom: 20px; }
.el-radio-button { border: 1px solid grey; } </style>
|