<template>
  <el-dialog :model-value="silent || modelValue" :class="['report-detail-dialog', { 'is-silent': silent }]" top="5vh"
    :close-on-click-modal="!silent" :show-close="!silent"
    @update:model-value="(v) => { if (!silent) $emit('update:modelValue', v); }" @open="onOpen">
    <div class="body-wrap" v-loading="loading || exporting" :element-loading-text="exporting ? '正在生成文件…' : undefined"
      ref="reportContentRef">
      <div class="body-header">
        <div class="body-title">{{ reportInfo }}</div>
        <img src="@/assets/image/close-btn.svg" alt="" class="close-btn" @click="closeDialog" />
      </div>

      <template v-if="detail.id">
        <!-- 报告封面 -->
        <div class="report-cover">
          <div class="cover-info">
            <div class="hospital-wrap">
              <div class="cover-hospital">{{ detail.hospital || "—" }}</div>
              <div class="cover-period">{{ coverPeriod }}</div>
            </div>

            <div class="cover-stat-row">
              高效 · 主动 · 安心
            </div>
            <div class="cover-meta">
              <div>上海康策软件有限公司</div>
              <div class="date">报告日期：{{ detail.date || "—" }}</div>
            </div>
          </div>
          <div class="cover-banner">
            <img src="@/assets/image/admin/reports/report-bg.svg" alt="">
          </div>
        </div>

        <!-- 服务综述 -->
        <section class="section-card report-section">
          <div class="border-title">服务综述</div>
          <div class="summary-card">
            <div class="summary-text">
              <span class="light">感谢贵院一直以来对上海康策的信任与配合。</span> <br>
              <span class="em">
                本期我们累计处理服务工单：<span class="blue">{{ 28
                }}次</span>，完成率达：<span class="green">{{ 95 }}%</span>；同时安排回访：<span class="cyan">{{ 3
                  }}次</span>、现场巡检：<span class="yellow">{{ 1 }}次</span>及参与培训：<span class="purple">{{ 1
                  }}次</span>，力求从响应、预防到能力共建，全方位护航医院信息化环境。
              </span> <br>
              <span class="light">
                每一次服务工单的闭环、每一次现场巡检，都承载着我们对医疗服务质量与患者安全的共同承诺。服务团队将持续精进，为医院智慧医疗建设提供坚实后盾。
              </span>
            </div>

            <img class="summery-bg" src="@/assets/image/admin/reports/summery-bg.svg" alt="">
            <!-- <div class="summary-illu" aria-hidden="true">👨‍⚕️</div> -->
          </div>
        </section>

        <!-- 月度请求趋势 -->
        <section class="section-card report-section" v-if="detail.monthlyTrend?.length">
          <div class="border-title">月度请求趋势</div>
          <div class="trend-chart">
            <v-chart :option="trendOption" autoresize class="trend-chart-canvas" />
          </div>
          <div class="trend-unit">单位:次</div>
        </section>

        <!-- 科室服务请求数量 -->
        <section class="section-card report-section" v-if="detail.departmentData?.length">
          <div class="border-title">科室服务请求数量</div>
          <div class="dept-chart">
            <v-chart :option="deptOption" autoresize class="dept-chart-canvas" />
          </div>
        </section>

        <!-- 服务等级 / 反馈渠道 占比 -->
        <section class="report-section grid">
          <div class="section-card" v-if="detail.issueTypeData?.length">
            <div class="border-title">问题类型请求分布</div>
            <div class="section-body">
              <div class="section-item" v-for="(item, index) in detail.issueTypeData" :key="item.name">
                <div class="section-bar" :style="{ background: item.bg, width: (item.ratio * 100) + '%' }"></div>
                <div class="section-data">
                  <div class="name">{{ item.name }}</div>
                  <div class="count">{{ item.count }}次</div>
                </div>
              </div>
            </div>
          </div>
          <div class="section-card" v-if="detail.priorityData?.length">
            <div class="border-title">优先级分布</div>
            <div class="section-body ring-body">
              <div class="ring-chart">
                <v-chart :option="priorityOption" autoresize class="ring-chart-canvas" />
                <div class="ring-center">
                  <div class="ring-center-label">总计</div>
                  <div class="ring-center-value">{{ priorityTotal }}</div>
                </div>
              </div>
              <ul class="ring-legend">
                <li class="ring-legend-item" v-for="(item, index) in detail.priorityData" :key="item.name">
                  <span class="ring-dot" :style="{ background: ringColors[index % ringColors.length] }"></span>
                  <span class="ring-legend-text">{{ item.name }} {{ item.count }}</span>
                </li>
              </ul>
            </div>
          </div>

          <div class="section-card" v-if="detail.feedBacks?.length">
            <div class="border-title">反馈渠道占比</div>
            <div class="section-body ring-body">
              <div class="ring-chart">
                <v-chart :option="feedbackChannelOption" autoresize class="ring-chart-canvas" />
                <div class="ring-center">
                  <div class="ring-center-label">总计</div>
                  <div class="ring-center-value">{{ feedbackChannelTotal }}</div>
                </div>
              </div>
              <ul class="ring-legend">
                <li class="ring-legend-item" v-for="(item, index) in sortedFeedbackChannelData" :key="item.name">
                  <span class="ring-dot" :style="{ background: ringColors[index % ringColors.length] }"></span>
                  <span class="ring-legend-text">{{ item.name }} {{ feedbackPercent(item.count) }}</span>
                </li>
              </ul>
            </div>
          </div>
        </section>

        <!-- 科室服务请求明细 -->
        <section class="section-card report-section fill" v-if="detail.orderDetails?.length">
          <div class="border-title">科室服务请求明细</div>
          <el-table :data="detail.orderDetails" class="report-table" :fit="false">
            <el-table-column prop="orderNo" label="工单号" width="100px" />
            <el-table-column prop="hospital" label="医院" width="auto" />
            <el-table-column prop="problem" label="问题描述" width="180px" />
            <el-table-column prop="type" label="类型" width="auto" />
            <el-table-column label="优先级" width="70px">
              <template #default="{ row }">
                <div class="priority-dot" :class="priorityClass(row.priority)">{{ row.priority }}</div>
              </template>
            </el-table-column>
            <el-table-column label="状态" width="80px">
              <template #default="{ row }">
                <div class="status-pill" :class="statusClass(row.status)">{{ row.status }}</div>
              </template>
            </el-table-column>
            <el-table-column prop="submitTime" label="提交时间" width="auto" />
            <el-table-column prop="completeTime" label="完成时间" width="auto" />
          </el-table>
        </section>
      </template>

      <el-empty v-else-if="!loading" description="暂无报告数据" />
    </div>

    <div class="body-footer">
      <el-button @click="closeDialog">取消</el-button>
      <el-button type="primary" @click="emit('download', detail)">下载报告</el-button>
    </div>
  </el-dialog>
