Jelajahi Sumber

style(course): 优化课程相关页面样式,提升视觉效果和响应式支持

- 新增并调整课程页面整体布局,增加渐变背景和最大宽度限制
- 优化课程分类标签、表格、分页和无数据状态的样式设计
- 调整课程选择对话框及内部组件的边距、圆角及阴影效果
- 增强课堂相关组件的响应式支持,调整移动端样式细节
- 统一并完善按钮、标签及悬浮效果,提升交互体验
wjx 2 minggu lalu
induk
melakukan
ba2106e9fe

+ 10 - 11
src/api/ai.js

@@ -1,25 +1,24 @@
 import axios from 'axios'
 import $httpApi from '@/api/index'
-/**
- * 根据类型获取字典值
- * @param dictType
- * @param callBack
- */
+
 export function askAI (data) {
   return axios.post($httpApi.aiUrl('/api/psrenEvalution'), data)
-  // return Promise.reject({})
 }
 
-
-//提交到服务端
+// 提交到服务端
 export function postGPSREN (data) {
   return axios.post($httpApi.httpUrl('/student/stuGoalInfo'), data) 
 }
 
 export function getStepModel (data) {
   return axios.get($httpApi.httpUrl('/student/stepModel/selectBySubject'), {
-      params: {
-        subjectName:data
-      }
+      params: { subjectName: data }
     }) 
 }
+
+// 读取 Redis 中的答题 Session(页面恢复用)
+export function getGpsrenSession (goalId, studentId) {
+  return axios.get($httpApi.aiUrl('/api/gpsrenSession'), {
+      params: { goalId, studentId }
+    })
+}

+ 1342 - 358
src/components/gpsren.vue

@@ -1,171 +1,442 @@
 <template>
-    <div> 
-        <el-form :model="form" ref="form" label-width="100px" class="demo-ruleForm" label-position="top">
-
-            <el-col :span="24">
-                <el-form-item label="G(目标导向):" class="cust-label">
-                    <div v-html="question.gOriented" style="font-weight: 700;font-size: 16px;"></div>
-                </el-form-item>
-            </el-col>
-
-            <el-steps :active="active" finish-status="success" simple style="margin-top: 20px">
-                <el-step>
-                    <div slot="title" style="border-radius: 10px;">
-                        <div style="display: flex;flex-direction: row;justify-content: center;align-items: center;">
-                            <span>P</span>
-                            <span>(问题定义)</span>
-                        </div>
+    <div class="gpsren-container"> 
+        <el-form :model="form" ref="form" class="gpsren-form">
+            <!-- 目标导向卡片 -->
+            <div class="goal-card">
+                <div class="goal-header">
+                    <i class="el-icon-aim"></i>
+                    <span class="goal-title">学习目标</span>
+                </div>
+                <div class="goal-content" v-html="question.gOriented"></div>
+            </div>
+
+            <!-- 进度步骤条 -->
+            <div class="steps-wrapper">
+                <div class="steps-header">
+                    <div class="progress-info">
+                        <span class="current-step">当前步骤:{{['P - 问题定义', 'S - 系统拆解', 'R - 结果整合', 'E - 结果评估', 'N - 总结新知识'][active]}}</span>
+                        <span class="progress-text">{{active + 1}}/5</span>
                     </div>
-                </el-step>
-                <el-step>
-                    <div slot="title" style="border-radius: 10px;">
-                        <div style="display: flex;flex-direction: row;justify-content: center;align-items: center;">
-                            <span>S</span>
-                            <span>(系统拆解)</span>
-                        </div>
+                    <div class="score-summary" v-if="active < 4">
+                        <span class="label">已获得分数:</span>
+                        <span class="value">{{totalScore}}</span>
+                        <span class="total">/{{totalMaxScore}}</span>
                     </div>
-                </el-step>
-                <el-step>
-                    <div slot="title" style="border-radius: 10px;">
-                        <div style="display: flex;flex-direction: row;justify-content: center;align-items: center;">
-                            <span>R</span>
-                            <span>(结果整合)</span>
+                </div>
+                <el-steps :active="active" finish-status="success" align-center class="custom-steps">
+                    <el-step>
+                        <div slot="title" class="step-title">
+                            <div class="step-badge" :class="{'active': active === 0, 'finished': active > 0}">P</div>
+                            <span class="step-name">问题定义</span>
+                            <div class="step-score" v-if="saveForm.pScore !== undefined">
+                                {{saveForm.pScore}}/{{stepscore.P}}
+                            </div>
                         </div>
-                    </div>
-                </el-step>
-                <el-step>
-                    <div slot="title" style="border-radius: 10px;">
-                        <div style="display: flex;flex-direction: row;justify-content: center;align-items: center;">
-                            <span>E</span>
-                            <span>(结果评估)</span>
+                    </el-step>
+                    <el-step>
+                        <div slot="title" class="step-title">
+                            <div class="step-badge" :class="{'active': active === 1, 'finished': active > 1}">S</div>
+                            <span class="step-name">系统拆解</span>
+                            <div class="step-score" v-if="saveForm.sScore !== undefined">
+                                {{saveForm.sScore}}/{{stepscore.S}}
+                            </div>
                         </div>
-                    </div>
-                </el-step>
-                <el-step>
-                    <div slot="title" style="border-radius: 10px;">
-                        <div style="display: flex;flex-direction: row;justify-content: center;align-items: center;">
-                            <span>N</span>
-                            <span>(总结新知识)</span>
+                    </el-step>
+                    <el-step>
+                        <div slot="title" class="step-title">
+                            <div class="step-badge" :class="{'active': active === 2, 'finished': active > 2}">R</div>
+                            <span class="step-name">结果整合</span>
+                            <div class="step-score" v-if="saveForm.rScore !== undefined">
+                                {{saveForm.rScore}}/{{stepscore.R}}
+                            </div>
+                        </div>
+                    </el-step>
+                    <el-step>
+                        <div slot="title" class="step-title">
+                            <div class="step-badge" :class="{'active': active === 3, 'finished': active > 3}">E</div>
+                            <span class="step-name">结果评估</span>
+                            <div class="step-score" v-if="saveForm.eScore !== undefined">
+                                {{saveForm.eScore}}/{{stepscore.E}}
+                            </div>
+                        </div>
+                    </el-step>
+                    <el-step>
+                        <div slot="title" class="step-title">
+                            <div class="step-badge" :class="{'active': active === 4}">N</div>
+                            <span class="step-name">总结新知识</span>
+                        </div>
+                    </el-step>
+                </el-steps>
+            </div>
+
+            <!-- 答题区域 -->
+            <div class="answer-section">
+                <!-- P阶段 -->
+                <div class="answer-card" v-if="active==0">
+                    <div class="answer-header">
+                        <div class="answer-title">
+                            <span class="phase-badge phase-p">P</span>
+                            <div class="title-content">
+                                <span class="main-title">问题定义 Problem</span>
+                                <span class="sub-title">准确描述问题,明确目标与需求</span>
+                            </div>
+                        </div>
+                        <div class="score-display" v-if="saveForm.pScore !== undefined">
+                            <div class="score-content">
+                                <span class="score-value">{{saveForm.pScore}}</span>
+                                <span class="score-divider">/</span>
+                                <span class="score-total">{{stepscore.P}}</span>
+                            </div>
+                            <span class="score-label">分</span>
                         </div>
                     </div>
-                </el-step>
-            </el-steps>
-            <!-- <div>
-            <el-button icon="el-icon-discover" size="small" type="success">AI助手</el-button>
-          </div> -->
-            <br />
-            <el-col :span="24" >
-                <div  class="test-area" v-if="active==0">
-                    <el-form-item class="test-form cust-label">
-
-                        <el-input type="textarea" class="custom-height" v-model="form.p" :placeholder="stepmodel.P"></el-input>
-                    </el-form-item>
-                    <div class="test-form ai-evaluate">
-                        <div v-if="showAIEvaluate"><i class="el-icon-loading"></i></div>
-                        <div v-else >
-                          <p v-html="resp"></p>   
+                    <div class="answer-content">
+                        <div class="input-area">
+                            <div class="input-header">
+                                <span class="input-label">你的答案</span>
+                                <span class="char-count">{{form.p ? form.p.length : 0}} 字</span>
+                            </div>
+                            <el-input 
+                                type="textarea" 
+                                v-model="form.p" 
+                                :placeholder="stepmodel.P"
+                                :autosize="{ minRows: 12, maxRows: 20 }"
+                                class="answer-textarea">
+                            </el-input>
+                        </div>
+                        <div class="ai-feedback-area">
+                            <div class="feedback-header">
+                                <div class="header-left">
+                                    <i class="el-icon-chat-dot-round"></i>
+                                    <span>AI 智能评估</span>
+                                </div>
+                                <el-tag v-if="saveForm.pScore !== undefined" size="small" :type="getScoreType(saveForm.pScore, stepscore.P)">
+                                    {{getScoreLevel(saveForm.pScore, stepscore.P)}}
+                                </el-tag>
+                            </div>
+                            <div class="feedback-content">
+                                <div v-if="showAIEvaluate" class="loading-state">
+                                    <div class="loading-animation">
+                                        <i class="el-icon-loading"></i>
+                                    </div>
+                                    <span>AI正在分析您的答案,请稍候...</span>
+                                </div>
+                                <div v-else-if="!aiResponseContent.P" class="empty-state">
+                                    <i class="el-icon-info"></i>
+                                    <span>点击"提交AI测评"按钮获取智能评估反馈</span>
+                                </div>
+                                <div ref="aiResponseP" class="ai-response" v-html="aiResponseContent.P"></div>
+                            </div>
                         </div>
                     </div>
                 </div>
 
-                <div  class="test-area" v-if="active==1">
-                     <el-form-item class="test-form cust-label">
-                    <el-input type="textarea" class="custom-height" v-model="form.s" :placeholder="stepmodel.S"></el-input>
-                </el-form-item>
-                    <div class="test-form ai-evaluate">
-                        <div v-if="showAIEvaluate"><i class="el-icon-loading"></i></div>
-                        <div v-else >
-                          <p v-html="resp"></p>   
+                <!-- S阶段 -->
+                <div class="answer-card" v-if="active==1">
+                    <div class="answer-header">
+                        <div class="answer-title">
+                            <span class="phase-badge phase-s">S</span>
+                            <div class="title-content">
+                                <span class="main-title">系统拆解 Systematic</span>
+                                <span class="sub-title">将复杂问题分解为可管理的子问题</span>
+                            </div>
+                        </div>
+                        <div class="score-display" v-if="saveForm.sScore !== undefined">
+                            <div class="score-content">
+                                <span class="score-value">{{saveForm.sScore}}</span>
+                                <span class="score-divider">/</span>
+                                <span class="score-total">{{stepscore.S}}</span>
+                            </div>
+                            <span class="score-label">分</span>
                         </div>
                     </div>
-                </div>
-
-                <div  class="test-area" v-if="active==2">
-                    <el-form-item class="test-form cust-label">
-                    <el-input type="textarea" class="custom-height" v-model="form.r" :placeholder="stepmodel.R"></el-input>
-                </el-form-item>
-                    <div class="test-form ai-evaluate">
-                         <div v-if="showAIEvaluate"><i class="el-icon-loading"></i></div>
-                        <div v-else >
-                          <p v-html="resp"></p>   
+                    <div class="answer-content">
+                        <div class="input-area">
+                            <div class="input-header">
+                                <span class="input-label">你的答案</span>
+                                <span class="char-count">{{form.s ? form.s.length : 0}} 字</span>
+                            </div>
+                            <el-input 
+                                type="textarea" 
+                                v-model="form.s" 
+                                :placeholder="stepmodel.S"
+                                :autosize="{ minRows: 12, maxRows: 20 }"
+                                class="answer-textarea">
+                            </el-input>
+                        </div>
+                        <div class="ai-feedback-area">
+                            <div class="feedback-header">
+                                <div class="header-left">
+                                    <i class="el-icon-chat-dot-round"></i>
+                                    <span>AI 智能评估</span>
+                                </div>
+                                <el-tag v-if="saveForm.sScore !== undefined" size="small" :type="getScoreType(saveForm.sScore, stepscore.S)">
+                                    {{getScoreLevel(saveForm.sScore, stepscore.S)}}
+                                </el-tag>
+                            </div>
+                            <div class="feedback-content">
+                                <div v-if="showAIEvaluate" class="loading-state">
+                                    <div class="loading-animation">
+                                        <i class="el-icon-loading"></i>
+                                    </div>
+                                    <span>AI正在分析您的答案,请稍候...</span>
+                                </div>
+                                <div v-else-if="!aiResponseContent.S" class="empty-state">
+                                    <i class="el-icon-info"></i>
+                                    <span>点击"提交AI测评"按钮获取智能评估反馈</span>
+                                </div>
+                                <div ref="aiResponseS" class="ai-response" v-html="aiResponseContent.S"></div>
+                            </div>
                         </div>
                     </div>
                 </div>
 
-                <div  class="test-area" v-if="active==3">
-                    <el-form-item class="test-form cust-label">
-                    <el-input type="textarea" class="custom-height" v-model="form.e" :placeholder="stepmodel.E"></el-input>
-                </el-form-item>
-                    <div class="test-form ai-evaluate">
-                         <div v-if="showAIEvaluate"><i class="el-icon-loading"></i></div>
-                        <div v-else >
-                          <p v-html="resp"></p>   
+                <!-- R阶段 -->
+                <div class="answer-card" v-if="active==2">
+                    <div class="answer-header">
+                        <div class="answer-title">
+                            <span class="phase-badge phase-r">R</span>
+                            <div class="title-content">
+                                <span class="main-title">结果整合 Result</span>
+                                <span class="sub-title">整合各部分解决方案,形成完整答案</span>
+                            </div>
+                        </div>
+                        <div class="score-display" v-if="saveForm.rScore !== undefined">
+                            <div class="score-content">
+                                <span class="score-value">{{saveForm.rScore}}</span>
+                                <span class="score-divider">/</span>
+                                <span class="score-total">{{stepscore.R}}</span>
+                            </div>
+                            <span class="score-label">分</span>
                         </div>
                     </div>
-                </div>
-
-                <div  class="test-area" v-if="active==4">
-                      <el-form-item class="test-form cust-label" style="width:100%;">
-                    <el-input type="textarea" class="custom-height" v-model="form.n" :placeholder="stepmodel.N"></el-input>
-                </el-form-item>
-                    <!-- <div class="test-form ai-evaluate">
-                         <div v-if="showAIEvaluate"><i class="el-icon-loading"></i></div>
-                        <div v-else >
-                          <p v-html="resp"></p>   
+                    <div class="answer-content">
+                        <div class="input-area">
+                            <div class="input-header">
+                                <span class="input-label">你的答案</span>
+                                <span class="char-count">{{form.r ? form.r.length : 0}} 字</span>
+                            </div>
+                            <el-input 
+                                type="textarea" 
+                                v-model="form.r" 
+                                :placeholder="stepmodel.R"
+                                :autosize="{ minRows: 12, maxRows: 20 }"
+                                class="answer-textarea">
+                            </el-input>
+                        </div>
+                        <div class="ai-feedback-area">
+                            <div class="feedback-header">
+                                <div class="header-left">
+                                    <i class="el-icon-chat-dot-round"></i>
+                                    <span>AI 智能评估</span>
+                                </div>
+                                <el-tag v-if="saveForm.rScore !== undefined" size="small" :type="getScoreType(saveForm.rScore, stepscore.R)">
+                                    {{getScoreLevel(saveForm.rScore, stepscore.R)}}
+                                </el-tag>
+                            </div>
+                            <div class="feedback-content">
+                                <div v-if="showAIEvaluate" class="loading-state">
+                                    <div class="loading-animation">
+                                        <i class="el-icon-loading"></i>
+                                    </div>
+                                    <span>AI正在分析您的答案,请稍候...</span>
+                                </div>
+                                <div v-else-if="!aiResponseContent.R" class="empty-state">
+                                    <i class="el-icon-info"></i>
+                                    <span>点击"提交AI测评"按钮获取智能评估反馈</span>
+                                </div>
+                                <div ref="aiResponseR" class="ai-response" v-html="aiResponseContent.R"></div>
+                            </div>
                         </div>
-                    </div> -->
+                    </div>
                 </div>
 
-                <div class="opt-area" v-if="active <4">
-                    <div class="opt-left">
-                        <el-button :disabled="showAIEvaluate" :icon="showAIEvaluate?'el-icon-loading':'el-icon-arrow-right'" style="width: 100%;" size="small" type="primary" plain  @click="onAIEvaluate">提交AI测评</el-button>
+                <!-- E阶段 -->
+                <div class="answer-card" v-if="active==3">
+                    <div class="answer-header">
+                        <div class="answer-title">
+                            <span class="phase-badge phase-e">E</span>
+                            <div class="title-content">
+                                <span class="main-title">结果评估 Evaluation</span>
+                                <span class="sub-title">验证解决方案的正确性与完整性</span>
+                            </div>
+                        </div>
+                        <div class="score-display" v-if="saveForm.eScore !== undefined">
+                            <div class="score-content">
+                                <span class="score-value">{{saveForm.eScore}}</span>
+                                <span class="score-divider">/</span>
+                                <span class="score-total">{{stepscore.E}}</span>
+                            </div>
+                            <span class="score-label">分</span>
+                        </div>
                     </div>
