فهرست منبع

精准提升学生端页面开发

吴朋磊 3 ماه پیش
والد
کامیت
9ee6b0b66b

تفاوت فایلی نمایش داده نمی شود زیرا این فایل بسیار بزرگ است
+ 485 - 163
package-lock.json


+ 1 - 0
package.json

@@ -52,6 +52,7 @@
     "vue-virtual-scroller": "^1.1.2",
     "vuex": "^3.6.2",
     "vuex-persistedstate": "^4.1.0",
+    "vxe-table": "^3.20.0",
     "xe-utils": "^3.5.13",
     "yarn": "^1.22.22"
   },

+ 1 - 0
src/assets/studentAnalysis/analysis.svg

@@ -0,0 +1 @@
+<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1770262130832" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="1870" width="20" height="20" xmlns:xlink="http://www.w3.org/1999/xlink"><path d="M874.624 68.288a102.4 102.4 0 0 1 102.4 102.4v682.624a102.4 102.4 0 0 1-102.336 102.4H256a38.4 38.4 0 0 1 0-76.8h618.688a25.6 25.6 0 0 0 25.6-25.6V401.088H123.648V512a38.4 38.4 0 1 1-76.8 0V170.688a102.4 102.4 0 0 1 102.4-102.4h725.312z m-234.496 453.184a38.4 38.4 0 0 1 46.08 5.76l95.616 93.12a38.4 38.4 0 0 1-53.568 55.04l-70.272-68.48-144.832 126.656a38.4 38.4 0 0 1-51.84-1.216L348.16 624.064l-233.088 235.648a38.4 38.4 0 0 1-54.656-54.08l259.776-262.4a38.4 38.4 0 0 1 53.888-0.704l114.944 110.08 145.152-126.848 5.952-4.288zM149.312 145.088c-14.08 0-25.6 11.52-25.6 25.6v153.6h776.512v-153.6a25.6 25.6 0 0 0-25.6-25.6H149.312z m130.432 51.2a38.4 38.4 0 0 1 0 76.8h-42.688a38.4 38.4 0 0 1 0-76.8h42.688z m512 0a38.4 38.4 0 0 1 0 76.8h-384a38.4 38.4 0 0 1 0-76.8h384z" p-id="1871" fill="#303133"></path></svg>

BIN
src/assets/studentAnalysis/basket.png


+ 1 - 0
src/assets/studentAnalysis/card.svg

@@ -0,0 +1 @@
+<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1770083294111" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="2518" width="14" height="14" xmlns:xlink="http://www.w3.org/1999/xlink"><path d="M927.656 219.877H96.004c-17.673 0-32 14.327-32 32v520c0 17.673 14.327 32 32 32h831.652c17.673 0 32-14.327 32-32v-520c0-17.672-14.327-32-32-32z m-32 520H128.004v-456h767.652v456z" fill="#333333" p-id="2519"></path><path d="M254.241 633.451c0.053-0.146 5.452-14.838 18.675-28.833 16.321-17.274 37.47-26.033 62.86-26.033 25.637 0 47.345 8.914 64.52 26.494 13.891 14.219 19.853 29.107 19.912 29.256l-0.098-0.258 59.956-22.389c-0.958-2.566-9.986-25.738-31.587-48.82-14.717-15.726-31.768-27.758-50.632-35.88 21.708-17.923 35.567-45.031 35.567-75.315 0-53.838-43.8-97.638-97.638-97.638s-97.638 43.8-97.638 97.638c0 30.334 13.905 57.48 35.676 75.402-18.733 8.194-35.523 20.342-49.85 36.224-21.018 23.298-29.346 46.698-30.226 49.29l60.599 20.586-0.096 0.276z m81.535-212.139c16.742 0 30.362 13.621 30.362 30.362s-13.621 30.362-30.362 30.362-30.362-13.621-30.362-30.362 13.62-30.362 30.362-30.362zM557.112 448h243.257c17.673 0 32-14.327 32-32s-14.327-32-32-32H557.112c-17.673 0-32 14.327-32 32s14.327 32 32 32zM557.112 576.838h146.257c17.673 0 32-14.327 32-32s-14.327-32-32-32H557.112c-17.673 0-32 14.327-32 32s14.327 32 32 32z" fill="#333333" p-id="2520"></path></svg>

+ 1 - 0
src/assets/studentAnalysis/circleBlue.svg

@@ -0,0 +1 @@
+<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1770198059469" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="2149" xmlns:xlink="http://www.w3.org/1999/xlink" width="16" height="16"><path d="M516.8 102.4a76.8 76.8 0 0 1 0 153.6l2.88-0.192v56.832a38.4 38.4 0 0 1 32.96 32.832l0.32 5.248a38.4 38.4 0 0 1-38.4 38.4l5.12-0.384v72.576a51.2 51.2 0 0 1 23.68 10.176l52.8-52.928a38.4 38.4 0 0 1 53.376-53.44l44.544-44.544a76.8 76.8 0 1 1 9.6 12.096l-43.52 43.52a38.4 38.4 0 0 1-52.864 53.12l-53.312 53.312a51.648 51.648 0 0 1 8.896 23.104h62.784a38.4 38.4 0 0 1 74.752 0.128l83.84 0.064a76.8 76.8 0 1 1-1.6 15.36h-81.728a38.4 38.4 0 0 1-75.712-0.128l-62.784-0.064a51.008 51.008 0 0 1-10.048 22.4l42.56 42.88a38.4 38.4 0 0 1 49.728 58.24l66.752 59.264a76.8 76.8 0 1 1-6.656 6.016l-4.352 4.736-63.488-64a38.4 38.4 0 0 1-42.24-2.24l-4.352-3.776a38.4 38.4 0 0 1-5.76-46.72l-43.392-43.84a50.88 50.88 0 0 1-21.504 8.576v62.336a38.4 38.4 0 0 1-5.12 76.48l5.12-0.384v86.72a76.8 76.8 0 0 1 73.6 69.312l0.32 7.424a76.8 76.8 0 1 1-89.28-75.776v-88.704a38.4 38.4 0 0 1 0-74.048v-63.36a50.816 50.816 0 0 1-15.04-4.736l-42.24 42.432a38.4 38.4 0 0 1-51.52 51.584l-62.528 62.592a76.8 76.8 0 1 1-11.072-10.752l61.44-61.44a38.4 38.4 0 0 1 56.512-51.968l-2.56-2.112 39.296-39.232a51.072 51.072 0 0 1-14.912-27.52H383.36a38.4 38.4 0 0 1-75.648-0.192l-56.96-0.064 0.064 0.64A76.8 76.8 0 0 1 181.504 598.4l-7.424 0.384a76.8 76.8 0 1 1 75.136-92.864h59.008a38.4 38.4 0 0 1 74.88 0.128h78.08a50.88 50.88 0 0 1 8.832-23.296l-52.864-53.248a38.4 38.4 0 0 1-52.736-53.248l-38.912-39.232a76.8 76.8 0 1 1 10.432-11.328l39.232 39.424a38.4 38.4 0 0 1 53.248 53.696l52.288 52.8a50.944 50.944 0 0 1 23.616-10.176V387.712a38.4 38.4 0 0 1 0-74.048v-58.688A76.8 76.8 0 0 1 516.8 102.4z" p-id="2150" fill="#2E64FA"></path></svg>

