<template>
  <div class="knowledge_graph">


    <div class="graph_header" v-if="activeView === 'list'">
      <!-- 自定义图例 -->
      <div class="legend">
        <div class="legend_item" :class="{ 'selected': selectedLegend.weak }" @click="toggleLegend('weak')">
          <span class="legend_dot weak" :style="selectedLegend.weak ? {} : { backgroundColor: '#ccc' }"></span>
          <span class="legend_text" :style="selectedLegend.weak ? {} : { color: '#999999' }">{{ '薄弱(0%≤得分率<60%)'
              }}</span>
        </div>
        <div class="legend_item" :class="{ 'selected': selectedLegend.good }" @click="toggleLegend('good')">
          <span class="legend_dot good" :style="selectedLegend.good ? {} : { backgroundColor: '#ccc' }"></span>
          <span class="legend_text" :style="selectedLegend.good ? {} : { color: '#999999' }">{{ '良好(60%≤得分率<85%)'
              }}</span>
        </div>
        <div class="legend_item" :class="{ 'selected': selectedLegend.excellent }" @click="toggleLegend('excellent')">
          <span class="legend_dot excellent"
            :style="selectedLegend.excellent ? {} : { backgroundColor: '#ccc' }"></span>
          <span class="legend_text" :style="selectedLegend.excellent ? {} : { color: '#999999' }">{{ '优秀(85%≤得分率)'
            }}</span>
        </div>
      </div>
      <!-- 视图切换按钮 - 移到knowledge_graph容器下 -->
      <div class="view_switcher_container">
        <el-button type="text" @click="switchView('graph')" class="switch_btn list_btn">
          <i class="icon_switch_graph">
            <img src="../../../assets/studentAnalysis/circleGrey.svg" alt="按图形查看">
          </i>
          按图形查看
        </el-button>
        <el-button type="graph" class="switch_btn graph_btn" @click="switchView('list')">
          <i class="icon_switch_list">
            <img src="../../../assets/studentAnalysis/iconBlue.svg" alt="按列表查看">
          </i>
          按列表查看
        </el-button>
      </div>
    </div>


    <!-- 图形查看容器 -->
    <div v-if="activeView === 'graph'" class="graph_content">
      <!-- 左侧图表 -->
      <div class="chart_container">
        <!-- 顶部容器：图例和视图切换按钮 -->
        <div class="top_container">
          <!-- 自定义图例 -->
          <div class="legend">
            <div class="legend_item" :class="{ 'selected': selectedLegend.weak }" @click="toggleLegend('weak')">
              <span class="legend_dot weak" :style="selectedLegend.weak ? {} : { backgroundColor: '#ccc' }"></span>
              <span class="legend_text" :style="selectedLegend.weak ? {} : { color: '#999999' }">{{ '薄弱(0%≤得分率<60%)'
                  }}</span>
            </div>
            <div class="legend_item" :class="{ 'selected': selectedLegend.good }" @click="toggleLegend('good')">
              <span class="legend_dot good" :style="selectedLegend.good ? {} : { backgroundColor: '#ccc' }"></span>
              <span class="legend_text" :style="selectedLegend.good ? {} : { color: '#999999' }">{{ '良好(60%≤得分率<85%)'
                  }}</span>
            </div>
            <div class="legend_item" :class="{ 'selected': selectedLegend.excellent }"
              @click="toggleLegend('excellent')">
              <span class="legend_dot excellent"
                :style="selectedLegend.excellent ? {} : { backgroundColor: '#ccc' }"></span>
              <span class="legend_text" :style="selectedLegend.excellent ? {} : { color: '#999999' }">{{ '优秀(85%≤得分率)'
                }}</span>
            </div>
          </div>
          <!-- 视图切换按钮  -->
          <div class="view_switcher_container" v-if="activeView === 'graph'" :class="activeView">
            <el-button type="graph" @click="switchView('graph')" class="switch_btn graph_btn">
              <i class="icon_switch_graph">
                <img src="../../../assets/studentAnalysis/circleBlue.svg" alt="按图形查看">
              </i>
              按图形查看
            </el-button>
            <el-button type="text" class="switch_btn list_btn" @click="switchView('list')">
              <i class="icon_switch_list"><img src="../../../assets/studentAnalysis/iconGrey.svg" alt="按列表查看"></i>
              按列表查看
            </el-button>
          </div>
        </div>
        <div ref="chart" class="chart" style="width: 100%;"></div>
      </div>

      <!-- 右侧容器，包含tab和知识点列表 -->
      <div class="knowledge_right_container">
        <!-- Tab切换 -->
        <div class="knowledge_tab">
          <div class="tab_item" :class="{ active: activeTab === 'all' }" @click="activeTab = 'all'">
            全部知识点
          </div>
          <div class="tab_item" :class="{ active: activeTab === 'highFreq' }" @click="activeTab = 'highFreq'">
            高频错题知识点
          </div>
          <div class="tab_item" :class="{ active: activeTab === 'zero' }" @click="activeTab = 'zero'">
            零分知识点
          </div>
        </div>

        <!-- 右侧知识点列表 -->
        <div class="knowledge_list">
          <!-- 暂无数据提示 -->
          <div class="module_chart no_content_data no_data" style="height: 240px; " element-loading-background="#ffffff"
            v-if="!knowledgeItems || knowledgeItems.length === 0">
            <span>暂无数据</span>
          </div>
          <!-- 正常列表数据 -->

          <div class="list_item" v-for="(item, index) in knowledgeItems" :key="index"
            @click="handleItemClick(item, index)" :class="{ active: selectedIndex === index }" v-else>
            <div class="item_header">
              <span class="item_dot" :style="{ backgroundColor: getDotColor(item, 'personalScoreRate') }"></span>
              <el-tooltip :content="item.knowledgeName" placement="top" effect="light"
                :disabled="!item.knowledgeName || item.knowledgeName.length < 15">
                <span class="item_title">{{ item.knowledgeName }}</span>
              </el-tooltip>
              <span class="item_tag" v-if="item.scoreRateDiff"
                :style="{ backgroundColor: parseFloat(item.scoreRateDiff) > 0 ? '#3BA272' : '#F56C6C' }">
                {{ item.scoreRateDiff }}%
              </span>
              <span class="item_tag" v-if="item.isPush == 1" style="background-color: #2E64FA;">
                有推题
              </span>
            </div>

            <div class="item_info">
              <!-- 班级/学生得分率 -->
              <span class="item_score">
                <span class="score_label" v-if="item.personalScoreRate">个人得分率:</span>
                <span :style="{ color: getDotColor(item, 'personalScoreRate') }" v-if="item.personalScoreRate">{{
                  item.personalScoreRate }}%</span>
                <span class="score_separator" v-if="item.classScoreRate">|</span>
                <span class="score_label">班级得分率:</span>
                <span v-if="item.classScoreRate" class="score_second">{{ item.classScoreRate }}%</span>
                <span v-if="!item.classScoreRate" :style="{ color: getDotColor(item, 'classScoreRate') }">{{
                  item.classScoreRate }}%</span>
              </span>

              <!-- 班级/学生得分率 -->
              <span class="item_exam_count">考试数: <span class="exam_count">{{ item.examNum || 0 }}</span></span>
            </div>
          </div>
        </div>
      </div>
    </div>

    <!-- 列表查看容器 -->
    <div v-if="activeView === 'list'" class="list_content">

      <vxe-table ref="treeTable" :data="tableData" style="width: 100%;" maxHeight="480px" border show-header
        :tree-config="{ childrenField: 'children', hasChildField: 'hasChildren', showIcon: true, iconOpen: 'el-icon-remove', iconClose: 'el-icon-circle-plus' }"
        :scroll-y="{ enabled: true, gt: 480 }" fixed-header :header-cell-style="{ color: '#333' }"
        @row-click="handleRowClick" @cell-click="handleCellClick" :row-class-name="rowClassName">

        <vxe-table-column type="tree" tree-node prop="title" :title="subjectName">
          <template #default="{ row }">
            <div class="knowledge_item">
              <span class="knowledge_title">{{ row.knowledgeName }}</span>
            </div>
          </template>
        </vxe-table-column>

        <!-- 个人得分率 -->
        <vxe-table-column prop="personalScoreRate" title="个人得分率" width="180" align="center">
          <template #default="{ row }">
            <div class="rate_info" v-if="row.personalScoreRate !== null">
              <span class="rate_dot" :class="getRateClass(row.personalScoreRate)"></span>
              <span class="rate_value">{{ row.personalScoreRate }}%</span>
            </div>
          </template>
        </vxe-table-column>
        <!-- 个人知识点状态 -->
        <vxe-table-column prop="personalScoreRate" title="个人知识点状态" width="120" align="center">
          <template #default="{ row }">
            <div class="status_info" v-if="row.personalScoreRate !== null">
              <span class="status_value"
                :style="{ color: getRateName(row.personalScoreRate) === '优秀' ? '#3BA272' : getRateName(row.personalScoreRate) === '良好' ? '#FAC858' : '#EE6666' }">
                {{ getRateName(row.personalScoreRate) }}
              </span>
            </div>
          </template>
        </vxe-table-column>

        <!-- 班级得分率 -->
        <vxe-table-column prop="classScoreRate" title="班级得分率" width="180" align="center">
          <template #default="{ row }">
            <div class="rate_info" v-if="row.classScoreRate !== null">
              <span class="rate_dot" :class="getRateClass(row.classScoreRate)"></span>
              <span class="rate_value">{{ row.classScoreRate }}%</span>
            </div>
          </template>
        </vxe-table-column>
        <!-- 班级知识点状态 -->
        <vxe-table-column prop="classScoreRate" title="班级知识点状态" width="120" align="center">
          <template #default="{ row }">
            <div class="status_info" v-if="row.classScoreRate !== null">
              <span class="status_value"
                :style="{ color: getRateName(row.classScoreRate) === '优秀' ? '#3BA272' : getRateName(row.classScoreRate) === '良好' ? '#FAC858' : '#EE6666' }">
                {{ getRateName(row.classScoreRate) }}
              </span>
            </div>
          </template>
        </vxe-table-column>

        <!-- 只有当班级名称不是年级且不为空时，才显示得分率差列 -->
        <vxe-table-column prop="diff" title="得分率差" width="150" align="center">
          <template #default="{ row }">
            <div class="rate_info" v-if="row.scoreRateDiff !== null">
              <span class="rate_dot" :class="getRateClass(row.scoreRateDiff)"></span>
              <span class="diff_value"
                :class="{ 'diff_negative': row.scoreRateDiff !== null && row.scoreRateDiff < 0 }">
                {{ row.scoreRateDiff !== null && row.scoreRateDiff > 0 ? '+' : '' }}{{ row.scoreRateDiff }}%
              </span>
            </div>
          </template>
        </vxe-table-column>
      </vxe-table>
    </div>
  </div>