</template>

<script setup>
import { computed, nextTick, ref, watch } from "vue";
import { ElMessage } from "element-plus";
import { getAdminReportDetail } from "@/service/modular/admin";
import { useReportPdfExport } from "@/composables/useReportPdfExport";
import { useReportDocxExport } from "@/composables/useReportDocxExport";
import VChart from "vue-echarts";
import { use } from "echarts/core";
import { CanvasRenderer } from "echarts/renderers";
import { LineChart, BarChart, PieChart } from "echarts/charts";
import {
  GridComponent,
  TooltipComponent,
} from "echarts/components";

use([CanvasRenderer, LineChart, BarChart, PieChart, GridComponent, TooltipComponent]);

const reportInfo = ref("");
const buildReportInfo = (row) => {
  const hospital = row?.hospital;
  const period = row?.period || "";
  const typeText = row?.type === "annual" ? "报告" : " 季度报告";
  return `${hospital} - ${period}${typeText}`;
};

const props = defineProps({
  modelValue: { type: Boolean, default: false },
  reportId: { type: [String, Number], default: "" },
  reportRow: { type: Object, default: null },
  /** 静默模式:true 时弹窗不展示给用户(定位屏幕外),但内部仍加载数据,父组件可调用 handleExportPdf */
  silent: { type: Boolean, default: false },
});
const emit = defineEmits(["update:modelValue", "download"]);

