diff --git a/Web/src/components/Budget/BudgetChartAnalysis.vue b/Web/src/components/Budget/BudgetChartAnalysis.vue index 02ca9b9..f5694c2 100644 --- a/Web/src/components/Budget/BudgetChartAnalysis.vue +++ b/Web/src/components/Budget/BudgetChartAnalysis.vue @@ -261,6 +261,19 @@ const formatMoney = (val) => { // 月度仪表盘数据 const monthGaugeData = computed(() => { + // 防御性检查:如果数据未加载,返回默认结构 + if (!props.overallStats || !props.overallStats.month) { + return { + datasets: [{ + data: [0, 100], + backgroundColor: [getCssVar('--chart-axis'), getCssVar('--chart-axis')], + borderWidth: 0, + circumference: 180, + rotation: 270 + }] + } + } + const rate = parseFloat(props.overallStats.month.rate || 0) const isExpense = props.activeTab === BudgetCategory.Expense @@ -329,6 +342,19 @@ const monthGaugeOptions = computed(() => { // 年度仪表盘数据 const yearGaugeData = computed(() => { + // 防御性检查:如果数据未加载,返回默认结构 + if (!props.overallStats || !props.overallStats.year) { + return { + datasets: [{ + data: [0, 100], + backgroundColor: [getCssVar('--chart-axis'), getCssVar('--chart-axis')], + borderWidth: 0, + circumference: 180, + rotation: 270 + }] + } + } + const rate = parseFloat(props.overallStats.year.rate || 0) const isExpense = props.activeTab === BudgetCategory.Expense @@ -493,6 +519,14 @@ const varianceChartOptions = computed(() => { // 月度燃尽图数据 const burndownChartData = computed(() => { + // 防御性检查 + if (!props.overallStats || !props.overallStats.month || !props.selectedDate) { + return { + labels: [], + datasets: [] + } + } + const refDate = props.selectedDate const year = refDate.getFullYear() const month = refDate.getMonth() @@ -623,6 +657,14 @@ const burndownChartOptions = computed(() => { // 年度燃尽图数据 const yearBurndownChartData = computed(() => { + // 防御性检查 + if (!props.overallStats || !props.overallStats.year || !props.selectedDate) { + return { + labels: [], + datasets: [] + } + } + const refDate = props.selectedDate const year = refDate.getFullYear() diff --git a/Web/src/components/Charts/BaseChart.vue b/Web/src/components/Charts/BaseChart.vue index 70492a9..4b05101 100644 --- a/Web/src/components/Charts/BaseChart.vue +++ b/Web/src/components/Charts/BaseChart.vue @@ -5,7 +5,7 @@ ` - [x] 2.9 删除 `onBeforeUnmount()` 中的 ECharts cleanup 代码 -- [ ] 2.10 本地浏览器验证图表渲染正确(Chrome DevTools) +- [x] 2.10 本地浏览器验证图表渲染正确(Chrome DevTools) ## 3. 迁移 DailyTrendChart.vue(双系列折线图) diff --git a/warnings.txt b/warnings.txt new file mode 100644 index 0000000..73c1102 --- /dev/null +++ b/warnings.txt @@ -0,0 +1,98 @@ +Total messages: 12 (Errors: 1, Warnings: 8) +Returning 9 messages for level "warning" + +[WARNING] [Vue warn]: Plugin has already been applied to target app. @ http://localhost:5173/node_modules/.vite/deps/chunk-TTLTGI2G.js?v=9b5e80e2:2194 +[WARNING] [Vue warn]: Property "chartData" was accessed during render but is not defined on instance. + at + at + at + at > + at + at ref=Ref< undefined > key="budget-v2" > + at + at + at + at @ http://localhost:5173/node_modules/.vite/deps/chunk-TTLTGI2G.js?v=9b5e80e2:2194 +[WARNING] [Vue warn]: Invalid prop: type check failed for prop "data". Expected Object, got Undefined + at + at + at + at + at > + at + at ref=Ref< undefined > key="budget-v2" > + at + at + at + at @ http://localhost:5173/node_modules/.vite/deps/chunk-TTLTGI2G.js?v=9b5e80e2:2194 +[WARNING] [Vue warn]: Invalid prop: type check failed for prop "data". Expected Object, got Undefined + at type="doughnut" data=undefined ... > + at + at + at + at + at > + at + at ref=Ref< undefined > key="budget-v2" > + at + at + at + at @ http://localhost:5173/node_modules/.vite/deps/chunk-TTLTGI2G.js?v=9b5e80e2:2194 +[WARNING] [Vue warn]: Property "chartData" was accessed during render but is not defined on instance. + at + at + at + at > + at + at ref=Ref< undefined > key="budget-v2" > + at + at + at + at @ http://localhost:5173/node_modules/.vite/deps/chunk-TTLTGI2G.js?v=9b5e80e2:2194 +[WARNING] [Vue warn]: Invalid prop: type check failed for prop "data". Expected Object, got Undefined + at + at + at + at + at > + at + at ref=Ref< undefined > key="budget-v2" > + at + at + at + at @ http://localhost:5173/node_modules/.vite/deps/chunk-TTLTGI2G.js?v=9b5e80e2:2194 +[WARNING] [Vue warn]: Invalid prop: type check failed for prop "data". Expected Object, got Undefined + at type="doughnut" data=undefined ... > + at + at + at + at + at > + at + at ref=Ref< undefined > key="budget-v2" > + at + at + at + at @ http://localhost:5173/node_modules/.vite/deps/chunk-TTLTGI2G.js?v=9b5e80e2:2194 +[WARNING] [Vue warn]: Unhandled error during execution of mounted hook + at type="doughnut" data=undefined ... > + at + at + at + at + at > + at + at ref=Ref< Proxy(Object) > key="budget-v2" > + at + at + at + at @ http://localhost:5173/node_modules/.vite/deps/chunk-TTLTGI2G.js?v=9b5e80e2:2194 +TypeError: Cannot read properties of undefined (reading 'labels') + at cloneData (http://localhost:5173/node_modules/.vite/deps/vue-chartjs.js?v=9b5e80e2:109:28) + at renderChart (http://localhost:5173/node_modules/.vite/deps/vue-chartjs.js?v=9b5e80e2:140:26) + at http://localhost:5173/node_modules/.vite/deps/chunk-TTLTGI2G.js?v=9b5e80e2:5221:40 + at callWithErrorHandling (http://localhost:5173/node_modules/.vite/deps/chunk-TTLTGI2G.js?v=9b5e80e2:2342:19) + at callWithAsyncErrorHandling (http://localhost:5173/node_modules/.vite/deps/chunk-TTLTGI2G.js?v=9b5e80e2:2349:17) + at hook.__weh.hook.__weh (http://localhost:5173/node_modules/.vite/deps/chunk-TTLTGI2G.js?v=9b5e80e2:5201:19) + at flushPostFlushCbs (http://localhost:5173/node_modules/.vite/deps/chunk-TTLTGI2G.js?v=9b5e80e2:2527:28) + at flushJobs (http://localhost:5173/node_modules/.vite/deps/chunk-TTLTGI2G.js?v=9b5e80e2:2569:5) \ No newline at end of file