+ 1 - 0
src/assets/studentAnalysis/circleGrey.svg

@@ -0,0 +1 @@
+<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1770198059469" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="2149" xmlns:xlink="http://www.w3.org/1999/xlink" width="16" height="16"><path d="M516.8 102.4a76.8 76.8 0 0 1 0 153.6l2.88-0.192v56.832a38.4 38.4 0 0 1 32.96 32.832l0.32 5.248a38.4 38.4 0 0 1-38.4 38.4l5.12-0.384v72.576a51.2 51.2 0 0 1 23.68 10.176l52.8-52.928a38.4 38.4 0 0 1 53.376-53.44l44.544-44.544a76.8 76.8 0 1 1 9.6 12.096l-43.52 43.52a38.4 38.4 0 0 1-52.864 53.12l-53.312 53.312a51.648 51.648 0 0 1 8.896 23.104h62.784a38.4 38.4 0 0 1 74.752 0.128l83.84 0.064a76.8 76.8 0 1 1-1.6 15.36h-81.728a38.4 38.4 0 0 1-75.712-0.128l-62.784-0.064a51.008 51.008 0 0 1-10.048 22.4l42.56 42.88a38.4 38.4 0 0 1 49.728 58.24l66.752 59.264a76.8 76.8 0 1 1-6.656 6.016l-4.352 4.736-63.488-64a38.4 38.4 0 0 1-42.24-2.24l-4.352-3.776a38.4 38.4 0 0 1-5.76-46.72l-43.392-43.84a50.88 50.88 0 0 1-21.504 8.576v62.336a38.4 38.4 0 0 1-5.12 76.48l5.12-0.384v86.72a76.8 76.8 0 0 1 73.6 69.312l0.32 7.424a76.8 76.8 0 1 1-89.28-75.776v-88.704a38.4 38.4 0 0 1 0-74.048v-63.36a50.816 50.816 0 0 1-15.04-4.736l-42.24 42.432a38.4 38.4 0 0 1-51.52 51.584l-62.528 62.592a76.8 76.8 0 1 1-11.072-10.752l61.44-61.44a38.4 38.4 0 0 1 56.512-51.968l-2.56-2.112 39.296-39.232a51.072 51.072 0 0 1-14.912-27.52H383.36a38.4 38.4 0 0 1-75.648-0.192l-56.96-0.064 0.064 0.64A76.8 76.8 0 0 1 181.504 598.4l-7.424 0.384a76.8 76.8 0 1 1 75.136-92.864h59.008a38.4 38.4 0 0 1 74.88 0.128h78.08a50.88 50.88 0 0 1 8.832-23.296l-52.864-53.248a38.4 38.4 0 0 1-52.736-53.248l-38.912-39.232a76.8 76.8 0 1 1 10.432-11.328l39.232 39.424a38.4 38.4 0 0 1 53.248 53.696l52.288 52.8a50.944 50.944 0 0 1 23.616-10.176V387.712a38.4 38.4 0 0 1 0-74.048v-58.688A76.8 76.8 0 0 1 516.8 102.4z" p-id="2150" fill="#999999"></path></svg>

+ 1 - 0
src/assets/studentAnalysis/collection.svg

@@ -0,0 +1 @@
+<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1770106604115" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="14431" data-spm-anchor-id="a313x.search_index.0.i13.5d733a81rLbCs3" width="20" height="20" xmlns:xlink="http://www.w3.org/1999/xlink"><path d="M781.186088 616.031873q17.338645 80.573705 30.59761 145.848606 6.119522 27.537849 11.219124 55.075697t9.689243 49.976096 7.649402 38.247012 4.079681 19.888446q3.059761 20.398406-9.179283 27.027888t-27.537849 6.629482q-5.099602 0-14.788845-3.569721t-14.788845-5.609562l-266.199203-155.027888q-72.414343 42.836653-131.569721 76.494024-25.498008 14.278884-50.486056 28.557769t-45.386454 26.517928-35.187251 20.398406-19.888446 10.199203q-10.199203 5.099602-20.908367 3.569721t-19.378486-7.649402-12.749004-14.788845-2.039841-17.848606q1.01992-4.079681 5.099602-19.888446t9.179283-37.737052 11.729084-48.446215 13.768924-54.055777q15.298805-63.23506 34.677291-142.788845-60.175299-52.015936-108.111554-92.812749-20.398406-17.338645-40.286853-34.167331t-35.697211-30.59761-26.007968-22.438247-11.219124-9.689243q-12.239044-11.219124-20.908367-24.988048t-6.629482-28.047809 11.219124-22.438247 20.398406-10.199203l315.155378-28.557769 117.290837-273.338645q6.119522-16.318725 17.338645-28.047809t30.59761-11.729084q10.199203 0 17.848606 4.589641t12.749004 10.709163 8.669323 12.239044 5.609562 10.199203l114.231076 273.338645 315.155378 29.577689q20.398406 5.099602 28.557769 12.239044t8.159363 22.438247q0 14.278884-8.669323 24.988048t-21.928287 26.007968z" p-id="14432" fill="#999999"></path></svg>