const loading = ref(false);
const exporting = ref(false);
const detail = ref({});

// 用于 PDF 导出:取到 .body-wrap 节点(去除 .body-header 后导出)
const reportContentRef = ref(null);
const { exportReportPdf } = useReportPdfExport();
const { exportReportDocx } = useReportDocxExport();

/**
 * 将详情内容导出为 PDF。
 *  - 不克隆 DOM,直接将 body-wrap 移到离屏容器后截图
 *  - 自动隐藏 body-header(不参与 PDF)
 *  - 保留 canvas/ECharts/svg 等真实绘制内容
 * @param overrideId 可选,传入 id 时若当前 detail 不是该报告则先加载
 * @param overrideRow 可选,传入 row 用于生成文件名
 */
const handleExportPdf = async (overrideId, overrideRow) => {
  const targetId = overrideId ?? props.reportId;
  const targetRow = overrideRow ?? props.reportRow;
  if (!targetId) {
    ElMessage.error('报告不存在');
    return;
  }
  exporting.value = true;
  try {
    // 更新标题(用于文件名)
    if (targetRow) reportInfo.value = buildReportInfo(targetRow);
    // 如果当前 detail 不是目标报告,先加载
    if (!detail.value?.id || detail.value.id !== targetId) {
      await loadDetail(targetId);
    }
    await nextTick();
    // 等 ECharts canvas 完成渲染(echarts canvas 渲染是异步的)
    await new Promise((r) => setTimeout(r, 500));
    const bodyWrap = reportContentRef.value;
    if (!bodyWrap) {
      ElMessage.error('未找到可导出的报告内容');
      return;
    }
    const fileName = `${(reportInfo.value || '服务报告').replace(/\s+/g, '_')}.pdf`;
    // 移交给 composable:它会自动遍历 body-wrap 的直接子元素,
    // 隐藏 .body-header / .el-loading-mask 等,逐段生成 PDF。
    // 子元素带 data-newpage="true" 时会从新一页开始。
    await exportReportPdf(bodyWrap, fileName, {
      silent: true, // 父组件已展示全局 loading
    });
  } catch (e) {
    console.error('[handleExportPdf] 失败:', e);
    ElMessage.error(e?.message || 'PDF 导出失败');
  } finally {
    exporting.value = false;
  }
};

/**
 * 将详情内容导出为 Word(docx)。
 *  - 截图 + 嵌入 docx(由 useReportDocxExport 实现)
 *  - 流程与 handleExportPdf 完全对齐
 */
const handleExportDocx = async (overrideId, overrideRow) => {
  const targetId = overrideId ?? props.reportId;
  const targetRow = overrideRow ?? props.reportRow;
  if (!targetId) {
    ElMessage.error('报告不存在');
    return;
  }
  exporting.value = true;
  try {
    if (targetRow) reportInfo.value = buildReportInfo(targetRow);
    if (!detail.value?.id || detail.value.id !== targetId) {
      await loadDetail(targetId);
    }
    await nextTick();
    await new Promise((r) => setTimeout(r, 500));
    const bodyWrap = reportContentRef.value;
    if (!bodyWrap) {
      ElMessage.error('未找到可导出的报告内容');
      return;
    }
    const fileName = `${(reportInfo.value || '服务报告').replace(/\s+/g, '_')}.docx`;
    await exportReportDocx(bodyWrap, fileName, {
      silent: true, // 父组件已展示全局 loading
    });
  } catch (e) {
    console.error('[handleExportDocx] 失败:', e);
    ElMessage.error(e?.message || 'Word 导出失败');
  } finally {
    exporting.value = false;
  }
};

// 暴露给父组件
defineExpose({ handleExportPdf, handleExportDocx });

