WXL
2026-09-17 3df460667d74868d0a54fce12d5e881bbd6c0c1a
src/views/statistics/donor.vue
@@ -67,23 +67,27 @@
            <span>中国分类分布</span>
          </div>
          <EChartsWrapper
            :id="'category-chart'"
            :options="categoryChartOptions"
            v-if="useMock"
            :id="'china-category-chart'"
            :options="chinaCategoryOptions"
            height="400px"
          />
          <el-empty v-else description="后端暂未提供中国分类统计接口"></el-empty>
        </el-card>
      </el-col>
      <el-col :span="12">
        <el-card>
          <div slot="header" class="clearfix">
            <span>死亡原因分析</span>
            <span>死亡原因分布</span>
          </div>
          <EChartsWrapper
            :id="'death-chart'"
            :options="deathChartOptions"
            v-if="useMock"
            :id="'death-cause-chart'"
            :options="deathCauseOptions"
            height="400px"
          />
          <el-empty v-else description="后端暂未提供死亡原因统计接口"></el-empty>
        </el-card>
      </el-col>
    </el-row>
@@ -94,71 +98,54 @@
        <span>捐献者详细信息</span>
      </div>
      <el-table
        v-loading="loading"
        :data="tableData"
        style="width: 100%"
        border
        stripe
      >
        <el-table-column label="捐献者编号" prop="donorNo" align="center"  />
        <el-table-column label="姓名" prop="name" align="center"  />
        <el-table-column label="性别" prop="gender" align="center" >
          <template slot-scope="{ row }">
            <el-tag :type="row.gender === '男' ? 'primary' : 'danger'" size="small">
              {{ row.gender }}
            </el-tag>
          </template>
        </el-table-column>
        <el-table-column label="年龄" prop="age" align="center"  />
        <el-table-column label="血型" prop="bloodType" align="center" >
          <template slot-scope="{ row }">
            <el-tag :type="getBloodTypeTag(row.bloodType)" size="small">
              {{ row.bloodType }}
            </el-tag>
          </template>
        </el-table-column>
        <el-table-column label="地区" prop="region" align="center"  />
        <el-table-column label="捐献时间" prop="donationTime" align="center"  />
        <el-table-column label="中国分类" prop="chinaCategory" align="center"  />
        <el-table-column label="死亡原因" prop="deathCause" align="center"  />
        <el-table-column label="捐献器官" prop="organs" align="center" >
          <template slot-scope="{ row }">
            <span>{{ row.organs.join('、') }}</span>
          </template>
        </el-table-column>
        <el-table-column label="操作" align="center" " fixed="right">
          <template slot-scope="{ row }">
            <el-button
              type="text"
              size="mini"
              @click="viewDonorDetail(row)"
            >
              详情
            </el-button>
          </template>
        </el-table-column>
      </el-table>
      <template v-if="useMock">
        <el-table
          v-loading="loading"
          :data="tableData"
          style="width: 100%"
          border
          stripe
        >
          <el-table-column label="捐献者编号" prop="donorNo" align="center" />
          <el-table-column label="姓名" prop="name" align="center" />
          <el-table-column label="性别" prop="gender" align="center" />
          <el-table-column label="年龄" prop="age" align="center" />
          <el-table-column label="血型" prop="bloodType" align="center" />
          <el-table-column label="地区" prop="region" align="center" />
          <el-table-column label="捐献时间" prop="donationTime" align="center" />
        </el-table>
      <el-pagination
        v-show="total > 0"
        :total="total"
        :page.sync="query.page"
        :limit.sync="query.limit"
        @current-change="handlePagination"
        @size-change="handlePageSizeChange"
        style="margin-top: 20px;"
        layout="total, sizes, prev, pager, next, jumper"
        :page-sizes="[10, 20, 50, 100]"
      />
        <el-pagination
          v-show="total > 0"
          :total="total"
          :page.sync="query.page"
          :limit.sync="query.limit"
          @current-change="handlePagination"
          @size-change="handlePageSizeChange"
          style="margin-top: 20px;"
          layout="total, sizes, prev, pager, next, jumper"
          :page-sizes="[10, 20, 50, 100]"
        />
      </template>
      <el-empty v-else description="后端暂未提供捐献者详细信息接口"></el-empty>
    </el-card>
  </div>
