8 天以前 f893393398429b326119279059befa0e350cc8ac
Merge remote-tracking branch 'origin/dev_NEW_pro' into dev_NEW_pro
已修改1个文件
542 ■■■■ 文件已修改
src/views/financialManagement/financialStatements/index.vue 542 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/financialManagement/financialStatements/index.vue
@@ -1,9 +1,9 @@
 <template>
  <div style="padding: 20px;">
    <!-- 页面标题和月份筛选 -->
    <div class="w-full md:w-auto flex items-center gap-3" style="margin-bottom: 20px;">
      <el-date-picker
        v-model="dateRange"
    <div class="w-full md:w-auto flex items-center gap-3"
         style="margin-bottom: 20px;">
      <el-date-picker v-model="dateRange"
        type="monthrange"
        format="YYYY-MM"
        value-format="YYYY-MM"
@@ -13,70 +13,66 @@
        :disabled-date="disabledDate"
        @change="handleDateChange"
        class="w-full md:w-auto"
        style="margin-right: 30px;"
      />
      <el-button
        type="primary"
                      style="margin-right: 30px;" />
      <el-button type="primary"
        icon="Refresh" 
        @click="resetDateRange"
        size="default"
      >
                 size="default">
        重置
      </el-button>
    </div>
    <main class="container mx-auto px-4 pb-10">
      <!-- 财务指标卡片 -->
      <div class="stats-cards">
        <!-- 总营收 -->
        <div class="stat-card stat-card-blue">
          <div class="stat-icon">
            <img src="@/assets/icons/png/walletBlue@2x.png" alt="总营收" />
            <img src="@/assets/icons/png/walletBlue@2x.png"
                 alt="总营收" />
          </div>
          <div class="stat-content">
            <div class="stat-label">总营收</div>
            <div class="stat-value">{{ formatMoney(pageInfo.totalIncome || 0) }} 元</div>
          </div>
        </div>
        <!-- 总支出 -->
        <div class="stat-card stat-card-orange">
          <div class="stat-icon">
            <img src="@/assets/icons/png/walletOrange@2x.png" alt="总支出" />
            <img src="@/assets/icons/png/walletOrange@2x.png"
                 alt="总支出" />
          </div>
          <div class="stat-content">
            <div class="stat-label">总支出</div>
            <div class="stat-value">{{ formatMoney(pageInfo.totalExpense || 0) }} 元</div>
          </div>
        </div>
        <!-- 总收入笔数 -->
        <div class="stat-card stat-card-green">
          <div class="stat-icon">
            <img src="@/assets/icons/png/walletGreen@2x.png" alt="总收入笔数" />
            <img src="@/assets/icons/png/walletGreen@2x.png"
                 alt="总收入笔数" />
          </div>
          <div class="stat-content">
            <div class="stat-label">总收入笔数</div>
            <div class="stat-value">{{ pageInfo.incomeNumber || 0 }} 笔</div>
          </div>
        </div>
        <!-- 总支出笔数 -->
        <div class="stat-card stat-card-red">
          <div class="stat-icon">
            <img src="@/assets/icons/png/walletRed@2x.png" alt="总支出笔数" />
            <img src="@/assets/icons/png/walletRed@2x.png"
                 alt="总支出笔数" />
          </div>
          <div class="stat-content">
            <div class="stat-label">总支出笔数</div>
            <div class="stat-value">{{ pageInfo.expenseNumber || 0 }} 笔</div>
          </div>
        </div>
        <!-- 净收入 -->
        <div class="stat-card stat-card-yellow">
          <div class="stat-icon">
            <img src="@/assets/icons/png/walletYellow@2x.png" alt="净收入" />
            <img src="@/assets/icons/png/walletYellow@2x.png"
                 alt="净收入" />
          </div>
          <div class="stat-content">
            <div class="stat-label">净收入</div>
@@ -84,15 +80,13 @@
          </div>
        </div>
      </div>
      <!-- 中间图表区域 -->
      <div class="charts-row">
        <!-- 左侧:收入支出分析 -->
        <el-card class="chart-card">
          <h2 class="section-title">收入支出分析</h2>
          <div class="pie-chart-container">
            <Echarts
              :legend="pieLegendIncomeExpense"
            <Echarts :legend="pieLegendIncomeExpense"
              :chartStyle="chartStylePie"
              :series="pieSeriesIncomeExpense"
              :tooltip="pieTooltipIncomeExpense" 