const loadDetail = async (overrideId) => {
  const id = overrideId ?? props.reportId;
  if (!id) return;
  loading.value = true;
  try {
    const data = await getAdminReportDetail(id);
    detail.value = data || {};
    Object.assign(detail.value, {
      // monthlyTrend: [
      //   {
      //     "month": "1月",
      //     "count": 10
      //   },
      //   {
      //     "month": "2月",
      //     "count": 14
      //   },
      //   {
      //     "month": "3月",
      //     "count": 7
      //   }
      // ],
      // departmentData: [{
      //   name: "检验科",
      //   count: "28"
      // }, {
      //   name: "门诊办",
      //   count: "23"
      // }, {
      //   name: "信息科",
      //   count: "22"
      // }, {
      //   name: "护理部",
      //   count: "20"
      // }, {
      //   name: "药房",
      //   count: "16"
      // }, {
      //   name: "住院部",
      //   count: "15"
      // }, {
      //   name: "检验科",
      //   count: "28"
      // }, {
      //   name: "门诊办",
      //   count: "23"
      // },],
      // issueTypeData: [{
      //   name: "系统故障",
      //   count: 8
      // }, {
      //   name: "使用咨询",
      //   count: 12
      // }, {
      //   name: "功能需求",
      //   count: 5
      // }, {
      //   name: "数据问题",
      //   count: 3
      // }],
      priorityData: [{
        name: "高优先级",
        count: detail.value.high
      }, {
        name: "中优先级",
        count: detail.value.medium
      }, {
        name: "低优先级",
        count: detail.value.low
      }],
      // feedBacks: [{
      //   name: "微信群",
      //   count: 8
      // }, {
      //   name: "微信",
      //   count: 12
      // }, {
      //   name: "电话",
      //   count: 5
      // }, {
      //   name: "钉钉群",
      //   count: 3
      // }, {
      //   name: "现场",
      //   count: 3
      // }, {
      //   name: "钉钉",
      //   count: 3
      // }, {
      //   name: "其他",
      //   count: 3
      // }],
    })
    const issueTypeBgMap = {
      '系统故障': 'linear-gradient( 90deg, #639FFF 0%, #3289FB 100%)',
      '使用咨询': 'linear-gradient( 90deg, #65D6DA 0%, #00C8B3 100%)',
      '功能需求': 'linear-gradient( 90deg, #90CD88 0%, #34C759 100%)',
      '数据问题': 'linear-gradient( 90deg, #B5A1FF 0%, #6155F5 100%)'
    }
    const total = detail.value.issueTypeData.reduce(((accumulator, item) => {
      return accumulator + item.count
    }), 0)

    detail.value.issueTypeData.forEach(item => {
      item.bg = issueTypeBgMap[item.name];
      item.ratio = item.count / total
    });

  } catch (e) {
    ElMessage.error(e?.message || "报告加载失败");
  } finally {
    loading.value = false;
  }
};

const onOpen = () => {
  loadDetail();
  reportInfo.value = buildReportInfo(props.reportRow);
}

watch(
  () => props.reportId,
  () => {
    if (props.modelValue) {
      reportInfo.value = buildReportInfo(props.reportRow);
      loadDetail();
    }
  },
);

const closeDialog = () => emit("update:modelValue", false);

const coverPeriod = computed(() => {
  const d = detail.value;
  if (!d || !d.id) return "服务报告";
  const periodText =
    d.type === "annual"
      ? `${d.period || ""}报告`
      : `${d.period} 季度报告`;
  return periodText;
});


// 科室柱状图颜色循环调色板
const deptColors = ["#3289FB", "#00C8B3", "#FF8D28", "#6155F5", "#34C759", "#00C0E8"];

// hex 颜色转 rgba（alpha 0~1）
const hexToRgba = (hex, alpha) => {
  const h = hex.replace("#", "");
  const r = parseInt(h.substring(0, 2), 16);
  const g = parseInt(h.substring(2, 4), 16);
  const b = parseInt(h.substring(4, 6), 16);
  return `rgba(${r},${g},${b},${alpha})`;
};

