Prechádzať zdrojové kódy

学生端错题复盘更新

dengshaobo 1 mesiac pred
rodič
commit
ec34b7c26d

+ 10 - 7
src/styles/common.scss

@@ -10628,14 +10628,17 @@ body {
 .target_step
 {
   display: flex;
-  justify-content: flex-start;
+  justify-content: center;
   align-items: center;
   padding: 10px 20px;
   height: 78px;
-
+  background: #fff;
+  box-sizing: border-box;
+  border-radius: 10px;
+  margin:auto;
   .step_item
   {
-    width: 260px;
+    width: 220px;
     height: 50px;
     border-radius: 10px 10px 10px 10px;
     border: 1px solid #DCDFE6;
@@ -10700,7 +10703,7 @@ body {
   .step_line
   {
     // min-width:200px;
-    width:calc(50% - 390px);
+    width:220px;
     height:20px;
     display: flex;
     justify-content: center;
@@ -10711,14 +10714,14 @@ body {
     color: #2E64FA;
     letter-spacing: 0.1em;
     overflow: hidden;
-    background-image: url("../assets/bg/line_bg.png");
+    background-image: url("@/assets/bg/line_bg.png");
     background-repeat: no-repeat;
-    background-size:80% 20px;
+    background-size:170px 20px;
     background-position: 50% 50%;
-
   }
 }
 
+
 //Ai组件对话框样式
 .ai_main
 {

+ 663 - 0
src/views/targetImprove/components/CommonTree.vue

@@ -0,0 +1,663 @@
+<template>
+  <!-- 公共树形组件:基于 Element UI el-tree 封装 -->
+  <!-- common_tree_wrapper:用作非 scoped 样式的全局命名空间,防止样式泄漏到其他组件 -->
+  <div class="common_tree_wrapper common_tree">
+    <!--
+      el-tree 核心配置说明:
+      - ref: 用于父组件通过 this.$refs 调用 el-tree 原生方法(如 setCheckedKeys、getCheckedNodes 等)
+      - data: 树形数据源(由父组件通过 props 传入)
+      - props: 配置 el-tree 如何读取数据结构中的字段(label/children)
+      - node-key: 每个树节点的唯一标识字段,用于选中/高亮定位
+      - show-checkbox: 开启多选复选框
+      - highlight-current: 高亮当前点击选中的节点
+      - default-expand-all: 默认展开所有节点
+    -->
+    <el-tree
+      ref="commonTree"
+      class="tree_container"
+      :data="treeData"
+      :props="treeProps"
+      :node-key="nodeKey"
+      :show-checkbox="showCheckbox"
+      :highlight-current="highlightCurrent"
+      :default-expand-all="defaultExpandAll"
+      :default-expanded-keys="defaultExpandedKeys"
+      :current-node-key="currentNodeKey"
+      :expand-on-click-node="expandOnClickNode"
+      @check="handleNodeCheck"
+    >
+      <!--
+        自定义树节点内容插槽(slot-scope)
+        - node: 当前节点的完整数据对象(label、children、data 等)
+        - data: 当前节点绑定的用户数据(即 treeData 中的每一项)
+      -->
+      <span class="custom_tree_node" slot-scope="{ node, data }">
+        <!-- 节点名称区域 -->
+        <span class="node_label" :title="data[treeProps.label]">
+          <!-- 名称文本单独包裹一层,确保省略号只作用于真正承载文字的元素 -->
+          <span class="node_label_text">{{ data[treeProps.label] }}</span>
+          <!-- 右侧计数(可选,数据存在 count 字段时显示) -->
+          <span
+            class="node_count"
+            v-if="data.count !== undefined && data.count !== null"
+          >
+            ({{ data.count }})
+          </span>
+        </span>
+
+        <!--
+          AI 讲解按钮(Element UI 文字按钮 type="text")
+          - 默认隐藏(opacity: 0)
+          - 通过父级 hover 显示
+          - @click.stop 阻止冒泡,避免触发树节点点击
+        -->
+        <el-button
+          class="ai_explain_btn"
+          type="text"
+          size="mini"
+          icon=""
+          @click.stop="HandleAiExplain(node, data)"
+        >
+          <img
+            src="@/assets/knowledgeGraph/aiIcon.png"
+            alt="AI讲解"
+            style="width: 16px; height: 16px"
+          />
+          <span>AI讲解</span>
+        </el-button>
+      </span>
+    </el-tree>
+  </div>
+</template>
+
+<script>
+/**
+ * CommonTree 公共树形组件
+ *
+ * 功能说明:
+ * 1. 基于 Element UI el-tree 二次封装,支持数据传入渲染
+ * 2. 支持多选复选框
+ * 3. 节点勾选回传(仅发送勾选节点的 key 数组,如 knowledgeId 列表)
+ * 4. 鼠标悬停节点行显示 "AI讲解" 按钮,点击打印并回传当前节点
+ *
+ * 父组件使用示例:
+ * <CommonTree
+ *   :tree-data="knowledgeTreeData"
+ *   :tree-props="{ label: 'knowledgeName', children: 'children' }"
+ *   node-key="knowledgeId"
+ *   show-checkbox
+ *   @nodeCheck="handleTreeCheck"
+ *   @ai-explain="handleAiExplain"
+ * />
+ *
+ * 父组件 handleTreeCheck 接收参数:
+ * - checkedKeys: Array — 所有勾选节点的 key 数组(勾选父节点时包含其全部子节点 key)
+ */
+export default {
+  name: "CommonTree",
+
+  // ==================== Props 配置(由父组件传入) ====================
+  props: {
+    /**
+     * 树形数据源
+     * 数据结构示例:
+     * [
+     *   { id: 1, label: '节点1', count: 10, children: [
+     *     { id: 11, label: '子节点1', count: 5 }
+     *   ]}
+     * ]
+     */
+    treeData: {
+      type: Array,
+      default: () => [],
+    },
+
+    /**
+     * el-tree 的 props 配置,用于映射数据结构的字段
+     * 默认:{ label: 'label', children: 'children' }
+     * 如使用其他字段名,可传:{ label: 'knowledgeName', children: 'childList' }
+     */
+    treeProps: {
+      type: Object,
+      default: () => ({
+        label: "label",
+        children: "children",
+      }),
+    },
+
+    /**
+     * 节点唯一标识字段名
+     * 用于选中、高亮、展开等操作的定位
+     */
+    nodeKey: {
+      type: String,
+      default: "id",
+    },
+
+    /** 是否显示多选复选框 */
+    showCheckbox: {
+      type: Boolean,
+      default: false,
+    },
+
+    /** 是否高亮当前点击的节点 */
+    highlightCurrent: {
+      type: Boolean,
+      default: true,
+    },
+
+    /** 是否默认展开所有节点 */
+    defaultExpandAll: {
+      type: Boolean,
+      default: true,
+    },
+
+    /**
+     * 默认展开的节点 key 数组
+     * 与 defaultExpandAll 互斥使用
+     */
+    defaultExpandedKeys: {
+      type: Array,
+      default: () => [],
+    },
+
+    /** 当前高亮选中的节点 key */
+    currentNodeKey: {
+      type: [String, Number],
+      default: "",
+    },
+
+    /**
+     * 点击节点时是否展开/收起
+     * false:只有点击小箭头才展开;点击节点文字只触发选中
+     * true:点击节点文字也会触发展开/收起
+     */
+    expandOnClickNode: {
+      type: Boolean,
+      default: false,
+    },
+  },
+  inject: ['openAiRobot'],//注入Ai机器人组件调用方法
+  // ==================== 数据状态 ====================
+  data() {
+    return {};
+  },
+  computed:{
+  
+    subjectName()
+    {
+      return this.$store.state.target.subjectName;
+    }
+  
+
+  },
+  // ==================== 生命周期 ====================
+  mounted() {
+    if (Array.isArray(this.treeData) && this.treeData.length > 0) {
+      clearTimeout(this._defaultSelectTimer);
+      this._defaultSelectTimer = setTimeout(() => {
+        this.applyDefaultFirstNode(this.treeData);
+      }, 100);
+    }
+  },
+
+
+
+  beforeDestroy() {
+    clearTimeout(this._defaultSelectTimer);
+  },
+
+  // ==================== Watch ====================
+  watch: {
+    treeData: {
+      handler(newVal) {
+        if (!Array.isArray(newVal) || newVal.length === 0) return;
+        // 用 setTimeout 确保 el-tree 内部节点已完全渲染(比 $nextTick 更可靠)
+        clearTimeout(this._defaultSelectTimer);
+        this._defaultSelectTimer = setTimeout(() => {
+          this.applyDefaultFirstNode(newVal);
+        }, 100);
+      },
+    },
+  },
+
+  // ==================== 方法 ====================
+  methods: {
+    /**
+     * 树节点勾选事件(多选,showCheckbox=true 时生效)
+     * 将所有勾选节点的 key(即 nodeKey 字段值,如 knowledgeId)数组发给父组件
+     * 勾选父节点时,el-tree 默认级联勾选其全部子节点,故数组中包含父节点及全部子节点 key
+     * @param {Object} data        - 当前勾选/取消的节点数据
+     * @param {Object} checkedInfo - 勾选状态详情 { checkedNodes, checkedKeys, halfCheckedKeys, halfCheckedNodes }
+     */
+    handleNodeCheck(data, checkedInfo) {
+        console.log("当前节点数据:", data);
+        console.log("勾选状态详情:", checkedInfo);
+      this.$emit("nodeCheck", checkedInfo.checkedKeys);
+    },
+
+    /**
+     * AI 讲解按钮点击事件
+     * 1. 打印当前节点数据(方便调试)
+     * 2. 通过 $emit 回传给父组件处理
+     *
+     * @param {Object} node  - el-tree 节点对象
+     * @param {Object} data  - 当前节点绑定的用户数据
+     */
+    HandleAiExplain(node, data) 
+    {
+        console.log("当前节点数据:", data);
+      let content = "科目:"+this.subjectName+",知识点:"+data.knowledgeName;
+      this.openAiRobot(content);
+
+    },
+
+    /**
+     * 对外暴露方法:获取所有勾选的节点(仅多选模式 showCheckbox=true 有效)
+     * @param {Boolean} leafOnly - 是否只返回叶子节点
+     * @returns {Array} 选中的节点对象数组
+     */
+    getCheckedNodes(leafOnly = false) {
+      if (!this.$refs.commonTree) return [];
+      return this.$refs.commonTree.getCheckedNodes(leafOnly);
+    },
+
+    /**
+     * 对外暴露方法:获取所有勾选节点的 key 数组
+     * @param {Boolean} leafOnly
+     * @returns {Array} 选中的节点 key 数组
+     */
+    getCheckedKeys(leafOnly = false) {
+      if (!this.$refs.commonTree) return [];
+      return this.$refs.commonTree.getCheckedKeys(leafOnly);
+    },
+
+    /**
+     * 对外暴露方法:通过 keys 设置哪些节点被选中
+     * @param {Array} keys       - 要选中的节点 key 数组
+     * @param {Boolean} leafOnly - 是否只设置叶子节点
+     */
+    setCheckedKeys(keys, leafOnly = false) {
+      if (!this.$refs.commonTree) return;
+      this.$refs.commonTree.setCheckedKeys(keys, leafOnly);
+    },
+
+    /**
+     * 对外暴露方法:清空所有选中节点
+     */
+    clearChecked() {
+      if (!this.$refs.commonTree) return;
+      this.$refs.commonTree.setCheckedKeys([]);
+    },
+
+    /**
+     * 对外暴露方法:设置当前高亮的节点
+     * @param {String|Number} key - 节点 key
+     */
+    setCurrentKey(key) {
+      if (!this.$refs.commonTree) return;
+      this.$refs.commonTree.setCurrentKey(key);
+    },
+
+    /**
+     * 默认勾选并展开第一个一级节点
+     * 直接通过 el-tree 内部 store 获取节点实例,避免 node-key 与数据字段不匹配导致的 key 查找失败
+     * @param {Array} data - 树形数据
+     */
+    applyDefaultFirstNode(data) {
+      if (!data || data.length === 0) return;
+      const treeRef = this.$refs.commonTree;
+      if (!treeRef || !treeRef.store || !treeRef.store.root) return;
+
+      // 1. 获取第一个顶层节点实例(绕过 key 匹配)
+      const rootNode = treeRef.store.root;
+      const childNodes = rootNode.childNodes;
+      if (!childNodes || childNodes.length === 0) return;
+
+      const firstNodeInstance = childNodes[0];
+      if (!firstNodeInstance) return;
+
+      // 2. 默认勾选第一个节点及其全部子节点(deep=true 级联勾选所有子节点)
+      if (this.showCheckbox) {
+        firstNodeInstance.setChecked(true, true);
+      }
+
+      // 3. 默认高亮选中第一个节点
+      treeRef.setCurrentKey(firstNodeInstance.key);
+
+      // 4. 默认展开第一个节点及其全部子节点(所有层级)
+      const expandAllChildren = (node) => {
+        if (!node) return;
+        node.expanded = true;
+        const subs = node.childNodes;
+        if (Array.isArray(subs) && subs.length > 0) {
+          subs.forEach((s) => expandAllChildren(s));
+        }
+      };
+      expandAllChildren(firstNodeInstance);
+
+      // 5. 触发 nodeCheck 事件,将所有勾选节点的 key 数组发给父组件
+      //    仅发送一个数组参数(包含第一个节点及其所有子节点的 key)
+      if (this.showCheckbox) {
+        const checkedKeys = treeRef.getCheckedKeys();
+        console.log("当前节点数据:", checkedKeys);
+        this.$emit("nodeCheck", checkedKeys);
+      }
+    },
+  },
+};
+</script>
+
+<!--
+  ==========================================================================
+  样式分两块:
+  1. 下面这个不带 scoped 的 style 块:专门覆盖 Element UI 原生类名(连接线、padding、间距、选中态)
+     - scoped + :deep 在 el-tree 深层级嵌套下经常不生效,改用非 scoped 搭配组件唯一根类
+       .common_tree_wrapper 做命名空间隔离,不会污染全局其他 el-tree
+  2. 后面带 scoped 的 style 块:放自定义节点内容(custom_tree_node / node_label / ai_explain_btn 等)
+  ==========================================================================
+-->
+<style lang="scss">
+/* ============== 可配置常量 ============== */
+$line_color: #dcdfe6; // 连接线颜色(虚线)
+$line_style: dashed; // 连接线样式
+$line_width: 1px; // 连接线宽度
+$indent_size: 35px; // 每层缩进
+$node_height: 36px; // 单行节点高度
+$node_padding_l: 15px; // 节点左侧 padding (用户要求:15px)
+$node_gap: 10px; // 节点上下间距   (用户要求:10px)
+$label_color: #333333; // 节点文字       (用户要求)
+$label_active: #2e64fa; // 选中节点文字    (用户要求)
+$label_fs: 14px; // 文字字号       (用户要求)
+$label_fw: 400; // 文字字重       (用户要求)
+$btn_color: #4f3eff; // AI讲解按钮颜色  (用户要求)
+
+/* =========================================================
+   命名空间:.common_tree_wrapper(只影响本组件)
+   ========================================================= */
+.common_tree_wrapper {
+  width: 100%;
+  height: 100%;
+  box-sizing: border-box;
+  padding: 8px 0;
+
+  /* ===================== 基础 ===================== */
+  .tree_container,
+  .el-tree {
+    width: 100%;
+    min-width: max-content; /* 整棵树按最宽节点内容撑开,所有节点行宽度一致 */
+    background: transparent;
+  }
+
+  /* 允许每个节点内容宽度超过容器,从而触发父容器横向滚动条 */
+  .el-tree-node__content {
+    padding-left: 0 !important;
+    padding-right: 0px;
+    height: $node_height;
+    line-height: $node_height;
+    background: transparent;
+    border-radius: 4px;
+    margin-top: 0;
+    margin-bottom: 0;
+    font-weight: $label_fw;
+    font-size: $label_fs;
+    color: $label_color;
+    width: 100%; /* 所有节点行跟随树宽度,保持一致 */
+    overflow: visible; /* 取消默认内容裁剪 */
+
+    &:hover {
+      background-color: #f0f7ff;
+    }
+  }
+
+  /* 第一级也统一 15px */
+  .el-tree > .el-tree-node > .el-tree-node__content {
+    padding-left: $node_padding_l !important;
+  }
+
+  /* ===================== 自定义展开收起图标样式 ===================== */
+  .el-tree-node__expand-icon {
+    width: 16px;
+    height: 16px;
+    display: flex !important;
+    align-items: center !important;
+    justify-content: center !important;
+    cursor: pointer;
+    margin-right: 8px;
+    padding: 0 !important;
+    border: none !important;
+    /* 去掉Element UI默认的transform旋转过渡动画,直接切换图标 */
+    transform: none !important;
+    transition: none !important;
+  }
+  /* 去掉展开状态的transform旋转 */
+  .el-tree-node__expand-icon.expanded {
+    transform: none !important;
+    -webkit-transform: none !important;
+  }
+
+  /* 隐藏Element UI默认的箭头伪元素 */
+  .el-tree-node__expand-icon::before {
+    display: none !important;
+  }
+
+  /* 收起状态:显示加号 icon_jia */
+  .el-tree-node__expand-icon:not(.expanded):not(.is-leaf)::after {
+    content: "\e64e";
+    font-family: "iconfont" !important;
+    font-size: 16px;
+    color: #e0e3e9;
+    display: inline-block;
+    width: 16px;
+    height: 16px;
+    line-height: 16px;
+    text-align: center;
+  }
+
+  /* 展开状态:显示减号 icon_jian */
+  .el-tree-node__expand-icon.expanded:not(.is-leaf)::after {
+    content: "\e64f";
+    font-family: "iconfont" !important;
+    font-size: 16px;
+    color: #2e64fa;
+    display: inline-block;
+    width: 16px;
+    height: 16px;
+    line-height: 16px;
+    text-align: center;
+  }
+
+  /* 叶子节点的占位符,保持对齐一致 */
+  .el-tree-node__expand-icon.is-leaf {
+    width: 0 !important;
+    height: 0 !important;
+    display: inline-block !important;
+    cursor: default;
+    visibility: hidden;
+    margin-right: 8px;
+    padding: 0 !important;
+  }
+
+  /* ===================== 虚线连接线(核心) ===================== */
+
+  /* 1. 竖虚线:画在 children 容器的左侧,贯穿所有子节点 */
+  .el-tree-node .el-tree-node__children {
+    overflow: visible;
+    position: relative;
+    margin-left: 0;
+    padding-left: 20px; // 层级缩进
+
+    &::before {
+      content: "";
+      position: absolute;
+      top: 0;
+      bottom: $node_gap + $node_height / 2; // 末端停在最后一个节点"半高"处,和横线接上
+      left: 18px; // 竖线 x 坐标
+      width: $line_width;
+      border-left: $line_width $line_style $line_color;
+    }
+  }
+
+  /* 2. 横虚线:画在每个节点行的左侧,从竖线方向延伸到文字左边 */
+  .el-tree-node {
+    position: relative;
+
+    > .el-tree-node__content::before {
+      content: "";
+      position: absolute;
+      top: 50%;
+      left: -($indent_size - 18px); // 起点对齐竖线
+      width: $indent_size - 20px; // 横线长度
+      height: 0;
+      border-top: $line_width $line_style $line_color;
+      pointer-events: none;
+    }
+  }
+
+  /* 3. 第一级节点不画横线 */
+  .el-tree > .el-tree-node > .el-tree-node__content::before {
+    display: none;
+  }
+
+  /* 4. 最后一个子节点:竖线在横线之下的部分用白色盖掉,形成"L"拐角 */
+  .el-tree-node > .el-tree-node__children > .el-tree-node:last-child {
+    > .el-tree-node__content::after {
+      content: "";
+      position: absolute;
+      top: 50%;
+      bottom: -$node_gap;
+      left: 18px - $indent_size; // 与竖线同 x
+      width: $line_width + 2px;
+      background: #fff; // 白色遮挡(面板必须是白色背景)
+      z-index: 1;
+    }
+  }
+
+  /* ===================== 选中 & 复选框 ===================== */
+  .el-tree-node.is-current > .el-tree-node__content {
+    background-color: #e6f0ff;
+    color: $label_active; // 让文字内容(含原生 el-tree label 模式)也变色
+
+    /* 额外命中自定义 slot 中的 .node_label,防止 scoped 里写的 #333 覆盖掉选中色 */
+    .node_label {
+      color: $label_active !important;
+      font-weight: $label_fw;
+    }
+  }
+
+  .el-checkbox {
+    margin-right: 6px;
+  }
+
+  /* ===================== AI 讲解按钮(Element UI 文字按钮) =====================
+     字体 400 / 14 / #4F3EFF;opacity 0 默认隐藏,hover 节点行显示
+  */
+
+  .ai_explain_btn.el-button--text {
+    display: inline-flex !important;
+    align-items: center;
+    justify-content: center;
+    gap: 4px;
+    padding: 4px 6px !important;
+    height: auto !important;
+    min-height: 24px;
+    margin-left: 8px;
+    opacity: 0;
+    transition: opacity 0.2s ease;
+    white-space: nowrap;
+    flex-shrink: 0;
+    position: relative;
+    z-index: 3;
+    font-weight: 400; // 用户要求
+    font-size: 14px; // 用户要求
+    color: $btn_color !important; // 用户要求:#4F3EFF
+
+    // 确保内部img和span都居中对齐
+    img {
+      display: inline-block;
+      vertical-align: middle;
+      flex-shrink: 0;
+      margin-right: 4px;
+    }
+    span {
+      display: inline-block;
+      vertical-align: middle;
+      line-height: 1;
+    }
+  }
+
+  .ai_explain_btn.el-button--text:hover {
+    color: darken($btn_color, 10%) !important;
+  }
+
+  .ai_explain_btn .ai_icon {
+    display: inline-block;
+    width: 16px;
+    height: 16px;
+    line-height: 16px;
+    text-align: center;
+    font-size: 10px;
+    font-weight: 600;
+    color: #fff;
+    background: $btn_color;
+    border-radius: 3px;
+    font-style: normal;
+    flex-shrink: 0;
+  }
+
+  .ai_explain_btn.el-button--text:hover .ai_icon {
+    background: darken($btn_color, 10%);
+  }
+
+  /* hover 节点行时,让 AI 讲解按钮淡入 */
+  .el-tree-node__content:hover .ai_explain_btn.el-button--text {
+    opacity: 1 !important;
+  }
+}
+</style>
+
+<!-- ===============================================================
+     以下 scoped 样式块:只处理"自定义节点内容"(我们自己模板里写的)
+     类名是自定义的,能被 scoped 正常命中,无需 :deep
+   =============================================================== -->
+<style lang="scss" scoped>
+.custom_tree_node {
+  display: flex;
+  align-items: center;
+  justify-content: space-between;
+  flex: 1;
+  width: 100%; /* 占满整个节点行宽度(跟随树整体宽度) */
+  padding-right: 8px;
+  height: 36px;
+  line-height: 36px;
+  white-space: nowrap;
+  position: relative;
+  z-index: 2;
+
+  /* ===== 节点文字(用户要求:400 / 14px / #333333) ===== */
+  .node_label {
+    flex: 1;
+    display: inline-flex;
+    align-items: center;
+    font-weight: 400;
+    font-size: 14px;
+    color: #333333;
+    white-space: nowrap;
+
+    /* 名称文本:完整显示,不省略 */
+    .node_label_text {
+      display: inline-block;
+      white-space: nowrap;
+      line-height: 1;
+    }
+
+    /* 计数(60):灰色小字,不收缩 */
+    .node_count {
+      color: #909399;
+      margin-left: 4px;
+      font-size: 13px;
+      flex-shrink: 0;
+    }
+  }
+}
+</style>

+ 68 - 93
src/views/targetImprove/consolidate/index.vue

@@ -7,16 +7,20 @@
         <div class="filter_list">
           <div class="list_check">
             <span class="label_name">范围:</span>
-            <el-checkbox-group v-model="checkGrades">
-              <el-checkbox :label="item.label" :value="item.value" v-for="item in gradeList" />
+            <el-checkbox-group v-model="checkGrades" @change="ChangeFilters">
+              <el-checkbox :label="item.value"  v-for="item in gradeList" :key="item.value">
+                 {{ item.label }}
+              </el-checkbox>
               
             </el-checkbox-group>
           </div>
           <div class="list_check">
             <span class="label_name">维度:</span>
-            <el-checkbox-group v-model="checkDimension">
-              <el-checkbox :label="item.label" :value="item.value" v-for="item in dimensionList" />
-              
+            <el-checkbox-group v-model="checkDimension" @change="ChangeFilters">
+              <el-checkbox :label="item.value" v-for="item in dimensionList" :key="item.value">
+                {{ item.label }}
+              </el-checkbox>
+
             </el-checkbox-group>
           </div>
           <div class="list_check">
@@ -27,7 +31,7 @@
               type="daterange"
               range-separator="至"
               start-placeholder="开始日期"
-              end-placeholder="结束日期">
+              end-placeholder="结束日期" value-format="yyyy-MM-dd" @change="ChangeDate">
             </el-date-picker>
           </div>
         </div>
@@ -45,9 +49,7 @@
             node-key="id"
             show-checkbox
             :default-expand-all="false"
-            @node-click="HandleTestNodeClick"
-            @node-check="HandleTestNodeCheck"
-            @ai-explain="HandleTestAiExplain"
+            @nodeCheck="HandleTestNodeCheck"
           />
         </div>
       </div>
@@ -83,7 +85,7 @@
 <script>
 import TargetSubject from "@/views/targetImprove/components/TargetSubject.vue"//顶部筛选科目组件
 import QuestionItem from "@/views/targetImprove/components/QuestionItem.vue"//题目公共组件
-import CommonTree from '@/components/CommonTree.vue';//树形组件
+import CommonTree from '@//views/targetImprove/components/CommonTree.vue';//树形组件
 import { mapState } from 'vuex'
 export default {
   components: {
@@ -108,10 +110,13 @@ export default {
           value: 2
         }
       ],//维度列表维度 1考试 2练习
+      // gradeList:[],//年级列表
+      knowledgeIds:[],//知识点选择
       checkGrades:[],//年级选择
-      checkDimension:[],//维度选择
+      checkDimension:[1],//维度选择 默认考试
       dataValue:[],//时间选择
-
+      startTime:'',//开始时间
+      endTime:'',//结束时间
       mockTreeData:[],//知识点树形数据
 
     }
@@ -134,45 +139,66 @@ export default {
   },
   mounted() 
   {
+    this.startTime=this.GetCurrentDate();
+    this.endTime=this.GetCurrentDate();
+    this.dataValue=[this.startTime,this.endTime];
     console.log('打印科目编码', this.gradeList)
+    this.checkGrades=[this.gradeList[this.gradeList.length-1].value];
     // this.GetTargetErrorTopData();//获取错题筛选数据
-    this.GetTargetErrorQuestionListData();//获取错题列表
-    this.GetTargetErrorKnowledgeList();//获取知识点树形数据
+    this.GetQuestionList();//获取错题列表
+    this.GetKnowledgeTreeData();//获取知识点树形数据
   },
   methods: { 
 
-    // // 获取错题筛选数据
-    // GetTargetErrorTopData()
-    // {
 
-    //   this.$api.target.getTargetErrorTopData().then(res => {
-    //     console.log('打印学生端错题头部信息', res)
-    //     if(res.code==200)
-    //     {
-    //       let courseItem=res.data.filter(item => item.courseCode == this.subjectCode)[0];
-    //       console.log('打印课程信息', courseItem)
-    //       this.gradeList = courseItem.grades;
-    //       console.log('打印年级列表', this.gradeList)
+     /**
+     * 【事件回传】复选框勾选变化(多选)
+     * @param {Array} checkedKeys - 所有勾选节点的 key 数组(勾选父节点时包含其全部子节点 key)
+     */
+    HandleTestNodeCheck(checkedKeys) {
+      console.log('%c[树形组件] node-check 勾选节点 key 数组: ', 'background:#3BA272;color:#fff;padding:4px 8px;border-radius:4px;', checkedKeys);
+      this.knowledgeIds = checkedKeys;
+      this.GetQuestionList();//获取错题列表
+    },
+
+    //筛选条件修改
+    ChangeFilters()
+    {
+      this.GetKnowledgeTreeData();//获取知识点树
+    },
+
+    //筛选数据改变
+    ChangeDate()
+    {
+      console.log("筛选数据改变了",this.dataValue);
+      this.startTime=this.dataValue[0];
+      this.endTime=this.dataValue[1];
+      this.GetKnowledgeTreeData();//获取知识点树
+    },
 
-    //     }
-    //   });
-    // },
-    
+    //获取当前时间
+    GetCurrentDate(){
+      const d = new Date()
+      const y = d.getFullYear()
+      const m = String(d.getMonth()+1).padStart(2,'0')
+      const day = String(d.getDate()).padStart(2,'0')
+      return `${y}-${m}-${day}`
+    },
 
     // 获取错题列表
-    GetTargetErrorQuestionListData()
+    GetQuestionList()
     {
       let params={
         pageParam: {
           pageNum: 1,
           pageSize: 10
         },
-        knowledgeIds: ['123'],
+        knowledgeIds: this.knowledgeIds,
         courseCode: this.subjectCode,
-        gradeCodes: [7],
-        types: [1,2],//维度 1考试 2练习
-        beginAt: "",
-        endAt: ""
+        gradeCodes: this.checkGrades,
+        types: this.checkDimension,//维度 1考试 2练习
+        beginAt: this.startTime+" 00:00:00",//开始时间
+        endAt: this.endTime+' 23:59:59',//结束时间
       };
       this.$api.target.getTargetErrorQuestionListData(params).then(res => {
         console.log('打印错题列表', res)
@@ -183,19 +209,19 @@ export default {
       });
     },
     // 获取知识点树形数据
-    GetTargetErrorKnowledgeList()
+    GetKnowledgeTreeData()
     {
       let params={
         pageParam: {
           pageNum: 1,
-          pageSize: 10
+          pageSize: 999
         },
-        knowledgeIds: ['123'],
+        // knowledgeIds: ['123'],
         courseCode: this.subjectCode,
-        gradeCodes: [7],
-        types: [1,2],//维度 1考试 2练习
-        beginAt: "",
-        endAt: ""
+        gradeCodes: this.checkGrades,
+        types: this.checkDimension,//维度 1考试 2练习
+        beginAt: this.startTime+" 00:00:00",//开始时间
+        endAt: this.endTime+' 23:59:59',//结束时间
       };
       this.$api.target.getTargetErrorKnowledgeList(params).then().then(res => {
         console.log('打印知识点列表数据', res)
@@ -207,57 +233,6 @@ export default {
       });
     },
 
-        /**
-     * 【事件回传1】树节点点击(单选)
-     * @param {Object} data - 当前节点用户数据
-     * @param {Object} node - el-tree 节点实例
-     */
-    HandleTestNodeClick(data, node) {
-      const logMsg =
-        `节点ID: ${data.id}\n` +
-        `节点名称: ${data.label}\n` +
-        `节点层级: ${node.level}\n` +
-        `是否叶子: ${node.isLeaf ? '是' : '否'}\n` +
-        `计数count: ${data.count ?? '无'}\n` +
-        `\n完整data: ${JSON.stringify(data, null, 2)}`;
-      console.log('%c[KnowledgeGraph] node-click 回传数据: ', 'background:#2E64FA;color:#fff;padding:4px 8px;border-radius:4px;', { data, node });
-      this.appendLog('info', '节点点击', logMsg);
-    },
-
-    /**
-     * 【事件回传2】复选框勾选变化(多选)
-     * @param {Object} data        - 当前操作的节点数据
-     * @param {Object} checkedInfo - 勾选状态详情 { checkedNodes, checkedKeys, halfCheckedKeys }
-     */
-    HandleTestNodeCheck(data, checkedInfo) {
-      const selectedLabels = checkedInfo.checkedNodes.map(n => n.label).join('、') || '(无)';
-      const logMsg =
-        `当前操作节点: ${data.label}\n` +
-        `已勾选节点数: ${checkedInfo.checkedNodes.length}\n` +
-        `已勾选key: [${checkedInfo.checkedKeys.join(', ')}]\n` +
-        `半选key: [${(checkedInfo.halfCheckedKeys || []).join(', ') || '无'}]\n` +
-        `\n已勾选节点名称: ${selectedLabels}`;
-      console.log('%c[KnowledgeGraph] node-check 回传数据: ', 'background:#3BA272;color:#fff;padding:4px 8px;border-radius:4px;', { data, checkedInfo });
-      this.appendLog('success', '复选框勾选', logMsg);
-    },
-
-    /**
-     * 【事件回传3】AI讲解按钮点击
-     * @param {Object} payload { nodeData, nodeInstance, nodeKey, nodeLabel }
-     */
-    HandleTestAiExplain(payload) {
-      const { nodeData, nodeKey, nodeLabel } = payload;
-      const logMsg =
-        `节点Key: ${nodeKey}\n` +
-        `节点名称: ${nodeLabel}\n` +
-        `节点层级: ${payload.nodeInstance.level}\n` +
-        `计数count: ${nodeData.count ?? '无'}\n` +
-        `\n完整节点数据: ${JSON.stringify(nodeData, null, 2)}`;
-      console.log('%c[KnowledgeGraph] ai-explain 回传数据: ', 'background:#FAC858;color:#333;padding:4px 8px;border-radius:4px;', payload);
-      this.appendLog('warn', 'AI讲解', logMsg);
-    },
-
-
   }
 };
 </script>

+ 3 - 0
src/views/targetImprove/practice/index.vue

@@ -16,6 +16,9 @@
         <div class="span_number">3</div>查看练习结果 
       </div>
 
+    </div>
+    <div class="page_jg_10">
+
     </div>
     <!-- 知识点图谱 -->
     <knowledgeGraph v-if="stepIndex==1"></knowledgeGraph>

+ 1 - 1
src/views/targetImprove/practice/practiceAnswer.vue

@@ -396,7 +396,7 @@ export default {
     box-sizing: border-box;
 
     .side_title {
-      font-weight: 500;
+      font-weight: 550;
       font-size: 16px;
       color: #333333;
     }

+ 1 - 1
version.json

@@ -1,5 +1,5 @@
 {
-  "version": "0.1.3_2026_8_18_0",
+  "version": "0.1.3_2026_8_21_0",
   "content": [
     {
       "time": "2024-11-1",