+ 1 - 0
src/assets/studentAnalysis/echarts.svg

@@ -0,0 +1 @@
+<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1769670608772" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="6499" width="14" height="14" xmlns:xlink="http://www.w3.org/1999/xlink"><path d="M494.5 926c-53.5 0-105.4-10.5-154.3-31.2-47.2-20-89.6-48.6-126-85-36.4-36.4-65-78.8-85-126C108.5 634.9 98 583 98 529.5c0-53.4 10.5-105.3 31.1-154.1 19.9-47.2 48.4-89.5 84.7-125.9 36.3-36.4 78.6-65 125.7-85 48.8-20.7 100.6-31.3 154-31.4l25.1-0.1v372.4H891l-0.1 25.1c-0.1 53.4-10.7 105.2-31.4 154-20 47.1-48.6 89.4-85 125.7s-78.8 64.8-125.9 84.7C599.8 915.5 547.9 926 494.5 926z m-25.9-742C289.7 197.3 148 347.3 148 529.5 148 720.6 303.4 876 494.5 876c182.2 0 332.2-141.7 345.5-320.6H468.6V184z" p-id="6500" fill="#666666"></path><path d="M583 98v343h343c0-189.4-153.6-343-343-343z" p-id="6501" fill="#666666"></path></svg>

+ 1 - 0
src/assets/studentAnalysis/iconBlue.svg

@@ -0,0 +1 @@
+<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1770193137434" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="8464" width="16" height="16" xmlns:xlink="http://www.w3.org/1999/xlink"><path d="M419.037 287.953h413.124c17.673 0 32-14.327 32-32s-14.327-32-32-32H419.037c-17.673 0-32 14.327-32 32s14.327 32 32 32zM419.028 543.17h411.608c17.673 0 32-14.327 32-32s-14.327-32-32-32H419.028c-17.673 0-32 14.327-32 32s14.327 32 32 32zM832.161 735.802H419.037c-17.673 0-32 14.327-32 32s14.327 32 32 32h413.124c17.673 0 32-14.327 32-32s-14.327-32-32-32z" fill="#2E64FA" p-id="8465"></path><path d="M256.037 255.953m-64 0a64 64 0 1 0 128 0 64 64 0 1 0-128 0Z" fill="#2E64FA" p-id="8466"></path><path d="M256.037 510.787m-64 0a64 64 0 1 0 128 0 64 64 0 1 0-128 0Z" fill="#2E64FA" p-id="8467"></path><path d="M256.037 767.621m-64 0a64 64 0 1 0 128 0 64 64 0 1 0-128 0Z" fill="#2E64FA" p-id="8468"></path></svg>

+ 1 - 0
src/assets/studentAnalysis/iconGrey.svg

@@ -0,0 +1 @@
+<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1770193137434" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="8464" width="16" height="16" xmlns:xlink="http://www.w3.org/1999/xlink"><path d="M419.037 287.953h413.124c17.673 0 32-14.327 32-32s-14.327-32-32-32H419.037c-17.673 0-32 14.327-32 32s14.327 32 32 32zM419.028 543.17h411.608c17.673 0 32-14.327 32-32s-14.327-32-32-32H419.028c-17.673 0-32 14.327-32 32s14.327 32 32 32zM832.161 735.802H419.037c-17.673 0-32 14.327-32 32s14.327 32 32 32h413.124c17.673 0 32-14.327 32-32s-14.327-32-32-32z" fill="#999999" p-id="8465"></path><path d="M256.037 255.953m-64 0a64 64 0 1 0 128 0 64 64 0 1 0-128 0Z" fill="#999999" p-id="8466"></path><path d="M256.037 510.787m-64 0a64 64 0 1 0 128 0 64 64 0 1 0-128 0Z" fill="#999999" p-id="8467"></path><path d="M256.037 767.621m-64 0a64 64 0 1 0 128 0 64 64 0 1 0-128 0Z" fill="#999999" p-id="8468"></path></svg>

+ 5 - 1
src/main.js

@@ -11,13 +11,17 @@ import { debounce } from "./utils/common";
 import * as echarts from "echarts";
 
 import "@/styles/element-variables.scss";
-// import "vxe-table/lib/style.css";
+// 引入vxe-table
+import VXETable from 'vxe-table';
+import 'vxe-table/lib/style.css';
+
 import "@/styles/common.scss";
 
 import "font-awesome/css/font-awesome.min.css";
 import './styles/XueKeWangQuestionStyles.css'
 import './assets/font2/iconfont.css'
 
+Vue.use(VXETable);
 // 解决el-radio报错
 Vue.directive('removeAriaHidden', {
   bind(el, binding) {

+ 7 - 0
src/router/index.js

@@ -88,6 +88,13 @@ let studentAnalysisReport = {
                         title: "个性化错题",
                     },
                 },
+                {
+                    path: "personalProfile",
+                    component: () => import("@/views/analysisReport/personalProfile/index"),
+                    meta: {
+                        title: "个人画像",
+                    },
+                },
             ],
         },
     ],

+ 87 - 0
src/views/analysisReport/personalProfile/KnowledgeTrack.vue