// 月度请求趋势折线图（适配后端返回字段 month/count）
const trendOption = computed(() => {
  const raw = detail.value?.monthlyTrend || [];
  const data = raw;
  const counts = data.map((d) => d.count);
  const maxCount = counts.length ? Math.max(...counts) : 0;
  // y 轴刻度固定为 5，最大向上取 5 的倍数且至少为 5
  const yMax = Math.max(5, Math.ceil(maxCount / 5) * 5);

  return {
    grid: { left: 32, right: 24, top: 36, bottom: 28 },
    tooltip: {
      trigger: "axis",
      backgroundColor: "#fff",
      borderColor: "#E0E0E0",
      textStyle: { color: "#1d2129", fontSize: 12 },
    },
    xAxis: {
      type: "category",
      data: data.map((d) => d.month),
      boundaryGap: false,
      axisLine: { lineStyle: { color: "#E4E7ED" } },
      axisTick: { show: false },
      axisLabel: { color: "#333333", fontSize: 12, fontWeight: 400 },
    },
    yAxis: {
      type: "value",
      min: 0,
      max: yMax,
      interval: 5,
      axisLine: { show: false },
      axisTick: { show: false },
      splitLine: { lineStyle: { color: "#F0F2F5", type: "solid" } },
      axisLabel: { color: "#86909C", fontSize: 12 },
    },
    series: [
      {
        type: "line",
        data: counts,
        smooth: true,
        symbol: "circle",
        symbolSize: 6,
        showSymbol: true,
        label: {
          show: true,
          position: "top",
          color: "#3289FB",
          fontSize: 11,
          fontWeight: 400,
          distance: 5,
        },
        lineStyle: { color: "#3289FB", width: 2 },
        itemStyle: {
          color: "#3289FB",
          borderColor: "#FFFFFF",
          borderWidth: 1,
        },
        emphasis: {
          focus: "series",
          itemStyle: { borderColor: "#3289FB", borderWidth: 2 },
        },
        areaStyle: {
          color: {
            type: "linear",
            x: 0,
            y: 0,
            x2: 0,
            y2: 1,
            colorStops: [
              { offset: 0, color: "rgba(50,137,251,0.4)" },
              { offset: 1, color: "rgba(50,137,251,0)" },
            ],
          },
        },
      },
    ],
  };
});

// 科室服务请求数量柱状图（适配后端返回字段 name/count）
const deptOption = computed(() => {
  const raw = detail.value?.departmentData || [];
  const data = raw
    .sort((a, b) => b.count - a.count);

  return {
    grid: { left: 10, right: 10, top: 10, bottom: 10 },
    tooltip: {
      trigger: "axis",
      axisPointer: { type: "shadow" },
      backgroundColor: "#fff",
      borderColor: "#E0E0E0",
      textStyle: { color: "#1d2129", fontSize: 12 },
    },
    xAxis: {
      type: "category",
      data: data.map((d) => d.name),
      // 保持默认 boundaryGap:true，避免首尾柱子一半被裁；ECharts 按 barCategoryGap 自动算柱宽
      axisLine: { show: false },
      axisTick: { show: false },
      axisLabel: {
        color: "#333333",
        fontSize: 12,
        fontWeight: 400,
        interval: 0,
        // 默认 8，x 轴文字距离柱子再加一倍
        margin: 16,
      },
    },
    yAxis: {
      type: "value",
      show: false,
    },
    series: [
      {
        type: "bar",
        // 间隔宽度占柱子的 10%；ECharts 自动算柱宽，使首尾柱子不超出绘图区
        barCategoryGap: "10%",
        data: data.map((d, i) => {
          const color = deptColors[i % deptColors.length];
          return {
            value: d.count,
            // 顶部 label 颜色与柱身渐变顶色保持一致
            label: { color },
            itemStyle: {
              // 四个角统一圆角
              borderRadius: [8, 8, 8, 8],
              color: {
                type: "linear",
                x: 0,
                y: 0,
                x2: 0,
                y2: 1,
                colorStops: [
                  { offset: 0, color }, // 顶部 100% 颜色
                  { offset: 1, color: hexToRgba(color, 0.2) }, // 底部 20% 颜色
                ],
              },
            },
          };
        }),
        label: {
          show: true,
          position: "top",
          color: "#3289FB",
          fontSize: 12,
          fontWeight: 400,
        },
      },
    ],
  };
});

// 优先级 / 反馈渠道环形图调色板（按需求循环）
const ringColors = [
  "#3289FB",
  "#00C0E8",
  "#34C759",
  "#FF8D28",
  "#6155F5",
  "#CB30E0",
  "#FF383C",
];

