feat:重构模块

This commit is contained in:
2025-10-08 22:06:39 +08:00
parent f60d78fe8b
commit 2e81e57774
222 changed files with 2267 additions and 3059 deletions

View File

@@ -0,0 +1,147 @@
<template>
<div class="bill-chart"
v-loading="billStore.isLoading"
element-loading-text="正在加载中...">
<div class="chart-container card-item">
<div class="content">
<span class="title">📊收支统计</span>
</div>
<div class="chart" ref="billDailyChartRef"/>
</div>
<div class="chart-container card-item">
<div class="content">
<span class="title">📊类别统计</span>
</div>
<div class="chart" ref="billCategoryChartRef"/>
</div>
<div class="chart-container card-item">
<div class="content">
<span class="title">📊账本统计</span>
</div>
<div class="chart" ref="billBookChartRef"/>
</div>
<div v-if="isMobile()" class="chart-container card-item">
<div class="content">
<span class="title">📊排行榜</span>
</div>
<div class="chart rank-chart">
<bill-rank />
</div>
</div>
<div v-else class="chart-container card-item">
<div class="content">
<span class="title">📊排行榜</span>
</div>
<div class="chart" ref="billRankChartRef"/>
</div>
</div>
</template>
<script setup lang="ts">
import BillRank from '@/components/Bill/BillRank.vue'
import { onMounted, ref, watch } from 'vue'
import * as echarts from 'echarts'
import { lineChartOptions, barChartOptions, pieChartOptions } from 'vue3-common/utils/eChartsUtil'
import { useBillStore } from '@/store/bill.ts'
import { useAppStore } from '@/store/app.ts'
import type { IStatsChart } from 'vue3-common/types'
import { isMobile } from 'vue3-common/utils/layoutUtil'
const billStore = useBillStore()
const appStore = useAppStore()
const billDailyChartRef = ref<HTMLElement>()
const billBookChartRef = ref<HTMLElement>()
const billCategoryChartRef = ref<HTMLElement>()
const billRankChartRef = ref<HTMLElement>()
let billDailyChart: echarts.ECharts
let billBookChart: echarts.ECharts
let billCategoryChart: echarts.ECharts
let billRankChart: echarts.ECharts
watch(() => billStore.isRefresh, () => {
updateChart()
})
onMounted(() => {
billDailyChart = echarts.init(billDailyChartRef.value as HTMLElement, appStore.isDark ? 'dark' : null)
billBookChart = echarts.init(billBookChartRef.value as HTMLElement, appStore.isDark ? 'dark' : null)
billCategoryChart = echarts.init(billCategoryChartRef.value as HTMLElement, appStore.isDark ? 'dark' : null)
if (!isMobile()) {
billRankChart = echarts.init(billRankChartRef.value as HTMLElement, appStore.isDark ? 'dark' : null)
}
})
const updateChart = () => {
const MAX_CATEGORY_COUNT = 5
const MAX_RANK_COUNT = 10
// 收支统计图
const dailyXAxis = billStore.billDateStatsList.map((item) => item.name)
const dailyYAxis = billStore.billDateStatsList.map((item) => item.value)
billDailyChart.setOption(lineChartOptions('日期', dailyXAxis, '金额(元)', dailyYAxis))
billDailyChart.setOption({
series: [{
itemStyle: {
color: billStore.billType === 'expensive' ? '#CA6C65' : '#6FBB69'
},
markPoint: {
label: {
color: '#FFFFFF'
}
},
label: {
show: false
}
}]
})
// 账本统计图
const bookXAxis = billStore.billBookStatsList.map((item) => item.name)
const bookYAxis = billStore.billBookStatsList.map((item) => item.value)
billBookChart.setOption(barChartOptions('账本', bookXAxis, '金额(元)', bookYAxis))
billBookChart.setOption({
series: [{
itemStyle: {
color: billStore.billType === 'expensive' ? '#CA6C65' : '#6FBB69'
},
markPoint: {
label: {
color: '#FFFFFF'
}
}
}]
})
// 类别统计图
const billCategoryList = billStore.billCategoryStatsList.slice(0, MAX_CATEGORY_COUNT)
billCategoryChart.setOption(pieChartOptions('rank', '元', billCategoryList))
if (isMobile()) {
billCategoryChart.setOption({
series: [{
radius: ['20%', '50%'],
label: {
formatter: '{b}: {d}%'
}
}]
})
}
// 排行榜统计图
const billRankList: IStatsChart[] = []
const resultList = billStore.billRecordList.filter((item) => item.type === billStore.billType)
resultList.sort((a, b) => b.amount - a.amount).forEach((item) => {
billRankList.push({
name: item.content,
value: item.amount
})
})
if (!isMobile()) {
billRankChart.setOption(pieChartOptions('rank', '元', billRankList.slice(0, MAX_RANK_COUNT)))
}
}
</script>