@@ -0,0 +1,87 @@
+<template>
+  <div class="knowledgeTrack">
+    <h3 class="title">历次考试知识点追踪</h3>
+
+    <!-- 内容区域 -->
+    <div class="map_content">
+      <!-- 考试范围说明 -->
+      <div class="knowledge_stats">
+        <p class="stats_text" v-for="(item, index) in knowledgeStats" :key="index">
+          <span class="dot"></span> <span v-html="item"></span>
+        </p>
+      </div>
+    </div>
+
+  </div>
+</template>
+
+<script>
+export default {
+  name: "KnowledgeTrack",
+  props: {
+    // 支持从父组件传入数据
+    knowledgeStats: {
+      type: Array,
+      default: () => []
+    }
+  },
+  data() {
+    return {
+      
+    };
+  },
+  computed: {
+    
+  },
+  mounted() {
+   
+  },
+  methods: {
+  }
+};
+</script>
+
+<style scoped lang="scss">
+.knowledgeTrack {
+  background-color: #ffffff;
+  border-radius: 10px;
+  padding: 20px;
+  box-sizing: border-box;
+
+  .title {
+    font-size: 16px;
+    font-weight: 500;
+    color: #333333;
+    margin: 0 0 15px 0;
+  }
+  .map_content {
+    background: #F7F7F8;
+    border-radius: 5px 5px 5px 5px;
+    border: 1px solid #EBEEF5;
+    padding: 12px;
+    p{
+      margin-bottom: 5px;
+    }
+    .range_text,.stats_text {
+      font-size: 14px;
+      line-height: 1.8;
+      color: #666;
+      padding-left: 17px;
+      position: relative;
+      text-align: justify;
+
+      .dot {
+        position: absolute;
+        left: 0;
+        top: 8px;
+        display: inline-block;
+        width: 6px;
+        height: 6px;
+        background: #666666;
+        border-radius: 50%;
+      }
+    }
+  }
+}  
+
+</style>

+ 199 - 0
src/views/analysisReport/personalProfile/MyGradeHistory.vue

@@ -0,0 +1,199 @@
+<template>
+  <div class="myGradeHistory">
+    <h3 class="title">我的历次成绩</h3>
+    <div class="content">
+      <el-table 
+        :data="tableData" 
+        style="width: 100%" border 
+        :header-cell-style="headerCellStyle" 
+        :cell-style="cellStyle" stripe
+      >
+        <el-table-column type="index" label="序号" width="70" align="center"></el-table-column>
+        <el-table-column prop="examName" label="考试名称"  align="center"></el-table-column>
+        <el-table-column prop="fullScore" label="满分" width="90" align="center"></el-table-column>
+        <el-table-column prop="rawScore" label="原始分" width="90" align="center"></el-table-column>
+        <el-table-column prop="classRank" label="班级排名" width="90" align="center"></el-table-column>
+        <el-table-column prop="gradeRank" label="年级排名" width="90" align="center"></el-table-column>
+        <el-table-column prop="standardScore" label="标准分" width="90" align="center"></el-table-column>
+        <el-table-column prop="scoreRate" label="得分率" width="90" align="center">
+          <template slot-scope="scope">
+            {{ scope.row.scoreRate }}%
+          </template>
+        </el-table-column>
+        <el-table-column label="操作" width="120" align="center">
+          <template slot-scope="scope">
+            <el-button size="mini" type="text" @click="viewDetails(scope.row)">查看答题卡</el-button>
+          </template>
+        </el-table-column>
+      </el-table>
+
+    </div>
+  </div>
+</template>
+
+<script>
+export default {
+  name: "MyGradeHistory",
+  data() {
+    return {
+      tableData: [
+        {
+          id: 1,
+          examName: '期中考试',
+          fullScore: 150,
+          rawScore: 120,
+          classRank: 5,
+          gradeRank: 20,
+          standardScore: 750,
+          scoreRate: 80
+        },
+        {
+          id: 2,
+          examName: '期末考试',
+          fullScore: 150,
+          rawScore: 135,
+          classRank: 2,
+          gradeRank: 10,
+          standardScore: 780,
+          scoreRate: 90
+        },
+        {
+          id: 3,
+          examName: '模拟考试',
+          fullScore: 150,
+          rawScore: 128,
+          classRank: 3,
+          gradeRank: 15,
+          standardScore: 765,
+          scoreRate: 85.3
+        }
+      ],
+    };
+  },
+  computed: {
+    headerCellStyle() {
+      return {
+        backgroundColor: '#F5F7FA',
+        color: '#303133',
+        height: '50px',
+        padding: '0',
+        margin: '0',
+        lineHeight: '50px'
+      };
+    },
+    cellStyle() {
+      return {
+        color: '#606266',
+        height: '50px',
+        padding: '0',
+        margin: '0',
+        lineHeight: '50px'
+      };
+    }
+  },
+  methods: {
+    viewDetails(row) {
+      this.$message({
+        message: `查看${row.examName}的详情`,
+        type: 'info'
+      });
+      // 实际项目中可以跳转到详情页面或展开详情
+    },
+  }
+}
+</script>
+
+<style scoped lang="scss">
+.myGradeHistory {
+  background-color: #ffffff;
+  border-radius: 10px;
+  padding: 20px;
+  box-sizing: border-box;
+
+  .title {
+    font-size: 16px;
+    font-weight: 500;
+    color: #333333;
+    margin: 0 0 10px 0;
+  }
+
+  /* 表格区域 */
+  .content {
+    /* 调整表格斑马条纹颜色 */
+    :deep(.el-table--striped .el-table__body tr.el-table__row--striped) {
+      background-color: #FAFAFA !important;
+    }
+    
+    /* 确保表头行高 */
+    :deep(.el-table__header tr) {
+      height: 50px !important;
+    }
+    
+    /* 确保表格内容行高 */
+    :deep(.el-table__body tr) {
+      height: 50px !important;
+    }
+    
+    /* 移除表头单元格内外边距 */
+    :deep(.el-table__header th.el-table__cell) {
+      padding: 0 !important;
+      margin: 0 !important;
+      height: 50px !important;
+      line-height: 50px !important;
+    }
+    
+    /* 移除表格内容单元格内外边距 */
+    :deep(.el-table__body td.el-table__cell) {
+      padding: 0 !important;
+      margin: 0 !important;
+      height: 50px !important;
+      line-height: 50px !important;
+    }
+    
+    /* 表格圆角样式 */
+    :deep(.el-table) {
+      border-radius: 6px !important;
+      overflow: hidden;
+    }
+    
+    /* 表头圆角 */
+    :deep(.el-table__header-wrapper) {
+      border-radius: 6px 6px 0 0;
+      overflow: hidden;
+    }
+    
+    /* 表尾圆角 */
+    :deep(.el-table__body-wrapper) {
+      border-radius: 0 0 6px 6px;
+      overflow: hidden;
+    }
+    
+    /* 表头首列圆角 */
+    :deep(.el-table__header th.el-table__cell:first-child) {
+      border-radius: 6px 0 0 0 !important;
+    }
+    
+    /* 表头末列圆角 */
+    :deep(.el-table__header th.el-table__cell:last-child) {
+      border-radius: 0 6px 0 0 !important;
+    }
+    
+    /* 表尾首列圆角 */
+    :deep(.el-table__body tr:last-child td.el-table__cell:first-child) {
+      border-radius: 0 0 0 6px !important;
+    }
+    
+    /* 表尾末列圆角 */
+    :deep(.el-table__body tr:last-child td.el-table__cell:last-child) {
+      border-radius: 0 0 6px 0 !important;
+    }
+
+    .pagination {
+      margin-top: 16px;
+      display: flex;
+      justify-content: flex-end;
+      align-items: center;
+    }
+  }
+}
+</style>