</template>
<script>
// 修正导入路径
import FilterPanel from '@/components/charts/FilterPanel.vue';
import EChartsWrapper from '@/components/charts/EChartsWrapper.vue';
import { caseSex, caseBloodType, caseAvgAge } from '@/api/businessApi';
import { toTotalsList, toNum } from '@/utils/totals';
import statisticsMode, { isStatisticsMock } from '@/utils/statisticsMode';
import { COLORS, PALETTE, axisTooltip, grid, legend } from '@/utils/chartStyle';
const AGE_GROUP_MAP = {
  '1': '<17岁',
  '2': '18-49岁',
  '3': '50-69岁',
  '4': '>69岁'
};
export default {
  name: 'DonorStatistics',
@@ -187,13 +174,13 @@
          type: 'select',
          multiple: true,
          options: [
            { label: '青岛地区', value: 'qingdao' },
            { label: '日照地区', value: 'rizhao' },
            { label: '济南地区', value: 'jinan' },
            { label: '烟台地区', value: 'yantai' },
            { label: '威海地区', value: 'weihai' },
            { label: '潍坊地区', value: 'weifang' },
            { label: '临沂地区', value: 'linyi' }
            { label: '青岛地区', value: '青岛地区' },
            { label: '日照地区', value: '日照地区' },
            { label: '济南地区', value: '济南地区' },
            { label: '烟台地区', value: '烟台地区' },
            { label: '威海地区', value: '威海地区' },
            { label: '潍坊地区', value: '潍坊地区' },
            { label: '临沂地区', value: '临沂地区' }
          ],
          width: '300px'
        },
