diff --git a/src/assets/SvgIcons/上升箭头.svg b/src/assets/SvgIcons/上升箭头.svg new file mode 100644 index 0000000..343582c --- /dev/null +++ b/src/assets/SvgIcons/上升箭头.svg @@ -0,0 +1,14 @@ + + + + + + + + + + + + + + diff --git a/src/assets/SvgIcons/下降箭头.svg b/src/assets/SvgIcons/下降箭头.svg new file mode 100644 index 0000000..99120a4 --- /dev/null +++ b/src/assets/SvgIcons/下降箭头.svg @@ -0,0 +1,14 @@ + + + + + + + + + + + + + + diff --git a/src/assets/SvgIcons/持平.svg b/src/assets/SvgIcons/持平.svg new file mode 100644 index 0000000..9185a41 --- /dev/null +++ b/src/assets/SvgIcons/持平.svg @@ -0,0 +1,14 @@ + + + + + + + + + + + + + + diff --git a/src/components/workspace/CashManagement.vue b/src/components/workspace/CashManagement.vue index 2cf5a8c..eb377da 100644 --- a/src/components/workspace/CashManagement.vue +++ b/src/components/workspace/CashManagement.vue @@ -1,13 +1,30 @@ - 现金管理 - 最后更新时间:{{ - workDataUpdateTime && workDataUpdateTime !== '1970-01-01 08:00:00' ? workDataUpdateTime : '该地区暂无数据' - }} - - - 总营收:{{ cashData.totalIncome }} + + + + 现金管理 + 最后更新时间:{{ + workDataUpdateTime && workDataUpdateTime !== '1970-01-01 08:00:00' ? workDataUpdateTime : '该地区暂无数据' + }} + + + + 总营收:{{ cashData.totalIncome }} + + + + + + + {{ market.name }}: + {{ market.value.toLocaleString() }} + + + + - + + @@ -37,12 +54,16 @@ const renderChart = () => { } const option = { tooltip: {trigger: 'item'}, - legend: {bottom: 10}, + legend: { + bottom: 5, // 增加底部距离的 + left: 'center' + }, series: [ { type: 'pie', radius: ['40%', '70%'], - data: cashData.value.markets + data: cashData.value.markets, + center: ['60%', '45%'] //图表靠右一点 } ] } @@ -55,6 +76,21 @@ onMounted(() => { diff --git a/src/components/workspace/GoldGraph.vue b/src/components/workspace/GoldGraph.vue index ee8cde4..d83a520 100644 --- a/src/components/workspace/GoldGraph.vue +++ b/src/components/workspace/GoldGraph.vue @@ -1,6 +1,6 @@ - + @@ -29,8 +29,9 @@ + style="width:20vw;margin-left:0.5vw;" value-format="YYYY-MM-DD HH:mm:ss" + :default-time="defaultTime" + :disabled-date="disabledDate" @change="handleDatePickerChange"/> 查询 @@ -38,15 +39,15 @@ - + 金币{{ activeTab === 'recharge' ? '充值' : '消费' }}排名 - + - + @@ -511,7 +512,7 @@ const updateChart = (chartData) => { type: 'bar', stack: 'recharge', data: chartData.rechargePermanent, - itemStyle: { color: '#5470c6' }, + itemStyle: {color: '#5470c6'}, barWidth: 30 }, { @@ -519,7 +520,7 @@ const updateChart = (chartData) => { type: 'bar', stack: 'recharge', data: chartData.rechargeFree, - itemStyle: { color: '#91cc75' }, + itemStyle: {color: '#91cc75'}, barWidth: 30 }, { @@ -527,7 +528,7 @@ const updateChart = (chartData) => { type: 'bar', stack: 'recharge', data: chartData.rechargeTask, - itemStyle: { color: '#fac858' }, + itemStyle: {color: '#fac858'}, barWidth: 30 } ] @@ -539,7 +540,7 @@ const updateChart = (chartData) => { type: 'bar', stack: 'consume', data: chartData.consumePermanent, - itemStyle: { color: '#5470c6' }, + itemStyle: {color: '#5470c6'}, barWidth: 30 }, { @@ -547,7 +548,7 @@ const updateChart = (chartData) => { type: 'bar', stack: 'consume', data: chartData.consumeFree, - itemStyle: { color: '#91cc75' }, + itemStyle: {color: '#91cc75'}, barWidth: 30 }, { @@ -555,7 +556,7 @@ const updateChart = (chartData) => { type: 'bar', stack: 'consume', data: chartData.consumeTask, - itemStyle: { color: '#fac858' }, + itemStyle: {color: '#fac858'}, barWidth: 30 } ] @@ -594,16 +595,24 @@ const updateChart = (chartData) => { data: markets.value, axisLabel: { interval: 0, - rotate: 30 + rotate: 0 } }, yAxis: { type: 'value', + splitLine: { + lineStyle: { + type: 'dashed', + width: 1, + color: '#000000' + } + }, axisLabel: { formatter: function (value) { return value.toLocaleString() } - } + }, + }, series: series, // dataZoom: [ @@ -639,7 +648,7 @@ const handleTabChange = () => { const getAdminData = async function () { try { - const result = await API({ url: '/admin/userinfo', data: {} }) + const result = await API({url: '/admin/userinfo', data: {}}) adminData.value = result console.log('用户信息', adminData.value) } catch (error) { @@ -649,7 +658,7 @@ const getAdminData = async function () { // 获取卡片数据 const getCardData = async () => { try { - const response = await API({ url: '/workbench/getCard', data: {} }) + const response = await API({url: '/workbench/getCard', data: {}}) workDataUpdateTime.value = response.updateTime // 周同比 sumWow.value = response.sumWow.toFixed(2) @@ -756,6 +765,7 @@ onUnmounted(() => { font-size: 16px; text-align: center; margin-bottom: 15px; + } @keyframes spin { @@ -767,4 +777,62 @@ onUnmounted(() => { transform: rotate(360deg); } } + +.graph-card { + background: #F3FAFF; + box-shadow: 0 0 8px 0 #00000040; +} + +.graph-card-list { + background: #F3FAFF; + box-shadow: 0 0 8px 0 #00000040; + padding: 12px; + + .card-select { + :deep(.el-input__wrapper) { + background-color: #E7F4FD !important; + box-shadow: 0 0 4px 0 rgba(0, 0, 0, 0.25) !important; + border: none !important; + } + + :deep(.el-input__inner) { + background-color: transparent !important; + } + + :deep(.el-input__suffix) { + background-color: transparent !important; + } + } + + /* 表格整体背景:把表格容器设为卡片背景 */ + :deep(.el-table) { + background-color: #F3FAFF !important; + box-shadow: none !important; + } + + /* 表头/表体 wrapper 与 table body 单元格 */ + :deep(.el-table__header-wrapper), + :deep(.el-table__body-wrapper), + :deep(.el-table__body), + :deep(.el-table__header), + :deep(.el-table__body tbody), + :deep(.el-table__body tr), + :deep(.el-table__row), + :deep(.el-table__cell), + :deep(.el-table__body td) { + background-color: transparent !important; + } + + /* 表头 */ + :deep(.el-table__header th) { + background-color: #F3FAFF !important; + } + + /* 行之间的分隔线(更像卡片内表格) */ + :deep(.el-table .el-table__row):not(:last-child) { + border-bottom: 1px solid rgba(0,0,0,0.06); + } + +} + diff --git a/src/components/workspace/GoldManagement.vue b/src/components/workspace/GoldManagement.vue index 37d85ef..46b5e9a 100644 --- a/src/components/workspace/GoldManagement.vue +++ b/src/components/workspace/GoldManagement.vue @@ -1,43 +1,40 @@ - - 金币管理 - 最后更新时间:{{ - workDataUpdateTime && workDataUpdateTime !== '1970-01-01 08:00:00' ? workDataUpdateTime : '该地区暂无数据' - }} - + + + + 金币管理 + 最后更新时间:{{ + workDataUpdateTime && workDataUpdateTime !== '1970-01-01 08:00:00' ? workDataUpdateTime : '该地区暂无数据' + }} + + - - - 当前金币余量 - {{ - currentGold / 100 - }} 较前一日 - {{ dailyChange / 100 }} - - - - - - - - - - - - - - - - - + + 当前金币余量 + {{ + currentGold / 100 + }} 较前一日 + {{ dailyChange / 100 }} + + + + + + + + + + - 永久金币:{{ currentPermanent / 100 }} + + 永久金币:{{ currentPermanent / 100 }} + 免费金币:{{ currentFree / 100 }} @@ -48,7 +45,7 @@ - 任务金币:{{ currentTask / 100 }} + 任务金币:{{ currentTask / 100 }} @@ -61,88 +58,76 @@ - + - + 全年累计充值金币数{{ yearlyRecharge / 100 }} - 折合新币累计金额:{{ yearlyMoney / 100 }} - 昨日新增金币:{{ recharge / 100 }} + 折合新币累计金额 + + {{ yearlyMoney / 100 }}新币 - - 其中永久金币:{{ money / 100 }} - - + + 昨日新增金币:{{ recharge / 100 }} + + 其中永久金币:{{ money / 100 }} - + + - + 全年累计消费金币数{{ yearlyReduce / 100 }} - 消耗:{{ yearlyConsume / 100 }} - 退款:{{ yearlyRefund / 100 }} - - - - 昨日新增消费:{{ dailyConsume / 100 }} - 昨日新增消耗:{{ dailyReduce / 100 }} - 昨日新增退款:{{ dailyRefund / 100 }} - - + + + + + + + + + - - 全年累计充值人头数{{ yearlyRechargeNum }} - 周同比:{{ sumWow }}% - - - - - - - - - - - - - - - - - 日环比:{{ sumDaily }}% - - - - - - - - - - - - - - - - - - - - 昨日充值人数:{{ ydayRechargeNum }} - 其中首充:{{ firstRecharge }} - - + + 全年累计充值人头数{{ yearlyRechargeNum }} + + + + + + 周同比:{{ sumWow }}% + + + + + + 日环比:{{ sumDaily }}% + + + + + + + + + + + + + + + + @@ -155,6 +140,11 @@ import API from '@/util/http' import dayjs from 'dayjs'; import utc from 'dayjs-plugin-utc' import {ArrowDownBold, ArrowUpBold, SemiSelect} from '@element-plus/icons-vue' +import svg1 from '@/assets/SvgIcons/折合新币累计金额.svg' +import svg2 from '@/assets/SvgIcons/周同比.svg' +import upArrow from '@/assets/SvgIcons/上升箭头.svg' +import downArrow from '@/assets/SvgIcons/下降箭头.svg' +import pingArrow from '@/assets/SvgIcons/持平.svg' dayjs.extend(utc) @@ -190,6 +180,7 @@ const length = ref(0) const goldTypeChart = ref(null) const rechargeGoldChart = ref(null) const consumeChart = ref(null) +const consumeDetailChart = ref(null) const rechargePeopleChart = ref(null) // 要加上所有市场的,还有额外计算的(总数 = 永久 + 6月 + 12月 + 免费 + 任务) @@ -271,9 +262,10 @@ const processData = (data) => { // 初始化图表 nextTick(() => { - initGoldTypeChart(); + // initGoldTypeChart(); initRechargeGoldChart(); initConsumeChart(); + initConsumeDetailChart(); initRechargePeopleChart(); }); } @@ -326,18 +318,40 @@ const initRechargeGoldChart = () => { series: [ { type: 'pie', - radius: ['50%', '70%'], + radius: ['60%', '85%'], + silent: true, + clockwise: true, + label: {show: false}, data: [ - {value: money.value / 100, name: '永久金币'}, - {value: (recharge.value - money.value) / 100, name: '其他金币'} - ], - label: { - show: true, - formatter: '{b}: {c}' - } + { + value: recharge.value / 100, + itemStyle: {color: '#80aaff'} + + } + ] + }, + { + type: 'pie', + radius: ['60%', '75%'], + startAngle: 180, + silent: true, + clockwise: true, + label: {show: false}, + data: [ + { + value: money.value / 100, + itemStyle: {color: '#f2c97d'} + + }, + { + value: (recharge.value / 100 - money.value / 100), + itemStyle: {color: 'transparent'} + } + ] } ] }; + myChart.setOption(option); } @@ -345,46 +359,157 @@ const initRechargeGoldChart = () => { const initConsumeChart = () => { const myChart = echarts.init(consumeChart.value); const option = { + legend: { + orient: 'vertical', + left: '10%', + top: '85', + icon: 'circle', + iconSize: 5, + textSize: 12, + itemWidth: 7, + itemHeight: 7, + }, + series: [ { type: 'pie', - radius: ['40%', '70%'], + radius: ['30%', '45%'], + center: ['50%', '35%'], + silent: true, + clockwise: true, + label: {show: false}, data: [ - {value: yearlyConsume.value / 100, name: '消耗'}, - {value: yearlyRefund.value / 100, name: '退款'} + { + value: yearlyConsume.value / 100, + name: '消耗:' + yearlyConsume.value / 100, + // name: '消耗:' + 1234567890, + itemStyle: {color: '#7DB7FA'} + + }, + { + value: yearlyRefund.value / 100, + name: '退款:' + yearlyRefund.value / 100, + itemStyle: {color: '#F7D47C'} + + } ], - label: { - show: true, - formatter: '{b}: {c}' - } } ] }; myChart.setOption(option); -} +}; +// 初始化消费明细环形图 +const initConsumeDetailChart = () => { + const myChart = echarts.init(consumeDetailChart.value); + const option = { + // 增加图表内边距,避免内容溢出 + legend: { + orient: 'vertical', + left: 'left', + top: '85', + icon: 'circle', + iconSize: 5, + itemWidth: 7, + itemHeight: 7, + }, + series: [ + { + type: 'pie', + radius: ['25%', '40%'], + center: ['50%', '25%'], + silent: true, + clockwise: true, + label: {show: false}, + data: [ + { + value: dailyConsume.value / 100, + name: '昨日新增消费:' + dailyConsume.value / 100, + itemStyle: {color: '#65C9C9'} + } + ] + }, + { + type: 'pie', + radius: ['25%', '35%'], + center: ['50%', '25%'], + + startAngle: 180, + silent: true, + clockwise: true, + label: {show: false}, + data: [ + { + value: dailyReduce.value / 100, + name: '昨日新增消耗:' + dailyReduce.value / 100, + // name: '昨日新增消耗:' + 1234567890, + itemStyle: {color: '#9469D1'} + }, + { + value: dailyRefund.value / 100, + name: '昨日新增退款:' + dailyRefund.value / 100, + itemStyle: {color: '#B8DB6E'} + } + ] + } + ] + }; + + myChart.setOption(option); +}; // 初始化充值人头环形图 const initRechargePeopleChart = () => { const myChart = echarts.init(rechargePeopleChart.value); const option = { + legend: { + orient: 'vertical', + left: 'left', + top: '85', + icon: 'circle', + iconSize: 5, + textSize: 18, + itemWidth: 7, + itemHeight: 7, + }, series: [ { type: 'pie', - radius: ['40%', '70%'], + radius: ['30%', '50%'], + center: ['50%', '35%'], + silent: true, + clockwise: true, + label: {show: false}, + data: [ + { + value: ydayRechargeNum.value, + name: '昨日充值人数:' + ydayRechargeNum.value, + itemStyle: {color: '#65C9C9'} + }, + ], + }, + { + type: 'pie', + radius: ['30%', '45%'], + center: ['50%', '35%'], + silent: true, + clockwise: true, + label: {show: false}, data: [ - {value: firstRecharge.value, name: '首充'}, - {value: (ydayRechargeNum.value - firstRecharge.value), name: '非首充'} + { + value: firstRecharge.value, + name: '其中首充:' + firstRecharge.value, + itemStyle: {color: '#9469D1'} + }, + { + value: ydayRechargeNum.value - firstRecharge.value, + itemStyle: {color: 'transparent'} + } ], - label: { - show: true, - formatter: '{b}: {c}' - } } ] }; myChart.setOption(option); } - // 获取卡片数据 const getCardData = async () => { try { @@ -406,6 +531,7 @@ const getCardData = async () => { console.error('获取卡片数据失败:', error) } } + const workDataUpdateTime = ref(null) @@ -415,12 +541,7 @@ onMounted(async () => { \ No newline at end of file diff --git a/src/views/home.vue b/src/views/home.vue index 3ca4933..f793730 100644 --- a/src/views/home.vue +++ b/src/views/home.vue @@ -330,28 +330,12 @@ function logout() { overflow: hidden; } -/* 头部样式 */ -.header { - /* 将纯色背景替换为线性渐变 */ - background: linear-gradient( - 90deg, - rgba(228, 240, 252, 1) 20%, - rgba(190, 218, 247, 1) 50%, - rgba(228, 240, 252, 1) 100% - ); - height: 6vh; - border-radius: 12px; - margin-bottom: 4px; - box-shadow: 0 2px 5px rgba(8, 4, 4, 0.1); - /* 添加阴影增强层次感 */ - z-index: 80; -} /* 主内容区域容器 */ .main-area { flex: 1; background: #E7F4FD; - /* 半透明白色背景 */ + /* 半透明浅色背景 */ /* backdrop-filter: blur(5px); */ /* 毛玻璃效果 */ border-radius: 12px; diff --git a/src/views/workspace/index.vue b/src/views/workspace/index.vue index 1a3d69f..f7d02fe 100644 --- a/src/views/workspace/index.vue +++ b/src/views/workspace/index.vue @@ -3,13 +3,13 @@ 数据总览 - + - + - + @@ -35,7 +35,7 @@ const markets = ref([]) const account = ref('') const activeTab = ref('recharge') -// 👉 tab 切换时重新调图表接口 +// tab 切换时重新调图表接口 const handleTabChange = async (tab) => { activeTab.value = tab await getGraphData()