+ 177 - 0
src/views/analysisReport/personalProfile/index.vue

@@ -0,0 +1,177 @@
+<template>
+    <div class="personalProfile">
+        <div class="report_header">
+            <el-radio-group v-model="radio1" @change="portraitTab">
+                <el-radio-button label="grade">年级画像</el-radio-button>
+                <el-radio-button label="class">班级画像</el-radio-button>
+            </el-radio-group>
+        </div>
+        
+        <!-- 我的历次成绩子组件 -->
+        <MyGradeHistory :mode="radio1" />
+
+        <!-- 历次考试知识点追踪 -->
+        <KnowledgeTrack :knowledge-stats="knowledgeStats" :mode="radio1" />
+
+        <!-- 零分知识点、高频错题知识点 -->
+        <zeroScoreKnowledge 
+            :table-data="treeData"
+            :fatal-vulnerability="fatalVulnerability" 
+            :high-vulnerability="highVulnerability"
+            :mode="radio1"
+        />
+    </div>
+</template>
+<script>
+import MyGradeHistory from './MyGradeHistory.vue';
+import KnowledgeTrack from './KnowledgeTrack.vue';
+import zeroScoreKnowledge from './zeroScoreKnowledge.vue';
+
+export default {
+    name: "PersonalProfile",
+    components: {
+        MyGradeHistory,
+        KnowledgeTrack,
+        zeroScoreKnowledge
+    },
+    computed: {
+        // 动态生成知识统计文本,使用repeatKnowledgeNum
+        knowledgeStats() {
+            const stats = [];
+            // 当konwLenght不等于0时,显示第一行文本
+            stats.push(
+            `共包含<span style='color:#2E64FA'>23</span>个知识点,
+            分别为<span style='color:#333333;font-weight:600;'>多角度探究作品意蕴、熟语;</span>`
+            ); //包含知识点
+            // 当repeatKnowledgeNum不等于0时,显示第二行文本
+            stats.push(
+                `其中<span style='color:#2E64FA'>15</span>个为多次考试的高频考点,
+                其中<span style='color:#333333;font-weight:600;'>概括分析、比较材料</span>
+                你的得分率<span style='color:#3BA272;font-weight:600;'>提升</span>
+                <span style='color:#333333;font-weight:600;'>文言文断句、文言文阅读、材料作文</span>
+                你的得分率<span style="color:#F56C6C;font-weight:600;">下降</span>,
+                希望针对下降的知识点进行总结和反思。`
+            ); //重复知识点
+            return stats;
+        },
+    },
+    data() {
+        return {
+            // 画像切换
+            radio1: "grade",
+
+            // 知识点树状图数据
+            treeData: [],
+            // 零分知识点数据
+            fatalVulnerability: [],
+            // 高频错题知识点数据
+            highVulnerability: [], 
+        };
+    },
+    created() {
+        //零分知识点、高频知识点
+        this.vulerabData()
+    },
+    methods: {
+        // 画像切换
+        portraitTab() {
+
+        },
+        // 零分知识点、高频错题知识点数据
+        vulerabData() {
+            // 零分知识点数据
+            this.fatalVulnerability = [
+                {
+                    "knowledgeName": "区间的关系与运算",
+                    "knowledgeId": 10550,
+                    "parentId": 10548,
+                    "gradeScoreRate": "50", // 年级得分率
+                    "classScoreRate": "54.55", // 班级得分率
+                    "scoreRateDiff": "4.55",   // 得分率差值
+                    "knowledgeType": 1, // 知识点类型 1:零分知识点 2:高频错题知识点
+                    "examNum": 2 // 考试次数
+                },
+                {
+                    "knowledgeName": "具体函数的定义域",
+                    "knowledgeId": 10552,
+                    "parentId": 10551,
+                    "gradeScoreRate": "37.9",
+                    "classScoreRate": "27.27",
+                    "scoreRateDiff": "-10.63",
+                    "knowledgeType": 1,
+                    "examNum": 2
+                }
+            ];
+            // 高频错题知识点数据
+            this.highVulnerability = [
+                {
+                    "knowledgeName": "抽象函数的定义域",
+                    "knowledgeId": 10553,
+                    "parentId": 10551,
+                    "gradeScoreRate": "6.45",
+                    "classScoreRate": "12.12",
+                    "scoreRateDiff": "5.67",
+                    "knowledgeType": 1,
+                    "examNum": 2
+                },
+                {
+                    "knowledgeName": "求函数的零点",
+                    "knowledgeId": 10820,
+                    "parentId": 10818,
+                    "gradeScoreRate": "34.03",
+                    "classScoreRate": "35.76",
+                    "scoreRateDiff": "1.73",
+                    "knowledgeType": 1,
+                    "examNum": 1
+                }
+            ];
+        },
+    },
+}
+</script>
+
+<style scoped lang="scss">
+.personalProfile{
+    // 确保所有子组件之间有10px的间隔
+    > * {
+        margin-bottom: 10px;
+        font-family: PingFang SC, PingFang SC;
+        font-size: 14px;
+        font-weight: 400;
+        color: #333333;
+    }
+    
+    > *:last-child {
+        margin-bottom: 0;
+    }
+    
+    // 画像切换
+    .report_header{
+        padding: 10px 0;
+        text-align: center;
+        font-size: 14px;
+        background: #ffffff;
+        border-radius: 10px;
+        display: flex;
+        align-items: center;
+        justify-content: flex-start;
+        padding-left: 10px;
+
+        /* 选中状态 */
+        :deep(.el-radio-button__orig-radio:checked + .el-radio-button__inner) {
+        font-weight: 600 !important;
+        color: #ffffff !important;
+        }
+
+        :deep(.el-radio-button__inner) {
+        height: 36px;
+        line-height: 36px;
+        padding: 0px;
+        width: 76px;
+        text-align: center;
+        color: #999999;
+        }
+    }
+}
+
+</style>