</template>

<script>
// 引入echarts
import * as echarts from 'echarts';

export default {
  name: 'KnowledgeGraph',
  props: {
    activeView: { // 当前视图，graph或list 年级画像还是学生画像
      type: String,
      default: 'graph',
      validator: (value) => {
        return ['graph', 'list'].includes(value);
      }
    },
    subjectName: {  // 科目名称
      type: String,
      default: '知识点'
    },
    subjectScoreRate: { // 科目得分率
      type: Number,
      default: 0
    },
    tableData: { // 知识点表格数据
      type: Array,
      default: () => []
    },
    fatalVulnerability: { // 零分知识点数据
      type: Array,
      default: () => []
    },
    highVulnerability: { // 高频错题知识点数据
      type: Array,
      default: () => []
    },
    allKnowledgeList: { // 全部知识点数据
      type: Array,
      default: () => []
    },
    classLevel: { // 判断是否是组合还是班级，还是年级
      type: [String, Number],
      default: ''
    },
    classGroupName: { // 班级组合名称
      type: String,
      default: ''
    },
    currentKnowledgeId: { // 当前选中的知识点ID
      type: [String, Number],
      default: ''
    },
  },
  computed: {
    // 根据当前tab返回对应的数据
    knowledgeItems() {
      if (this.activeTab === 'zero') {
        return this.fatalVulnerability || [];
      } else if (this.activeTab === 'highFreq') {
        return this.highVulnerability || [];
      } else if (this.activeTab === 'all') {
        return this.allKnowledgeList || [];
      }
      return [];
    }
  },
  data() {
    return {
      chart: null, // echarts实例
      // 组件挂载状态标记
      _isMounted: false,
      // 首次渲染标志，用于控制初始化时的透明度逻辑
      _isFirstRender: true,
      // Tab切换状态
      activeTab: 'all',
      // 图例选中状态
      selectedLegend: {
        weak: true,
        good: true,
        excellent: true
      },
      // 选中的知识点索引
      selectedIndex: 0,
      // 当前选中的行数据
      selectedRow: null,
      // 当前选中的知识点ID，用于控制节点透明度
      selectedKnowledgeId: '',
      // 树形表格展开行keys
      expandRowKeys: []
    };
  },
  mounted() {
    // 设置组件挂载状态
    this._isMounted = true;

    // 无论在什么模式下，只要默认视图是图形视图就初始化echarts图表
    if (this.activeView === 'graph') {
      this.$nextTick(() => {
        this.initChart();
      });
    }
  },
  beforeDestroy() {
    // 设置组件未挂载状态
    this._isMounted = false;
    // 销毁echarts实例
    if (this.chart) {
      this.chart.dispose();
    }
  },
  watch: {
    // 监听classLevel变化，当对比选择器数据变化时更新对比选项
    classLevel: {
      handler(newVal, oldVal) {

      },
      immediate: true
    },
    // 监听classGroupName变化，当班级组合名称变化时更新对比选项
    classGroupName: {
      handler(newVal, oldVal) {
        if (newVal) {
        }
      },
      immediate: true
    },
    // 监听activeView变化，当切换到图形视图时重新初始化图表，切换到列表视图时销毁图表
    activeView(newView, oldView) {
      if (newView === 'graph') {
        this.$nextTick(() => {
          this.initChart();
        });
      } else if (newView === 'list') {
        // 切换到列表视图时销毁图表实例
        if (this.chart) {
          this.chart.dispose();
          this.chart = null;
        }
        // 切换到列表视图时，展开所有树形节点
        this.$nextTick(() => {
          this.expandAllNodes();
        });
      }
    },
    // 监听tab切换，更新选中索引并通知父组件
    activeTab(newTab, oldTab) {
      this.selectedIndex = 0;

      // 根据当前tab获取对应的数据列表
      const currentList = this.knowledgeItems;
      // 如果有数据，更新selectedKnowledgeId为第一条数据的ID
      if (currentList && currentList.length > 0) {
        this.selectedKnowledgeId = currentList[0].knowledgeId;
        // 如果当前是图形视图且图表已初始化，更新图表选中状态
        if (this.activeView === 'graph' && this.chart) {
          this.updateChart();
        }
      } else {
        // 如果没有数据，清空selectedKnowledgeId
        this.selectedKnowledgeId = '';
      }

      // 只有当组件已挂载且tab值实际发生变化，并且不是初始化时，才向父组件发送事件
      // 这是为了避免在视图切换时重复调用接口
      if (this._isMounted && newTab !== oldTab) {
        // 向父组件发送tab切换事件
        this.$emit('activeTabChange', newTab);
      }
    },
    // 监听数据变化，重新设置默认选中项
    fatalVulnerability: {
      deep: true,
      handler() {
        // 仅当当前视图是图形视图且数据发生变化时才更新默认选中
        if (this.activeView === 'graph') {
          this.setDefaultSelection();
        }
      }
    },
    highVulnerability: {
      deep: true,
      handler() {
        // 仅当当前视图是图形视图且数据发生变化时才更新默认选中
        if (this.activeView === 'graph') {
          this.setDefaultSelection();
        }
      }
    },
    allKnowledgeList: {
      deep: true,
      handler() {
        // 仅当当前视图是图形视图且数据发生变化时才更新默认选中
        if (this.activeView === 'graph') {
          this.setDefaultSelection();
        }
      }
    },
    // 监听tableData变化，更新展开行
    tableData: {
      deep: true,
      handler() {
        // 当tableData变化时，重新展开所有节点
        if (this.activeView === 'list') {
          this.$nextTick(() => {
            this.expandAllNodes();
          });
        }
        if (this.chart) {
          this.$nextTick(() => {
            this.updateChart();
          });
        }
      }
    },
    // 监听当前选中的知识点ID变化，更新图表高亮状态
    currentKnowledgeId: {
      handler(newVal) {
        // 更新selectedKnowledgeId，确保图表使用正确的高亮状态
        this.selectedKnowledgeId = newVal;
        // 仅当当前视图是图形视图且图表已初始化时才更新
        if (this.activeView === 'graph' && this.chart) {
          this.updateChart();
        }
      }
    }
  },
  methods: {
    // 设置默认选中项
    setDefaultSelection() {
      // 保存当前tab值，用于比较是否需要修改
      const oldActiveTab = this.activeTab;
      let selectedItem = null;

      // 优先级：全部知识点> 高频错题知识点 > 零分知识点 
      if (this.allKnowledgeList && this.allKnowledgeList.length > 0) {
        // 如果前两者都没有数据但全部知识点有数据，切换到全部知识点并选中第一条
        if (this.activeTab !== 'all') {
          this.activeTab = 'all';
        }
        this.selectedIndex = 0;
        selectedItem = this.allKnowledgeList[0];
      } else if (this.highVulnerability && this.highVulnerability.length > 0) {
        // 如果全部知识点没有数据但高频错题知识点有数据，切换到高频错题知识点并选中第一条
        if (this.activeTab !== 'highFreq') {
          this.activeTab = 'highFreq';
        }
        this.selectedIndex = 0;
        selectedItem = this.highVulnerability[0];
      } else if (this.fatalVulnerability && this.fatalVulnerability.length > 0) {
        // 如果零分知识点有数据，切换到零分知识点并选中第一条
        if (this.activeTab !== 'zero') {
          this.activeTab = 'zero';
        }
        this.selectedIndex = 0;
        selectedItem = this.fatalVulnerability[0];
      }

      // 如果有选中项，更新selectedKnowledgeId，实现初始化默认选择
      if (selectedItem) {
        this.selectedKnowledgeId = selectedItem.knowledgeId;
        // 如果当前是图形视图且图表已初始化，更新图表选中状态
        if (this.activeView === 'graph' && this.chart) {
          this.updateChart();
        }
      }

      // 只有当tab值实际发生变化时，才触发选中事件
      // 初始化时不触发，避免重复调用接口
      if (this._isMounted && oldActiveTab !== this.activeTab) {
        // 组件已挂载且tab值发生变化时才发送事件
      }
    },

    // 递归收集所有节点的key，用于展开所有树形节点
    collectAllRowKeys() {
      const keys = [];

      // 递归函数，收集所有有children的节点key
      const collectKeys = (data) => {
        if (!data || !Array.isArray(data)) return;

        data.forEach(item => {
          // 如果节点有children，将其key添加到keys数组中
          if (item.children && item.children.length > 0) {
            // 使用knowledgeId作为key
            keys.push(item.knowledgeId);
            // 递归处理children
            collectKeys(item.children);
          }
        });
      };

      // 调用递归函数
      collectKeys(this.tableData);

      // 更新expandRowKeys数组
      this.expandRowKeys = keys;
    },

    // 使用vxe-table API展开所有树形节点
    expandAllNodes() {
      // 获取vxe-table实例
      const treeTable = this.$refs.treeTable;
      if (treeTable) {
        // 递归收集所有需要展开的节点
        const expandNodes = [];
        const collectExpandNodes = (data) => {
          if (!data || !Array.isArray(data)) return;
          data.forEach(item => {
            if (item.children && item.children.length > 0) {
              expandNodes.push(item);
              collectExpandNodes(item.children);
            }
          });
        };
        collectExpandNodes(this.tableData);

        // 使用vxe-table 3.7.5兼容的API展开所有节点
        if (treeTable.setExpandRows) {
          // 如果支持setExpandRows方法
          treeTable.setExpandRows(expandNodes);
        } else if (treeTable.setTreeExpand) {
          // 如果支持setTreeExpand方法
          expandNodes.forEach(node => {
            treeTable.setTreeExpand(node, true);
          });
        }
      }
    },

    // 切换查看方式
    switchView(view) {
      // 通过emit事件通知父组件更新activeView
      this.$emit('view-change', view);
    },

    // 年级、班级组合判断
    classIsGroup() {
      if (this.classLevel == 1) {
        return true;
      } else
        return false;
    },

    // 切换图例选中状态
    toggleLegend(type) {
      this.selectedLegend[type] = !this.selectedLegend[type];

      // 生成scoreRateTypes数组
      let scoreRateTypes = [];
      if (this.selectedLegend.weak) scoreRateTypes.push(1);
      if (this.selectedLegend.good) scoreRateTypes.push(2);
      if (this.selectedLegend.excellent) scoreRateTypes.push(3);

      // 如果包含所有值，则传null，否则传数组
      if (scoreRateTypes.length === 3) {
        scoreRateTypes = null;
      }

      // 向父组件发送图例变化事件，包含scoreRateTypes和当前activeTab对应的knowledgeType
      let knowledgeType = 0;
      if (this.activeTab === 'highFreq') {
        knowledgeType = 1;
      } else if (this.activeTab === 'zero') {
        knowledgeType = 2;
      } else {
        knowledgeType = 0;
      }

      this.$emit('legend-change', { scoreRateTypes, knowledgeType });

    },

    // 根据得分率获取对应的颜色
    getNodeColor(scoreRate) {
      const rate = parseFloat(scoreRate);
      if (rate >= 85) {
        return '#3BA272'; // 优秀 - 绿色
      } else if (rate >= 60) {
        return '#FAC858'; // 良好 - 黄色
      } else {
        return '#EE6666'; // 薄弱 - 红色
      }
    },

    // 更新图表缩放和布局参数，防止窗口变化时图表变形
    updateChartLayout() {
      if (this.chart) {
        // 重新计算最外层知识点数量
        const countOutermostNodes = (data) => {
          let count = 0;
          const traverse = (nodes) => {
            nodes.forEach(node => {
              if (node.children && node.children.length > 0) {
                traverse(node.children);
              } else {
                count++;
              }
            });
          };
          traverse(data);
          return count;
        };
        
        const outermostCount = countOutermostNodes(this.tableData);
        
        // 重新计算合适的缩放比例
        const getOptimalZoom = () => {
          const screenWidth = window.innerWidth;
          let zoom = 1.05;
          
          if (screenWidth < 1100) {
            zoom = 1.05;
          } else if (screenWidth >= 1100 && screenWidth <= 1200) {
            zoom = 1.05;
          } else {
            zoom = 1.05;
          }
          
          if (outermostCount <= 5) {
            zoom *= 1.0;
          }
          
          return zoom;
        };
        
        // 重新计算内外半径
        const getOptimalRadius = () => {
          if (outermostCount <= 5) {
            return ['20%', '65%'];
          }
          return ['12%', '75%'];
        };
        
        // 更新图表的所有动态参数
        this.chart.setOption({
          series: [{
            // 更新缩放比例
            zoom: getOptimalZoom(),
            // 更新内外半径
            radius: getOptimalRadius(),
            // 更新层级间距
            layerPadding: outermostCount <= 5 ? [20, 10] : [10, 5]
          }]
        });
      }
    },

    // 初始化echarts图表
    initChart() {
      try {
        // 检查chart容器是否存在
        if (!this.$refs.chart) {
          console.error('图表容器不存在');
          return;
        }
        this.createChart();
      }
      catch (error) {
        console.error('图表初始化失败:', error);
      }
    },

    // 创建图表
    createChart() {
      try {
        // 检查chart容器是否存在
        if (!this.$refs.chart) {
          console.error('图表容器不存在');
          return;
        }
        // 销毁现有的图表实例
        if (this.chart) {
          this.chart.dispose();
        }
        // 创建echarts实例
        this.chart = echarts.init(this.$refs.chart);

        // 保存当前组件实例的引用
        const vm = this;

        // 根据得分率获取对应的级别
        const getNodeLevel = (scoreRate) => {
          const rate = parseFloat(scoreRate);
          // 处理scoreRate为null、undefined或非数字的情况
          if (isNaN(rate)) {
            return 'weak'; // 默认为薄弱
          }
          if (rate >= 85) {
            return 'excellent'; // 优秀
          } else if (rate >= 60) {
            return 'good'; // 良好
          } else {
            return 'weak'; // 薄弱
          }
        };

        // 基于表格数据生成树形图数据
        // 添加一个可选参数overrideKnowledgeId，用于临时覆盖当前的currentKnowledgeId
        const generateTreeData = (data, level = 0, overrideKnowledgeId = null) => {
          // 使用传入的overrideKnowledgeId或默认使用vm.selectedKnowledgeId
          const currentKnowledgeId = overrideKnowledgeId !== null ? overrideKnowledgeId : vm.selectedKnowledgeId;

          return data.map(item => {
            // 根据节点是否为最外围节点
            const isOutermost = !item.children || item.children.length === 0;

            // 检查当前节点是否匹配选中的知识点ID
            const isMatched = isOutermost && String(item.knowledgeId) === String(currentKnowledgeId);

            // 设置节点大小：选中状态16px，未选中状态10px，非叶子节点5px
            let symbolSize = 5;
            if (isOutermost) {
              symbolSize = isMatched ? 15 : 10;
            }

            // 获取节点级别，优先使用对应级别的得分率，若缺失则使用另一级别作为备选
            const scoreRate = item.personalScoreRate;
            const nodeLevel = getNodeLevel(scoreRate);
            
            // 计算节点样式，使用与nodeLevel相同的得分率逻辑
            const itemColor = isOutermost ? vm.getNodeColor(scoreRate) : '#BFC1C7';
            // 仅对最外层节点应用图例过滤，非外层节点始终显示
            const shouldShow = !isOutermost || vm.selectedLegend[nodeLevel];
            
            // 设置节点透明度：显示为1，隐藏为0
            const opacity = shouldShow ? 1 : 0;
            
            const node = {
              name: item.knowledgeName,
              symbolSize: symbolSize,
              // 使用已计算的scoreRate作为value，确保数据一致性
              value: scoreRate,
              itemStyle: {
                color: itemColor,
                opacity: opacity
              },
              // 当节点是最外层且被隐藏时，隐藏连接到该节点的线
              lineStyle: {
                opacity: shouldShow ? 1 : 0
              },
              // 添加isOutermost属性用于tooltip判断
              isOutermost: isOutermost,
              // 保存知识ID用于匹配
              knowledgeId: item.knowledgeId
            };

            if (item.children && item.children.length > 0) {
              node.children = generateTreeData(item.children, level + 1, overrideKnowledgeId);
            }

            return node;
          });
        };

        // 计算最外层知识点数量（叶子节点数量），用于动态调整布局
        const countOutermostNodes = (data) => {
          let count = 0;
          const traverse = (nodes) => {
            nodes.forEach(node => {
              if (node.children && node.children.length > 0) {
                traverse(node.children);
              } else {
                count++;
              }
            });
          };
          traverse(data);
          return count;
        };
        
        // 获取最外层知识点数量
        const outermostCount = countOutermostNodes(this.tableData);
        
        // 计算合适的缩放比例，根据屏幕宽度和节点数量动态调整
        const getOptimalZoom = () => {
          const screenWidth = window.innerWidth;
          let zoom = 1.05;
          
          // 根据屏幕宽度调整缩放
          if (screenWidth < 1100) {
            zoom = 1.05;
          } else if (screenWidth >= 1100 && screenWidth <= 1200) {
            zoom = 1.05;
          } else {
            zoom = 1.05;
          }
          
          // 根据节点数量调整缩放，节点少的时候适当放大
          if (outermostCount <= 5) {
            zoom *= 1.0;
          }
          
          return zoom;
        };
        
        // 根据节点数量动态调整内外半径，防止节点遮盖
        const getOptimalRadius = () => {
          // 节点数量少的时候，增大内半径，缩小外半径，使节点分布更合理
          if (outermostCount <= 5) {
            return ['20%', '65%'];
          }
          // 节点数量多的时候，使用默认半径
          return ['12%', '75%'];
        };
        
        // 配置项
        const option = {
          tooltip: {
            formatter: (params) => {
              // 检查是否为根节点
              if (params.treePathInfo && params.treePathInfo.length === 1) {
                // 根节点也属于非最外层节点，只显示名称
                return params.name;
              }

              // 检查节点是否为最外层节点（叶子节点）
              // 使用isOutermost属性或检查data.isOutermost
              const isOutermost = params.data && params.data.isOutermost;

              if (isOutermost) {
                // 最外层节点显示完整信息（名称+得分率）
                return `${params.name}<br/>得分率: ${params.value !== null && params.value !== undefined ? params.value : '0'}%`;
              } else {
                // 非最外层节点只显示名称
                return params.name;
              }
            }
          },
          animationDurationUpdate: 1500,
          animationEasingUpdate: 'quinticInOut',
          series: [
            {
              type: 'tree',
              layout: 'radial',
              symbol: 'circle',
              initialTreeDepth: 999, // 设置一个足够大的值，确保所有节点都展开
              expandAndCollapse: false,
              // 调整树状图布局参数，确保节点均匀分布
              orient: 'radial',
              roam: true,
              
              // 使用边距控制图表位置，实现水平垂直居中
              left: '8%',   // 左边距（百分比/像素）
              right: '8%',  // 右边距
              top: '8%',    // 上边距
              bottom: '8%', // 下边距

              // 根据节点数量动态调整内外半径，防止节点遮盖
              radius: getOptimalRadius(),
              
              // 动态计算合适的缩放比例，根据屏幕宽度和节点数量调整
              zoom: getOptimalZoom(),
              scaleLimit: {
                min: 0.2,
                max: 5
              },

              // 调整节点大小比例和间距，确保节点不遮盖
              nodeScaleRatio: 1,
              // 根据节点数量调整层级间距，节点少的时候增大间距
              layerPadding: outermostCount <= 5 ? [20, 10] : [10, 5],
              roam: true,

              // 使用表格数据生成树形结构
              data: [
                {
                  name: this.subjectName,
                  symbolSize: 5, // 根节点大小
                  value: this.subjectScoreRate, // 添加value属性，用于显示得分率
                  itemStyle: {
                    // 根节点为非最外层节点，使用#EBEEF5颜色
                    color: '#BFC1C7'
                  },
                  // 标记为非最外层节点
                  isOutermost: false,
                  children: generateTreeData(this.tableData)
                }
              ],
              label: {
                show: false
              },
              lineStyle: {
                color: '#ECEEF3',
                width: 1,
                type: 'solid'
              },
              emphasis: {
                focus: 'adjacency',
                lineStyle: {
                  width: 1
                }
              }
            }
          ]
        };

        // 设置配置项
        this.chart.setOption(option);

        // 初始化后调用resize确保图表正确显示
        this.chart.resize();

        // 添加图表点击事件监听
        this.chart.on('click', (params) => {
          // 明确识别点击类型
          const isOuterNodeClick = params.data && params.data.isOutermost;
          const isEmptyAreaClick = !params.data || !params.componentType || params.componentType === '';
          const isNonOuterNodeClick = params.data && !params.data.isOutermost;

          if (isOuterNodeClick) {
            // 处理最外层节点点击
            // 确定当前显示的列表数据
            let targetList = [];
            if (this.activeTab === 'zero') {
              targetList = this.fatalVulnerability;
            } else if (this.activeTab === 'highFreq') {
              targetList = this.highVulnerability;
            } else {
              targetList = this.allKnowledgeList;
            }

            // 1. 首先尝试直接从当前列表中根据名称查找
            let knowledgeItem = targetList.find(item => item.knowledgeName === params.name);
            let targetIndex = -1;

            if (knowledgeItem) {
              targetIndex = targetList.findIndex(item => item.knowledgeId === knowledgeItem.knowledgeId);
            }

            // 2. 如果在当前列表中找不到，尝试从其他列表中查找
            if (!knowledgeItem) {
              const allLists = [this.allKnowledgeList, this.highVulnerability, this.fatalVulnerability];
              for (const list of allLists) {
                knowledgeItem = list.find(item => item.knowledgeName === params.name);
                if (knowledgeItem) {
                  // 找到后切换到对应tab
                  if (list === this.highVulnerability) {
                    this.activeTab = 'highFreq';
                    targetList = this.highVulnerability;
                  } else if (list === this.fatalVulnerability) {
                    this.activeTab = 'zero';
                    targetList = this.fatalVulnerability;
                  } else {
                    this.activeTab = 'all';
                    targetList = this.allKnowledgeList;
                  }
                  targetIndex = targetList.findIndex(item => item.knowledgeId === knowledgeItem.knowledgeId);
                  break;
                }
              }
            }

            // 3. 如果还是找不到，尝试从tableData中查找
            if (!knowledgeItem) {
              const findKnowledgeItem = (data) => {
                for (let item of data) {
                  if (item.knowledgeName === params.name) {
                    return item;
                  }
                  if (item.children && item.children.length > 0) {
                    const found = findKnowledgeItem(item.children);
                    if (found) return found;
                  }
                }
                return null;
              };

              knowledgeItem = findKnowledgeItem(this.tableData);

              if (knowledgeItem) {
                // 在所有列表中查找匹配的knowledgeId
                const allLists = [this.allKnowledgeList, this.highVulnerability, this.fatalVulnerability];
                for (const list of allLists) {
                  targetIndex = list.findIndex(item => {
                    // 考虑类型转换，确保比较准确
                    return String(item.knowledgeId) === String(knowledgeItem.knowledgeId);
                  });
                  if (targetIndex !== -1) {
                    // 切换到对应tab
                    if (list === this.highVulnerability) {
                      this.activeTab = 'highFreq';
                      targetList = this.highVulnerability;
                    } else if (list === this.fatalVulnerability) {
                      this.activeTab = 'zero';
                      targetList = this.fatalVulnerability;
                    } else {
                      this.activeTab = 'all';
                      targetList = this.allKnowledgeList;
                    }
                    break;
                  }
                }
              }
            }

            if (knowledgeItem && targetIndex !== -1) {
              // 向父组件发送事件
              this.$emit('knowledge-item-click', {
                item: knowledgeItem,
                index: targetIndex
              });

              // 更新选中索引和选中知识点ID
              this.selectedIndex = targetIndex;
              this.selectedKnowledgeId = knowledgeItem.knowledgeId;

              // 将首次渲染标志设为false，后续点击操作将应用透明度降低逻辑
              // this._isFirstRender = false;

              // 重新生成图表数据，确保只有当前选中节点高亮
              this.chart.setOption({
                series: [{
                  data: [
                    {
                      name: this.subjectName,
                      symbolSize: 5,
                      value: this.subjectScoreRate,
                      itemStyle: {
                        color: '#BFC1C7',
                        opacity: 1
                      },
                      isOutermost: false,
                      children: generateTreeData(this.tableData, 0, this.selectedKnowledgeId)
                    }
                  ]
                }]
              }, {
                animation: true,
                animationDuration: 300
              });

              // 滚动到选中项
              this.$nextTick(() => {
                const listContainer = this.$el.querySelector('.knowledge_list');
                const listItems = listContainer.querySelectorAll('.list_item');
                if (listItems[targetIndex]) {
                  listContainer.scrollTop = listItems[targetIndex].offsetTop - 100;
                }
              });
            } else {
              // 打印详细调试信息
              console.log('点击处理调试信息:', {
                paramsName: params.name,
                params: params,
                knowledgeItem: knowledgeItem,
                targetIndex: targetIndex,
                activeTab: this.activeTab,
                targetListLength: targetList.length,
                targetListSample: targetList.slice(0, 3),
                tableDataSample: this.tableData.slice(0, 1)
              });
            }
          }
          else if (isEmptyAreaClick || isNonOuterNodeClick) {
            // 点击空白区域或非最外层节点，恢复所有节点透明度
            // 清空selectedKnowledgeId，确保所有节点都高亮
            this.selectedKnowledgeId = '';

            // 调用generateTreeData时传入overrideKnowledgeId为空字符串，确保所有节点都不透明
            const updatedOption = {
              series: [{
                data: [
                  {
                    name: this.subjectName,
                    symbolSize: 5,
                    value: this.subjectScoreRate,
                    itemStyle: {
                      color: '#BFC1C7',
                      opacity: 1
                    },
                    isOutermost: false,
                    // 传入overrideKnowledgeId为空字符串，确保生成的所有节点都不透明
                    children: generateTreeData(this.tableData, 0, '')
                  }
                ]
              }]
            };
            // 更新图表，使用动画实现平滑过渡
            this.chart.setOption(updatedOption, {
              animation: true,
              animationDuration: 300
            });

            // 向父组件发送事件，清除选中的知识点ID
            this.$emit('knowledge-item-click', {
              item: null,
              index: -1
            });
          }
        });

        // 监听窗口大小变化
        window.addEventListener('resize', () => {
          if (this.chart) {
            this.chart.resize();
            this.updateChartLayout();
          }
        });
      }
      catch (error) {
        console.error('图表创建失败:', error);
      }
    },

    // 更新图表数据
    updateChart() {
      try {
        if (this.activeView === 'graph' && this.$refs.chart) {
          // 重新创建图表，实现刷新效果
          this.createChart();
        }
      }
      catch (error) {
        console.error('图表更新失败:', error);
      }
    },

    // 根据得分率获取对应的样式类
    getRateClass(rate) {
      const rateValue = parseFloat(rate);
      if (rateValue >= 85) {
        return 'rate_excellent';
      } else if (rateValue >= 60) {
        return 'rate_good';
      } else {
        return 'rate_weak';
      }
    },

    // 根据得分率获取对应的状态名称
    getRateName(rate) {
      const rateValue = parseFloat(rate);
      if (rateValue >= 85) {
        return '优秀';
      } else if (rateValue >= 60) {
        return '良好';
      } else {
        return '薄弱';
      }
    },

    // 行样式类名方法 - vxe-table 3.7.5版本兼容
    rowClassName({ row }) {
      // 使用selectedRow引用比较，避免修改数据
      if (this.selectedRow && this.selectedRow.knowledgeId === row.knowledgeId) {
        return 'selected-row';
      }
      return row.highlight ? 'row_highlight' : '';
    },

    // 处理知识点列表项点击事件
    handleItemClick(item, index) {
      // 更新选中索引
      this.selectedIndex = index;
      // 更新选中知识点ID，实现反向选择功能
      this.selectedKnowledgeId = item.knowledgeId;
      // 向父组件发送事件，传递点击的知识点数据
      this.$emit('knowledge-item-click', { item, index });

      // 如果当前是图形视图且图表已初始化，更新图表选中状态
      if (this.activeView === 'graph' && this.chart) {
        this.updateChart();
      }
    },

    // 处理树形表格行点击事件
    handleRowClick(row) {
      // 检查是否为最后一级节点（没有children或children为空）
      const isLastLevel = !row.children || row.children.length === 0;

      if (isLastLevel) {
        // 设置当前行为选中行，不修改数据，只更新引用
        this.selectedRow = row;

        // 调用handleItemClick方法处理点击事件
        this.handleItemClick(row, -1);
      }
    },

    // 处理单元格点击事件
    handleCellClick({ row }) {
      // 调用行点击事件处理逻辑
      this.handleRowClick(row);
    },

    // 根据知识点得分率获取对应的点颜色
    getDotColor(item, scoreRateType) {
      // 个人得分率personalScoreRate
      const scoreRate = scoreRateType === 'personalScoreRate' ? item.personalScoreRate : item.classScoreRate;
      const rate = parseFloat(scoreRate);
      if (rate >= 85) {
        return '#3BA272'; // 优秀 - 绿色
      } else if (rate >= 60 && rate < 84) {
        return '#FAC858'; // 良好 - 黄色
      } else if (rate < 59) {
        return '#EE6666'; // 薄弱 - 红色
      }
    }
  }
};
</script>