-                     <div class="opt-left">
-                        <el-button  :disabled="showAIEvaluate" icon="el-icon-check" v-if="active<4" style="width: 100%;" size="small" type="success" plain  @click="onNext">下一步</el-button>
+                    <div class="answer-content">
+                        <div class="input-area">
+                            <div class="input-header">
+                                <span class="input-label">你的答案</span>
+                                <span class="char-count">{{form.e ? form.e.length : 0}} 字</span>
+                            </div>
+                            <el-input 
+                                type="textarea" 
+                                v-model="form.e" 
+                                :placeholder="stepmodel.E"
+                                :autosize="{ minRows: 12, maxRows: 20 }"
+                                class="answer-textarea">
+                            </el-input>
+                        </div>
+                        <div class="ai-feedback-area">
+                            <div class="feedback-header">
+                                <div class="header-left">
+                                    <i class="el-icon-chat-dot-round"></i>
+                                    <span>AI 智能评估</span>
+                                </div>
+                                <el-tag v-if="saveForm.eScore !== undefined" size="small" :type="getScoreType(saveForm.eScore, stepscore.E)">
+                                    {{getScoreLevel(saveForm.eScore, stepscore.E)}}
+                                </el-tag>
+                            </div>
+                            <div class="feedback-content">
+                                <div v-if="showAIEvaluate" class="loading-state">
+                                    <div class="loading-animation">
+                                        <i class="el-icon-loading"></i>
+                                    </div>
+                                    <span>AI正在分析您的答案,请稍候...</span>
+                                </div>
+                                <div v-else-if="!aiResponseContent.E" class="empty-state">
+                                    <i class="el-icon-info"></i>
+                                    <span>点击"提交AI测评"按钮获取智能评估反馈</span>
+                                </div>
+                                <div ref="aiResponseE" class="ai-response" v-html="aiResponseContent.E"></div>
+                            </div>
+                        </div>
                     </div>
                 </div>
-                <div v-else  class="opt-area" >
-                 <el-button  :disabled="showAIEvaluate" icon="el-icon-check" style="width: 100%;" size="small" type="success" plain  @click="onFinish">完成</el-button>
-                </div>
-            </el-col> 
-             
-        </el-form>
 
-
-
-        <!-- <template>
-            <el-dialog :visible.sync="dialogResultVisible" width="50%" top="0" custom-class="GPSREN" :modal="false"
-              :modal-append-to-body="false">
-                <div slot="title" class="cust-title">
-                    AI评价 <i :class="aiTestClass"></i>
+                <!-- N阶段 -->
+                <div class="answer-card summary-card" v-if="active==4">
+                    <div class="answer-header">
+                        <div class="answer-title">
+                            <span class="phase-badge phase-n">N</span>
+                            <div class="title-content">
+                                <span class="main-title">总结新知识 New Knowledge</span>
+                                <span class="sub-title">反思学习过程,提炼关键知识点</span>
+                            </div>
+                        </div>
+                        <div class="total-score">
+                            <div class="total-content">
+                                <span class="total-label">总分</span>
+                                <div class="total-value-wrapper">
+                                    <span class="total-value">{{totalScore}}</span>
+                                    <span class="total-divider">/</span>
+                                    <span class="total-max">{{totalMaxScore}}</span>
+                                </div>
+                            </div>
+                        </div>
+                    </div>
+                    <div class="answer-content single-column">
+                        <div class="input-area">
+                            <div class="input-header">
+                                <span class="input-label">你的总结</span>
+                                <span class="char-count">{{form.n ? form.n.length : 0}} 字</span>
+                            </div>
+                            <el-input 
+                                type="textarea" 
+                                v-model="form.n" 
+                                :placeholder="stepmodel.N"
+                                :autosize="{ minRows: 15, maxRows: 25 }"
+                                class="answer-textarea">
+                            </el-input>
+                        </div>
+                    </div>
                 </div>
 
-                <div class="block">
-                    <div v-html="resp"></div>
+                <!-- 操作按钮 -->
+                <div class="action-buttons">
+                    <template v-if="active < 4">
+                        <div class="button-group">
+                            <el-button 
+                                v-if="active > 0"
+                                type="info"
+                                size="medium"
+                                @click="onPrev"
+                                class="action-btn">
+                                <i class="el-icon-left"></i>
+                                上一步
+                            </el-button>
+                            <el-button 
+                                :disabled="showAIEvaluate" 
+                                :loading="showAIEvaluate"
+                                type="primary" 
+                                size="medium"
+                                @click="onAIEvaluate"
+                                class="action-btn primary-btn">
+                                <i class="el-icon-cpu" v-if="!showAIEvaluate"></i>
+                                {{showAIEvaluate ? 'AI评估中...' : '提交AI测评'}}
+                            </el-button>
+                            <el-button 
+                                :disabled="showAIEvaluate" 
+                                type="success" 
+                                size="medium"
+                                @click="onNext"
+                                class="action-btn success-btn">
+                                下一步
+                                <i class="el-icon-right"></i>
+                            </el-button>
+                        </div>
+                        <div class="tips-text">
+                            <i class="el-icon-info"></i>
+                            建议先提交AI测评获取反馈后再进入下一步
+                        </div>
+                    </template>
+                    <template v-else>
+                        <div class="finish-section">
+                            <div class="finish-summary">
+                                <div class="summary-item">
+                                    <span class="label">完成步骤</span>
+                                    <span class="value">4/4</span>
+                                </div>
+                                <div class="summary-item">
+                                    <span class="label">总得分</span>
+                                    <span class="value highlight">{{totalScore}}/{{totalMaxScore}}</span>
+                                </div>
+                                <div class="summary-item">
+                                    <span class="label">得分率</span>
+                                    <span class="value">{{totalMaxScore > 0 ? Math.round((totalScore/totalMaxScore)*100) : 0}}%</span>
+                                </div>
+                            </div>
+                            <div class="button-group">
+                                <el-button
+                                    type="info"
+                                    size="medium"
+                                    @click="onPrev"
+                                    class="action-btn">
+                                    <i class="el-icon-left"></i>
+                                    上一步
+                                </el-button>
+                                <el-button 
+                                    :disabled="showAIEvaluate" 
+                                    type="success" 
+                                    size="large"
+                                    @click="onFinish"
+                                    class="action-btn finish-btn">
+                                    <i class="el-icon-circle-check"></i>
+                                    提交并完成学习
+                                </el-button>
+                            </div>
+                        </div>
+                    </template>
                 </div>
-
-                <span slot="footer" class="dialog-footer" v-if="aiTestClass=='el-icon-reading'">
-                    <el-button icon="el-icon-arrow-right" size="small" type="primary" plain v-if="active<4"
-                        @click="()=>{active++;dialogResultVisible = false;}">AI评测</el-button>
-                    <el-button type="primary" @click="()=>{dialogResultVisible = false;dialogVisible = false}"
-                        size="small" v-else-if="active==4">提交</el-button>
-                    <el-button @click="dialogResultVisible = false" size="small">修改</el-button>
-                    <el-button @click="()=>{dialogResultVisible = false; active=0;}" size="small">重新答题</el-button>
-                </span>
-            </el-dialog>
-        </template> -->
+            </div>
+        </el-form>
     </div>
 </template>
 
 <script>
 import Axios from 'axios';
 import { getDictValueByType } from '../api/dict'
-
 import { mockAI, steps ,tips} from '../mock/gpsren';
+import {askAI, postGPSREN, getStepModel, getGpsrenSession} from '../api/ai'
 
-import {askAI,postGPSREN,getStepModel} from '../api/ai' 
 let thisPage = null
-
 let stepMapToCnt = {}
 
 export default {
@@ -193,7 +464,16 @@ export default {
             uploadAction: this.$httpApi.httpUrl('/api/upload/2'),
             dialogVisible: false,
             form: {},
-            saveForm:{},
+            saveForm:{
+                pScore: undefined,
+                sScore: undefined,
+                rScore: undefined,
+                eScore: undefined,
+                pAnswer: '',
+                sAnswer: '',
+                rAnswer: '',
+                eAnswer: ''
+            },
             config: {
                 zIndex: 0
             },
@@ -202,18 +482,26 @@ export default {
             aiTestItem: [],
             aiTestClass: "el-icon-reading",
             resp:'',
+            aiResponseContent: {
+                P: '',
+                S: '',
+                R: '',
+                E: ''
+            },
             stepmodel: {
-                        "P": "",
-                        "S":"",
-                        "R":"",
-                        "E":""
-                        },
+                "P": "",
+                "S":"",
+                "R":"",
+                "E":"",
+                "N":""
+            },
             stepscore: {
-                        "P": 0,
-                        "S":0,
-                        "R":0,
-                        "E":0
-                        },
+                "P": 0,
+                "S":0,
+                "R":0,
+                "E":0
+            },
+            abortController: null
         }
     },
 
@@ -233,17 +521,14 @@ export default {
                 "P":"",
                 "S":"",
                 "R":"",
-                "E":""
-                }
-            console.log("this.stepmodel===> ",this.stepmodel)
+                "E":"",
+                "N":""
+            }
             
-            //todo
-             getStepModel().then(resp=>{
-                console.log(resp)
+            getStepModel().then(resp=>{
                 if(resp.status == 200) {
                     let res = resp.data
                     if(res.code == 1) {
-                        
                          let stepModels = res.data.dataList
                          for(let n =0 ;n<stepModels.length;n++) {
                             let m = stepModels[n]
@@ -252,22 +537,121 @@ export default {
                          }
                     }
                 }
-             }).finally(d=>{
-                console.log("this.stepmodel",this.stepmodel)
+             }).then(() => {
+                // 尝试恢复之前的答题进度
+                const studentId = JSON.parse(localStorage.getItem('userInfo')).id
+                const goalId = this.$props.question.id
+                return getGpsrenSession(goalId, studentId).then(resp => {
+                    if (resp.status === 200 && resp.data.code === 1 && resp.data.data) {
+                        this.restoreSession(resp.data.data)
+                    }
+                }).catch(() => {
+                    // 读取失败不影响正常答题
+                })
+             }).finally(() => {
                 loading.close()
              })
         })
-      
     },
 