+ 1150 - 0
src/views/analysisReport/personalProfile/zeroScoreKnowledge.vue

@@ -0,0 +1,1150 @@
+<template>
+  <div class="knowledge_graph">
+
+    <div class="graph_header" v-if="activeView === 'list'">
+      <!-- 自定义图例 -->
+      <div class="legend" >
+        <div class="legend_item" :class="{ 'selected': selectedLegend.weak }" >
+          <span class="legend_dot weak"></span>
+          <span class="legend_text">{{ "薄弱(0%≤得分率<60%)" }}</span>
+        </div>
+        <div class="legend_item" :class="{ 'selected': selectedLegend.good }" >
+          <span class="legend_dot good"></span>
+          <span class="legend_text">{{ "良好(60%≤得分率<85%)" }}</span>
+        </div>
+        <div class="legend_item" :class="{ 'selected': selectedLegend.excellent }" >
+          <span class="legend_dot excellent"></span>
+          <span class="legend_text">{{ "优秀(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/circleBlue.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">
+            <!-- @click="toggleLegend('weak')"  @click="toggleLegend('good')" @click="toggleLegend('excellent')" -->
+            <div class="legend_item" :class="{ 'selected': selectedLegend.weak }" >
+              <span class="legend_dot weak"></span>
+              <span class="legend_text">{{ "薄弱(0%≤得分率<60%)" }}</span>
+            </div>
+            <div class="legend_item" :class="{ 'selected': selectedLegend.good }" >
+              <span class="legend_dot good"></span>
+              <span class="legend_text">{{ "良好(60%≤得分率<85%)" }}</span>
+            </div>
+            <div class="legend_item" :class="{ 'selected': selectedLegend.excellent }" >
+              <span class="legend_dot excellent"></span>
+              <span class="legend_text">{{ "优秀(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 === 'zero' }" @click="activeTab = 'zero'">
+            零分知识点
+          </div>
+          <div class="tab_item" :class="{ active: activeTab === 'highFreq' }" @click="activeTab = 'highFreq'">
+            高频错题知识点  
+          </div>
+        </div>
+
+        <!-- 右侧知识点列表 -->
+        <div class="knowledge_list">
+          <div class="list_item" v-for="(item, index) in knowledgeItems" :key="index" 
+               @click="handleItemClick(item, index)" :class="{ active: selectedIndex === index }">
+            <div class="item_header">
+              <span class="item_dot"></span>
+              <el-tooltip
+                :content="item.knowledgeName"
+                placement="top"
+                effect="light"
+                :disabled="item.knowledgeName.length < 15"
+              >
+                <span class="item_title">{{item.knowledgeName}}</span>
+              </el-tooltip>
+              <span class="item_tag" v-if="item.scoreRateDiff">{{ item.scoreRateDiff }} %</span>
+            </div>
+            <div class="item_info">
+              <span class="item_score">
+                <span class="score_label">得分率:</span>
+                <span class="score_first" v-if="item.gradeScoreRate">{{item.gradeScoreRate}}%</span>
+                <span class="score_separator" v-if="item.classScoreRate">|</span>
+                <span class="score_second" v-if="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 :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' }">
+
+        <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="classRate" 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="gradeScoreRate" title="年级得分率" width="180" align="center">
+          <template #default="{ row }">
+            <div class="rate_info">
+              <span class="rate_dot" :class="getRateClass(row.gradeScoreRate)"></span>
+              <span class="rate_value">{{ row.gradeScoreRate }}%</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: 'zeroScoreKnowledge',
+  props: {
+    mode: {
+      type: String,
+      default: 'grade',
+      validator: (value) => {
+        return ['grade', 'class'].includes(value);
+      }
+    },
+    // 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: () => []
+    },
+    classGroupName: { // 班级名称
+      type: String,
+      default: ''
+    },
+    fatalVulnerability: { // 零分知识点数据
+      type: Array,
+      default: () => []
+    },
+    highVulnerability: { // 高频错题知识点数据
+      type: Array,
+      default: () => []
+    }
+  },
+
+  computed: {
+    // 根据当前tab返回对应的数据
+    knowledgeItems() {
+      return this.activeTab === 'zero' ? this.fatalVulnerability : this.highVulnerability;
+    }
+  },
+  data() {
+    return {
+        chart: null, // echarts实例
+        // 图例选中状态
+        selectedLegend: {
+        weak: true,
+        good: true,
+        excellent: true
+        },
+        // 选中的知识点索引
+        selectedIndex: 0,
+        // 零分知识点、高频知识点Tab切换状态
+        activeTab: 'zero',
+
+        // 按图形查看、按列表查看
+        activeView: 'graph',
+        
+    };
+  },
+  mounted() {
+    // 无论在什么模式下,只要默认视图是图形视图就初始化echarts图表
+    if (this.activeView === 'graph') {
+      this.$nextTick(() => {
+        this.initChart();
+      });
+    }
+    
+    // 实现默认选中逻辑
+    this.setDefaultSelection();
+  },
+  beforeDestroy() {
+    // 销毁echarts实例
+    if (this.chart) {
+      this.chart.dispose();
+    }
+  },
+  watch: {
+    // 监听mode变化,当切换到班级模式时,班级得分率列和得分率差列才显示
+    mode(newMode) {
+      this.$nextTick(() => {
+        this.activeView ='graph';
+        this.initChart();
+      });
+    },
+    // 监听activeView变化,当切换到图形视图时重新初始化图表,切换到列表视图时销毁图表
+    activeView(newView) {
+      if (newView === 'graph') {
+        this.$nextTick(() => {
+          this.initChart();
+        });
+      } else if (newView === 'list') {
+        // 切换到列表视图时销毁图表实例
+        if (this.chart) {
+          this.chart.dispose();
+          this.chart = null;
+        }
+      }
+    },
+    // 监听tab切换,更新选中索引
+    activeTab() {
+      this.selectedIndex = 0;
+    },
+    // 监听数据变化,重新设置默认选中项
+    fatalVulnerability: {
+      deep: true,
+      handler() {
+        this.setDefaultSelection();
+      }
+    },
+    highVulnerability: {
+      deep: true,
+      handler() {
+        this.setDefaultSelection();
+      }
+    }
+  },
+  methods: {
+    // 设置默认选中项
+    setDefaultSelection() {
+      // 如果零分知识点没有数据,切换到高频错题知识点并选中第一条
+      if (this.fatalVulnerability.length === 0 && this.highVulnerability.length > 0) {
+        this.activeTab = 'highFreq';
+        this.selectedIndex = 0;
+        // 不再自动发送选中事件,只设置选中状态
+      } else {
+        this.activeTab = 'zero';
+        // 否则默认选中零分知识点的第一条
+        this.selectedIndex = 0;
+        // 不再自动发送选中事件,只设置选中状态
+      }
+    },
+    
+    // 切换查看方式
+    switchView(view) {
+        console.log(view);
+        //通过emit事件通知父组件更新activeView
+        //this.$emit('view-change', view);
+        this.activeView = view;
+    },
+
+    // 根据得分率获取对应的颜色
+    getNodeColor(scoreRate) {
+      const rate = parseFloat(scoreRate);
+      if (rate >= 85) {
+        return '#3BA272'; // 优秀 - 绿色
+      } else if (rate >= 60) {
+        return '#FAC858'; // 良好 - 黄色
+      } else {
+        return '#EE6666'; // 薄弱 - 红色
+      }
+    },
+
+    // 根据屏幕宽度计算合适的缩放值
+    getZoomValue() {
+      const screenWidth = window.innerWidth;
+      if (screenWidth <1100) {
+        return 1.0; // 小屏幕
+      } else if (screenWidth >= 1100 && screenWidth <= 1200) {
+        return 1.15; // 中等屏幕
+      } else  {
+        return 1.2; // 超大屏幕
+      }
+    },
+    
+    // 更新图表缩放
+    updateChartZoom() {
+      if (this.chart) {
+        const zoom = this.getZoomValue();
+        this.chart.setOption({
+          series: [
+            {
+              zoom: zoom,
+            }
+          ]
+        });
+      }
+    },
+
+    // 初始化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);
+          if (rate >= 85) {
+            return 'excellent'; // 优秀
+          } else if (rate >= 60) {
+            return 'good'; // 良好
+          } else {
+            return 'weak'; // 薄弱
+          }
+        };
+
+        // 基于表格数据生成树形图数据
+        const generateTreeData = (data, level = 0) => {
+          return data.filter(item => {
+            // 获取节点级别
+            const nodeLevel = getNodeLevel(item.gradeScoreRate);
+            // 根据图例选中状态决定是否显示节点
+            return vm.selectedLegend[nodeLevel];
+          }).map(item => {
+            // 根据级别设置统一的节点大小
+            const nodeSizes = [24, 16, 12, 10, 6];
+            const symbolSize = nodeSizes[Math.min(level, nodeSizes.length - 1)];
+            
+            const node = {
+              name: item.knowledgeName,
+              symbolSize: symbolSize,
+              // 根据班级名称是否为年级来选择使用gradeScoreRate或classScoreRate
+              value: vm.classGroupName === '年级' ? item.gradeScoreRate : item.classScoreRate,
+              itemStyle: {
+                color: vm.getNodeColor(item.gradeScoreRate)
+              }
+            };
+
+            if (item.children && item.children.length > 0) {
+              node.children = generateTreeData(item.children, level + 1);
+            }
+
+            return node;
+          });
+        };
+
+        // 配置项
+        const option = {
+          tooltip: {
+            formatter: (params) => {
+              // 只有根节点(treePathInfo存在且长度为1)使用组件的subjectScoreRate作为得分率
+              if (params.treePathInfo && params.treePathInfo.length === 1) {
+                return `${params.name}<br/>得分率: ${this.subjectScoreRate}%`;
+              }
+              // 其他节点(包括treePathInfo不存在的情况)都使用value作为得分率
+              return `${params.name}<br/>得分率: ${params.value !== null && params.value !== undefined ? params.value : '0'}%`;
+            }
+          },
+          animationDurationUpdate: 1500,
+          animationEasingUpdate: 'quinticInOut',
+          series: [
+            {
+              type: 'tree',
+              layout: 'radial',
+              symbol: 'circle',
+              initialTreeDepth: 999, // 设置一个足够大的值,确保所有节点都展开
+              expandAndCollapse: true,
+              // 调整树状图布局参数,确保节点均匀分布
+              orient: 'radial',
+              roam: true,
+
+              // 使用基础配置实现居中
+              center: ['12%', '10%'],
+
+              zoom: this.getZoomValue(),
+              scaleLimit: {
+                min: 0.2,
+                max: 5
+              },
+
+              // 调整节点大小比例和间距,确保图表在容器中居中
+              nodeScaleRatio: 1,
+              layerPadding: [10, 5],
+              roam: true,
+
+              // 使用表格数据生成树形结构
+              data: [
+                {
+                  name: this.subjectName,
+                  symbolSize: 48,
+                  value: this.subjectScoreRate, // 添加value属性,用于显示得分率
+                  itemStyle: {
+                    // 根据得分率动态设置颜色
+                    color: this.subjectScoreRate >= 85 ? '#3BA272' : // 优秀 - 绿色
+                           this.subjectScoreRate >= 60 ? '#FAC858' : // 良好 - 黄色
+                           '#EE6666' // 薄弱 - 红色
+                  },
+                  children: generateTreeData(this.tableData)
+                }
+              ],
+              label: {
+                show: false
+              },
+              lineStyle: {
+                color: '#ECEEF3',
+                width: 2,
+                type: 'solid'
+              },
+              emphasis: {
+                focus: 'adjacency',
+                lineStyle: {
+                  width: 2
+                }
+              }
+            }
+          ]
+        };
+
+        // 设置配置项
+        this.chart.setOption(option);
+
+        // 初始化后调用resize确保图表正确显示
+        this.chart.resize();
+
+        // 监听窗口大小变化
+        window.addEventListener('resize', () => {
+          if (this.chart) {
+            this.chart.resize();
+            this.updateChartZoom();
+          }
+        });
+      }
+      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';
+      }
+    },
+
+    // 行样式类名方法
+    rowClassName({ row }) {
+      return row.highlight ? 'row_highlight' : '';
+    },
+
+    // 处理知识点列表项点击事件
+// 向父组件发送事件,传递点击的知识点数据
+    handleItemClick(item, index) {
+      // 更新选中索引
+      this.selectedIndex = index;
+      // 向父组件发送事件,传递点击的知识点数据
+      this.$emit('knowledge-item-click', { item, index });
+    }
+  }
+};
+</script>
+
+<style lang="scss" scoped>
+.knowledge_graph {
+  background: #FFFFFF;
+  border-radius: 10px;
+  padding: 20px;
+  margin-bottom: 10px;
+  position: relative;
+
+    .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;
+
+            &.selected {
+                opacity: 1;
+                font-weight: 500;
+            }
+
+            &: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: 265px;
+      height: 630px;
+      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;
+      height: 590px;
+      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;
+
+            &.selected {
+              opacity: 1;
+              font-weight: 500;
+            }
+
+            &: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 {
+        width: 100%;
+        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: 265px;
+      height: 630px;
+      overflow-y: auto;
+      padding-right: 10px;
+
+      /* 滚动条样式 */
+      &::-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: #a1a1a1;
+      }
+
+      .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 {
+            background: #F56C6C;
+            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;
+            }
+          }
+        }
+      }
+    }
+  }
+
+  .list_content {
+    border-radius: 10px 10px 10px 10px;
+    max-height: 480px;
+    // border: 1px solid #E9EBEF;
+    // padding: 16px;
+
+    .vxe-table {
+      border-radius: 8px;
+      overflow-y: auto;
+      overflow-x: hidden;
+
+      .vxe-table--header {
+        display: table-header-group !important;
+        visibility: visible !important;
+        opacity: 1 !important;
+        height: auto !important;
+
+      }
+
+      :deep(.el-icon-circle-plus) {
+        color: #DCDFE6 !important;
+        font-size: 16px !important;
+      }
+
+      :deep(.el-icon-remove) {
+        color: #2E64FA !important;
+        font-size: 16px !important;
+      }
+
+      .vxe-table--body {
+        .vxe-body--row {
+          height: 52px;
+          border-bottom: 1px solid #F0F2F5;
+
+          &:hover {
+            background-color: #f5f7fa;
+          }
+
+          &.row_highlight {
+            background-color: rgba(195, 219, 255, 0.2);
+          }
+        }
+      }
+
+      /* 树形表格样式 */
+      .vxe-table {
+
+        /* 自定义树形图标样式 */
+        .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;
+        }
+      }
+    }
+
+    .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;
+    }
+
+    .rate_dot {
+      display: inline-block;
+      width: 10px;
+      height: 10px;
+      border-radius: 50%;
+
+      &.rate_excellent {
+        background-color: #3BA272;
+      }
+
+      &.rate_good {
+        background-color: #FAC858;
+      }
+
+      &.rate_weak {
+        background-color: #EE6666;
+      }
+    }
+
+    .rate_value {
+      font-size: 16px;
+      color: #606266;
+    }
+
+    .diff_value {
+      font-size: 16px;
+      color: #606266;
+
+      &.diff_negative {
+        color: #F56C6C;
+      }
+    }
+  }
+}
+</style>