<style lang="scss" scoped>
.knowledge_graph {
  background: #FFFFFF;
  border-radius: 10px;
  padding: 20px;
  margin-bottom: 10px;
  position: relative;

  /* 选中行样式 - 确保所有情况下都能正确应用 */
  :deep(.vxe-body--row.selected-row),
  :deep(.selected-row) {
    background-color: rgba(46, 100, 250, 0.1) !important;
    color: #2E64FA !important;

    /* 确保所有子元素也继承文字颜色 */
    * {
      color: #2E64FA !important;
    }

    /* 特殊处理评分点样式 */
    .rate_dot {
      border-color: rgba(46, 100, 250, 0.1) !important;
    }
  }

  .graph_header {
    margin-bottom: 20px;
    position: relative;
    display: flex;
    justify-content: space-between;
    align-items: center;

    .legend {
      display: flex;
      gap: 20px;

      .legend_item {
        display: flex;
        align-items: center;
        gap: 5px;
        cursor: pointer;
        opacity: 0.7;
        transition: all 0.3s ease;
        font-weight: 500;

        &.selected {
          opacity: 1;
        }

        &:hover {
          opacity: 1;
        }

        .legend_dot {
          width: 20px;
          height: 10px;
          border-radius: 2px;
          transition: all 0.3s ease;
          background: #999999; // 默认灰色

          &.weak {
            background: #EE6666;
          }

          &.good {
            background: #FAC858;
          }

          &.excellent {
            background: #3BA272;
          }
        }

        .legend_text {
          font-size: 12px;
          color: #999999; // 默认灰色文字
          transition: all 0.3s ease;
        }

        // 选中状态样式
        &.selected {
          .legend_dot.weak {
            background: #EE6666;
          }

          .legend_dot.good {
            background: #FAC858;
          }

          .legend_dot.excellent {
            background: #3BA272;
          }

          .legend_text {
            color: #333;
          }
        }
      }

    }
  }

  // 视图切换按钮样式
  .view_switcher_container {
    display: flex;
    gap: 20px;
    z-index: 10;
    justify-content: flex-end;
    font-size: 14px;

    .switch_btn {
      display: flex;
      align-items: center;
      padding: 0;
      background-color: transparent;
      border: none;
      border-radius: 0;
      font-size: 14px;
      transition: color 0.3s ease;
      cursor: pointer;
      font-weight: 400;
      color: #999999;

      &:hover {
        color: #2E64FA;
      }
    }

    .graph_btn {
      color: #2E64FA;
    }

    // 图标样式，确保与文字对齐
    .icon_switch_graph,
    .icon_switch_list {
      img {
        display: inline-block;
        vertical-align: middle;
        margin: 0;
        padding: 0;
        margin-top: -3px;
      }
    }

    // 鼠标悬停时图片换色效果
    .switch_btn:hover .icon_switch_graph img,
    .switch_btn:hover .icon_switch_list img {
      filter: brightness(0) saturate(100%) invert(34%) sepia(100%) saturate(5000%) hue-rotate(210deg) brightness(95%) contrast(100%);
    }
  }

  // 对比选择器样式
  .comparison_selector {
    display: flex;
    align-items: center;
    gap: 10px;

    .student_position {
      font-size: 14px;
      color: #999999;
    }

    // 对比选择器按钮样式
    :deep(.el-button-group) {
      .el-button {
        padding: 7px 10px;
        // border-radius: 4px;

        &:not(.el-button--primary) {
          color: #999999;
          background-color: #FFFFFF;
          border-color: #DCDFE6;

          &:hover {
            color: #2E64FA;
            border-color: #C6E2FF;
          }
        }

        &.el-button--primary {
          background-color: #2E64FA;
          color: #FFFFFF;
          border-color: #2E64FA;

          &:hover {
            background-color: #409EFF;
            border-color: #409EFF;
          }
        }
      }
    }
  }

  .graph_content {
    display: flex;
    gap: 20px;
    position: relative;

    .knowledge_tab {
      display: flex;
      border-bottom: 1px solid #ECEEF3;
      margin-bottom: 15px;

      .tab_item {
        height: 40px;
        line-height: 40px;
        cursor: pointer;
        font-size: 14px;
        color: #666666;
        position: relative;
        transition: all 0.3s ease;
        margin-right: 20px;

        &.active {
          color: #2E64FA;
          font-weight: 500;

          &::after {
            content: '';
            position: absolute;
            bottom: -1px;
            left: 0;
            width: 100%;
            height: 2px;
            background-color: #2E64FA;
          }
        }

        &:hover {
          color: #2E64FA;
        }

        // 零分知识点：根据文字宽度自适应，不需要内间距
        // &:first-child {
        //   padding: 0;
        //   white-space: nowrap;
        // }

        // // 高频错题知识点：占满剩余宽度
        // &:last-child {
        //   padding: 0;
        //   white-space: nowrap;
        // }
      }
    }

    .knowledge_right_container {
      width: 350px;
      display: flex;
      flex-direction: column;
    }

    .chart_container {
      flex: 1;
      min-width: 0;
      border-radius: 10px 10px 10px 10px;
      border: 1px solid #E9EBEF;
      position: relative;
      padding: 20px;
      overflow: hidden;

      .top_container {
        display: flex;
        justify-content: space-between;
        align-items: flex-start;
        flex-wrap: wrap;
        gap: 10px;
        margin-bottom: 10px;
      }

      .legend {
        display: flex;
        gap: 20px;
        flex-wrap: wrap; // 小屏幕下自动换行
        flex: 1;
        min-width: 0;

        .legend_item {
          display: flex;
          align-items: center;
          gap: 5px;
          cursor: pointer;
          opacity: 0.7;
          transition: all 0.3s ease;
          font-weight: 500;

          &.selected {
            opacity: 1;
          }

          &:hover {
            opacity: 1;
          }

          .legend_dot {
            width: 20px;
            height: 10px;
            border-radius: 2px;
            transition: all 0.3s ease;
            background: #999999; // 默认灰色

            &.weak {
              background: #EE6666;
            }

            &.good {
              background: #FAC858;
            }

            &.excellent {
              background: #3BA272;
            }
          }

          .legend_text {
            font-size: 12px;
            color: #999999; // 默认灰色文字
            transition: all 0.3s ease;
          }

          // 选中状态样式
          &.selected {
            .legend_dot.weak {
              background: #EE6666;
            }

            .legend_dot.good {
              background: #FAC858;
            }

            .legend_dot.excellent {
              background: #3BA272;
            }

            .legend_text {
              color: #333;
            }
          }
        }

      }

      .chart {
        display: flex;
        justify-content: center;
        align-items: center;
        min-height: 590px;
      }

      .view_switcher_container {
        display: flex;
        gap: 20px;
        z-index: 10;
        justify-content: flex-end;
        font-size: 14px;
        white-space: nowrap; // 防止按钮换行
      }
    }

    .knowledge_list {
      width: 100%;
      height: 630px;
      overflow-y: auto;
      padding-right: 10px;
      position: relative;

      /* 滚动条样式 */
      &::-webkit-scrollbar {
        width: 6px;
      }

      &::-webkit-scrollbar-track {
        background: #f1f1f1;
        border-radius: 3px;
      }

      &::-webkit-scrollbar-thumb {
        background: #c1c1c1;
        border-radius: 3px;
      }

      &::-webkit-scrollbar-thumb:hover {
        background: #a8a8a8;
      }

      /* 暂无数据样式 */
      .no_data {
        position: absolute;
        top: 50%;
        left: 50%;
        transform: translate(-50%, -50%);
        font-size: 14px;
        color: #909399;
        text-align: center;
        width: 100%;
        height: 100%;
        display: flex;
        align-items: center;
        justify-content: center;
        border-radius: 8px;

        span {
          margin-top: 23%;
        }
      }

      .list_item {
        background: rgba(255, 255, 255, 0.1);
        border-radius: 6px;
        padding: 10px;
        margin-bottom: 10px;
        cursor: pointer;

        &:last-child {
          margin-bottom: 0;
        }

        &:hover,
        &.active {
          background: rgba(46, 100, 250, 0.1);
          border-radius: 6px;
        }

        .item_header {
          display: flex;
          align-items: center;
          margin-bottom: 8px;

          .item_dot {
            display: inline-block;
            width: 8px;
            height: 8px;
            background: #EE6666;
            border-radius: 50%;
            margin-right: 8px;
          }

          .item_title {
            font-size: 14px;
            font-weight: 500;
            color: #333;
            flex: 1;
            white-space: nowrap;
            overflow: hidden;
            text-overflow: ellipsis;
            min-width: 0;
          }

          .item_tag {
            margin-left: 5px;
            color: #FFFFFF;
            font-size: 12px;
            padding: 4px 6px;
            border-radius: 4px;
            font-weight: 400;
          }
        }

        .item_info {
          font-size: 12px;
          color: #999;
          margin-top: 8px;
          display: flex;
          justify-content: space-between;
          align-items: center;

          .item_score {
            text-align: left;

            .score_label {
              color: #999999;
            }

            .score_first {
              color: #F56C6C;
            }

            .score_separator {
              color: #999999;
              margin: 0 4px;
            }

            .score_second {
              color: #666666;
            }
          }

          .item_exam_count {
            text-align: right;
            color: #999999;

            .exam_count {
              color: #2E64FA;
            }
          }
        }
      }
    }
  }

  // vxe表格样式
  .list_content {
    border-radius: 10px 10px 10px 10px;


    .vxe-table {

      // 展开收起的样式
      :deep(.el-icon-circle-plus) {
        color: #DCDFE6 !important;
        font-size: 16px !important;
      }

      :deep(.el-icon-remove) {
        color: #2E64FA !important;
        font-size: 16px !important;
      }
    }

    /* 设置表格行高度和光标样式 */
    :deep {
      .vxe-table {
        border-radius: 8px;
        overflow-y: auto;
        overflow-x: hidden;

        // 使用CSS变量设置全局行高
        --vxe-ui-table-row-height-default: 20px !important;

        // 表头样式
        .vxe-table--header {
          display: table-header-group !important;
          visibility: visible !important;
          opacity: 1 !important;
          height: 52px !important;
        }

        /* 设置表头高度 */
        .vxe-table--header {
          .vxe-header--row {
            height: 52px !important;
          }
        }

        // 行样式 - 使用更具体的选择器
        .vxe-table--body {

          // 表格行样式
          tbody {
            tr {
              border-bottom: 1px solid #F0F2F5;
              cursor: pointer !important;
              height: 20px !important;
              line-height: 20px !important;
              min-height: 20px !important;
              max-height: 20px !important;

              &:hover {
                background-color: #f5f7fa !important;
              }

              &.row_highlight {
                background-color: rgba(195, 219, 255, 0.2);
                cursor: pointer !important;
              }

              &.selected-row {
                background-color: rgba(195, 219, 255, 0.2) !important;
                color: #2E64FA !important;
                cursor: pointer !important;
              }
            }
          }
        }

        // 单元格样式，设置内边距为0，确保行高由行高属性控制
        .vxe-body--column,
        .vxe-header--column {
          padding: 0 !important;
          height: 20px !important;
          line-height: 20px !important;
          min-height: 20px !important;
          max-height: 20px !important;
        }

        // 表格主体最小高度设置
        .vxe-table--body {
          min-height: 0 !important;
        }

        /* 自定义树形图标样式 */
        .vxe-tree-icon {
          display: inline-flex;
          align-items: center;
          justify-content: center;
          width: 14px;
          height: 14px;
          border-radius: 50%;
          margin-right: 6px;
          font-size: 12px;
          font-weight: bold;
          line-height: 1;
        }

        /* 展开状态的节点 */
        .vxe-tree-icon--minus {
          background-color: #409EFF;
          color: white;
        }

        /* 可展开但未展开的节点 */
        .vxe-tree-icon--plus {
          background-color: #C0C4CC;
          color: white;
        }

        // 斑马纹
        .vxe-table--body {
          tr:nth-child(even) {
            background-color: #F5F7FA;
          }
        }
      }
    }


    .knowledge_item {
      display: flex;
      align-items: center;

      .knowledge_title {
        font-size: 14px;
        color: #606266;
      }
    }

    .rate_info {
      // display: flex;
      align-items: center;
      gap: 8px;
      justify-content: center;
      width: 80px;
      margin: 0 auto;
      position: relative;
    }

    .rate_dot {
      display: inline-block;
      width: 6px;
      height: 6px;
      border-radius: 50%;
      position: absolute;
      top: 8px;
      left: 2px;

      &.rate_excellent {
        background-color: #3BA272;
      }

      &.rate_good {
        background-color: #FAC858;
      }

      &.rate_weak {
        background-color: #EE6666;
      }
    }

    .rate_value {
      font-size: 14px;
      color: #606266;
    }

    .diff_value {
      font-size: 14px;
      color: #606266;

      &.diff_negative {
        color: #F56C6C;
      }
    }
  }
}
</style>