@@ -110,7 +104,6 @@
            </div>
          </div>
        </el-card>
        <!-- 右侧:行项盈利分析 -->
        <el-card class="chart-card">
          <h2 class="section-title">行项盈利分析</h2>
@@ -128,8 +121,7 @@
              <span class="bar-stat-value">{{ formatMoney(pageInfo.totalIncome || 0) }}</span>
            </div>
          </div>
          <Echarts
            ref="barChart"
          <Echarts ref="barChart"
            :chartStyle="chartStyle"
            :grid="barGrid"
            :legend="barLegend"
@@ -141,12 +133,10 @@
          </Echarts>
        </el-card>
      </div>
      <!-- 底部:营收趋势分析 -->
      <el-card class="trend-chart-card">
        <h2 class="section-title">营收趋势分析</h2>
        <Echarts
          ref="trendChart"
        <Echarts ref="trendChart"
          :chartStyle="chartStyle"
          :grid="grid"
          :legend="trendLegend"
@@ -162,51 +152,62 @@
</template>
<script setup>
import { ref, computed, onMounted, reactive, nextTick, getCurrentInstance } from 'vue';
import 'element-plus/dist/index.css';
  import {
    ref,
    computed,
    onMounted,
    reactive,
    nextTick,
    getCurrentInstance,
  } from "vue";
  import "element-plus/dist/index.css";
import Echarts from "@/components/Echarts/echarts.vue";
import { reportForms,reportIncome,reportExpense } from "@/api/financialManagement/financialStatements";
  import {
    reportForms,
    reportIncome,
    reportExpense,
  } from "@/api/financialManagement/financialStatements";
import dayjs from "dayjs";
// 日期范围
const dateRange = ref(null);
const { proxy } = getCurrentInstance();
const chartStyle = {
    width: '100%',
    height: '100%', // 设置图表容器的高度
  position:'relative',
}
    width: "100%",
    height: "100%", // 设置图表容器的高度
    position: "relative",
  };
const grid = {
    left: '3%',
        right: '4%',
        bottom: '3%',
        containLabel: true
}
    left: "3%",
    right: "4%",
    bottom: "3%",
    containLabel: true,
  };
const lineLegend = {
    show: false,
}
  };
// 折线图提示框
const tooltip = reactive({
  trigger: 'axis',
    trigger: "axis",
  axisPointer: {
    type: 'line',
    lineStyle: { color: '#aaa' }
      type: "line",
      lineStyle: { color: "#aaa" },
  },
  // 自定义内容
  formatter: function (params) {
    if (!params || !params.length) return ''
    const axisLabel = params[0].axisValueLabel || params[0].axisValue || ''
      if (!params || !params.length) return "";
      const axisLabel = params[0].axisValueLabel || params[0].axisValue || "";
    const rows = params
      .map(p => {
        const colorDot = `<span style="display:inline-block;margin-right:6px;width:8px;height:8px;border-radius:50%;background:${p.color}"></span>`
        return `${colorDot}${p.seriesName}: ${p.value}`
          const colorDot = `<span style="display:inline-block;margin-right:6px;width:8px;height:8px;border-radius:50%;background:${p.color}"></span>`;
          return `${colorDot}${p.seriesName}: ${p.value}`;
      })
      .join('<br/>')
    return `<div>${axisLabel}</div><div>${rows}</div>`
  }
})
const lineSeries0 = ref([])
const lineSeries1 = ref([])
        .join("<br/>");
      return `<div>${axisLabel}</div><div>${rows}</div>`;
    },
  });
  const lineSeries0 = ref([]);
  const lineSeries1 = ref([]);
// 根据月份范围生成 x 轴数据
const generateMonthLabels = (startMonth, endMonth) => {
@@ -214,9 +215,9 @@
  let current = dayjs(startMonth);
  const end = dayjs(endMonth);
  
  while (current.isBefore(end) || current.isSame(end, 'month')) {
    while (current.isBefore(end) || current.isSame(end, "month")) {
    labels.push(`${current.month() + 1}月`);
    current = current.add(1, 'month');
      current = current.add(1, "month");
  }
  
  return labels;
@@ -224,129 +225,140 @@
const xAxis0 = ref([
  {
    type: 'category',
      type: "category",
    axisTick: { show: true, alignWithLabel: true },
    data: [],
  },
]);
const xAxis1 = ref([
  {
    type: 'category',
      type: "category",
    axisTick: { show: true, alignWithLabel: true },
    data: [],
  },
]);
const yAxis0 = [
{
    type: 'value',
    name: '收入统计', // 左侧y轴
    position: 'left',
      type: "value",
      name: "收入统计", // 左侧y轴
      position: "left",
    min: 0,
    // 坐标轴名称样式
    nameTextStyle: {
      color: '#000',
        color: "#000",
      fontSize: 14,
    },
  }
]
    },
  ];
