|
|
@@ -81,7 +81,7 @@
|
|
|
</template>
|
|
|
|
|
|
<script setup>
|
|
|
-import { ref, onMounted, computed, inject, watch } from 'vue'
|
|
|
+import { ref, onMounted, onUnmounted, computed, inject, watch } from 'vue'
|
|
|
import { useUserStore } from '@/stores/user'
|
|
|
import { useTeamStore } from '@/stores/team'
|
|
|
import { getAllTeamStatistics, getIncomeStatistics } from '@/services/api'
|
|
|
@@ -221,16 +221,22 @@ const renderChart = () => {
|
|
|
// 如果已有图表实例,先销毁
|
|
|
if (chartInstance.value) {
|
|
|
chartInstance.value.destroy()
|
|
|
+ chartInstance.value = null
|
|
|
}
|
|
|
|
|
|
const ctx = chartElement.getContext('2d')
|
|
|
|
|
|
- // 准备数据
|
|
|
- const labels = incomeStats.value.dates
|
|
|
- // 直接使用 API 返回的数据(已根据选择的团队过滤)
|
|
|
- const data = incomeStats.value.total
|
|
|
- const tipData = incomeStats.value.totalTip
|
|
|
- const commissionData = incomeStats.value.totalCommission
|
|
|
+ // 准备数据并验证
|
|
|
+ const labels = incomeStats.value.dates || []
|
|
|
+ const data = incomeStats.value.total || []
|
|
|
+ const tipData = incomeStats.value.totalTip || []
|
|
|
+ const commissionData = incomeStats.value.totalCommission || []
|
|
|
+
|
|
|
+ // 验证数据完整性
|
|
|
+ if (!labels.length || !data.length) {
|
|
|
+ console.warn('图表数据不完整,跳过渲染')
|
|
|
+ return
|
|
|
+ }
|
|
|
|
|
|
const datasets = [
|
|
|
{
|
|
|
@@ -260,28 +266,33 @@ const renderChart = () => {
|
|
|
]
|
|
|
|
|
|
// 创建图表
|
|
|
- chartInstance.value = new Chart(ctx, {
|
|
|
- type: 'line',
|
|
|
- data: { labels, datasets },
|
|
|
- options: {
|
|
|
- responsive: true,
|
|
|
- maintainAspectRatio: false,
|
|
|
- plugins: {
|
|
|
- legend: {
|
|
|
- position: 'top'
|
|
|
+ try {
|
|
|
+ chartInstance.value = new Chart(ctx, {
|
|
|
+ type: 'line',
|
|
|
+ data: { labels, datasets },
|
|
|
+ options: {
|
|
|
+ responsive: true,
|
|
|
+ maintainAspectRatio: false,
|
|
|
+ plugins: {
|
|
|
+ legend: {
|
|
|
+ position: 'top'
|
|
|
+ },
|
|
|
+ tooltip: {
|
|
|
+ mode: 'index',
|
|
|
+ intersect: false
|
|
|
+ }
|
|
|
},
|
|
|
- tooltip: {
|
|
|
- mode: 'index',
|
|
|
- intersect: false
|
|
|
- }
|
|
|
- },
|
|
|
- scales: {
|
|
|
- y: {
|
|
|
- beginAtZero: true
|
|
|
+ scales: {
|
|
|
+ y: {
|
|
|
+ beginAtZero: true
|
|
|
+ }
|
|
|
}
|
|
|
}
|
|
|
- }
|
|
|
- })
|
|
|
+ })
|
|
|
+ } catch (error) {
|
|
|
+ console.error('图表渲染失败:', error)
|
|
|
+ chartInstance.value = null
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
// 监听团队选择变化
|
|
|
@@ -297,6 +308,14 @@ onMounted(async () => {
|
|
|
await loadTeamStats()
|
|
|
await loadIncomeStats()
|
|
|
})
|
|
|
+
|
|
|
+// 组件卸载时清理图表实例
|
|
|
+onUnmounted(() => {
|
|
|
+ if (chartInstance.value) {
|
|
|
+ chartInstance.value.destroy()
|
|
|
+ chartInstance.value = null
|
|
|
+ }
|
|
|
+})
|
|
|
</script>
|
|
|
|
|
|
<style scoped>
|