// 计算单个数组 count 总和
const sumCount = (list = []) =>
  list.reduce((acc, item) => acc + (Number(item.count) || 0), 0);

const priorityTotal = computed(() => sumCount(detail.value?.priorityData));
const feedbackChannelTotal = computed(() =>
  sumCount(detail.value?.feedBacks),
);

// 反馈渠道百分比（取整，不留小数）
const feedbackPercent = (count) => {
  const total = feedbackChannelTotal.value;
  if (!total) return "0%";
  return Math.round((Number(count) / total) * 100) + "%";
};

// 反馈渠道数据：按 count 从大到小排序（不修改源数据）
const sortedFeedbackChannelData = computed(() =>
  [...(detail.value?.feedBacks || [])].sort(
    (a, b) => (Number(b.count) || 0) - (Number(a.count) || 0),
  ),
);

// 通用环形图 option：默认环宽 12px，扇形之间 1px 白色间隔
const buildRingOption = (list = [], ringWidth = 16) => ({
  color: ringColors,
  tooltip: {
    trigger: "item",
    backgroundColor: "#fff",
    borderColor: "#E0E0E0",
    textStyle: { color: "#1d2129", fontSize: 12 },
  },
  series: [
    {
      type: "pie",
      radius: ["42px", `${42 + ringWidth}px`],
      center: ["50%", "50%"],
      avoidLabelOverlap: false,
      itemStyle: {
        borderColor: "#fff",
        borderWidth: 1,
      },
      // canvas 宽高固定不变大，关闭 hover 默认的扇形放大避免溢出
      emphasis: {
        scale: false,
        scaleSize: 0,
      },
      label: { show: false },
      labelLine: { show: false },
      data: list.map((item) => ({
        name: item.name,
        value: Number(item.count) || 0,
      })),
    },
  ],
});

const priorityOption = computed(() =>
  buildRingOption(detail.value?.priorityData || []),
);
// 反馈渠道占比：按 count 从大到小排序，环比默认加粗 4px（即 12 + 4 = 16px）
const feedbackChannelOption = computed(() =>
  buildRingOption(sortedFeedbackChannelData.value, 16),
);

const palette = ["#5B8FF9", "#5AD8A6", "#F6BD16", "#E8684A", "#9270CA", "#6DC8EC", "#FF99C3"];
const barColor = (i) => palette[i % palette.length];

const priorityClass = (p) =>
  p === "高" ? "high" : p === "中" ? "medium" : "low";
const statusClass = (s) =>
  s === "已完成" ? "done" : s === "待处理" ? "pending" : 'info';
</script>

<style lang="scss">
.report-detail-dialog {
  width: 800px;
  max-width: 90vw;

  .body-header {
    margin-bottom: 32px;
  }
}

// 静默模式:弹窗定位到屏幕外,用户不可见,但 DOM 完整渲染,html2canvas 可截图
.report-detail-dialog.is-silent {
  position: fixed !important;
  top: -99999px !important;
  left: 0 !important;
  pointer-events: none;
  z-index: -1;
  // 覆盖 el-dialog 默认的 transform 居中
  transform: none !important;
  margin: 0 !important;
}

// .report-detail-dialog {