@@ -206,19 +193,6 @@
          endPlaceholder: '结束月份',
          valueFormat: 'yyyy-MM',
          width: '300px'
        },
        {
          label: '年龄段',
          prop: 'ageRange',
          type: 'select',
          multiple: true,
          options: [
            { label: '<17岁', value: '0-17' },
            { label: '18-49岁', value: '18-49' },
            { label: '50-69岁', value: '50-69' },
            { label: '>69岁', value: '70-100' }
          ],
          width: '200px'
        },
        {
          label: '性别',
@@ -258,115 +232,109 @@
      // 图表配置
      ageChartOptions: {},
      genderBloodChartOptions: {},
      categoryChartOptions: {},
      deathChartOptions: {},
      // 接口返回数据
      sexData: [],
      bloodData: [],
      // 无接口图表的模拟数据(仅 mock 模式展示)
      chinaCategoryData: [
        { name: '中国一类(DBD)', value: 45 },
        { name: '中国二类(DCD)', value: 35 },
        { name: '中国三类(DBCD)', value: 20 }
      ],
      deathCauseData: [
        { name: '脑血管疾病', value: 40 },
        { name: '颅脑损伤', value: 30 },
        { name: '心脏疾病', value: 15 },
        { name: '其他原因', value: 15 }
      ],
      // 捐献者详细信息模拟数据(无后端接口,仅 mock 模式展示)
      donorList: [
        { donorNo: 'D2024001', name: '张伟', gender: '男', age: 45, bloodType: 'A', region: '青岛地区', donationTime: '2024-03-15' },
        { donorNo: 'D2024002', name: '王芳', gender: '女', age: 38, bloodType: 'B', region: '青岛地区', donationTime: '2024-03-22' },
        { donorNo: 'D2024003', name: '李娜', gender: '女', age: 52, bloodType: 'O', region: '日照地区', donationTime: '2024-04-02' },
        { donorNo: 'D2024004', name: '刘洋', gender: '男', age: 29, bloodType: 'AB', region: '青岛地区', donationTime: '2024-04-18' },
        { donorNo: 'D2024005', name: '陈静', gender: '女', age: 47, bloodType: 'A', region: '济南地区', donationTime: '2024-05-06' },
        { donorNo: 'D2024006', name: '杨强', gender: '男', age: 33, bloodType: 'B', region: '烟台地区', donationTime: '2024-05-21' },
        { donorNo: 'D2024007', name: '赵敏', gender: '女', age: 41, bloodType: 'O', region: '青岛地区', donationTime: '2024-06-03' },
        { donorNo: 'D2024008', name: '黄磊', gender: '男', age: 55, bloodType: 'A', region: '潍坊地区', donationTime: '2024-06-17' },
        { donorNo: 'D2024009', name: '周杰', gender: '男', age: 62, bloodType: 'O', region: '临沂地区', donationTime: '2024-07-01' },
        { donorNo: 'D2024010', name: '吴霞', gender: '女', age: 26, bloodType: 'AB', region: '日照地区', donationTime: '2024-07-15' },
        { donorNo: 'D2024011', name: '徐磊', gender: '男', age: 48, bloodType: 'B', region: '青岛地区', donationTime: '2024-08-09' },
        { donorNo: 'D2024012', name: '孙丽', gender: '女', age: 35, bloodType: 'O', region: '威海地区', donationTime: '2024-08-24' },
        { donorNo: 'D2024013', name: '马超', gender: '男', age: 44, bloodType: 'A', region: '济南地区', donationTime: '2024-09-05' },
        { donorNo: 'D2024014', name: '朱婷', gender: '女', age: 58, bloodType: 'B', region: '青岛地区', donationTime: '2024-09-19' },
        { donorNo: 'D2024015', name: '胡军', gender: '男', age: 31, bloodType: 'O', region: '烟台地区', donationTime: '2024-10-08' },
        { donorNo: 'D2024016', name: '郭涛', gender: '男', age: 68, bloodType: 'A', region: '青岛地区', donationTime: '2024-10-22' },
        { donorNo: 'D2024017', name: '何平', gender: '女', age: 39, bloodType: 'AB', region: '潍坊地区', donationTime: '2024-11-06' },
        { donorNo: 'D2024018', name: '高翔', gender: '男', age: 50, bloodType: 'B', region: '临沂地区', donationTime: '2024-11-20' },
        { donorNo: 'D2024019', name: '林芳', gender: '女', age: 27, bloodType: 'O', region: '青岛地区', donationTime: '2024-12-04' },
        { donorNo: 'D2024020', name: '罗刚', gender: '男', age: 42, bloodType: 'A', region: '日照地区', donationTime: '2024-12-18' },
        { donorNo: 'D2023021', name: '郑爽', gender: '女', age: 34, bloodType: 'B', region: '青岛地区', donationTime: '2023-06-10' },
        { donorNo: 'D2023022', name: '梁宇', gender: '男', age: 57, bloodType: 'O', region: '济南地区', donationTime: '2023-07-25' },
        { donorNo: 'D2023023', name: '谢娜', gender: '女', age: 49, bloodType: 'A', region: '威海地区', donationTime: '2023-08-14' },
        { donorNo: 'D2023024', name: '韩冰', gender: '男', age: 23, bloodType: 'AB', region: '青岛地区', donationTime: '2023-09-30' }
      ],
      // 表格数据
      tableData: [],
      total: 0,
      // 模拟数据
      mockData: {
        table: [
          { id: 1, donorNo: 'D2024001', name: '张三', gender: '男', age: 45, bloodType: 'A', region: '青岛地区', donationTime: '2024-01-15', chinaCategory: '中国一类(DBD)', deathCause: '脑外伤', organs: ['全肝', '左肾', '右肾'] },
          { id: 2, donorNo: 'D2024002', name: '李四', gender: '女', age: 32, bloodType: 'B', region: '青岛地区', donationTime: '2024-01-20', chinaCategory: '中国二类(DCD)', deathCause: '心搏骤停', organs: ['心脏', '眼角膜'] },
          { id: 3, donorNo: 'D2024003', name: '王五', gender: '男', age: 58, bloodType: 'O', region: '日照地区', donationTime: '2024-02-10', chinaCategory: '中国三类(DBCD)', deathCause: '脑血管意外', organs: ['全肝', '胰腺'] },
          { id: 4, donorNo: 'D2024004', name: '赵六', gender: '男', age: 28, bloodType: 'AB', region: '济南地区', donationTime: '2024-02-15', chinaCategory: '中国一类(DBD)', deathCause: '交通事故', organs: ['全肺', '左肾', '右肾'] },
          { id: 5, donorNo: 'D2024005', name: '钱七', gender: '女', age: 65, bloodType: 'A', region: '烟台地区', donationTime: '2024-02-20', chinaCategory: '中国二类(DCD)', deathCause: '心肌梗死', organs: ['心脏'] },
          { id: 6, donorNo: 'D2024006', name: '孙八', gender: '男', age: 42, bloodType: 'B', region: '威海地区', donationTime: '2024-03-05', chinaCategory: '中国一类(DBD)', deathCause: '脑肿瘤', organs: ['左肾', '右肾', '眼角膜'] },
          { id: 7, donorNo: 'D2024007', name: '周九', gender: '男', age: 37, bloodType: 'O', region: '潍坊地区', donationTime: '2024-03-10', chinaCategory: '中国三类(DBCD)', deathCause: '脑外伤', organs: ['肝脏', '胰腺', '眼角膜'] },
          { id: 8, donorNo: 'D2024008', name: '吴十', gender: '女', age: 25, bloodType: 'AB', region: '临沂地区', donationTime: '2024-03-15', chinaCategory: '中国二类(DCD)', deathCause: '交通事故', organs: ['心脏', '肺'] }
        ],
        age: [
          { ageRange: '<17岁', male: 5, female: 3 },
          { ageRange: '18-49岁', male: 45, female: 30 },
          { ageRange: '50-69岁', male: 35, female: 25 },
          { ageRange: '>69岁', male: 10, female: 8 }
        ],
        gender: [
          { name: '男性', value: 95 },
          { name: '女性', value: 66 }
        ],
        blood: [
          { name: 'A型', value: 45 },
          { name: 'B型', value: 38 },
          { name: 'O型', value: 52 },
          { name: 'AB型', value: 26 }
        ],
        category: [
          { name: '中国一类(DBD)', value: 85 },
          { name: '中国二类(DCD)', value: 55 },
          { name: '中国三类(DBCD)', value: 21 }
        ],
        death: [
          { name: '脑外伤', value: 45 },
          { name: '心搏骤停', value: 35 },
          { name: '脑血管意外', value: 35 },
          { name: '交通事故', value: 20 },
          { name: '心肌梗死', value: 25 },
          { name: '其他', value: 15 }
        ]
      }
      total: 0
    };
  },
  computed: {
    useMock() {
      return isStatisticsMock();
    },
    chinaCategoryOptions() {
      return this.buildPieOptions('中国分类', this.chinaCategoryData);
    },
    deathCauseOptions() {
      return this.buildPieOptions('死亡原因', this.deathCauseData);
    }
  },
  created() {
    this.loadData();
    // 数据源(mock/真实接口)切换时重新加载
    this.$watch(() => statisticsMode.useMock, () => this.loadData());
  },
  methods: {
    // 组装查询条件
    buildQuery() {
      const q = {};
      if (this.query.region && this.query.region.length) {
        q.area = this.query.region.join(',');
      }
      if (this.query.monthRange && this.query.monthRange.length === 2) {
        q.startTime = this.query.monthRange[0];
        q.endTime = this.query.monthRange[1];
      }
      if (this.query.sex) q.sex = this.query.sex;
      if (this.query.bloodType) q.boodType = this.query.bloodType;
      return q;
    },
    // 加载数据
    async loadData() {
      this.loading = true;
      try {
        await new Promise(resolve => setTimeout(resolve, 500));
        const q = this.buildQuery();
        const [sexRes, bloodRes, avgRes] = await Promise.all([
          caseSex(q),
          caseBloodType(q),
          caseAvgAge(q)
        ]);
        // 处理表格数据
        let filteredData = [...this.mockData.table];
        this.sexData = toTotalsList(sexRes);
        this.bloodData = toTotalsList(bloodRes);
        const avgList = toTotalsList(avgRes);
        if (this.query.region.length > 0) {
          filteredData = filteredData.filter(item =>
            this.query.region.includes(item.region.replace('地区', '').toLowerCase())
          );
        }
        if (this.query.monthRange && this.query.monthRange.length === 2) {
          const [start, end] = this.query.monthRange;
          filteredData = filteredData.filter(item =>
            item.donationTime >= start && item.donationTime <= end
          );
        }
        if (this.query.ageRange.length > 0) {
          filteredData = filteredData.filter(item => {
            const age = item.age;
            return this.query.ageRange.some(range => {
              if (range === '0-17') return age < 18;
              if (range === '18-49') return age >= 18 && age <= 49;
              if (range === '50-69') return age >= 50 && age <= 69;
              if (range === '70-100') return age >= 70;
              return false;
            });
          });
        }
        if (this.query.gender) {
          filteredData = filteredData.filter(item => item.gender === this.query.gender);
        }
        if (this.query.bloodType) {
          filteredData = filteredData.filter(item => item.bloodType === this.query.bloodType);
        }
        // 分页
        const start = (this.query.page - 1) * this.query.limit;
        this.tableData = filteredData.slice(start, start + this.query.limit);
        this.total = filteredData.length;
        // 更新概览数据
        this.updateOverviewData(filteredData);
        // 更新图表
        this.updateOverviewData(avgList);
        this.updateCharts();
        // 捐献者详细信息无 /opo/totals 聚合接口,使用模拟数据补全
        this.updateDonorTable();
      } catch (error) {
        console.error('加载数据失败:', error);
        this.$message.error('数据加载失败');
@@ -376,220 +344,164 @@
    },
    // 更新概览数据
    updateOverviewData(data) {
      if (data.length === 0) return;
      const total = data.length;
      const males = data.filter(item => item.gender === '男').length;
      const females = data.filter(item => item.gender === '女').length;
      const avgAge = data.reduce((sum, item) => sum + item.age, 0) / total;
    updateOverviewData(avgList) {
      const males = this.sexData.reduce((sum, item) => sum + toNum(item.manCount), 0);
      const females = this.sexData.reduce((sum, item) => sum + toNum(item.womanCount), 0);
      const total = males + females;
      const avgAge = avgList.length
        ? toNum(avgList.reduce((sum, item) => sum + toNum(item.avgAge), 0) / avgList.length)
        : 0;
      this.overviewData[0].value = total;
      this.overviewData[1].value = `${((males / total) * 100).toFixed(1)}%`;
      this.overviewData[2].value = `${((females / total) * 100).toFixed(1)}%`;
      this.overviewData[1].value = total > 0 ? `${((males / total) * 100).toFixed(1)}%` : '0%';
      this.overviewData[2].value = total > 0 ? `${((females / total) * 100).toFixed(1)}%` : '0%';
      this.overviewData[3].value = avgAge.toFixed(1);
    },
    // 更新图表
    updateCharts() {
      // 年龄分布图
      // 年龄分布图(左男右女,清爽发散金字塔)
      this.ageChartOptions = {
        tooltip: {
          trigger: 'axis',
          axisPointer: {
            type: 'shadow'
          }
        tooltip: axisTooltip(),
        legend: legend(['男性', '女性']),
        grid: grid(),
        xAxis: {
          type: 'value',
          axisLine: { show: false },
          axisTick: { show: false },
          axisLabel: { color: '#8a919f', fontSize: 12, formatter: value => Math.abs(value) },
          splitLine: { lineStyle: { type: 'dashed', color: '#f0f1f5' } }
        },
        legend: {
          data: ['男性', '女性']
        yAxis: {
          type: 'category',
          data: this.sexData.map(item => AGE_GROUP_MAP[item.ageGroup] || item.ageGroup || '未知'),
          axisLine: { show: false },
          axisTick: { show: false },
          axisLabel: { color: '#606266', fontSize: 13 }
        },
        grid: {
          left: '3%',
          right: '4%',
          bottom: '3%',
          containLabel: true
        },
        xAxis: [
          {
            type: 'value',
            position: 'bottom',
            axisLabel: {
              formatter: function(value) {
                return Math.abs(value);
              }
            }
          }
        ],
        yAxis: [
          {
            type: 'category',
            axisTick: {
              show: false
            },
            data: this.mockData.age.map(item => item.ageRange)
          }
        ],
        series: [
          {
            name: '男性',
            type: 'bar',
            stack: '性别',
            data: this.mockData.age.map(item => item.male),
            itemStyle: { color: '#409EFF' }
            barMaxWidth: 18,
            data: this.sexData.map(item => toNum(item.manCount)),
            itemStyle: { color: COLORS.blue, borderRadius: [4, 0, 0, 4] }
          },
          {
            name: '女性',
            type: 'bar',
            stack: '性别',
            data: this.mockData.age.map(item => -item.female),
            itemStyle: { color: '#F56C6C' }
            barMaxWidth: 18,
            data: this.sexData.map(item => -toNum(item.womanCount)),
            itemStyle: { color: COLORS.coral, borderRadius: [0, 4, 4, 0] }
          }
        ]
      };
      // 性别与血型组合图
      // 性别与血型分布图(同心环,配色清爽)
      const males = this.bloodData.reduce((sum, item) => sum + toNum(item.manCount), 0);
      const females = this.bloodData.reduce((sum, item) => sum + toNum(item.womanCount), 0);
      const bloodPie = this.bloodData.map(item => ({
        name: item.boodType || '未知',
        value: toNum(item.boodTypeCount) || (toNum(item.manCount) + toNum(item.womanCount))
      }));
      this.genderBloodChartOptions = {
        tooltip: {
          trigger: 'item',
          formatter: '{a} <br/>{b} : {c} ({d}%)'
        },
        legend: {
          data: [
            '男性', '女性',
            'A型', 'B型', 'O型', 'AB型'
          ],
          top: 20
        },
        grid: {
          top: '20%',
          bottom: '20%',
          left: '10%',
          right: '10%'
        },
        legend: { data: ['男性', '女性', ...this.bloodData.map(item => item.boodType || '未知')], top: 20 },
        series: [
          {
            name: '性别分布',
            type: 'pie',
            radius: [0, '30%'],
            radius: [0, '40%'],
            center: ['25%', '50%'],
            label: {
              position: 'inner',
              fontSize: 12
            },
            data: this.mockData.gender
            label: { position: 'inner', fontSize: 12 },
            data: [
              { name: '男性', value: males },
              { name: '女性', value: females }
            ],
            color: [COLORS.blue, COLORS.coral]
          },
          {
            name: '血型分布',
            type: 'pie',
            radius: ['40%', '55%'],
            radius: ['55%', '75%'],
            center: ['25%', '50%'],
            data: this.mockData.blood
          },
          {
            name: '性别血型对比',
            type: 'pie',
            radius: [0, '30%'],
            center: ['75%', '50%'],
            label: {
              position: 'inner',
              fontSize: 12
            },
            data: [
              { name: '男-A', value: 20 },
              { name: '男-B', value: 15 },
              { name: '男-O', value: 25 },
              { name: '男-AB', value: 10 },
              { name: '女-A', value: 12 },
              { name: '女-B', value: 8 },
              { name: '女-O', value: 10 },
              { name: '女-AB', value: 5 }
            ]
            label: { fontSize: 14, color: '#606266' },
            data: bloodPie,
            color: [COLORS.amber, COLORS.teal, COLORS.purple, COLORS.orange]
          }
        ]
      };
    },
      // 中国分类分布图
      this.categoryChartOptions = {
    // 捐献者详细信息(无接口,模拟数据补全 + 过滤分页)
    updateDonorTable() {
      let list = this.donorList;
      if (this.query.region && this.query.region.length) {
        list = list.filter(item => this.query.region.includes(item.region));
      }
      if (this.query.monthRange && this.query.monthRange.length === 2) {
        const start = this.query.monthRange[0];
        const end = this.query.monthRange[1];
        list = list.filter(item => {
          const m = item.donationTime.slice(0, 7);
          return m >= start && m <= end;
        });
      }
      if (this.query.gender) {
        list = list.filter(item => item.gender === this.query.gender);
      }
      if (this.query.bloodType) {
        list = list.filter(item => item.bloodType === this.query.bloodType);
      }
      this.total = list.length;
      const start = (this.query.page - 1) * this.query.limit;
      this.tableData = list.slice(start, start + this.query.limit);
    },
    // 生成饼图配置(无接口图表的 mock 展示)
    buildPieOptions(name, data) {
      return {
        color: PALETTE,
        tooltip: {
          trigger: 'item',
          formatter: '{a} <br/>{b} : {c} ({d}%)'
        },
        legend: {
          orient: 'vertical',
          right: 10,
          top: 'center',
          data: this.mockData.category.map(item => item.name)
          left: 'left',
          top: 'middle',
          itemWidth: 10,
          itemHeight: 10,
          itemGap: 16,
          textStyle: { fontSize: 14, color: '#606266' },
          data: data.map(item => item.name)
        },
        series: [
          {
            name: '中国分类',
            name,
            type: 'pie',
            radius: ['30%', '70%'],
            center: ['40%', '50%'],
            roseType: 'radius',
            label: {
              show: true
            },
            radius: '55%',
            center: ['55%', '50%'],
            itemStyle: { borderColor: '#fff', borderWidth: 2 },
            label: { fontSize: 15, color: '#606266', formatter: '{b} {d}%' },
            labelLine: { lineStyle: { color: '#c0c4cc' } },
            data,
            emphasis: {
              label: {
                show: true
              itemStyle: {
                shadowBlur: 10,
                shadowOffsetX: 0,
                shadowColor: 'rgba(0, 0, 0, 0.5)'
              }
            },
            data: this.mockData.category
            }
          }
        ]
      };
      // 死亡原因分析图
      this.deathChartOptions = {
        tooltip: {
          trigger: 'item',
          formatter: '{b}: {c} ({d}%)'
        },
        legend: {
          orient: 'vertical',
          left: 10,
          top: 'center',
          data: this.mockData.death.map(item => item.name)
        },
        series: [
          {
            name: '死亡原因',
            type: 'pie',
            radius: ['30%', '60%'],
            center: ['60%', '50%'],
            avoidLabelOverlap: false,
            label: {
              show: true,
              formatter: '{b|{b}}\n{c|{c} ({d}%)}',
              rich: {
                b: {
                  fontSize: 12,
                  lineHeight: 20
                },
                c: {
                  fontSize: 10,
                  color: '#999'
                }
              }
            },
            emphasis: {
              label: {
                show: true,
                fontSize: '16',
                fontWeight: 'bold'
              }
            },
            data: this.mockData.death
          }
        ]
      };
    },
    // 获取血型标签类型
    getBloodTypeTag(type) {
      const map = { 'A': 'danger', 'B': 'primary', 'O': 'success', 'AB': 'warning' };
      return map[type] || 'info';
    },
    // 处理查询
@@ -628,14 +540,6 @@
    // 处理导出
    handleExport() {
      this.$message.info('导出功能开发中...');
    },
    // 查看捐献者详情
    viewDonorDetail(row) {
      this.$router.push({
        path: '/donor/detail',
        query: { id: row.id }
      });
    }
  }
};