+    computed: {
+        totalScore() {
+            let total = 0
+            console.log('计算总分 - saveForm:', JSON.stringify(this.saveForm));
+            if (this.saveForm.pScore !== undefined) {
+                total += this.saveForm.pScore
+                console.log('P分数:', this.saveForm.pScore);
+            }
+            if (this.saveForm.sScore !== undefined) {
+                total += this.saveForm.sScore
+                console.log('S分数:', this.saveForm.sScore);
+            }
+            if (this.saveForm.rScore !== undefined) {
+                total += this.saveForm.rScore
+                console.log('R分数:', this.saveForm.rScore);
+            }
+            if (this.saveForm.eScore !== undefined) {
+                total += this.saveForm.eScore
+                console.log('E分数:', this.saveForm.eScore);
+            }
+            console.log('计算得出总分:', total);
+            return total
+        },
+        totalMaxScore() {
+            const maxScore = (this.stepscore.P || 0) + (this.stepscore.S || 0) + 
+                   (this.stepscore.R || 0) + (this.stepscore.E || 0);
+            console.log('总满分:', maxScore, 'stepscore:', JSON.stringify(this.stepscore));
+            return maxScore;
+        }
+    },
 
     methods: {
+        // 恢复 Redis 中的答题进度
+        restoreSession(session) {
+            const stepOrder = ['P', 'S', 'R', 'E']
+            const steps = session.steps || {}
+            let lastCompletedIndex = -1
+
+            stepOrder.forEach((step, index) => {
+                const record = steps[step]
+                if (!record) return
+
+                // 恢复答案输入框
+                this.form[step.toLowerCase()] = record.studentAnswer || ''
+
+                // 恢复 saveForm(分数 + 答案)
+                const newSaveForm = { ...this.saveForm }
+                newSaveForm[`${step.toLowerCase()}Answer`] = record.studentAnswer || ''
+                if (record.score !== undefined && record.score !== null) {
+                    newSaveForm[`${step.toLowerCase()}Score`] = record.score
+                }
+                this.saveForm = newSaveForm
+
+                // 恢复 AI 回复展示
+                this.aiResponseContent[step] = record.aiResponse || ''
+
+                lastCompletedIndex = index
+            })
+
+            // 恢复 N 阶段总结
+            if (steps['N'] && steps['N'].studentAnswer) {
+                this.form.n = steps['N'].studentAnswer
+            }
+
+            // 跳到最后完成阶段(停在该阶段,允许继续或回看)
+            if (lastCompletedIndex >= 0) {
+                this.active = lastCompletedIndex
+                this.$nextTick(() => {
+                    const step = stepOrder[lastCompletedIndex]
+                    const el = this.$refs[`aiResponse${step}`]
+                    if (el) el.innerHTML = this.aiResponseContent[step]
+                })
+            }
+        },
+
+        // 获取分数等级
+        getScoreLevel(score, maxScore) {
+            const percentage = (score / maxScore) * 100
+            if (percentage >= 90) return '优秀'
+            if (percentage >= 80) return '良好'
+            if (percentage >= 70) return '中等'
+            if (percentage >= 60) return '及格'
+            return '待提高'
+        },
+
+        // 获取分数类型(用于tag颜色)
+        getScoreType(score, maxScore) {
+            const percentage = (score / maxScore) * 100
+            if (percentage >= 90) return 'success'
+            if (percentage >= 70) return ''
+            if (percentage >= 60) return 'warning'
+            return 'danger'
+        },
 
         //提交测评
         onAIEvaluate() {
             let step = steps[this.active] 
             if(!!!this.form[`${step.toLowerCase()}`]) {
-                //没有学生答案
                 this.$message({
                         type: 'warning',
                         message: '请输入答案',
@@ -277,63 +661,175 @@ export default {
             }
             this.showAIEvaluate = true
             let run = () => { 
-               return  this.remoteAskAI(this.$props.question.courseName ,
-                step,
-                this.$props.question.gOriented,
-                this.$props.question[`${step.toLowerCase()}ScoreStd`] + ' '+ this.stepmodel[step],
-                this.form[`${step.toLowerCase()}`],
-                this.stepscore[step]
-             )
+               return  this.remoteAskAI(
+                    this.$props.question.courseName,
+                    step,
+                    this.$props.question.gOriented,
+                    this.$props.question[`${step.toLowerCase()}ScoreStd`] + ' '+ this.stepmodel[step],
+                    this.form[`${step.toLowerCase()}`],
+                    this.stepscore[step]
+               )
             }
             run().finally(f=>{ this.showAIEvaluate = false; })
         },
 
-        //
-        remoteAskAI(cn, sn, g,sa,ssa,_s) {
-            console.log(cn,sn,g,sa,ssa)
+        extractScoreFromHtml(content) {
+            const match = content.match(/\[\[SCORE:(\d+)\]\]/g);
+            if (match) {
+                // 取最后一个(末尾)
+                const last = match[match.length - 1];
+                const score = parseInt(last.match(/\[\[SCORE:(\d+)\]\]/)[1]);
+                console.log('提取到的分数:', score);
+                return score;
+            }
+            console.log('未找到分数标记,原文片段:', content.substring(0, 200));
+            return 0;
+        },
+
+        // 去掉评分标记,返回纯展示 HTML
+        stripScoreTag(content) {
+            return content.replace(/\[\[SCORE:\d+\]\]/g, '').trim();
+        },
+ 
+        async remoteAskAI(cn, sn, g, sa, ssa, _s) {
             this.resp = ''
-            return askAI({
-                memoryId:1,
-                courseName:cn,
-                stepName:sn,
-                goal:g,
-                standardAnswer:sa,
-                studentAnswer:ssa,
-                score:_s
-            }).then(r=>{
-                if(r.status == 200) {
-                    let res = r.data
-                    if(res.code == 1) {
-                        console.log(res.data)
-                        try{
-                            let jData = JSON.parse(res.data)
-                            this.resp = jData.text
-                            this.score = jData.score 
-                        }catch(e){
-                            console.log(e)
-                            this.resp = "AI返回值不符合格式要求"
+            this.score = 0
+            this.abortController = new AbortController()
+            
+            const step = steps[this.active]
+            const refName = `aiResponse${step}`;
+            this.aiResponseContent[step] = '';
+            
+            await this.$nextTick()
+            const el = this.$refs[refName]
+            if (el) {
+                el.innerHTML = '';
+            }
+            
+            try {
+                const requestData = {
+                    goalId: this.$props.question.id,
+                    studentId: JSON.parse(localStorage.getItem('userInfo')).id,
+                    courseName: cn,
+                    stepName: sn,
+                    goal: g,
+                    studentAnswer: ssa,
+                    score: _s
+                }
+                
+                const apiUrl = this.$httpApi.aiUrl('/api/psrenEvalution')
+                
+                const response = await fetch(apiUrl, {
+                    method: 'POST',
+                    headers: {
+                        'Content-Type': 'application/json',
+                        'Authorization': localStorage.getItem('token'),
+                        'Platform': 'educationStudent'
+                    },
+                    body: JSON.stringify(requestData),
+                    signal: this.abortController.signal
+                })
+                
+                if (!response.ok) throw new Error('评估请求失败')
+                
+                const reader = response.body.getReader()
+                const decoder = new TextDecoder()
+                let buffer = ''
+                let fullContent = ''
+                
+                while (true) {
+                    const { done, value } = await reader.read()
+                    if (done) break
+                    
+                    buffer += decoder.decode(value, { stream: true })
+                    
+                    const lines = buffer.split('\n')
+                    buffer = lines.pop() || ''
+                    
+                    for (const line of lines) {
+                        if (line.startsWith('data:')) {
+                            const content = line.substring(5).trim()
+                            if (content) {
+                                fullContent += content
+                                this.resp += content
+                                
+                                // 渲染时去掉评分标记,避免显示在页面上
+                                const displayHtml = this.stripScoreTag(fullContent);
+                                this.aiResponseContent[step] = displayHtml;
+                                
+                                const el = this.$refs[refName]
+                                if (el) {
+                                    el.innerHTML = displayHtml;
+                                    await new Promise(resolve => setTimeout(resolve, 30))
+                                }
+                            }
+                        }
+                    }
+                }
+                
+                if (buffer.trim() && buffer.startsWith('data:')) {
+                    const content = buffer.substring(5).trim()
+                    if (content) {
+                        fullContent += content
+                        this.resp += content
+                        const displayHtml = this.stripScoreTag(fullContent);
+                        this.aiResponseContent[step] = displayHtml;
+                        
+                        const el = this.$refs[refName]
+                        if (el) {
+                            el.innerHTML = displayHtml;
                         }
-                    } else {
-                        this.resp = res.message
+                    }
+                }
+                
+                this.score = this.extractScoreFromHtml(fullContent);
+                
+                return this.resp
+                
+            } catch (error) {
+                if (error.name === 'AbortError') {
+                    this.resp = '评估已取消'
+                    this.aiResponseContent[step] = '评估已取消';
+                    const el = this.$refs[refName]
+                    if (el) {
+                        el.innerHTML = '评估已取消';
                     }
                 } else {
-                    this.resp = "AI超时"
+                    console.error('AI评估错误:', error)
+                    this.resp = "服务故障,请重试"
+                    this.aiResponseContent[step] = "服务故障,请重试";
+                    const el = this.$refs[refName]
+                    if (el) {
+                        el.innerHTML = "服务故障,请重试";
+                    }
                 }
-              
                 return this.resp
-            }).catch(c=>{
-                this.resp = "服务故障,请重试"
-            }).finally(()=>{
-                //记录本地
-                this.saveForm[`${sn.toLowerCase()}Answer`] = ssa
-                this.saveForm[`${sn.toLowerCase()}Score`] = this.score
+            } finally {
+                // 创建新的 saveForm 对象来触发响应式更新
+                const newSaveForm = { ...this.saveForm }
+                newSaveForm[`${sn.toLowerCase()}Answer`] = ssa
+                newSaveForm[`${sn.toLowerCase()}Score`] = this.score
+                this.saveForm = newSaveForm
+                
+                console.log('保存分数:', `${sn.toLowerCase()}Score`, '=', this.score);
+                console.log('当前saveForm:', JSON.stringify(this.saveForm));
+            }
+        },
+
+        onPrev() {
+            if (this.active <= 0) return
+            this.active--
+            this.showAIEvaluate = false
+            // 恢复该阶段的 AI 回复到 DOM
+            this.$nextTick(() => {
+                const step = ['P', 'S', 'R', 'E', 'N'][this.active]
+                const el = this.$refs[`aiResponse${step}`]
+                if (el) el.innerHTML = this.aiResponseContent[step] || ''
             })
         },
 
         onNext() { 
-            //保存答案
             let step = steps[this.active]
-
             let a = this.saveForm[`${step.toLowerCase()}Answer`]
            
             if(!!!a) {
@@ -345,255 +841,743 @@ export default {
                 return
             }
  
-            //进入到下一个步骤
+            console.log('进入下一步前 - 当前步骤:', step, '当前saveForm:', JSON.stringify(this.saveForm));
             this.active ++ 
+            console.log('进入下一步后 - 新步骤:', this.active, '总分应该是:', this.totalScore);
 
             this.resp = ''
             this.showAIEvaluate = false
             this.score = 0
-
+            
+            this.$nextTick(() => {
+                const nextStep = steps[this.active]
+                if (nextStep && this.aiResponseContent[nextStep] !== undefined) {
+                    this.aiResponseContent[nextStep] = '';
+                }
+                const refName = `aiResponse${nextStep}`
+                const el = this.$refs[refName]
+                if (el) {
+                    el.innerHTML = '';
+                }
+            })
         },
 
         onFinish() {
-            //保存
-             
-             let params = { 
+            let params = { 
                 goalInfoId: this.$props.question.id,
-                nAnswer:this.form.n
-             }
-             let p = Object.assign(params,this.saveForm)
+                nAnswer: this.form.n
+            }
+            let p = Object.assign(params, this.saveForm)
               
-             postGPSREN(p).then(d=>{
+            postGPSREN(p).then(d=>{
                 console.log("postGPSREN",d)
                 if(d.status == 200) {
-                  let dt =  d.data || {}
-                  if(dt.code == 1) {
-                   this.$props.finish && this.$props.finish()
-                  }
+                    let dt = d.data || {}
+                    if(dt.code == 1) {
+                        this.$props.finish && this.$props.finish()
+                    }
                 }
-             }) 
-            
+            }) 
         },
-  
     },
 
     filters: {
        getStepModelTips(s) {
             let cs = this.stepmodel[s]
-            console.log("dddd==>",cs)
             if(!!cs) {
-               return  cs['requires'] || ""
+               return cs['requires'] || ""
             } 
             return ""
         },
     }, 
-        
 }
 </script>
 
-<style lang="scss">
-.el-dialog__header {
-    background-color: #477efa !important;
-    color: aliceblue !important;
+<style lang="scss" scoped>
+
+
+.gpsren-container {
+    max-width: 1400px;
+    margin: 0 auto;
+    padding: 24px;
+    background: #f5f7fa;
+    min-height: 100vh;
 }
 
-.el-dialog__close {
-    color: aliceblue !important;
+.gpsren-form {
+    width: 100%;
 }
 
-.GPSREN {
-    margin-bottom: 0px !important;
+/* 目标卡片 */
+.goal-card {
+    background: #ffffff;
+    border-radius: 8px;
+    padding: 20px 24px;
+    margin-bottom: 24px;
+    box-shadow: 0 2px 8px rgba(0, 0, 0, 0.06);
+    border-left: 3px solid #409EFF;
 
-    .cust-title {
-        text-align: center;
-        font-size: 20px;
+    .goal-header {
+        display: flex;
+        align-items: center;
+        margin-bottom: 12px;
+        
+        i {
+            font-size: 20px;
+            color: #409EFF;
+            margin-right: 10px;
+        }
+
+        .goal-title {
+            font-size: 16px;
+            font-weight: 600;
+            color: #303133;
+        }
     }
 
-    .test-area{
+    .goal-content {
+        font-size: 15px;
+        line-height: 1.6;
+        color: #606266;
+        padding-left: 30px;
+    }
+}
 
+/* 步骤条 */
+.steps-wrapper {
+    background: #ffffff;
+    border-radius: 8px;
+    padding: 20px 24px;
+    margin-bottom: 24px;
+    box-shadow: 0 2px 8px rgba(0, 0, 0, 0.06);
+
+    .steps-header {
         display: flex;
-        align-items:flex-start;
         justify-content: space-between;
-        gap: 10px;
-        height: 350px;
+        align-items: center;
+        margin-bottom: 20px;
+        padding-bottom: 16px;
+        border-bottom: 1px solid #EBEEF5;
+
+        .progress-info {
+            display: flex;
+            align-items: center;
+            gap: 16px;
+
+            .current-step {
+                font-size: 16px;
+                font-weight: 600;
+                color: #303133;
+            }
 
-        .test-form{
-          width:50%;
+            .progress-text {
+                font-size: 14px;
+                color: #909399;
+                background: #F5F7FA;
+                padding: 4px 12px;
+                border-radius: 12px;
+            }
         }
 
-        .ai-evaluate{
-            color:#333;
-            background-color: #eee;
-            border: solid 1px #eee;
-            height: calc(100%);
-            overflow: auto;
+        .score-summary {
+            display: flex;
+            align-items: baseline;
+            gap: 6px;
+
+            .label {
+                font-size: 13px;
+                color: #606266;
+            }
+
+            .value {
+                font-size: 24px;
+                font-weight: 600;
+                color: #409EFF;
+            }
+
+            .total {
+                font-size: 14px;
+                color: #909399;
+            }
         }
     }
 
-    .cust-label {
-        font-weight: bold;
+    ::v-deep .custom-steps {
+        .el-step__head {
+            &.is-process {
+                color: #409EFF;
+                border-color: #409EFF;
+            }
 
-        .el-form-item__label {
-            color: #67C23A !important;
+            &.is-finish {
+                color: #67C23A;
+                border-color: #67C23A;
+            }
         }
 
+        .el-step__line {
+            background-color: #E4E7ED;
+        }
     }
 
-    .custom-height .el-textarea__inner {
-        height: 350px;
-        /* 设置你想要的高度 */
-    }
-
-    .opt-area{
-        // background-color: #67C23A;
-        color:#eee;
+    .step-title {
         display: flex;
-        align-items:center;
-        justify-content: space-between;
-        gap: 10px;
+        flex-direction: column;
+        align-items: center;
+        gap: 8px;
+
+        .step-badge {
+            width: 44px;
+            height: 44px;
+            border-radius: 50%;
+            background: #E4E7ED;
+            color: #909399;
+            display: flex;
+            align-items: center;
+            justify-content: center;
+            font-size: 18px;
+            font-weight: 600;
+            transition: all 0.3s;
+
+            &.active {
+                background: #409EFF;
+                color: white;
+                box-shadow: 0 0 0 4px rgba(64, 158, 255, 0.2);
+            }
+
+            &.finished {
+                background: #67C23A;
+                color: white;
+            }
+        }
 
-        .opt-left{
-            width: 50%;
-            height: 100%;
+        .step-name {
+            font-size: 13px;
+            color: #606266;
+            font-weight: 500;
+        }
+
+        .step-score {
+            font-size: 12px;
+            color: #F56C6C;
+            font-weight: 600;
+            background: #FEF0F0;
+            padding: 3px 10px;
+            border-radius: 10px;
         }
     }
 }
 
-.testbox p {
-    display: inline-block;
-}
+/* 答题区域 */
+.answer-section {
+    .answer-card {
+        background: #ffffff;
+        border-radius: 8px;
+        padding: 24px;
+        margin-bottom: 20px;
+        box-shadow: 0 2px 8px rgba(0, 0, 0, 0.06);
+
+        .answer-header {
+            display: flex;
+            justify-content: space-between;
+            align-items: center;
+            margin-bottom: 20px;
+            padding-bottom: 12px;
+            border-bottom: 1px solid #EBEEF5;
+
+            .answer-title {
+                display: flex;
+                align-items: center;
+                gap: 14px;
+
+                .phase-badge {
+                    width: 48px;
+                    height: 48px;
+                    border-radius: 8px;
+                    display: flex;
+                    align-items: center;
+                    justify-content: center;
+                    font-size: 20px;
+                    font-weight: 600;
+                    color: white;
+                    flex-shrink: 0;
+
+                    &.phase-p {
+                        background: #409EFF;
+                    }
 
+                    &.phase-s {
+                        background: #67C23A;
+                    }
 
-/*.el-upload--picture-card {*/
-/*  width: 100px !important;*/
-/*  height: 90px !important;*/
-/*  line-height: 100px !important;*/
-/*  vertical-align: top;*/
-/*}*/
-.tops {
-    display: inline-block;
-    text-align: center;
-    width: 100px;
-    height: 40px;
-    line-height: 40px;
-    border-radius: 40px;
-    background-color: #FAD303;
-    box-shadow: 3px 2px 0 0 rgba(250, 213, 3, 0.445);
-}
+                    &.phase-r {
+                        background: #E6A23C;
+                    }
 
-.el-pagination {
-    margin-top: 15px;
-    text-align: center;
-}
+                    &.phase-e {
+                        background: #F56C6C;
+                    }
 
-.title3 .count {
-    position: relative;
-    overflow: overlay;
-    display: inline-block;
-    font-weight: bolder;
-    left: 86px;
-    color: red;
-    font-size: 45px;
-}
+                    &.phase-n {
+                        background: #909399;
+                    }
+                }
 
-.title3 .mark {
-    width: 205px;
-    top: 85px;
-    left: 57%;
-    height: 64px;
-    position: absolute;
-}
+                .title-content {
+                    display: flex;
+                    flex-direction: column;
+                    gap: 4px;
 
-.el-radio-button__inner,
-.el-radio-group {
-    padding-top: 20px !important;
-    display: block !important;
-}
+                    .main-title {
+                        font-size: 18px;
+                        font-weight: 600;
+                        color: #303133;
+                        line-height: 1.2;
+                    }
 
-.testinfo {
-    padding-left: 30px;
-    padding-top: 22px;
-}
+                    .sub-title {
+                        font-size: 13px;
+                        color: #909399;
+                        line-height: 1.2;
+                    }
+                }
+            }
 
-.title3 {
-    width: 100%;
-    height: 30px;
-    text-align: center;
-}
+            .score-display {
+                display: flex;
+                align-items: center;
+                gap: 8px;
+                background: #F5F7FA;
+                padding: 8px 16px;
+                border-radius: 6px;
+                border: 2px solid #409EFF;
+
+                .score-content {
+                    display: flex;
+                    align-items: baseline;
+                    gap: 2px;
+
+                    .score-value {
+                        font-size: 28px;
+                        font-weight: 600;
+                        color: #409EFF;
+                        line-height: 1;
+                    }
 
-.subbtnbox {
-    width: 100%;
-    text-align: center;
-    padding: 20px;
+                    .score-divider {
+                        font-size: 18px;
+                        color: #DCDFE6;
+                        margin: 0 2px;
+                    }
+
+                    .score-total {
+                        font-size: 16px;
+                        color: #909399;
+                        line-height: 1;
+                    }
+                }
 
-    .btn {
-        width: 100px;
-        background-color: red;
+                .score-label {
+                    font-size: 13px;
+                    color: #606266;
+                }
+            }
+
+            .total-score {
+                background: #F0F9FF;
+                padding: 10px 20px;
+                border-radius: 6px;
+                border: 2px solid #67C23A;
+
+                .total-content {
+                    display: flex;
+                    flex-direction: column;
+                    align-items: center;
+                    gap: 4px;
+
+                    .total-label {
+                        font-size: 12px;
+                        color: #606266;
+                    }
+
+                    .total-value-wrapper {
+                        display: flex;
+                        align-items: baseline;
+                        gap: 2px;
+
+                        .total-value {
+                            font-size: 32px;
+                            font-weight: 600;
+                            color: #67C23A;
+                            line-height: 1;
+                        }
+
+                        .total-divider {
+                            font-size: 20px;
+                            color: #DCDFE6;
+                            margin: 0 2px;
+                        }
+
+                        .total-max {
+                            font-size: 18px;
+                            color: #909399;
+                            line-height: 1;
+                        }
+                    }
+                }
+            }
+        }
+
+        .answer-content {
+            display: grid;
+            grid-template-columns: 1fr 1fr;
+            gap: 20px;
+
+            &.single-column {
+                grid-template-columns: 1fr;
+            }
+
+            .input-area {
+                .input-header {
+                    display: flex;
+                    justify-content: space-between;
+                    align-items: center;
+                    margin-bottom: 8px;
+
+                    .input-label {
+                        font-size: 14px;
+                        font-weight: 600;
+                        color: #303133;
+                    }
+
+                    .char-count {
+                        font-size: 12px;
+                        color: #909399;
+                    }
+                }
+
+                ::v-deep .answer-textarea {
+                    .el-textarea__inner {
+                        border: 1px solid #DCDFE6;
+                        border-radius: 4px;
+                        padding: 12px;
+                        font-size: 14px;
+                        line-height: 1.6;
+                        transition: border-color 0.2s;
+
+                        &:focus {
+                            border-color: #409EFF;
+                        }
+
+                        &::placeholder {
+                            color: #C0C4CC;
+                        }
+                    }
+                }
+            }
+
+            .ai-feedback-area {
+                background: #F5F7FA;
+                border-radius: 4px;
+                padding: 16px;
+                border: 1px solid #E4E7ED;
+
+                .feedback-header {
+                    display: flex;
+                    justify-content: space-between;
+                    align-items: center;
+                    margin-bottom: 12px;
+                    padding-bottom: 10px;
+                    border-bottom: 1px solid #DCDFE6;
+
+                    .header-left {
+                        display: flex;
+                        align-items: center;
+                        gap: 6px;
+
+                        i {
+                            font-size: 16px;
+                            color: #409EFF;
+                        }
+
+                        span {
+                            font-size: 14px;
+                            font-weight: 600;
+                            color: #303133;
+                        }
+                    }
+                }
+
+                .feedback-content {
+                    min-height: 200px;
+                    max-height: 500px;
+                    overflow-y: auto;
+
+                    .loading-state {
+                        display: flex;
+                        flex-direction: column;
+                        align-items: center;
+                        justify-content: center;
+                        padding: 50px 20px;
+                        color: #606266;
+
+                        .loading-animation {
+                            width: 48px;
+                            height: 48px;
+                            border-radius: 50%;
+                            background: #ECF5FF;
+                            display: flex;
+                            align-items: center;
+                            justify-content: center;
+                            margin-bottom: 16px;
+
+                            i {
+                                font-size: 24px;
+                                color: #409EFF;
+                                animation: rotate 1.5s linear infinite;
+                            }
+                        }
+
+                        span {
+                            font-size: 13px;
+                        }
+                    }
+
+                    .empty-state {
+                        display: flex;
+                        flex-direction: column;
+                        align-items: center;
+                        justify-content: center;
+                        padding: 50px 20px;
+                        color: #909399;
+
+                        i {
+                            font-size: 48px;
+                            margin-bottom: 12px;
+                            opacity: 0.5;
+                        }
+
+                        span {
+                            font-size: 13px;
+                            text-align: center;
+                        }
+                    }
+
+                    .ai-response {
+                        font-size: 14px;
+                        line-height: 1.7;
+                        color: #606266;
+                        white-space: pre-wrap;
+                        word-wrap: break-word;
+
+                        ::v-deep {
+                            h1, h2, h3, h4, h5, h6 {
+                                margin: 14px 0 10px;
+                                color: #303133;
+                                font-weight: 600;
+                            }
+
+                            p {
+                                margin: 6px 0;
+                            }
+
+                            ul, ol {
+                                padding-left: 20px;
+                                margin: 10px 0;
+                            }
+
+                            li {
+                                margin: 4px 0;
+                            }
+
+                            strong {
+                                color: #303133;
+                                font-weight: 600;
+                            }
+
+                            code {
+                                background: #FDF6EC;
+                                padding: 2px 6px;
+                                border-radius: 3px;
+                                font-family: 'Courier New', monospace;
+                                color: #E6A23C;
+                            }
+                        }
+                    }
+                }
+            }
+        }
     }
-}
 
-.testbox {
-    display: inline-block;
-    margin-top: 20px
+    .summary-card {
+        border: 2px solid #67C23A;
+        background: linear-gradient(to bottom, #ffffff 0%, #f0f9ff 100%);
+    }
 }
 
-.btnbox {
-    display: flex;
-    display: -webkit-flex;
-    justify-content: space-around;
-    padding-left: 100px;
-    margin-top: 30px;
-    padding-right: 100px;
-}
+/* 操作按钮 */
+.action-buttons {
+    margin-top: 24px;
 
-.play {
-    display: inline-block;
-    height: 30px;
-    line-height: 30px;
-    padding-left: 10px;
-    color: red;
-    cursor: pointer;
-
-    .cp {
-        font-size: 20px;
-        vertical-align: middle;
+    .button-group {
+        display: flex;
+        justify-content: center;
+        gap: 16px;
+        margin-bottom: 12px;
     }
 
-    .ai-ana {
-        color: skyblue;
+    .tips-text {
+        text-align: center;
+        font-size: 13px;
+        color: #909399;
+        display: flex;
+        align-items: center;
+        justify-content: center;
+        gap: 4px;
+
+        i {
+            font-size: 14px;
+        }
     }
-}
 
+    .action-btn {
+        min-width: 140px;
+        height: 40px;
+        font-size: 15px;
+        font-weight: 500;
+        border-radius: 4px;
+
+        i {
+            font-size: 16px;
+        }
+
+        &.primary-btn {
+            background: #409EFF;
+            border-color: #409EFF;
+
+            &:hover:not(:disabled) {
+                background: #66b1ff;
+                border-color: #66b1ff;
+            }
+        }
+
+        &.success-btn {
+            background: #67C23A;
+            border-color: #67C23A;
 
-.typing-effect {
-    overflow: hidden;
-    /* 确保超出部分的内容不显示 */
-    border-right: .15em solid orange;
-    /* 光标效果 */
-    white-space: nowrap;
-    /* 防止文本换行 */
-    animation: typing 3s steps(20, end), blink-caret .75s step-end infinite;
+            &:hover:not(:disabled) {
+                background: #85ce61;
+                border-color: #85ce61;
+            }
+        }
+
+        &.finish-btn {
+            background: #67C23A;
+            border-color: #67C23A;
+            min-width: 200px;
+            height: 48px;
+            font-size: 16px;
+
+            &:hover:not(:disabled) {
+                background: #85ce61;
+                border-color: #85ce61;
+            }
+        }
+    }
+
+    .finish-section {
+        display: flex;
+        flex-direction: column;
+        align-items: center;
+        gap: 20px;
+
+        .finish-summary {
+            display: flex;
+            gap: 32px;
+            padding: 16px 32px;
+            background: #F5F7FA;
+            border-radius: 8px;
+            border: 1px solid #E4E7ED;
+
+            .summary-item {
+                display: flex;
+                flex-direction: column;
+                align-items: center;
+                gap: 6px;
+
+                .label {
+                    font-size: 13px;
+                    color: #909399;
+                }
+
+                .value {
+                    font-size: 20px;
+                    font-weight: 600;
+                    color: #303133;
+
+                    &.highlight {
+                        color: #67C23A;
+                        font-size: 24px;
+                    }
+                }
+            }
+        }
+    }
 }
 
-@keyframes typing {
+/* 动画 */
+@keyframes rotate {
     from {
-        width: 0
+        transform: rotate(0deg);
     }
-
     to {
-        width: 100%
+        transform: rotate(360deg);
     }
 }
 
-@keyframes blink-caret {
+/* 滚动条样式 */
+.feedback-content::-webkit-scrollbar {
+    width: 8px;
+}
 
-    from,
-    to {
-        border-color: transparent
+.feedback-content::-webkit-scrollbar-track {
+    background: #f1f1f1;
+    border-radius: 4px;
+}
+
+.feedback-content::-webkit-scrollbar-thumb {
+    background: #c1c1c1;
+    border-radius: 4px;
+
+    &:hover {
+        background: #a8a8a8;
+    }
+}
+
+/* 响应式设计 */
+@media (max-width: 1200px) {
+    .answer-content {
+        grid-template-columns: 1fr !important;
+    }
+}
+
+@media (max-width: 768px) {
+    .gpsren-container {
+        padding: 16px;
     }
 
-    50% {
-        border-color: orange
+    .goal-card,
+    .steps-wrapper,
+    .answer-card {
+        padding: 20px;
+    }
+
+    .action-buttons {
+        flex-direction: column;
+
+        .action-btn {
+            width: 100%;
+        }
     }
 }
 </style>

+ 51 - 27
src/views/common/footer-common.vue

@@ -21,38 +21,62 @@ export default {
 };
 </script>
 
-<style type="less" scoped>
+<style lang="scss" scoped>
+.footer {
+  background: linear-gradient(135deg, #2c3e50 0%, #34495e 100%);
+  text-align: center;
+  color: #fff;
+  padding: 24px 0;
+  position: relative;
+  z-index: 10;
+
+  .container {
+    display: flex;
+    justify-content: center;
+    align-items: center;
+    flex-direction: column;
+  }
+
+  .gg {
+    font-size: 14px;
+    color: rgba(255, 255, 255, 0.7);
+    padding: 8px 16px;
+    letter-spacing: 1px;
+  }
+
+  p {
+    font-size: 14px;
+    color: rgba(255, 255, 255, 0.5);
+    margin-top: 8px;
+  }
+
   .el-link {
-    margin-left: 10px;
-    font-size: 18px;
+    margin-left: 16px;
+    font-size: 14px;
+    color: rgba(255, 255, 255, 0.7);
+    transition: all 0.3s ease;
+
+    &:hover {
+      color: #409EFF;
+      transform: translateY(-2px);
+    }
   }
+}
+
+// 响应式设计
+@media (max-width: 768px) {
   .footer {
-    background-color: #333;
-    text-align: center;
-    color: #fff;
-    /* padding: 25px 0; */
-    position: absolute;
-    bottom: 0;
-    height: 50px;
-    width: 100%;
-    .container{
-      display: flex;
-      justify-content: center;
-      align-items: center;
-      background-position: right top;
-      background-size: cover;
-      margin-top: .75rem;
-      .gg{
-        padding: 0.05rem .1rem;
-        font-size: 14px;
-      }
-    }
-    div {
-      font-size: 18px;
+    padding: 16px 0;
+
+    .gg {
+      font-size: 13px;
+      padding: 6px 12px;
     }
+
     p {
-      font-size: 22px;
-      font-weight: 200;
+      font-size: 13px;
+      margin-top: 6px;
     }
   }
+}
 </style>

+ 88 - 49
src/views/common/header-common.vue

@@ -299,54 +299,76 @@ export default {
 </script>
 <style lang="less" scoped>
 .el-dropdown-link {
-  width: 50px;
   cursor: pointer;
-  color: aliceblue;
+  color: #fff;
+  display: flex;
+  align-items: center;
+  gap: 8px;
+  padding-right: 24px;
+  font-size: 14px;
+  font-weight: 500;
 
   img {
-    width: 32px;
-    height: 32px;
-    display: inline-block;
-    vertical-align: middle;
+    width: 34px;
+    height: 34px;
+    border-radius: 50%;
+    object-fit: cover;
+    border: 2px solid rgba(255, 255, 255, 0.6);
+    box-shadow: 0 2px 8px rgba(0, 0, 0, 0.15);
+  }
+
+  .el-icon-arrow-down {
+    font-size: 12px;
+    opacity: 0.8;
   }
 }
 
 .header {
-  // height: 100px;
-  background-color: #7898F4;
+  background: linear-gradient(135deg, #1a6fd4 0%, #3B70FF 50%, #5b8fff 100%);
   margin: 0 auto;
   position: relative;
   display: flex;
   align-items: center;
+  height: 64px;
+  box-shadow: 0 4px 20px rgba(59, 112, 255, 0.35);
+
+  &::after {
+    content: '';
+    position: absolute;
+    bottom: 0;
+    left: 0;
+    right: 0;
+    height: 1px;
+    background: linear-gradient(90deg, transparent, rgba(255,255,255,0.3), transparent);
+  }
 
   .el-dropdown {
     position: absolute;
     right: 0;
-    // top: 35px;
-    // height: 36px;
-    // line-height: 36px;
     cursor: pointer;
+    display: flex;
+    align-items: center;
+    height: 100%;
+    transition: background 0.2s;
 
-    .cp {
-      font-size: 36px;
-      color: #009CDE;
-      padding-right: 5px;
-      vertical-align: middle;
+    &:hover {
+      background: rgba(255, 255, 255, 0.08);
     }
   }
 
   .systemtitle {
-    width: 250px;
-    // height: 100%;
-    ;
+    width: 200px;
+    flex-shrink: 0;
     overflow: hidden;
-    // padding-left: 20px;
-    // padding-top: 20px;
-    // padding-bottom: 10px;
+    padding-left: 20px;
+    display: flex;
+    align-items: center;
 
     img {
       width: 100%;
-      height: 100%;
+      height: auto;
+      max-height: 44px;
+      object-fit: contain;
     }
   }
 
@@ -355,68 +377,85 @@ export default {
     left: 50%;
     top: 50%;
     transform: translate(-50%, -50%);
+    margin-left: 80px;
     display: flex;
-    border: 1px solid #52565a;
-    border-radius: 16px;
+    border-radius: 24px;
     overflow: visible;
-    background: aliceblue;
+    background: rgba(255, 255, 255, 0.12);
+    border: 1px solid rgba(255, 255, 255, 0.25);
+    backdrop-filter: blur(4px);
+    padding: 3px;
 
     .activeitem {
-      padding: 15px;
-      font-size: 16px;
+      padding: 7px 22px;
+      font-size: 14px;
       position: relative;
-      span{
-        color:black;
+      cursor: pointer;
+      border-radius: 20px;
+      transition: all 0.25s ease;
+
+      span {
+        color: rgba(255, 255, 255, 0.85);
+        font-weight: 500;
+        letter-spacing: 0.5px;
+        transition: color 0.2s;
       }
 
       &:first-child {
-        border-radius: 16px 0 0 16px
+        border-radius: 20px;
       }
 
       &:last-child {
-        border-radius: 0 16px 16px 0
+        border-radius: 20px;
       }
 
       .itemli {
         width: 94px;
         position: absolute;
         left: 0;
-        top: 51px;
+        top: 44px;
         z-index: 111;
         display: none;
+        background: #fff;
+        border-radius: 8px;
+        box-shadow: 0 8px 24px rgba(59, 112, 255, 0.2);
+        overflow: hidden;
 
         li {
           width: 100%;
-          padding: 15px;
-          color: #cbddf7
-        }
-
-        li:hover {
-          color: #cbddf7;
+          padding: 12px 16px;
+          color: #3B70FF;
+          font-size: 13px;
+          transition: background 0.2s;
+
+          &:hover {
+            background: #f0f5ff;
+          }
         }
       }
     }
 
     .active {
-      background-color: #cbddf7;
-      // color: #fff;
-      span{
-        color: #3B70FF;
+      background: rgba(255, 255, 255, 0.28);
+      box-shadow: 0 2px 10px rgba(0, 0, 0, 0.1);
+
+      span {
+        color: #fff;
+        font-weight: 600;
       }
     }
 
     .activeitem:hover {
-      background-color: #cbddf7;
-      color: #fff;
-      cursor: pointer;
+      background: rgba(255, 255, 255, 0.2);
+
+      span {
+        color: #fff;
+      }
 
       .itemli {
         display: block;
-        background-color: #fff;
-        border-radius: 0 0 6px 6px;
       }
     }
   }
-
 }
 </style>

+ 13 - 5
src/views/common/main-common.vue

@@ -29,12 +29,20 @@
   }
 </script>
 
-<style scoped>
-
-.main{ 
-  margin: auto;
-  height: calc(100% - 150px);
+<style lang="scss" scoped>
+.main { 
+  margin: 0 auto;
+  min-height: calc(100vh - 160px);
+  padding: 24px 0;
   overflow: auto;
+  background: #f5f7fa;
 }
 
+// 响应式设计
+@media (max-width: 768px) {
+  .main { 
+    padding: 16px 0;
+    min-height: calc(100vh - 140px);
+  }
+}
 </style>

+ 203 - 187
src/views/course/courses.vue

@@ -713,20 +713,166 @@ export default {
 </script>
 
 <style lang="scss" scoped>
+.container {
+  padding: 24px;
+  background: linear-gradient(135deg, #f0f4ff 0%, #f5f7fa 100%);
+  min-height: 100vh;
+}
+
+.learnstyle-page {
+  padding: 24px;
+  background: linear-gradient(135deg, #f0f4ff 0%, #f5f7fa 100%);
+  min-height: 100vh;
+  max-width: 1400px;
+  margin: 0 auto;
+}
+
+// 顶部标题栏
+.assess-tips {
+  background: #fff;
+  border-radius: 16px;
+  padding: 20px 24px;
+  margin-bottom: 20px;
+  border: 1px solid #e8eeff;
+  box-shadow: 0 4px 20px rgba(59, 112, 255, 0.08);
+
+  .col-1 {
+    display: flex;
+    justify-content: space-between;
+    align-items: center;
+
+    span {
+      font-size: 17px;
+      font-weight: 600;
+      color: #1a2a4a;
+      letter-spacing: 0.3px;
+    }
+
+    .el-button {
+      background: linear-gradient(135deg, #3B70FF 0%, #5b8fff 100%);
+      border: none;
+      color: #fff;
+      border-radius: 8px;
+      padding: 9px 22px;
+      font-size: 14px;
+      font-weight: 500;
+      box-shadow: 0 4px 12px rgba(59, 112, 255, 0.3);
+      transition: all 0.25s;
+
+      &:hover {
+        transform: translateY(-1px);
+        box-shadow: 0 6px 16px rgba(59, 112, 255, 0.4);
+      }
+    }
+  }
+}
+
+// 课程分类标签
+.category_name {
+  display: flex;
+  flex-wrap: wrap;
+  gap: 10px;
+  padding: 8px 0;
+
+  .elTag {
+    cursor: pointer;
+    height: 32px;
+    line-height: 30px;
+    padding: 0 16px;
+    border-radius: 16px;
+    font-size: 13px;
+    font-weight: 500;
+    transition: all 0.25s ease;
+    display: inline-flex;
+    align-items: center;
+    justify-content: center;
+
+    &:hover {
+      transform: translateY(-2px);
+      box-shadow: 0 4px 12px rgba(59, 112, 255, 0.25);
+    }
+  }
+
+  ::v-deep .el-tag--success {
+    background: linear-gradient(135deg, #3B70FF 0%, #5b8fff 100%);
+    border: none;
+    color: #fff;
+    box-shadow: 0 2px 8px rgba(59, 112, 255, 0.35);
+  }
+
+  ::v-deep .el-tag--info {
+    background: #fff;
+    border: 1px solid #dce4f5;
+    color: #606266;
+
+    &:hover {
+      border-color: #3B70FF;
+      color: #3B70FF;
+    }
+  }
+}
 
-::v-deep th {
-  color: #303133 !important;
+// 表格样式
+.list-data {
+  background: #fff;
+  border-radius: 16px;
+  border: 1px solid #e8eeff;
+  box-shadow: 0 4px 20px rgba(59, 112, 255, 0.08);
+  overflow: hidden;
 }
 
-.el-dialog__header {
-    background-color: #477efa !important;
-    color: aliceblue !important;
+.list-header {
+  padding: 16px 20px;
+  border-bottom: 1px solid #f0f4ff;
+  background: linear-gradient(135deg, #f8faff 0%, #f0f4ff 100%);
+
+  .top {
+    min-height: 40px;
+    display: flex;
+    align-items: center;
+  }
 }
 
-.el-dialog__close {
-    color: aliceblue !important;
+// 表格样式
+.table-body {
+  background: #fff;
+  overflow: hidden;
+
+  ::v-deep .el-table {
+    font-size: 14px;
+
+    .el-table__header-wrapper {
+      background: #f8faff;
+    }
+
+    th {
+      color: #1a2a4a;
+      font-weight: 600;
+      padding: 14px 0;
+      background: #f8faff;
+    }
+
+    td {
+      padding: 13px 0;
+    }
+
+    .cell {
+      color: #606266;
+    }
+
+    .el-button--text {
+      color: #3B70FF;
+      font-size: 14px;
+      font-weight: 500;
+
+      &:hover {
+        color: #5b8fff;
+      }
+    }
+  }
 }
 
+// 选课对话框
 .course-selection-dialog {
   height: calc(100% - 50px);
   display: flex;
@@ -735,17 +881,17 @@ export default {
   .el-dialog__body {
     flex: 1;
     overflow-y: hidden;
-    padding: 10px 20px 20px;
+    padding: 20px;
   }
 }
 
 .course-selection-container {
-  height: calc(100vh - 150px); // 减去对话框标题和其他元素的高度
+  height: calc(100vh - 150px);
   display: flex;
   flex-direction: column;
   overflow: hidden;
   padding: 20px;
-  max-width: 1200px;
+  max-width: 1400px;
   margin: 0 auto;
 }
 
@@ -756,63 +902,46 @@ export default {
 
 .flex-item {
   flex: 1;
-  min-height: 0; // 允许项目收缩
+  min-height: 0;
 }
 
-.selection-header {
-  flex-shrink: 0; // 不收缩
-  text-align: center;
-  margin-bottom: 20px;
-  padding-bottom: 15px;
-  border-bottom: 1px solid #eee;
-
-  .header-title {
-    h2 {
-      color: #303133;
-      margin-bottom: 8px;
-      font-size: 20px;
-    }
+.section-title {
+  font-size: 15px;
+  font-weight: 600;
+  color: #1a2a4a;
+  margin-bottom: 16px;
+  display: flex;
+  align-items: center;
+  padding: 10px 16px;
+  background: linear-gradient(135deg, #f8faff 0%, #f0f4ff 100%);
+  border-radius: 8px;
+  border-left: 4px solid #3B70FF;
 
-    p {
-      color: #909399;
-      font-size: 14px;
-    }
+  i {
+    margin-right: 10px;
+    color: #3B70FF;
+    font-size: 16px;
   }
 }
 
 .cascader-section {
-  flex-shrink: 0; // 不收缩
   margin-bottom: 20px;
-  padding: 15px;
-  background: #f5f7fa;
+  padding: 16px;
+  background: #fff;
   border-radius: 8px;
+  box-shadow: 0 2px 12px rgba(0, 0, 0, 0.06);
 }
 
 .courses-section {
-  flex: 1; // 占据剩余空间
-  min-height: 0; // 允许收缩
+  flex: 1;
+  min-height: 0;
   display: flex;
   flex-direction: column;
-  padding: 15px;
+  padding: 16px;
   background: #fff;
   border-radius: 8px;
-  box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.1);
+  box-shadow: 0 2px 12px rgba(0, 0, 0, 0.06);
   overflow: hidden;
-
-}
-
-.section-title {
-  font-size: 18px;
-  font-weight: 500;
-  color: #606266;
-  margin-bottom: 15px;
-  display: flex;
-  align-items: center;
-
-  i {
-    margin-right: 8px;
-    color: #409EFF;
-  }
 }
 
 .courses-table-wrapper {
@@ -822,7 +951,7 @@ export default {
   flex-direction: column;
   overflow: hidden;
   border: 1px solid #ebeef5;
-  border-radius: 4px;
+  border-radius: 8px;
 
   .adaptive-table {
     flex: 1;
@@ -843,22 +972,22 @@ export default {
 
 // 表格滚动条美化
 .courses-table-wrapper .el-table__body-wrapper::-webkit-scrollbar {
-  width: 6px;
-  height: 6px;
+  width: 8px;
+  height: 8px;
 }
 
 .courses-table-wrapper .el-table__body-wrapper::-webkit-scrollbar-track {
   background: #f1f1f1;
-  border-radius: 3px;
+  border-radius: 4px;
 }
 
 .courses-table-wrapper .el-table__body-wrapper::-webkit-scrollbar-thumb {
   background: #c1c1c1;
-  border-radius: 3px;
-}
+  border-radius: 4px;
 
-.courses-table-wrapper .el-table__body-wrapper::-webkit-scrollbar-thumb:hover {
-  background: #a8a8a8;
+  &:hover {
+    background: #a8a8a8;
+  }
 }
 
 .no-courses {
@@ -866,151 +995,38 @@ export default {
   display: flex;
   align-items: center;
   justify-content: center;
+  padding: 60px 20px;
 }
 
 .course-name {
-  font-weight: 500;
+  font-weight: 600;
   color: #303133;
+  font-size: 15px;
 }
 
 .course-description {
-  color: #606266;
+  color: #909399;
   font-size: 14px;
+  line-height: 1.6;
 }
 
-.no-courses {
-  text-align: center;
-  padding: 40px 0;
-}
-
-.dialog-footer {
-  text-align: right;
-  padding: 20px;
-  border-top: 1px solid #eee;
-}
-
-.homewort-part {
-  .assess-tips {
-    background-color: aliceblue;
-    border-radius: 5px;
-    padding: 10px;
+// 响应式设计
+@media (max-width: 768px) {
+  .container {
+    padding: 16px;
   }
-}
 
-.list-data {
-  .list-header {
-    .top {
-      margin-top: 10px;
-      padding: 10px;
-      font-size: 14px;
-    }
+  .assess-tips {
+    padding: 16px;
   }
-}
-
-.category_name {
-  display: flex;
-  justify-content: flex-start;
-  gap: 10px;
-  flex-wrap: wrap;
-}
 
-.elTag {
-  cursor: pointer;
-}
-
-.learnstyle-page {
-  // background-color: aliceblue;
-  height: 100%;
-  max-width: 1200px;
-}
-
-.demoList ul {
-  width: 100%;
-  box-sizing: border-box;
-  margin-bottom: 100px;
-}
-
-.demoList {
-  padding-top: 30px;
-}
-
-.course_detail {
-  padding-top: 6px;
-  max-height: 48px;
-  line-height: 20px;
-  display: -webkit-box;
-  -webkit-line-clamp: 2;
-  -webkit-box-orient: vertical;
-  overflow: hidden;
-  font-size: 14px;
-  color: #93999f
-}
-
-.demoList li {
-  box-sizing: border-box;
-  width: 192px;
-  min-height: 160px;
-  float: left;
-  margin-right: 40px;
-  margin-bottom: 30px;
-  text-align: left;
-
-  img {
-    cursor: pointer;
-    width: 100%;
-    height: 108px;
-    display: block;
-    border-radius: 8px;
-
-    &:hover {
-      opacity: 0.7;
-    }
+  .category_name {
+    gap: 8px;
   }
-}
-
-.typeitem {
-  cursor: pointer;
-  width: 300px;
-
-  .title {
-    padding-top: 8px;
-    font-weight: bold;
 
-    &:hover {
-      cursor: pointer;
-      color: red;
-    }
+  .elTag {
+    padding: 6px 16px;
+    font-size: 14px;
   }
 }
-
-.demoList li {
-  width: 30%;
-}
-
-.demoList .page {
-  position: relative;
-  left: 0;
-  bottom: 50px;
-  width: 100%;
-  text-align: center;
-}
-
-.demoList li .image {
-  height: 199px;
-  width: 100%;
-  display: block;
-}
-
-.top .item {
-  margin-left: 20px;
-}
-
-.grid-head {
-  margin-bottom: 30px;
-}
-
-.col-1 {
-  width: 100%;
-  color: #999;
-}
 </style>

+ 145 - 73
src/views/education/exam.vue

@@ -157,95 +157,167 @@
 </script>
 
 
-<style scoped>
-
-  .el-row .box-card {
-    width: 30% !important;
-    display: inline-block !important;
-    margin: 15px !important;
-  }
-
-  .no_data {
-    margin-top: 40px;
-    line-height: 300px;
-    text-align: center;
-    font-size: 20px;
-    color: rgb(155, 155, 155);
-  }
-  .exam_list {
-    width: 100%;
-    min-height: 300px;
-    display: inline-block;
+<style lang="scss" scoped>
+.container {
+  padding: 24px;
+  background-color: #f5f7fa;
+  min-height: 100vh;
+}
+
+.learnstyle-page {
+  padding: 24px;
+  background-color: #f5f7fa;
+  min-height: 100vh;
+}
+
+// 顶部科目筛选
+.subject {
+  margin-bottom: 24px;
+  
+  #nav {
+    display: flex;
+    flex-wrap: wrap;
+    gap: 12px;
+    align-items: center;
   }
 
-  .el-pagination {
-    margin-top: 25px;
-    text-align: center;
+  .on {
+    background: linear-gradient(135deg, rgba(64, 158, 255, 0.15) 0%, rgba(64, 158, 255, 0.05) 100%);
+    color: #409EFF;
+    border-radius: 20px;
+    border: 1px solid rgba(64, 158, 255, 0.2);
   }
 
-  .subject .on {
-    background: rgba(204,136,0,.1);
-    color: #c80;
-  }
-
-  .subject a {
+  a {
     font-size: 15px;
     line-height: 40px;
-    min-width: 60px;
-    padding: 0 15px;
-    margin-top: 10px;
-    margin-right: 25px;
+    min-width: 70px;
+    padding: 0 20px;
     float: left;
-  }
-
-  .subject a:hover {
+    border-radius: 20px;
+    transition: all 0.3s ease;
     cursor: pointer;
-    background: rgba(204,136,0,.1);
-    color: #c80;
+    color: #606266;
+    background-color: #fff;
+    border: 1px solid #DCDFE6;
+
+    &:hover {
+      background: linear-gradient(135deg, rgba(64, 158, 255, 0.1) 0%, rgba(64, 158, 255, 0.02) 100%);
+      color: #409EFF;
+      border-color: rgba(64, 158, 255, 0.3);
+      transform: translateY(-2px);
+      box-shadow: 0 4px 12px rgba(64, 158, 255, 0.15);
+    }
   }
+}
+
+// 测评列表卡片
+.exam_list {
+  display: grid;
+  grid-template-columns: repeat(auto-fill, minmax(320px, 1fr));
+  gap: 20px;
+  padding: 10px 0;
+
+  .box-card {
+    border-radius: 12px;
+    transition: all 0.3s ease;
+    border: none;
+    box-shadow: 0 2px 12px rgba(0, 0, 0, 0.08);
+
+    &:hover {
+      transform: translateY(-4px);
+      box-shadow: 0 8px 24px rgba(64, 158, 255, 0.15);
+    }
 
-  .paper {
-    cursor: pointer;
-  }
-  .el-button {
-    font-size: 12px;
-  }
-  .title {
-    font-weight: 700;
-    font-size: 16px;
+    .clearfix {
+      padding-bottom: 16px;
+      border-bottom: 1px solid #EBEEF5;
+      
+      span {
+        font-size: 18px;
+        font-weight: 600;
+        color: #303133;
+      }
+    }
+
+    .text {
+      font-size: 14px;
+      color: #606266;
+      margin-bottom: 8px;
+      padding-bottom: 8px;
+      border-bottom: 1px dashed #EBEEF5;
+
+      &:last-child {
+        border-bottom: none;
+        margin-bottom: 0;
+        padding-bottom: 0;
+      }
+
+      i {
+        margin-right: 6px;
+        color: #909399;
+      }
+    }
+
+    .el-tag {
+      font-size: 13px;
+      padding: 4px 10px;
+      border-radius: 6px;
+    }
+
+    .el-button {
+      font-size: 14px;
+      padding: 8px 16px;
+      color: #409EFF;
+      
+      &:hover {
+        color: #66b1ff;
+        background-color: rgba(64, 158, 255, 0.05);
+      }
+    }
   }
-  .paper a:hover {
-    color: #11a68d;
+}
+
+// 无数据状态
+.no_data {
+  margin-top: 60px;
+  padding: 60px 20px;
+  text-align: center;
+  font-size: 16px;
+  color: #909399;
+  background-color: #fff;
+  border-radius: 12px;
+  box-shadow: 0 2px 12px rgba(0, 0, 0, 0.06);
+
+  i {
+    font-size: 48px;
+    margin-bottom: 16px;
+    color: #C0C4CC;
   }
-
-  .el-table {
-    top: 15px;
+}
+
+// 分页器
+.el-pagination {
+  margin-top: 32px;
+  text-align: center;
+  padding: 20px 0;
+}
+
+// 响应式设计
+@media (max-width: 768px) {
+  .container {
+    padding: 16px;
   }
 
-  .top .item {
-    margin-left: 20px;
-  }
-  .text {
+  .subject a {
+    min-width: 50px;
+    padding: 0 12px;
     font-size: 14px;
   }
 
-  .item {
-    margin-bottom: 5px;
-    padding-bottom: 5px;
-  }
-  .clearfix:before,
-  .clearfix:after {
-    display: table;
-    content: "";
-  }
-  .clearfix:after {
-    clear: both
-  }
-  .grid-head{margin-bottom: 30px;}
-  .grid-content-right{text-align: right;color:#24794b;}
-  .grid-content-right:hover {
-    color: #3a8ee6;
-    cursor: pointer;
+  .exam_list {
+    grid-template-columns: 1fr;
+    gap: 16px;
   }
-  .grid-content-left{text-align: left;color:#24794b;}
+}
 </style>

+ 534 - 964
src/views/education/wrongBook.vue

@@ -1,383 +1,215 @@
 <template>
-  <div class="container learnstyle-page">
-    <!-- 学生信息概览 -->
-    <el-row :gutter="20" class="overview-section">
-      <!-- 学生基本信息卡片 -->
-      <el-col :xs="24" :sm="24" :md="16" :lg="16" :xl="16">
-        <el-card class="student-info-card" shadow="hover">
-          <div class="student-basic-info" @click="showLearningChart">
-            <div class="avatar-section">
-              <el-avatar :size="90" :src="studentInfo.avatar" class="student-avatar"></el-avatar>
-              <div class="online-status"></div>
+  <div class="learnstyle-page">
+
+    <!-- 顶部个人信息横幅 -->
+    <div class="profile-banner">
+      <div class="banner-content">
+        <div class="avatar-wrap">
+          <el-avatar :size="76" :src="studentInfo.avatar" class="student-avatar"></el-avatar>
+          <div class="online-dot"></div>
+        </div>
+        <div class="profile-info">
+          <div class="profile-name">
+            {{ studentInfo.name }}
+            <span class="grade-badge" v-if="studentInfo.grade">{{ studentInfo.grade }}</span>
+          </div>
+          <div class="profile-meta">
+            <i class="el-icon-mobile-phone"></i> {{ studentInfo.studentId }}
+          </div>
+        </div>
+        <div class="profile-stats">
+          <div class="pstat-item">
+            <div class="pstat-value">{{ studentInfo.totalStudyHours }}</div>
+            <div class="pstat-label">总学时(h)</div>
+          </div>
+          <div class="pstat-divider"></div>
+          <div class="pstat-item">
+            <div class="pstat-value">{{ studentInfo.studyDays }}</div>
+            <div class="pstat-label">学习天数</div>
+          </div>
+          <div class="pstat-divider"></div>
+          <div class="pstat-item">
+            <div class="pstat-value">{{ weeklyStats.goalCompletion }}%</div>
+            <div class="pstat-label">本周完成率</div>
+          </div>
+          <div class="pstat-divider"></div>
+          <div class="pstat-item">
+            <div class="pstat-value">82%</div>
+            <div class="pstat-label">平均效率</div>
+          </div>
+        </div>
+      </div>
+    </div>
+
+    <!-- 主体内容 -->
+    <el-row :gutter="20" class="main-section">
+
+      <!-- 左侧边栏 -->
+      <el-col :xs="24" :sm="24" :md="7" :lg="7">
+
+        <!-- 本周概览 -->
+        <div class="side-card">
+          <div class="side-card-header">
+            <i class="el-icon-data-analysis"></i>
+            <span>本周学习概览</span>
+          </div>
+          <div class="side-card-body">
+            <div class="week-stat-row">
+              <div class="week-stat-icon" style="background:rgba(59,112,255,0.1)">
+                <i class="el-icon-timer" style="color:#3B70FF"></i>
+              </div>
+              <div class="week-stat-text">
+                <span class="week-stat-label">本周学习时长</span>
+                <span class="week-stat-value">{{ weeklyStats.week }} 小时</span>
+              </div>
             </div>
-            <div class="info-section">
-              <h2>{{ studentInfo.name }} <span class="grade-tag">{{ studentInfo.grade }}</span></h2>
-              <p class="student-id"><i class="el-icon-user"></i> 联系方式: {{ studentInfo.studentId }}</p>
+            <div class="week-stat-row">
+              <div class="week-stat-icon" style="background:rgba(82,196,26,0.1)">
+                <i class="el-icon-flag" style="color:#52c41a"></i>
+              </div>
+              <div class="week-stat-text">
+                <span class="week-stat-label">目标完成率</span>
+                <el-progress
+                  :percentage="weeklyStats.goalCompletion"
+                  :stroke-width="7"
+                  status="success"
+                  :format="formatProgress"
+                  class="week-progress">
+                </el-progress>
+              </div>
             </div>
-            <div class="stats-section">
-              <div class="stat-item">
-                <div class="stat-icon">
-                  <i class="el-icon-time"></i>
-                </div>
-                <div class="stat-content">
-                  <el-tag type="primary" class="stat-tag">{{ studentInfo.totalStudyHours }}小时</el-tag>
-                  <span class="stat-label">总学习时长</span>
-                </div>
+            <div class="week-stat-row">
+              <div class="week-stat-icon" style="background:rgba(250,140,22,0.1)">
+                <i class="el-icon-star-off" style="color:#fa8c16"></i>
               </div>
-              <div class="stat-item">
-                <div class="stat-icon">
-                  <i class="el-icon-data-line"></i>
-                </div>
-                <div class="stat-content">
-                  <el-tag type="success" class="stat-tag">{{ studentInfo.studyDays }}天</el-tag>
-                  <span class="stat-label">学习天数</span>
-                </div>
+              <div class="week-stat-text">
+                <span class="week-stat-label">本周平均效率</span>
+                <span class="week-stat-value">82%</span>
               </div>
             </div>
           </div>
-        </el-card>
-        <!-- 新增:学习提醒卡片 -->
-        <el-card class="reminder-card" shadow="hover" style="margin-top: 20px;">
-          <div slot="header">
-            <span><i class="el-icon-bell"></i> 学习提醒</span>
+        </div>
+
+        <!-- 学习提醒 -->
+        <div class="side-card" style="margin-top:16px">
+          <div class="side-card-header">
+            <i class="el-icon-bell"></i>
+            <span>学习提醒</span>
           </div>
-          <div class="reminder-content">
+          <div class="side-card-body">
             <div class="reminder-item">
-              <i class="el-icon-warning-outline reminder-icon"></i>
+              <div class="reminder-dot"></div>
               <span>实现一个基于二叉树的表达式求值器</span>
             </div>
             <div class="reminder-item">
-              <i class="el-icon-warning-outline reminder-icon"></i>
+              <div class="reminder-dot"></div>
               <span>在一个n*n的二维迷宫中,求从出口到入口的最短路径</span>
             </div>
-            <!-- <div class="reminder-item">
-              <i class="el-icon-warning-outline reminder-icon"></i>
-              <span>物理实验报告:下周一</span>
-            </div> -->
           </div>
-        </el-card>
-      </el-col>
+        </div>
 
-      <!-- 快捷统计卡片 -->
-      <el-col :xs="24" :sm="24" :md="8" :lg="8" :xl="8" style="height: 518px">
-        <el-card class="quick-stats-card" shadow="hover">
-          <div slot="header" class="clearfix">
-            <span><i class="el-icon-data-analysis"></i> 本周学习概览</span>
+        <!-- 本月汇总 -->
+        <div class="side-card" style="margin-top:16px">
+          <div class="side-card-header">
+            <i class="el-icon-s-data"></i>
+            <span>本月汇总</span>
           </div>
-          <div class="quick-stats-content">
-            <!-- <div class="stat-row">
-              <div class="stat-icon-wrapper">
-                <i class="el-icon-sunny"></i>
+          <div class="side-card-body">
+            <div class="month-stat-item">
+              <div class="month-stat-icon" style="background:#e8f4ff">
+                <i class="el-icon-time" style="color:#1890ff"></i>
               </div>
-              <div class="stat-text">
-                <span class="stat-title">今日学习时长</span>
-                <span class="stat-value highlight">{{ weeklyStats.today }}小时</span>
-              </div>
-            </div> -->
-            <div class="stat-row">
-              <div class="stat-icon-wrapper">
-                <i class="el-icon-timer"></i>
-              </div>
-              <div class="stat-text">
-                <span class="stat-title">本周学习时长</span>
-                <span class="stat-value">{{ weeklyStats.week }}小时</span>
+              <div>
+                <div class="month-stat-label">总时长</div>
+                <div class="month-stat-value">2.5 小时</div>
               </div>
             </div>
-            <!-- <div class="stat-row">
-              <div class="stat-icon-wrapper">
-                <i class="el-icon-refresh"></i>
-              </div>
-              <div class="stat-text">
-                <span class="stat-title">学习连续天数</span>
-                <span class="stat-value">{{ weeklyStats.streak }}天</span>
+            <div class="month-stat-item">
+              <div class="month-stat-icon" style="background:#f0fff4">
+                <i class="el-icon-star-off" style="color:#52c41a"></i>
               </div>
-            </div> -->
-            <div class="stat-row">
-              <div class="stat-icon-wrapper">
-                <i class="el-icon-flag"></i>
-              </div>
-              <div class="stat-text">
-                <span class="stat-title">本周目标完成率</span>
-                <el-progress
-                  :percentage="weeklyStats.goalCompletion"
-                  :stroke-width="12"
-                  status="success"
-                  :format="formatProgress">
-                </el-progress>
+              <div>
+                <div class="month-stat-label">平均效率</div>
+                <div class="month-stat-value">77.7%</div>
               </div>
             </div>
-
-            <!-- 新增:学习效率统计 -->
-            <div class="stat-row efficiency-row">
-              <div class="stat-icon-wrapper">
-                <i class="el-icon-star-off"></i>
+            <div class="month-stat-item">
+              <div class="month-stat-icon" style="background:#fff8e6">
+                <i class="el-icon-trophy" style="color:#fa8c16"></i>
               </div>
-              <div class="stat-text">
-                <span class="stat-title">本周平均效率</span>
-                <span class="stat-value">82%</span>
+              <div>
+                <div class="month-stat-label">最佳科目</div>
+                <div class="month-stat-value">数据结构与算法</div>
               </div>
             </div>
           </div>
-        </el-card>
+        </div>
+
       </el-col>
-    </el-row>
 
-    <!-- 学习记录区域 -->
-    <el-row :gutter="20">
-      <el-col :span="24">
-        <el-card class="study-records-card" shadow="hover">
-          <div slot="header" class="clearfix">
-            <span><i class="el-icon-notebook-2"></i> 学习记录</span>
-            <!-- <div style="float: right;">
-              <el-button type="primary" size="mini" @click="showLearningChart" plain>
-                <i class="el-icon-data-line"></i> 学习趋势
-              </el-button>
-              <el-button type="success" size="mini" @click="showSubjectsChart" plain>
-                <i class="el-icon-pie-chart"></i> 科目统计
-              </el-button>
-              <el-button type="warning" size="mini" @click="exportRecords" plain>
-                <i class="el-icon-download"></i> 导出记录
-              </el-button>
-            </div> -->
+      <!-- 右侧:学习记录时间轴 -->
+      <el-col :xs="24" :sm="24" :md="17" :lg="17">
+        <div class="records-card">
+          <div class="records-header">
+            <div class="records-title">
+              <i class="el-icon-notebook-2"></i>
+              <span>学习记录</span>
+            </div>
+            <span class="records-count">共 {{ learningRecords.length }} 条</span>
           </div>
-
-          <!-- 新增:筛选条件 -->
-          <!-- <div class="filter-section">
-            <el-row :gutter="15">
-              <el-col :span="6">
-                <el-select v-model="filterSubject" placeholder="选择科目" size="small" clearable>
-                  <el-option label="全部科目" value=""></el-option>
-                  <el-option label="数学" value="数学"></el-option>
-                  <el-option label="英语" value="英语"></el-option>
-                  <el-option label="物理" value="物理"></el-option>
-                  <el-option label="化学" value="化学"></el-option>
-                  <el-option label="语文" value="语文"></el-option>
-                </el-select>
-              </el-col>
-              <el-col :span="10">
-                <el-date-picker
-                  v-model="filterDateRange"
-                  type="daterange"
-                  range-separator="至"
-                  start-placeholder="开始日期"
-                  end-placeholder="结束日期"
-                  size="small"
-                  clearable>
-                </el-date-picker>
-              </el-col>
-              <el-col :span="8">
-                <el-button type="primary" size="small" @click="applyFilter">筛选</el-button>
-                <el-button size="small" @click="resetFilter">重置</el-button>
-              </el-col>
-            </el-row>
-          </div> -->
-
-          <el-table
-            :data="learningRecords"
-            style="width: 100%"
-            stripe
-            class="learning-table"
-            :header-cell-style="{background: '#f5f7fa', color: '#606266'}">
-            <el-table-column prop="date" label="日期" width="120" align="center">
-              <template slot-scope="scope">
-                <div class="date-cell">
-                  <i class="el-icon-date"></i>
-                  <span>{{ scope.row.date }}</span>
-                </div>
-              </template>
-            </el-table-column>
-            <el-table-column prop="startTime" label="开始时间" width="100" align="center"></el-table-column>
-            <el-table-column prop="duration" label="学习时长" width="130" align="center">
-              <template slot-scope="scope">
-                <el-tag size="medium" type="primary" effect="dark">{{ scope.row.duration }}</el-tag>
-              </template>
-            </el-table-column>
-
-            <el-table-column prop="subject" label="知识点" width="120" align="center">
-              <template slot-scope="scope">
-                <el-tag v-for="(val,index) in scope.row.subject" :key="`c_${index}`" effect="light" class="subject-tag">
-                  {{ val }}
-                </el-tag>
-              </template>
-            </el-table-column>
-            <el-table-column prop="content" label="学习内容">
-              <template slot-scope="scope">
-                <div class="content-cell">
-                  {{ scope.row.content }}
-                  <el-tag v-if="scope.row.efficiency" size="mini" :type="scope.row.efficiency > 80 ? 'success' : scope.row.efficiency > 60 ? 'warning' : 'danger'" class="efficiency-tag">
-                    效率 {{ scope.row.efficiency }}%
-                  </el-tag>
-                </div>
-              </template>
-            </el-table-column>
-            <!-- <el-table-column label="操作" width="100" align="center">
-              <template slot-scope="scope">
-                <el-button size="mini" @click="viewDetail(scope.row)" type="text">
-                  <i class="el-icon-view"></i> 详情
-                </el-button>
-              </template>
-            </el-table-column> -->
-          </el-table>
-
-          <!-- <el-pagination
-            background
-            @current-change="handleCurrentChange"
-            :current-page="currentPage"
-            :page-size="pageSize"
-            :total="totalRecords"
-            layout="total, prev, pager, next, jumper"
-            class="pagination">
-          </el-pagination> -->
-
-          <!-- 新增:学习总结 -->
-          <div class="summary-section">
-            <el-row :gutter="20">
-              <el-col :span="8">
-                <div class="summary-item">
-                  <div class="summary-icon" style="background-color: #e6f7ff;">
-                    <i class="el-icon-time" style="color: #1890ff;"></i>
-                  </div>
-                  <div class="summary-content">
-                    <div class="summary-title">本月总时长</div>
-                    <div class="summary-value">2.5 小时</div>
-                  </div>
-                </div>
-              </el-col>
-              <el-col :span="8">
-                <div class="summary-item">
-                  <div class="summary-icon" style="background-color: #f6ffed;">
-                    <i class="el-icon-star-off" style="color: #52c41a;"></i>
+          <div class="records-body">
+            <div
+              v-for="(record, index) in learningRecords"
+              :key="index"
+              class="record-item">
+              <div class="record-timeline">
+                <div class="timeline-dot"></div>
+                <div class="timeline-line" v-if="index < learningRecords.length - 1"></div>
+              </div>
+              <div class="record-content">
+                <div class="record-top">
+                  <div class="record-date-block">
+                    <i class="el-icon-date"></i>
+                    <span class="record-date">{{ record.date }}</span>
+                    <span class="record-time">{{ record.startTime }}</span>
                   </div>
-                  <div class="summary-content">
-                    <div class="summary-title">平均效率</div>
-                    <div class="summary-value">77.7%</div>
+                  <div class="record-right">
+                    <span class="duration-badge">
+                      <i class="el-icon-time"></i>
+                      {{ record.duration }}
+                    </span>
+                    <el-tag
+                      v-if="record.efficiency"
+                      size="mini"
+                      :type="record.efficiency > 80 ? 'success' : record.efficiency > 60 ? 'warning' : 'danger'"
+                      class="efficiency-tag">
+                      效率 {{ record.efficiency }}%
+                    </el-tag>
                   </div>
                 </div>
-              </el-col>
-              <el-col :span="8">
-                <div class="summary-item">
-                  <div class="summary-icon" style="background-color: #fff7e6;">
-                    <i class="el-icon-trophy" style="color: #fa8c16;"></i>
-                  </div>
-                  <div class="summary-content">
-                    <div class="summary-title">最佳科目</div>
-                    <div class="summary-value">数据结构与算法</div>
+                <div class="record-body-content">
+                  <p class="record-text">{{ record.content }}</p>
+                  <div class="record-tags">
+                    <el-tag
+                      v-for="(tag, ti) in record.subject"
+                      :key="ti"
+                      size="mini"
+                      class="subject-tag">
+                      {{ tag }}
+                    </el-tag>
                   </div>
                 </div>
-              </el-col>
-            </el-row>
-          </div>
-        </el-card>
-      </el-col>
-    </el-row>
-
-    <!-- 学习趋势图表弹窗 -->
-    <el-dialog
-      title="学习时间趋势"
-      :visible.sync="learningChartVisible"
-      width="80%"
-      :before-close="handleChartClose"
-      class="chart-dialog"
-      top="5vh">
-      <div class="chart-header">
-        <div style="float: right;">
-          <el-radio-group v-model="chartPeriod" size="mini" @change="changeChartPeriod">
-            <el-radio-button label="week"><i class="el-icon-date"></i> 近7天</el-radio-button>
-            <el-radio-button label="month"><i class="el-icon-calendar"></i> 近30天</el-radio-button>
-            <el-radio-button label="quarter"><i class="el-icon-trend-charts"></i> 近90天</el-radio-button>
-          </el-radio-group>
-        </div>
-      </div>
-      <div id="learningChart" style="width: 100%; height: 400px; margin-top: 20px;"></div>
-      <div class="chart-summary">
-        <el-row :gutter="20">
-          <el-col :span="6">
-            <div class="summary-card">
-              <div class="summary-icon" style="background-color: #e6f7ff;">
-                <i class="el-icon-top" style="color: #1890ff;"></i>
-              </div>
-              <div class="summary-content">
-                <div class="summary-title">最高学习时长</div>
-                <div class="summary-value">4.2 小时</div>
-              </div>
-            </div>
-          </el-col>
-          <el-col :span="6">
-            <div class="summary-card">
-              <div class="summary-icon" style="background-color: #f6ffed;">
-                <i class="el-icon-bottom" style="color: #52c41a;"></i>
-              </div>
-              <div class="summary-content">
-                <div class="summary-title">最低学习时长</div>
-                <div class="summary-value">1.5 小时</div>
               </div>
             </div>
-          </el-col>
-          <el-col :span="6">
-            <div class="summary-card">
-              <div class="summary-icon" style="background-color: #fff7e6;">
-                <i class="el-icon-s-data" style="color: #fa8c16;"></i>
-              </div>
-              <div class="summary-content">
-                <div class="summary-title">平均学习时长</div>
-                <div class="summary-value">2.8 小时</div>
-              </div>
-            </div>
-          </el-col>
-          <el-col :span="6">
-            <div class="summary-card">
-              <div class="summary-icon" style="background-color: #f9f0ff;">
-                <i class="el-icon-trophy" style="color: #722ed1;"></i>
-              </div>
-              <div class="summary-content">
-                <div class="summary-title">最佳学习日</div>
-                <div class="summary-value">10月13日</div>
-              </div>
-            </div>
-          </el-col>
-        </el-row>
-      </div>
-    </el-dialog>
-
-    <!-- 科目统计图表弹窗 -->
-    <el-dialog
-      title="科目学习统计"
-      :visible.sync="subjectsChartVisible"
-      width="70%"
-      :before-close="handleSubjectsChartClose"
-      class="chart-dialog"
-      top="8vh">
-      <el-row :gutter="30">
-        <el-col :xs="24" :sm="24" :md="14" :lg="14" :xl="14">
-          <div id="subjectsChart" style="width: 100%; height: 350px;"></div>
-        </el-col>
-        <el-col :xs="24" :sm="24" :md="10" :lg="10" :xl="10">
-          <div class="subjects-list">
-            <div class="subjects-header">
-              <span>科目</span>
-              <span>学习时长</span>
-              <span>占比</span>
-            </div>
-            <div v-for="(subject, index) in subjectStats" :key="subject.name" class="subject-item">
-              <div class="subject-rank">
-                <el-tag :type="index < 3 ? 'danger' : ''" size="mini" effect="plain">
-                  {{ index + 1 }}
-                </el-tag>
-              </div>
-              <span class="subject-name">{{ subject.name }}</span>
-              <el-progress
-                :percentage="subject.percentage"
-                :stroke-width="12"
-                :show-text="false"
-                :color="getSubjectColor(index)">
-              </el-progress>
-              <span class="subject-hours">{{ subject.hours }}小时</span>
-              <span class="subject-percent">{{ subject.percentage }}%</span>
+            <div v-if="!learningRecords.length" class="empty-records">
+              <i class="el-icon-document"></i>
+              <p>暂无学习记录</p>
             </div>
           </div>
-        </el-col>
-      </el-row>
-    </el-dialog>
+        </div>
+      </el-col>
+
+    </el-row>
   </div>
 </template>
 
@@ -391,9 +223,9 @@ export default {
   data() {
     return {
       studentInfo: {
-        name: this.$store.state.user.userInfo.name,
-        studentId: this.$store.state.user.userInfo.mobile,
-        grade: this.$store.state.user.userInfo.gradeInfoName,
+        name: '',
+        studentId: '',
+        grade: '',
         enrollmentDate: '2021-09-01',
         avatar: UserAvatar,
         totalStudyHours: 2.5,
@@ -455,7 +287,17 @@ export default {
       filterDateRange: ''
     }
   },
+  mounted() {
+    this.initStudentInfo()
+  },
   methods: {
+    initStudentInfo() {
+      // Use getter so it falls back to localStorage on page refresh
+      const info = this.$store.getters['user/getUserInfo'] || {}
+      this.studentInfo.name = info.name || ''
+      this.studentInfo.studentId = info.mobile || ''
+      this.studentInfo.grade = info.gradeInfoName || ''
+    },
     showLearningChart() {
       // this.learningChartVisible = true
       // this.$nextTick(() => {
@@ -710,687 +552,415 @@ export default {
 </script>
 
 <style lang="scss" scoped>
+
+// ── 页面 ──────────────────────────────────────────────
 .learnstyle-page {
-  padding: 20px;
-  background-color: #f5f7fa;
+  padding: 24px;
+  background: linear-gradient(135deg, #f0f4ff 0%, #f5f7fa 100%);
+  min-height: 100vh;
+  max-width: 1400px;
+  margin: 0 auto;
 }
 
-.overview-section {
-  margin-bottom: 20px;
-
-  .el-col {
-    margin-bottom: 20px;
-  }
+.main-section {
+  margin-top: 20px;
 }
 
-.student-info-card {
-  height: 100%;
-  border-radius: 10px;
-  transition: all 0.3s ease;
-  border: none;
-
-  &:hover {
-    transform: translateY(-3px);
-    box-shadow: 0 6px 18px rgba(0, 0, 0, 0.1) !important;
+// ── 顶部横幅 ──────────────────────────────────────────
+.profile-banner {
+  background: linear-gradient(135deg, #1a6fd4 0%, #3B70FF 60%, #5b8fff 100%);
+  border-radius: 20px;
+  padding: 28px 32px;
+  box-shadow: 0 8px 32px rgba(59, 112, 255, 0.3);
+  position: relative;
+  overflow: hidden;
+
+  &::before {
+    content: '';
+    position: absolute;
+    top: -40px; right: -40px;
+    width: 200px; height: 200px;
+    background: rgba(255,255,255,0.06);
+    border-radius: 50%;
   }
-
-  .student-basic-info {
-    display: flex;
-    align-items: center;
-    padding: 25px;
-    cursor: pointer;
-    transition: all 0.3s;
-    border-radius: 8px;
-    position: relative;
-    overflow: hidden;
-
-    &:hover {
-      background-color: #f8fafc;
-
-      &::before {
-        content: '';
-        position: absolute;
-        top: 0;
-        left: 0;
-        width: 4px;
-        height: 100%;
-        background-color: #5b8cff;
-      }
-    }
-
-    .avatar-section {
-      margin-right: 25px;
-      position: relative;
-
-      .student-avatar {
-        border: 3px solid #e6f7ff;
-        box-shadow: 0 2px 10px rgba(91, 140, 255, 0.2);
-      }
-
-      .online-status {
-        position: absolute;
-        bottom: 5px;
-        right: 5px;
-        width: 15px;
-        height: 15px;
-        background-color: #52c41a;
-        border: 2px solid #fff;
-        border-radius: 50%;
-      }
-    }
-
-    .info-section {
-      flex: 1;
-      min-width: 180px;
-
-      h2 {
-        margin: 0 0 12px 0;
-        font-size: 24px;
-        color: #333;
-        font-weight: 600;
-        display: flex;
-        align-items: center;
-
-        .grade-tag {
-          font-size: 13px;
-          background: linear-gradient(to right, #5b8cff, #36cbcb);
-          color: white;
-          padding: 2px 10px;
-          border-radius: 12px;
-          margin-left: 10px;
-          font-weight: normal;
-          box-shadow: 0 2px 4px rgba(91, 140, 255, 0.2);
-        }
-      }
-
-      .student-id, .enrollment-date {
-        margin: 8px 0;
-        color: #666;
-        font-size: 14px;
-        display: flex;
-        align-items: center;
-
-        i {
-          margin-right: 8px;
-          font-size: 16px;
-          color: #909399;
-        }
-      }
-
-      .progress-ring {
-        margin-top: 15px;
-        display: flex;
-        align-items: center;
-
-        .el-progress {
-          margin-right: 10px;
-        }
-
-        .progress-label {
-          font-size: 13px;
-          color: #909399;
-        }
-      }
-    }
-
-    .stats-section {
-      display: flex;
-      flex-direction: column;
-      gap: 20px;
-      min-width: 160px;
-
-      .stat-item {
-        display: flex;
-        align-items: center;
-        background-color: #f8fafc;
-        padding: 10px 15px;
-        border-radius: 8px;
-        transition: all 0.3s;
-
-        &:hover {
-          background-color: #f0f5ff;
-        }
-
-        .stat-icon {
-          width: 36px;
-          height: 36px;
-          background-color: #e6f7ff;
-          border-radius: 8px;
-          display: flex;
-          align-items: center;
-          justify-content: center;
-          margin-right: 12px;
-
-          i {
-            font-size: 18px;
-            color: #5b8cff;
-          }
-        }
-
-        .stat-content {
-          .stat-tag {
-            font-size: 15px;
-            padding: 0 12px;
-            height: 28px;
-            line-height: 26px;
-            border-radius: 14px;
-            font-weight: bold;
-            box-shadow: 0 2px 4px rgba(91, 140, 255, 0.2);
-          }
-
-          .stat-label {
-            display: block;
-            margin-top: 5px;
-            font-size: 12px;
-            color: #909399;
-          }
-        }
-      }
-    }
+  &::after {
+    content: '';
+    position: absolute;
+    bottom: -60px; left: 30%;
+    width: 280px; height: 280px;
+    background: rgba(255,255,255,0.04);
+    border-radius: 50%;
   }
 }
 
-.quick-stats-card {
-  height: 100%;
-  border-radius: 10px;
-  transition: all 0.3s ease;
-  border: none;
+.banner-content {
+  display: flex;
+  align-items: center;
+  gap: 24px;
+  position: relative;
+  z-index: 1;
+}
 
-  &:hover {
-    transform: translateY(-3px);
-    box-shadow: 0 6px 18px rgba(0, 0, 0, 0.1) !important;
+.avatar-wrap {
+  position: relative;
+  flex-shrink: 0;
+  .student-avatar {
+    border: 3px solid rgba(255,255,255,0.6);
+    box-shadow: 0 4px 16px rgba(0,0,0,0.2);
   }
-
-  ::v-deep .el-card__header {
-    border-bottom: 1px solid #ebeef5;
-    padding: 16px 20px;
-    font-weight: 600;
-    color: #333;
-
-    i {
-      margin-right: 8px;
-      color: #5b8cff;
-    }
-  }
-
-  .quick-stats-content {
-    padding: 5px 10px;
-
-    .stat-row {
-      display: flex;
-      align-items: center;
-      margin-bottom: 20px;
-      padding: 8px 10px;
-      border-radius: 8px;
-      transition: all 0.3s;
-
-      &:hover {
-        background-color: #f8fafc;
-      }
-
-      &.efficiency-row {
-        margin-bottom: 0;
-      }
-
-      .stat-icon-wrapper {
-        width: 36px;
-        height: 36px;
-        background-color: #f6f6f6;
-        border-radius: 8px;
-        display: flex;
-        align-items: center;
-        justify-content: center;
-        margin-right: 15px;
-
-        i {
-          font-size: 18px;
-          color: #5b8cff;
-        }
-      }
-
-      .stat-text {
-        flex: 1;
-
-        .stat-title {
-          font-size: 13px;
-          color: #909399;
-          display: block;
-          margin-bottom: 3px;
-        }
-
-        .stat-value {
-          font-weight: bold;
-          font-size: 16px;
-          color: #333;
-
-          &.highlight {
-            color: #5b8cff;
-            font-size: 18px;
-          }
-        }
-
-        .el-progress {
-          margin-top: 5px;
-        }
-      }
-    }
+  .online-dot {
+    position: absolute;
+    bottom: 3px; right: 3px;
+    width: 14px; height: 14px;
+    background: #52c41a;
+    border: 2px solid #fff;
+    border-radius: 50%;
   }
 }
 
-.reminder-card {
-  border-radius: 10px;
-  transition: all 0.3s ease;
-  border: none;
-
-  &:hover {
-    transform: translateY(-3px);
-    box-shadow: 0 6px 18px rgba(0, 0, 0, 0.1) !important;
+.profile-info {
+  flex: 1;
+  .profile-name {
+    font-size: 22px;
+    font-weight: 700;
+    color: #fff;
+    display: flex;
+    align-items: center;
+    gap: 10px;
+    margin-bottom: 6px;
   }
-
-  ::v-deep .el-card__header {
-    border-bottom: 1px solid #ebeef5;
-    padding: 16px 20px;
-    font-weight: 600;
-    color: #333;
-
-    i {
-      margin-right: 8px;
-      color: #5b8cff;
-    }
+  .grade-badge {
+    font-size: 12px;
+    font-weight: 500;
+    background: rgba(255,255,255,0.2);
+    border: 1px solid rgba(255,255,255,0.4);
+    color: #fff;
+    padding: 2px 10px;
+    border-radius: 10px;
   }
-
-  .reminder-content {
-    padding: 10px;
-
-    .reminder-item {
-      display: flex;
-      align-items: center;
-      margin-bottom: 10px;
-      padding: 8px;
-      background-color: #fff9f0;
-      border-radius: 6px;
-      border-left: 3px solid #fa8c16;
-
-      &:last-child {
-        margin-bottom: 0;
-      }
-
-      .reminder-icon {
-        color: #fa8c16;
-        margin-right: 10px;
-        font-size: 16px;
-      }
-
-      span {
-        font-size: 13px;
-        color: #666;
-      }
-    }
+  .profile-meta {
+    font-size: 13px;
+    color: rgba(255,255,255,0.75);
+    display: flex;
+    align-items: center;
+    gap: 6px;
+    i { font-size: 14px; }
   }
 }
 
-.study-records-card {
-  border-radius: 10px;
-  transition: all 0.3s ease;
-  border: none;
+.profile-stats {
+  display: flex;
+  align-items: center;
+  gap: 0;
+  background: rgba(255,255,255,0.12);
+  border: 1px solid rgba(255,255,255,0.2);
+  border-radius: 14px;
+  padding: 14px 24px;
+  backdrop-filter: blur(4px);
+}
 
-  &:hover {
-    transform: translateY(-3px);
-    box-shadow: 0 6px 18px rgba(0, 0, 0, 0.1) !important;
+.pstat-item {
+  text-align: center;
+  padding: 0 20px;
+  .pstat-value {
+    font-size: 22px;
+    font-weight: 700;
+    color: #fff;
+    line-height: 1.2;
   }
-
-  ::v-deep .el-card__header {
-    border-bottom: 1px solid #ebeef5;
-    padding: 16px 20px;
-    font-weight: 600;
-    color: #333;
-
-    i {
-      margin-right: 8px;
-      color: #5b8cff;
-    }
+  .pstat-label {
+    font-size: 11px;
+    color: rgba(255,255,255,0.7);
+    margin-top: 3px;
+    white-space: nowrap;
   }
+}
 
-  .filter-section {
-    margin-bottom: 15px;
-    padding: 10px;
-    background-color: #f8fafc;
-    border-radius: 8px;
+.pstat-divider {
+  width: 1px;
+  height: 36px;
+  background: rgba(255,255,255,0.25);
+}
 
-    ::v-deep .el-select,
-    ::v-deep .el-date-editor {
-      width: 100%;
-    }
-  }
+// ── 侧边卡片 ──────────────────────────────────────────
+.side-card {
+  background: #fff;
+  border-radius: 16px;
+  border: 1px solid #e8eeff;
+  box-shadow: 0 4px 20px rgba(59, 112, 255, 0.07);
+  overflow: hidden;
+}
 
-  .learning-table {
-    margin-bottom: 15px;
+.side-card-header {
+  display: flex;
+  align-items: center;
+  gap: 8px;
+  padding: 14px 18px;
+  background: linear-gradient(135deg, #f8faff 0%, #f0f4ff 100%);
+  border-bottom: 1px solid #eef2ff;
+  font-size: 14px;
+  font-weight: 600;
+  color: #1a2a4a;
+  i { color: #3B70FF; font-size: 15px; }
+}
 
-    .date-cell {
-      display: flex;
-      align-items: center;
-      justify-content: center;
+.side-card-body {
+  padding: 14px 16px;
+}
 
-      i {
-        margin-right: 5px;
-        color: #909399;
-      }
-    }
+// 本周概览行
+.week-stat-row {
+  display: flex;
+  align-items: center;
+  gap: 12px;
+  padding: 10px 12px;
+  border-radius: 10px;
+  border: 1px solid #eef2ff;
+  margin-bottom: 10px;
+  transition: all 0.2s;
+  &:last-child { margin-bottom: 0; }
+  &:hover { border-color: #c5d5ff; background: #f8faff; }
+}
 
-    .subject-tag {
-      font-size: 13px;
-      padding: 0 12px;
-      height: 28px;
-      line-height: 26px;
-      border-radius: 14px;
-      font-weight: 500;
-    }
+.week-stat-icon {
+  width: 36px; height: 36px;
+  border-radius: 9px;
+  display: flex; align-items: center; justify-content: center;
+  flex-shrink: 0;
+  i { font-size: 17px; }
+}
 
-    .content-cell {
-      display: flex;
-      align-items: center;
+.week-stat-text {
+  flex: 1;
+  .week-stat-label { font-size: 12px; color: #909399; display: block; margin-bottom: 3px; }
+  .week-stat-value { font-size: 15px; font-weight: 700; color: #1a2a4a; }
+  .week-progress { margin-top: 4px; }
+}
 
-      .efficiency-tag {
-        margin-left: 10px;
-        height: 20px;
-        line-height: 18px;
-      }
-    }
+// 学习提醒
+.reminder-item {
+  display: flex;
+  align-items: flex-start;
+  gap: 10px;
+  padding: 10px 12px;
+  background: linear-gradient(135deg, #fff8f0 0%, #fff3e6 100%);
+  border-radius: 10px;
+  border-left: 3px solid #fa8c16;
+  margin-bottom: 10px;
+  &:last-child { margin-bottom: 0; }
+  span { font-size: 13px; color: #606266; line-height: 1.6; }
+}
 
-    .el-button--text {
-      color: #5b8cff;
+.reminder-dot {
+  width: 8px; height: 8px;
+  background: #fa8c16;
+  border-radius: 50%;
+  flex-shrink: 0;
+  margin-top: 5px;
+}
 
-      i {
-        margin-right: 5px;
-      }
-    }
-  }
+// 本月汇总
+.month-stat-item {
+  display: flex;
+  align-items: center;
+  gap: 12px;
+  padding: 10px 12px;
+  border-radius: 10px;
+  border: 1px solid #eef2ff;
+  margin-bottom: 10px;
+  transition: all 0.2s;
+  &:last-child { margin-bottom: 0; }
+  &:hover { border-color: #c5d5ff; background: #f8faff; }
+}
 
-  .pagination {
-    margin-top: 20px;
-    text-align: center;
-  }
+.month-stat-icon {
+  width: 36px; height: 36px;
+  border-radius: 9px;
+  display: flex; align-items: center; justify-content: center;
+  flex-shrink: 0;
+  i { font-size: 17px; }
+}
 
-  .summary-section {
-    margin-top: 20px;
-    padding-top: 20px;
-    border-top: 1px solid #eee;
+.month-stat-label { font-size: 12px; color: #909399; margin-bottom: 2px; }
+.month-stat-value { font-size: 14px; font-weight: 700; color: #1a2a4a; }
 
-    .summary-item {
-      display: flex;
-      align-items: center;
-      padding: 15px;
-      background-color: #f8fafc;
-      border-radius: 8px;
-      height: 100%;
+// ── 学习记录卡片 ──────────────────────────────────────
+.records-card {
+  background: #fff;
+  border-radius: 16px;
+  border: 1px solid #e8eeff;
+  box-shadow: 0 4px 20px rgba(59, 112, 255, 0.07);
+  overflow: hidden;
+}
 
-      .summary-icon {
-        width: 40px;
-        height: 40px;
-        border-radius: 8px;
-        display: flex;
-        align-items: center;
-        justify-content: center;
-        margin-right: 15px;
+.records-header {
+  display: flex;
+  align-items: center;
+  justify-content: space-between;
+  padding: 16px 20px;
+  background: linear-gradient(135deg, #f8faff 0%, #f0f4ff 100%);
+  border-bottom: 1px solid #eef2ff;
+}
 
-        i {
-          font-size: 20px;
-        }
-      }
+.records-title {
+  display: flex;
+  align-items: center;
+  gap: 8px;
+  font-size: 15px;
+  font-weight: 600;
+  color: #1a2a4a;
+  i { color: #3B70FF; font-size: 16px; }
+}
 
-      .summary-content {
-        .summary-title {
-          font-size: 13px;
-          color: #909399;
-          margin-bottom: 5px;
-        }
+.records-count {
+  font-size: 12px;
+  color: #909399;
+  background: #f0f4ff;
+  border: 1px solid #dce4f5;
+  padding: 3px 10px;
+  border-radius: 10px;
+}
 
-        .summary-value {
-          font-size: 16px;
-          font-weight: bold;
-          color: #333;
-        }
-      }
-    }
-  }
+.records-body {
+  padding: 20px 24px;
 }
 
-.chart-dialog {
-  ::v-deep .el-dialog {
-    border-radius: 10px;
-    box-shadow: 0 5px 30px rgba(0, 0, 0, 0.1);
+// 时间轴记录项
+.record-item {
+  display: flex;
+  gap: 16px;
+  margin-bottom: 4px;
+}
 
-    &__header {
-      border-bottom: 1px solid #ebeef5;
-      padding: 15px 20px;
+.record-timeline {
+  display: flex;
+  flex-direction: column;
+  align-items: center;
+  flex-shrink: 0;
+  padding-top: 4px;
+}
 
-      .el-dialog__title {
-        font-weight: 600;
-        color: #333;
-      }
-    }
+.timeline-dot {
+  width: 12px; height: 12px;
+  background: linear-gradient(135deg, #3B70FF, #5b8fff);
+  border-radius: 50%;
+  border: 2px solid #fff;
+  box-shadow: 0 0 0 3px rgba(59,112,255,0.2);
+  flex-shrink: 0;
+}
 
-    &__body {
-      padding: 20px;
-    }
-  }
+.timeline-line {
+  width: 2px;
+  flex: 1;
+  min-height: 24px;
+  background: linear-gradient(to bottom, #c5d5ff, #e8eeff);
+  margin: 6px 0;
+}
 
-  .chart-header {
-    margin-bottom: 10px;
+.record-content {
+  flex: 1;
+  background: linear-gradient(135deg, #f8faff 0%, #f5f7fa 100%);
+  border: 1px solid #e8eeff;
+  border-radius: 12px;
+  padding: 14px 16px;
+  margin-bottom: 16px;
+  transition: all 0.25s;
+  &:hover {
+    border-color: #c5d5ff;
+    box-shadow: 0 4px 16px rgba(59,112,255,0.1);
+    transform: translateX(3px);
   }
+}
 
-  .chart-summary {
-    margin-top: 30px;
-
-    .summary-card {
-      display: flex;
-      align-items: center;
-      padding: 15px;
-      background-color: #f8fafc;
-      border-radius: 8px;
-      height: 100%;
-
-      .summary-icon {
-        width: 40px;
-        height: 40px;
-        border-radius: 8px;
-        display: flex;
-        align-items: center;
-        justify-content: center;
-        margin-right: 15px;
+.record-top {
+  display: flex;
+  align-items: center;
+  justify-content: space-between;
+  margin-bottom: 10px;
+}
 
-        i {
-          font-size: 20px;
-        }
-      }
+.record-date-block {
+  display: flex;
+  align-items: center;
+  gap: 6px;
+  i { color: #3B70FF; font-size: 14px; }
+  .record-date { font-size: 13px; font-weight: 600; color: #1a2a4a; }
+  .record-time { font-size: 12px; color: #909399; }
+}
 
-      .summary-content {
-        .summary-title {
-          font-size: 13px;
-          color: #909399;
-          margin-bottom: 5px;
-        }
+.record-right {
+  display: flex;
+  align-items: center;
+  gap: 8px;
+}
 
-        .summary-value {
-          font-size: 16px;
-          font-weight: bold;
-          color: #333;
-        }
-      }
-    }
-  }
+.duration-badge {
+  display: inline-flex;
+  align-items: center;
+  gap: 4px;
+  background: linear-gradient(135deg, #3B70FF 0%, #5b8fff 100%);
+  color: #fff;
+  font-size: 12px;
+  font-weight: 500;
+  padding: 3px 10px;
+  border-radius: 10px;
+  box-shadow: 0 2px 8px rgba(59,112,255,0.3);
+  i { font-size: 12px; }
 }
 
-.subjects-list {
-  background-color: #f8fafc;
-  border-radius: 8px;
-  padding: 15px;
+.efficiency-tag {
+  height: 22px;
+  line-height: 20px;
+  display: inline-flex;
+  align-items: center;
+}
 
-  .subjects-header {
-    display: flex;
-    justify-content: space-between;
-    padding: 0 10px 10px 10px;
-    margin-bottom: 10px;
-    border-bottom: 1px solid #ebeef5;
+.record-body-content {
+  .record-text {
     font-size: 13px;
-    color: #909399;
-    font-weight: 500;
-
-    span {
-      flex: 1;
-
-      &:nth-child(1) {
-        flex: 2;
-      }
-
-      &:nth-child(3) {
-        text-align: right;
-      }
-    }
-  }
-
-  .subject-item {
-    display: flex;
-    align-items: center;
-    padding: 10px;
-    margin-bottom: 8px;
-    background-color: #fff;
-    border-radius: 6px;
-    transition: all 0.3s;
-
-    &:hover {
-      transform: translateX(5px);
-      box-shadow: 0 2px 8px rgba(0, 0, 0, 0.05);
-    }
-
-    &:last-child {
-      margin-bottom: 0;
-    }
-
-    .subject-rank {
-      width: 24px;
-      margin-right: 10px;
-
-      .el-tag {
-        width: 24px;
-        height: 24px;
-        padding: 0;
-        display: flex;
-        align-items: center;
-        justify-content: center;
-        border-radius: 50%;
-      }
-    }
-
-    .subject-name {
-      flex: 2;
-      font-size: 13px;
-      color: #333;
-      font-weight: 500;
-    }
-
-    .el-progress {
-      flex: 3;
-      margin: 0 10px;
-    }
-
-    .subject-hours {
-      flex: 1;
-      font-size: 13px;
-      color: #5b8cff;
-      font-weight: 500;
-      text-align: center;
-    }
-
-    .subject-percent {
-      flex: 1;
-      font-size: 13px;
-      color: #909399;
-      text-align: right;
-    }
+    color: #606266;
+    line-height: 1.7;
+    margin: 0 0 10px 0;
   }
 }
 
-@media (max-width: 992px) {
-  .student-info-card {
-    .student-basic-info {
-      flex-direction: column;
-      text-align: center;
-
-      .avatar-section {
-        margin-right: 0;
-        margin-bottom: 15px;
-      }
-
-      .stats-section {
-        flex-direction: row;
-        margin-top: 20px;
-        width: 100%;
-        justify-content: space-around;
-      }
-    }
-  }
+.record-tags {
+  display: flex;
+  flex-wrap: wrap;
+  gap: 6px;
+}
 
-  .chart-dialog {
-    ::v-deep .el-dialog {
-      width: 90% !important;
-    }
+.subject-tag {
+  height: 22px;
+  line-height: 20px;
+  padding: 0 9px;
+  border-radius: 11px;
+  font-size: 11px;
+  font-weight: 500;
+  display: inline-flex;
+  align-items: center;
+  background: rgba(59,112,255,0.08);
+  border-color: rgba(59,112,255,0.2);
+  color: #3B70FF;
+}
 
-    .el-col {
-      margin-bottom: 20px;
-    }
-  }
+// 空状态
+.empty-records {
+  text-align: center;
+  padding: 60px 20px;
+  color: #c0c4cc;
+  i { font-size: 48px; display: block; margin-bottom: 12px; }
+  p { font-size: 14px; margin: 0; }
 }
 
+// ── 响应式 ────────────────────────────────────────────
 @media (max-width: 768px) {
-  .student-info-card {
-    .student-basic-info {
-      .stats-section {
-        flex-direction: column;
-        gap: 15px;
-      }
-    }
-  }
-
-  .subjects-list {
-    .subject-item {
-      flex-wrap: wrap;
-
-      .subject-name {
-        order: 1;
-        flex: 0 0 100%;
-        margin-bottom: 5px;
-      }
-
-      .el-progress {
-        order: 3;
-        flex: 1;
-        margin: 5px 10px 0 0;
-      }
-
-      .subject-hours {
-        order: 2;
-        flex: none;
-        margin-left: auto;
-      }
-
-      .subject-percent {
-        order: 4;
-        flex: none;
-      }
-    }
-  }
-
-  .filter-section {
-    ::v-deep .el-col {
-      margin-bottom: 10px;
-    }
-  }
-
-  .summary-section {
-    ::v-deep .el-col {
-      margin-bottom: 15px;
-    }
-  }
+  .learnstyle-page { padding: 16px; }
+  .profile-banner { padding: 20px; }
+  .banner-content { flex-direction: column; align-items: flex-start; gap: 16px; }
+  .profile-stats { width: 100%; justify-content: space-around; padding: 12px 16px; }
+  .pstat-item { padding: 0 10px; }
+  .main-section { margin-top: 16px; }
+  .records-body { padding: 16px; }
 }
 </style>

+ 33 - 12
src/views/home.vue

@@ -122,8 +122,18 @@ export default {
 </script>
 
 <style lang='scss' scoped>
+.home {
+  height: 100vh;
+  background: linear-gradient(135deg, #f5f7fa 0%, #eef1f5 100%);
+  padding: 20px;
+}
+
 #knowmap {
-  height: 100%;
+  height: calc(100vh - 140px);
+  width: 100%;
+  border-radius: 12px;
+  box-shadow: 0 2px 12px rgba(0, 0, 0, 0.08);
+  background: #fff;
 }
 
 h2 {
@@ -131,12 +141,13 @@ h2 {
   text-align: center;
   margin: 40px 0;
   font-weight: normal;
+  color: #303133;
 }
 
 h3 {
   font-size: 18px;
   text-align: center;
-  color: #737373;
+  color: #909399;
   margin: 40px 0;
   font-weight: normal;
 }
@@ -185,12 +196,12 @@ h3 {
     height: 108px;
     display: block;
     border-radius: 8px;
+    transition: all 0.3s ease;
 
     &:hover {
       opacity: 0.7;
-      /* .course_title{
-          color:#ca0000;
-        }*/
+      transform: translateY(-4px);
+      box-shadow: 0 8px 24px rgba(0, 0, 0, 0.15);
     }
   }
 }
@@ -205,7 +216,7 @@ h3 {
 
     &:hover {
       cursor: pointer;
-      color: red;
+      color: #409EFF;
     }
   }
 }
@@ -234,12 +245,22 @@ h3 {
   }
 }
 
-.home {
-  overflow: hidden;
-  height: 100%;
-  display: flex;
-  align-items: center;
-  justify-content: center;
+// 响应式设计
+@media (max-width: 768px) {
+  .home {
+    padding: 16px;
+  }
+
+  #knowmap {
+    height: calc(100vh - 120px);
+  }
+
+  .demoList li {
+    width: 100%;
+    float: none;
+    margin-right: 0;
+    margin-bottom: 20px;
+  }
 }
 </style>
 

+ 65 - 2
src/views/userCenter/index.vue

@@ -1,6 +1,6 @@
 <template>
   <div class="container learnstyle-page">
-    <el-card style="position: relative; top: 15%; min-height: 300px" >
+    <el-card>
       <el-row class="tac">
         <el-col style="width: 20%" :span="12">
           <el-menu
@@ -60,6 +60,69 @@
   }
 </script>
 
-<style scoped>
+<style lang="scss" scoped>
+.container,
+.learnstyle-page {
+  padding: 24px;
+  background: linear-gradient(135deg, #f0f4ff 0%, #f5f7fa 100%);
+  min-height: 100vh;
+  max-width: 1400px;
+  margin: 0 auto;
+}
 
+// 外层卡片
+::v-deep .el-card {
+  border-radius: 16px;
+  box-shadow: 0 4px 20px rgba(59, 112, 255, 0.08);
+  border: 1px solid #e8eeff;
+  background: #fff;
+  top: 0 !important;
+}
+
+// 侧边菜单
+.el-menu-vertical-demo {
+  border-right: none;
+  background: linear-gradient(135deg, #f8faff 0%, #f0f4ff 100%);
+  border-radius: 12px;
+  min-height: 300px;
+  padding: 8px;
+
+  ::v-deep .el-menu-item {
+    height: 50px;
+    line-height: 50px;
+    margin: 4px 0;
+    border-radius: 10px;
+    transition: all 0.25s ease;
+    color: #606266;
+    font-weight: 500;
+    font-size: 14px;
+
+    i {
+      color: #3B70FF;
+      margin-right: 10px;
+      font-size: 16px;
+      vertical-align: middle;
+    }
+
+    &:hover {
+      background: linear-gradient(135deg, #3B70FF 0%, #5b8fff 100%);
+      color: #fff;
+      box-shadow: 0 4px 14px rgba(59, 112, 255, 0.3);
+      i { color: #fff; }
+    }
+
+    &.is-active {
+      background: linear-gradient(135deg, #3B70FF 0%, #5b8fff 100%);
+      color: #fff;
+      box-shadow: 0 4px 14px rgba(59, 112, 255, 0.3);
+      i { color: #fff; }
+    }
+  }
+}
+
+.el-col { padding: 0; }
+
+@media (max-width: 768px) {
+  .container, .learnstyle-page { padding: 16px; }
+}
 </style>

+ 61 - 27
src/views/userCenter/userInfo.vue

@@ -184,31 +184,65 @@
 </script>
 
 <style scoped>
-  .user_content {
-    margin-left: 5%;
-  }
-
-  .avatar-uploader .el-upload {
-    border: 1px dashed #d9d9d9;
-    border-radius: 6px;
-    cursor: pointer;
-    position: relative;
-    overflow: hidden;
-  }
-  .avatar-uploader .el-upload:hover {
-    border-color: #409EFF;
-  }
-  .avatar-uploader-icon {
-    font-size: 28px;
-    color: #8c939d;
-    width: 90px;
-    height: 90px;
-    line-height: 90px;
-    text-align: center;
-  }
-  .avatar {
-    width: 178px;
-    height: 178px;
-    display: block;
-  }
+.user_content {
+  padding: 24px 32px;
+}
+
+::v-deep .el-form-item__label {
+  color: #1a2a4a;
+  font-weight: 500;
+}
+
+::v-deep .el-input__inner {
+  border-radius: 8px;
+  border-color: #dce4f5;
+  transition: border-color 0.25s, box-shadow 0.25s;
+}
+::v-deep .el-input__inner:focus {
+  border-color: #3B70FF;
+  box-shadow: 0 0 0 2px rgba(59, 112, 255, 0.1);
+}
+
+::v-deep .el-select .el-input__inner {
+  border-radius: 8px;
+}
+
+::v-deep .el-button--primary {
+  background: linear-gradient(135deg, #3B70FF 0%, #5b8fff 100%);
+  border: none;
+  border-radius: 8px;
+  padding: 10px 28px;
+  font-weight: 500;
+  box-shadow: 0 4px 12px rgba(59, 112, 255, 0.3);
+  transition: all 0.25s;
+}
+::v-deep .el-button--primary:hover {
+  transform: translateY(-1px);
+  box-shadow: 0 6px 16px rgba(59, 112, 255, 0.4);
+}
+
+.avatar-uploader .el-upload {
+  border: 2px dashed #c5d5ff;
+  border-radius: 10px;
+  cursor: pointer;
+  position: relative;
+  overflow: hidden;
+  transition: border-color 0.25s;
+}
+.avatar-uploader .el-upload:hover {
+  border-color: #3B70FF;
+}
+.avatar-uploader-icon {
+  font-size: 28px;
+  color: #3B70FF;
+  width: 90px;
+  height: 90px;
+  line-height: 90px;
+  text-align: center;
+}
+.avatar {
+  width: 178px;
+  height: 178px;
+  display: block;
+}
 </style>