.report-cover {
  background: linear-gradient(90deg, #EAF3FF 0%, #D5E7FF 100%);
  border-radius: 16px 16px 16px 16px;
  border: 1px solid #ACBED4;
  padding: 24px;
  padding-left: 0px;
  padding-right: 46px;
  display: flex;
  align-items: center;
  // min-height: 186px;

  .cover-info {
    flex: 1;

    .hospital-wrap {
      position: relative;
      padding-left: 24px;
      color: #3289FB;

      &::before {
        content: "";
        display: block;
        background-color: #3289FB;
        width: 4px;
        height: 47px;
        border-radius: 2px;
        position: absolute;
        left: 0;
        top: 50%;
        transform: translateY(-50%);
      }

      .cover-hospital {
        font-weight: bold;
        font-size: 24px;
        line-height: 32px;
      }

      .cover-period {
        margin-top: 1px;
        font-weight: 600;
        font-size: 16px;
        line-height: 21px;
      }
    }

    .cover-stat-row {
      padding-left: 24px;
      margin: 15px 0;
      font-weight: 400;
      font-size: 14px;
      color: #1D2129;
      line-height: 19px;
    }

    .cover-meta {
      padding-left: 24px;
      font-weight: 400;
      font-size: 12px;
      color: #1D2129;
      line-height: 16px;

      .date {
        margin-top: 4px;
      }
    }
  }

  .cover-banner {
    height: calc(100% + 48px);
    margin: -24px 0;
    background-image: url(@/assets/image/admin/reports/report-bg-light.svg);
    background-size: auto 100%;
    background-position: left top;
    padding-left: 104px;
    display: flex;
    align-items: center;

    img {
      width: 98%;
      height: 98%;
      object-fit: cover;
    }
  }
}

.report-section {
  margin-top: 24px;
  border-radius: 16px 16px 16px 16px;
  border: 1px solid #E0E0E0;
  overflow: hidden;

  .border-title {
    margin-bottom: 16px;
  }

  &.grid {
    display: flex;
    flex-wrap: nowrap;
    border: none;
    border-radius: none;
    gap: 16px;

    .section-card {
      border: 1px solid #E0E0E0;
      border-radius: 16px 16px 16px 16px;
      flex: 1;

      .section-body {
        display: flex;
        flex-direction: column;
        justify-content: center;
        align-items: center;
        gap: 12px;
        height: 160px;
        overflow: visible;

        // 优先级 / 反馈渠道 环形图布局
        &.ring-body {
          flex-direction: row;
          align-items: center;
          justify-content: center;

        }

        .ring-chart {
          position: relative;
          width: 120px;
          height: 120px;
          flex-shrink: 0;

          .ring-chart-canvas {
            width: 100%;
            height: 100%;
          }

          .ring-center {
            position: absolute;
            top: 50%;
            left: 50%;
            transform: translate(-50%, -50%);
            display: flex;
            flex-direction: column;
            align-items: center;
            pointer-events: none;

            .ring-center-label {
              font-weight: 400;
              font-size: 11px;
              line-height: 14px;
              color: #666666;
            }

            .ring-center-value {
              font-weight: bold;
              font-size: 18px;
              line-height: 24px;
              color: #1D2129;
            }
          }
        }

        .ring-legend {
          list-style: none;
          margin: 0;
          padding: 0;
          display: flex;
          flex-direction: column;
          gap: 2px;

          .ring-legend-item {
            display: flex;
            align-items: center;
            gap: 6px;

            .ring-dot {
              width: 4px;
              height: 4px;
              border-radius: 50%;
              flex-shrink: 0;
            }

            .ring-legend-text {
              font-weight: 400;
              font-size: 11px;
              color: #666666;
              line-height: 20px;
            }
          }
        }

        .section-item {
          width: 100%;
          position: relative;
          height: 28px;
          background: #E7EDF6;
          border-radius: 12px 12px 12px 12px;
          padding: 4px;

          .section-bar {
            height: 100%;
            border-radius: 9px 9px 9px 9px;
          }

          .section-data {
            position: absolute;
            left: 0;
            top: 0;
            width: 100%;
            height: 100%;
            padding: 4px 8px 4px 12px;
            display: flex;
            justify-content: space-between;
            align-items: center;

            .name {
              font-weight: 400;
              font-size: 11px;
              color: #FFFFFF;
            }

            .count {
              font-weight: bold;
              font-size: 12px;
              color: rgba($color: #000000, $alpha: 0.3);
            }
          }
        }
      }
    }
  }

  .summary-card {
    padding: 15px 23px;
    background: linear-gradient(180deg, #EBF4FF 0%, rgba(234, 243, 255, 0.5) 100%);
    border-radius: 16px 16px 16px 16px;
    font-weight: 400;
    font-size: 14px;
    color: #666666;
    line-height: 36px;
    padding-right: 95px;
    position: relative;

    .summary-text {
      background-image: linear-gradient(to bottom, transparent 0, transparent 35px, #CADBEE 35px, #CADBEE 36px);
      background-position: left 0;
      background-size: 100% 36px;
      background-repeat: repeat-y;

      .blue {
        color: #3289FB;
        font-weight: bold;
      }

      .green {
        color: #34C759;
        font-weight: bold;
      }

      .cyan {
        color: #00C3D0;
        font-weight: bold;
      }

      .yellow {
        color: #FF8D28;
        font-weight: bold;
      }

      .purple {
        color: #6155F5;
        font-weight: bold;
      }
    }

    .summery-bg {
      position: absolute;
      width: 112px;
      height: 194px;
      right: -8px;
      bottom: -4px;
      object-fit: contain;
    }

    span {
      position: relative;
      display: inline-block;
      // width: 100%;
      // text-decoration: underline solid #CADBEE;
      // text-underline-offset: 11px;
    }

    .em {
      color: #1D2129;
    }
  }

  .section-card,
  &.section-card {
    padding: 18px 16px;

    &.fill {
      padding: 0;

      .border-title {
        padding: 18px 0 0 16px;
      }
    }
  }

  .section-title {
    font-size: 15px;
    font-weight: 600;
    color: #1d2129;
    margin-bottom: 12px;
  }
}


.trend-chart {
  position: relative;
  background: #fff;
  height: 260px;

  .trend-chart-canvas {
    width: 100%;
    height: 100%;
  }
}

.trend-unit {
  font-weight: 400;
  font-size: 12px;
  color: #666666;
  text-align: right;
}

.dept-chart {
  position: relative;
  background: #fff;
  height: 260px;

  .dept-chart-canvas {
    width: 100%;
    height: 100%;
  }
}

.report-table {
  overflow: hidden;
  width: 100% !important;
  transform: translateY(1px);

  &::before {
    display: none !important;
  }

  // 强制按列宽布局,内容自动换行,横向不溢出
  &.el-table {
    // table-layout: fixed;
    width: 100% !important;

    // 去掉外层滚动容器
    .el-table__inner-wrapper {
      overflow-x: hidden !important;
    }

    // 表头与单元格:强制换行,长内容不溢出
    th.el-table__cell,
    td.el-table__cell {
      white-space: normal !important;
      word-break: break-all !important;
      overflow-wrap: break-word !important;
      text-align: left;
      vertical-align: middle;
      // 移除所有竖列 border（保留横向）
      border-right: none !important;
    }

    // 表头行样式
    thead th.el-table__cell {
      background: #F9FAFF !important;
      height: 42px;
      font-size: 14px;
      font-weight: 400;
      color: #666666;
      line-height: 18px;
    }

    // 内容行容器
    tbody tr {
      background: #fff;
    }

    // 内容行单元格
    tbody td.el-table__cell {
      height: 60px;
      background: #fff;
      font-size: 14px;
      // font-weight: 500;
      color: #666666;
      line-height: 18px;
    }

    // 内容容器也允许换行
    .cell {
      white-space: normal !important;
      word-break: break-all !important;
      overflow-wrap: break-word !important;
      line-height: 1.4;
    }
  }

  // 移除最外层竖列 border（保留上下）
  &.el-table--border {
    border-left: none !important;
    border-right: none !important;
  }

  .priority-dot {
    width: 50px;
    height: 30px;
    display: flex;
    align-items: center;
    justify-content: center;
    border-radius: 8px 8px 8px 8px;
    font-weight: 500;
    font-size: 14px;
    gap: 4px;
    color: var(--current-color) !important;


    &.high {
      --current-color: #FF383C;
      background: #FFEBEC;
    }

    &.medium {
      background: #ffefe2;
      --current-color: #FF8D28;
    }

    &.low {
      background: #eaf3ff;
      --current-color: #3289fb;
    }

    &::before {
      content: "";
      display: block;
      width: 8px;
      height: 8px;
      border-radius: 50%;
      background-color: var(--current-color);
    }
  }

  .status-pill {
    width: 66px;
    height: 30px;
    text-align: center;
    line-height: 30px;
    border-radius: 8px 8px 8px 8px;
    font-weight: 500;
    font-size: 14px;


    &.done {
      background: #E8FFEE;
      color: #34C759;
    }


    &.pending {
      background: #FFEFE2;
      color: #FF8D28;
    }

    &.info {
      background: #999;
      color: #666;
    }
  }
}

// }
</style>