+ 5 - 2
src/views/analysisReport/studentPage/mainPage.vue

@@ -34,8 +34,10 @@
                                 <button class="mm_btn mb_10" :class="{ active: activeBtn === pathOne }"
                                     @click="toPage(pathOne)">成绩分析</button>
 
-                                <!-- <button class="mm_btn" :class="{ active: activeBtn === pathTwo }"
-                                    @click="toPage(pathTwo)">个性化错题</button> -->
+                                <button class="mm_btn" :class="{ active: activeBtn === pathTwo }"
+                                    @click="toPage(pathTwo)">个性化错题</button>
+                                <button class="mm_btn" :class="{ active: activeBtn === pathThree }"
+                                    @click="toPage(pathThree)">个人画像</button>
                             </div>
 
                             <div class="right">
@@ -93,6 +95,7 @@ export default {
             activeBtn: this.$route.path,
             pathOne: '/studentAnalysisReport/reportDetails/scrolReport',
             pathTwo: '/studentAnalysisReport/reportDetails/personalWrongQuestions',
+            pathThree: '/studentAnalysisReport/reportDetails/personalProfile',//个人画像
             isLianXiao: false,//是否联校
             stuPdfLoading:false,
         };

برخی فایل ها در این مقایسه diff نمایش داده نمی شوند زیرا تعداد فایل ها بسیار زیاد است