const yAxis1 = [
{
    type: 'value',
    name: '支出统计', // 左侧y轴
    position: 'left',
      type: "value",
      name: "支出统计", // 左侧y轴
      position: "left",
    min: 0,
    // 坐标轴名称样式
    nameTextStyle: {
      color: '#000',
        color: "#000",
      fontSize: 14,
    },
  }
]
    },
  ];
const chartStylePie = {
    width: '100%',
    height: '100%' // 设置图表容器的高度
}
const pieColors = ['#F04864','#FACC14', '#8543E0', '#1890FF', '#13C2C2','#2FC25B']; // 可根据实际调整
    width: "100%",
    height: "100%", // 设置图表容器的高度
  };
  const pieColors = [
    "#F04864",
    "#FACC14",
    "#8543E0",
    "#1890FF",
    "#13C2C2",
    "#2FC25B",
  ]; // 可根据实际调整
const pieData0 = ref([]);
const pieData1 = ref([]);
const pieLegend0 = computed(() => ({
  show: true,
  top: 'center',
  left: '60%',
  orient: 'vertical',
  icon: 'circle',
  data: (pieData0.value || []).filter(item => item && item.name).map(item => item.name),
    top: "center",
    left: "60%",
    orient: "vertical",
    icon: "circle",
    data: (pieData0.value || [])
      .filter(item => item && item.name)
      .map(item => item.name),
  formatter: function(name) {
    if (!name) return '';
      if (!name) return "";
    const item = pieData0.value.find(i => i && i.name === name);
    if (!item) return name;
    return `${name} | ${item.percent} ${item.amount}`;
  },
  textStyle: {
    color: '#333',
      color: "#333",
    fontSize: 14,
    lineHeight: 26,
  }
    },
}));
const pieLegend1 = computed(() => ({
  show: true,
  top: 'center',
  left: '60%',
  orient: 'vertical',
  icon: 'circle',
  data: (pieData1.value || []).filter(item => item && item.name).map(item => item.name),
    top: "center",
    left: "60%",
    orient: "vertical",
    icon: "circle",
    data: (pieData1.value || [])
      .filter(item => item && item.name)
      .map(item => item.name),
  formatter: function(name) {
    if (!name) return '';
      if (!name) return "";
    const item = pieData1.value.find(i => i && i.name === name);
    if (!item) return name;
    return `${name} | ${item.percent} ${item.amount}`;
  },
  textStyle: {
    color: '#333',
      color: "#333",
    fontSize: 14,
    lineHeight: 26,
  }
    },
}));
const materialPieSeries0 = computed(() => [
  {
    type: 'pie',
    radius: ['50%', '65%'],
    center: ['25%', '50%'],
      type: "pie",
      radius: ["50%", "65%"],
      center: ["25%", "50%"],
    avoidLabelOverlap: false,
    itemStyle: {
      borderColor: '#fff',
      borderWidth: 2
        borderColor: "#fff",
        borderWidth: 2,
    },
    label: {
      show: false
        show: false,
    },
    data: (pieData0.value || []).filter(item => item && item.name),
    color: pieColors
  }
      color: pieColors,
    },
]);
const materialPieSeries1 = computed(() => [
  {
    type: 'pie',
    radius: ['50%', '65%'],
    center: ['25%', '50%'],
      type: "pie",
      radius: ["50%", "65%"],
      center: ["25%", "50%"],
    avoidLabelOverlap: false,
    itemStyle: {
      borderColor: '#fff',
      borderWidth: 2
        borderColor: "#fff",
        borderWidth: 2,
    },
    label: {
      show: false
        show: false,
    },
    data: (pieData1.value || []).filter(item => item && item.name),
    color: pieColors
  }
      color: pieColors,
    },
]);
const pieTooltip = reactive({
    trigger: 'item',
    trigger: "item",
  formatter: function(params) {
    // 检查数据是否存在
    if (!params.data) return params.name;
@@ -359,17 +371,18 @@
        <div>金额:${params.data.amount}</div>
      </div>
    `;
  }
})
    },
  });
const pageInfo = ref({
})
  const pageInfo = ref({});
// 格式化金额
const formatMoney = (value) => {
  if (!value && value !== 0) return '0';
  return Number(value).toLocaleString('zh-CN', { minimumFractionDigits: 2, maximumFractionDigits: 2 });
  const formatMoney = value => {
    if (!value && value !== 0) return "0";
    return Number(value).toLocaleString("zh-CN", {
      minimumFractionDigits: 2,
      maximumFractionDigits: 2,
    });
};
// 收入支出分析饼图
@@ -379,94 +392,101 @@
  const total = totalIncome + totalExpense;
  if (total === 0) {
    return [
      { name: '收入', value: 0, percent: '0%' },
      { name: '支出', value: 0, percent: '0%' }
        { name: "收入", value: 0, percent: "0%" },
        { name: "支出", value: 0, percent: "0%" },
    ];
  }
  const incomePercent = ((totalIncome / total) * 100).toFixed(0);
  const expensePercent = ((totalExpense / total) * 100).toFixed(0);
  return [
    { name: '收入', value: totalIncome, percent: `${incomePercent}%` },
    { name: '支出', value: totalExpense, percent: `${expensePercent}%` }
      { name: "收入", value: totalIncome, percent: `${incomePercent}%` },
      { name: "支出", value: totalExpense, percent: `${expensePercent}%` },
  ];
});
const pieLegendIncomeExpense = computed(() => ({
  show: false
    show: false,
}));
const pieTooltipIncomeExpense = reactive({
  trigger: 'item',
    trigger: "item",
  formatter: function(params) {
    if (!params.data) return params.name;
    return `${params.name}占比 ${params.percent}%`;
  }
    },
});
const pieSeriesIncomeExpense = computed(() => [
  {
    type: 'pie',
    radius: ['0%', '70%'],
    center: ['50%', '50%'],
      type: "pie",
      radius: ["0%", "70%"],
      center: ["50%", "50%"],
    avoidLabelOverlap: true,
    itemStyle: {
      borderColor: '#fff',
      borderWidth: 2
        borderColor: "#fff",
        borderWidth: 2,
    },
    label: {
      show: true,
      position: 'outside',
        position: "outside",
      formatter: function(params) {
        return `${params.name}占比 ${params.percent}%`;
      },
      fontSize: 14,
      color: '#333'
        color: "#333",
    },
    labelLine: {
      show: true,
      length: 15,
      length2: 10,
      lineStyle: {
        color: '#333'
      }
          color: "#333",
        },
    },
    emphasis: {
      label: {
        show: true,
        fontSize: 16,
        fontWeight: 'bold'
      }
          fontWeight: "bold",
        },
    },
    data: pieDataIncomeExpense.value,
    color: ['#1890FF', '#FACC14']
  }
      color: ["#1890FF", "#FACC14"],
    },
]);
// 行项盈利分析柱状图
const barXAxis = computed(() => {
  return [{
    type: 'category',
    data: (allBarTypes.value && allBarTypes.value.length > 0) ? allBarTypes.value : ['项目1', '项目2', '项目3', '项目4', '项目5', '项目6', '项目7'],
    return [
      {
        type: "category",
        data:
          allBarTypes.value && allBarTypes.value.length > 0
            ? allBarTypes.value
            : ["项目1", "项目2", "项目3", "项目4", "项目5", "项目6", "项目7"],
    axisTick: { show: true, alignWithLabel: true },
  }];
      },
    ];
});
const barYAxis = [{
  type: 'value',
  name: '单位: 元',
  position: 'left',
  const barYAxis = [
    {
      type: "value",
      name: "单位: 元",
      position: "left",
  min: 0,
  nameTextStyle: {
    color: '#000',
        color: "#000",
    fontSize: 14,
  },
}];
    },
  ];
const barGrid = {
  left: '3%',
  right: '4%',
  bottom: '3%',
  containLabel: true
    left: "3%",
    right: "4%",
    bottom: "3%",
    containLabel: true,
};
const barLegend = {
@@ -477,8 +497,12 @@
// 获取所有类型名称
const allBarTypes = computed(() => {
  const incomeTypes = (lineSeries0.value || []).map(item => item.name || item.typeName).filter(Boolean);
  const expenseTypes = (lineSeries1.value || []).map(item => item.name || item.typeName).filter(Boolean);
    const incomeTypes = (lineSeries0.value || [])
      .map(item => item.name || item.typeName)
      .filter(Boolean);
    const expenseTypes = (lineSeries1.value || [])
      .map(item => item.name || item.typeName)
      .filter(Boolean);
  return [...new Set([...incomeTypes, ...expenseTypes])];
});
@@ -486,23 +510,25 @@
  if (allBarTypes.value.length === 0) {
    return [
      {
        name: '支出',
        type: 'bar',
          name: "支出",
          type: "bar",
        data: [],
        itemStyle: { color: '#1890FF' }
          itemStyle: { color: "#1890FF" },
      },
      {
        name: '收入',
        type: 'bar',
          name: "收入",
          type: "bar",
        data: [],
        itemStyle: { color: '#13C2C2' }
      }
          itemStyle: { color: "#13C2C2" },
        },
    ];
  }
  
  // 计算每个项目的总收入(汇总所有月份)
  const incomeData = allBarTypes.value.map(typeName => {
    const incomeItem = (lineSeries0.value || []).find(item => (item.name || item.typeName) === typeName);
      const incomeItem = (lineSeries0.value || []).find(
        item => (item.name || item.typeName) === typeName
      );
    if (incomeItem && incomeItem.data && Array.isArray(incomeItem.data)) {
      return incomeItem.data.reduce((sum, val) => sum + (Number(val) || 0), 0);
    }
@@ -511,7 +537,9 @@
  
  // 计算每个项目的总支出(汇总所有月份)
  const expenseData = allBarTypes.value.map(typeName => {
    const expenseItem = (lineSeries1.value || []).find(item => (item.name || item.typeName) === typeName);
      const expenseItem = (lineSeries1.value || []).find(
        item => (item.name || item.typeName) === typeName
      );
    if (expenseItem && expenseItem.data && Array.isArray(expenseItem.data)) {
      return expenseItem.data.reduce((sum, val) => sum + (Number(val) || 0), 0);
    }
@@ -520,37 +548,38 @@
  
  return [
    {
      name: '支出',
      type: 'bar',
        name: "支出",
        type: "bar",
      data: expenseData,
      itemStyle: { color: '#1890FF' }
        itemStyle: { color: "#1890FF" },
    },
    {
      name: '收入',
      type: 'bar',
        name: "收入",
        type: "bar",
      data: incomeData,
      itemStyle: { color: '#13C2C2' }
    }
        itemStyle: { color: "#13C2C2" },
      },
  ];
});
const barTooltip = reactive({
  trigger: 'axis',
    trigger: "axis",
  axisPointer: {
    type: 'shadow'
      type: "shadow",
  },
  formatter: function (params) {
    if (!params || !params.length) return '';
    const axisLabel = params[0].axisValueLabel || params[0].axisValue || '';
      if (!params || !params.length) return "";
      const axisLabel = params[0].axisValueLabel || params[0].axisValue || "";
    const rows = params
      .map(p => {
        const colorDot = `<span style="display:inline-block;margin-right:6px;width:8px;height:8px;border-radius:50%;background:${p.color}"></span>`;
        const value = typeof p.value === 'number' ? p.value.toFixed(2) : p.value;
          const value =
            typeof p.value === "number" ? p.value.toFixed(2) : p.value;
        return `${colorDot}${p.seriesName} ${value}`;
      })
      .join('<br/>');
        .join("<br/>");
    return `<div>${axisLabel}</div><div>${rows}</div>`;
  }
    },
});
// 营收趋势分析
@@ -560,22 +589,26 @@
  right: 10,
};
const trendYAxis = [{
  type: 'value',
  name: '单位: 元',
  position: 'left',
  const trendYAxis = [
    {
      type: "value",
      name: "单位: 元",
      position: "left",
  min: 0,
  nameTextStyle: {
    color: '#000',
        color: "#000",
    fontSize: 14,
  },
}];
    },
  ];
const trendSeries = computed(() => {
  // 汇总所有支出类型的数据
  let expenseTrend = [];
  if (lineSeries1.value.length > 0) {
    const monthCount = Math.max(...lineSeries1.value.map(item => item.data?.length || 0));
      const monthCount = Math.max(
        ...lineSeries1.value.map(item => item.data?.length || 0)
      );
    expenseTrend = Array(monthCount).fill(0);
    lineSeries1.value.forEach(item => {
      if (item.data && Array.isArray(item.data)) {
@@ -591,7 +624,9 @@
  // 汇总所有收入类型的数据
  let incomeTrend = [];
  if (lineSeries0.value.length > 0) {
    const monthCount = Math.max(...lineSeries0.value.map(item => item.data?.length || 0));
      const monthCount = Math.max(
        ...lineSeries0.value.map(item => item.data?.length || 0)
      );
    incomeTrend = Array(monthCount).fill(0);
    lineSeries0.value.forEach(item => {
      if (item.data && Array.isArray(item.data)) {
@@ -606,31 +641,35 @@
  
  return [
    {
      name: '支出',
      type: 'line',
        name: "支出",
        type: "line",
      data: expenseTrend,
      itemStyle: { color: '#1890FF' },
      smooth: true
        itemStyle: { color: "#1890FF" },
        smooth: true,
    },
    {
      name: '收入',
      type: 'line',
        name: "收入",
        type: "line",
      data: incomeTrend,
      itemStyle: { color: '#13C2C2' },
      smooth: true
    }
        itemStyle: { color: "#13C2C2" },
        smooth: true,
      },
  ];
});
// 获取最近六个月的范围
const getLastSixMonths = () => {
  const endMonth = dayjs().format('YYYY-MM');
  const startMonth = dayjs().subtract(5, 'month').format('YYYY-MM');
    const endMonth = dayjs().format("YYYY-MM");
    const startMonth = dayjs().subtract(5, "month").format("YYYY-MM");
  return [startMonth, endMonth];
};
const getData = async () => {
  if (!dateRange.value || !Array.isArray(dateRange.value) || dateRange.value.length !== 2) {
    if (
      !dateRange.value ||
      !Array.isArray(dateRange.value) ||
      dateRange.value.length !== 2
    ) {
    return;
  }
  const startDateStr = dateRange.value[0];
@@ -643,7 +682,7 @@
  const startDate = dayjs(startDateStr);
  const endDate = dayjs(endDateStr);
  if (!startDate.isValid() || !endDate.isValid()) {
    console.error('无效的日期格式');
      console.error("无效的日期格式");
    return;
  }
  
@@ -653,56 +692,62 @@
  xAxis1.value[0].data = monthLabels;
  
  // 开始月份拼接第一天,结束月份拼接最后一天
  const entryDateStart = startDate.startOf('month').format('YYYY-MM-DD');
  const entryDateEnd = endDate.endOf('month').format('YYYY-MM-DD');
    const entryDateStart = startDate.startOf("month").format("YYYY-MM-DD");
    const entryDateEnd = endDate.endOf("month").format("YYYY-MM-DD");
  
  try {
    const {code,data} = await reportForms({entryDateStart, entryDateEnd});
    if(code === 200 && data) {
      pageInfo.value = data || {};
      // 安全处理数据,过滤掉 null 或 undefined
      pieData0.value = (data.incomeType || []).filter(item => item && item.typeName).map(item=>({
        name:item.typeName || '',
        value:item.account || 0,
        percent:`${((item.proportion || 0) * 100).toFixed(2)}%`,
        amount:`¥${(item.account || 0).toFixed(2)}`
      }))
      pieData1.value = (data.expenseType || []).filter(item => item && item.typeName).map(item=>({
        name:item.typeName || '',
        value:item.account || 0,
        percent:`${((item.proportion || 0) * 100).toFixed(2)}%`,
        amount:`¥${(item.account || 0).toFixed(2)}`
      }))
    }
      // const {code,data} = await reportForms({entryDateStart, entryDateEnd});
      // if(code === 200 && data) {
      //   pageInfo.value = data || {};
      //   // 安全处理数据,过滤掉 null 或 undefined
      //   pieData0.value = (data.incomeType || []).filter(item => item && item.typeName).map(item=>({
      //     name:item.typeName || '',
      //     value:item.account || 0,
      //     percent:`${((item.proportion || 0) * 100).toFixed(2)}%`,
      //     amount:`¥${(item.account || 0).toFixed(2)}`
      //   }))
      //   pieData1.value = (data.expenseType || []).filter(item => item && item.typeName).map(item=>({
      //     name:item.typeName || '',
      //     value:item.account || 0,
      //     percent:`${((item.proportion || 0) * 100).toFixed(2)}%`,
      //     amount:`¥${(item.account || 0).toFixed(2)}`
      //   }))
      // }
  } catch (error) {
    console.error('获取财务指标数据失败:', error);
      console.error("获取财务指标数据失败:", error);
  }
  try{
    const {code,data} = await reportIncome({entryDateStart, entryDateEnd});
    if(code==200 && data && Array.isArray(data)){
      lineSeries0.value = data.filter(item => item && item.typeName).map(item=>({
        name:item.typeName || '',
        type: 'line',
        data:(item.account || []).map(val => Number(val) || 0)
      }))
    }
      // const { code, data } = await reportIncome({ entryDateStart, entryDateEnd });
      // if (code == 200 && data && Array.isArray(data)) {
      //   lineSeries0.value = data
      //     .filter(item => item && item.typeName)
      //     .map(item => ({
      //       name: item.typeName || "",
      //       type: "line",
      //       data: (item.account || []).map(val => Number(val) || 0),
      //     }));
      // }
  }catch (error) {
    console.error('获取财务指标数据失败:', error);
      console.error("获取财务指标数据失败:", error);
  }
  try{
    const {code,data} = await reportExpense({entryDateStart, entryDateEnd});
    if(code==200 && data && Array.isArray(data)){
      lineSeries1.value = data.filter(item => item && item.typeName).map(item=>({
        name:item.typeName || '',
        type: 'line',
        data:(item.account || []).map(val => Number(val) || 0)
      }))
    }
      // const { code, data } = await reportExpense({
      //   entryDateStart,
      //   entryDateEnd,
      // });
      // if (code == 200 && data && Array.isArray(data)) {
      //   lineSeries1.value = data
      //     .filter(item => item && item.typeName)
      //     .map(item => ({
      //       name: item.typeName || "",
      //       type: "line",
      //       data: (item.account || []).map(val => Number(val) || 0),
      //     }));
      // }
  }catch (error) {
    console.error('获取财务指标数据失败:', error);
      console.error("获取财务指标数据失败:", error);
  }
};
// 初始化
onMounted(() => {
@@ -716,9 +761,13 @@
});
// 限制月份选择范围(最多12个月)
const disabledDate = (time) => {
  const disabledDate = time => {
  // 如果没有选择开始月份,不禁用任何日期
  if (!dateRange.value || !Array.isArray(dateRange.value) || !dateRange.value[0]) {
    if (
      !dateRange.value ||
      !Array.isArray(dateRange.value) ||
      !dateRange.value[0]
    ) {
    return false;
  }
  
@@ -726,19 +775,19 @@
  const currentMonth = dayjs(time);
  
  // 如果当前月份在开始月份之前,禁用
  if (currentMonth.isBefore(startMonth, 'month')) {
    if (currentMonth.isBefore(startMonth, "month")) {
    return true;
  }
  
  // 计算最大允许的月份(开始月份 + 11个月 = 12个月)
  const maxMonth = startMonth.add(11, 'month');
    const maxMonth = startMonth.add(11, "month");
  
  // 禁用超过12个月的月份
  return currentMonth.isAfter(maxMonth, 'month');
    return currentMonth.isAfter(maxMonth, "month");
};
// 处理月份范围变化
const handleDateChange = (newRange) => {
  const handleDateChange = newRange => {
  if (!newRange || !Array.isArray(newRange) || newRange.length !== 2) {
    return;
  }
@@ -746,12 +795,12 @@
  // 验证月份范围不超过12个月
  const startDate = dayjs(newRange[0]);
  const endDate = dayjs(newRange[1]);
  const monthDiff = endDate.diff(startDate, 'month');
    const monthDiff = endDate.diff(startDate, "month");
  
  if (monthDiff > 11) {
    proxy.$modal.msgWarning('最多只能选择12个月份');
      proxy.$modal.msgWarning("最多只能选择12个月份");
    // 自动调整为12个月
    const adjustedEnd = startDate.add(11, 'month').format('YYYY-MM');
      const adjustedEnd = startDate.add(11, "month").format("YYYY-MM");
    dateRange.value = [newRange[0], adjustedEnd];
    getData();
    return;
@@ -767,7 +816,6 @@
  dateRange.value = getLastSixMonths();
  getData();
};
</script>
<style scoped lang="scss">
@@ -951,10 +999,10 @@
    position: absolute;
    left: 0;
    top: 2px;
    content: '';
      content: "";
    width: 4px;
    height: 18px;
    background-color: #002FA7;
      background-color: #002fa7;
    border-radius: 2px;
  }
}