diff --git a/Html/.log b/Html/.log index 5abdd46..d4e00c9 100644 --- a/Html/.log +++ b/Html/.log @@ -434,3 +434,34 @@ Traceback (most recent call last): File "/usr/lib/python3/dist-packages/cryptography/exceptions.py", line 9, in from cryptography.hazmat.bindings._rust import exceptions as rust_exceptions pyo3_runtime.PanicException: Python API call failed +[2025-10-28 14:36:27,578] ERROR in app: Exception on /dashboard [GET] +Traceback (most recent call last): + File "/home/flask/hsmooc/.venv/lib/python3.10/site-packages/flask/app.py", line 1511, in wsgi_app + response = self.full_dispatch_request() + File "/home/flask/hsmooc/.venv/lib/python3.10/site-packages/flask/app.py", line 919, in full_dispatch_request + rv = self.handle_user_exception(e) + File "/home/flask/hsmooc/.venv/lib/python3.10/site-packages/flask_cors/extension.py", line 176, in wrapped_function + return cors_after_request(app.make_response(f(*args, **kwargs))) + File "/home/flask/hsmooc/.venv/lib/python3.10/site-packages/flask/app.py", line 917, in full_dispatch_request + rv = self.dispatch_request() + File "/home/flask/hsmooc/.venv/lib/python3.10/site-packages/flask/app.py", line 902, in dispatch_request + return self.ensure_sync(self.view_functions[rule.endpoint])(**view_args) # type: ignore[no-any-return] + File "/home/flask/hsmooc/hsa/Html/apps/auth/decorators.py", line 61, in wrapper + return func(*args, **kwargs) + File "/home/flask/hsmooc/hsa/Html/apps/views/dashboard.py", line 28, in dashboard + return render_template( + File "/home/flask/hsmooc/.venv/lib/python3.10/site-packages/flask/templating.py", line 150, in render_template + return _render(app, template, context) + File "/home/flask/hsmooc/.venv/lib/python3.10/site-packages/flask/templating.py", line 131, in _render + rv = template.render(context) + File "/home/flask/hsmooc/.venv/lib/python3.10/site-packages/jinja2/environment.py", line 1295, in render + self.environment.handle_exception() + File "/home/flask/hsmooc/.venv/lib/python3.10/site-packages/jinja2/environment.py", line 942, in handle_exception + raise rewrite_traceback_stack(source=source) + File "/home/flask/hsmooc/hsa/Html/apps/templates/dashboard.html", line 17, in top-level template code + {% include 'learning-path.html' %} + File "/home/flask/hsmooc/.venv/lib/python3.10/site-packages/flask/templating.py", line 65, in get_source + return self._get_source_fast(environment, template) + File "/home/flask/hsmooc/.venv/lib/python3.10/site-packages/flask/templating.py", line 99, in _get_source_fast + raise TemplateNotFound(template) +jinja2.exceptions.TemplateNotFound: learning-path.html diff --git a/Html/apps/static/css/learning-path.css b/Html/apps/static/css/learning-path.css new file mode 100644 index 0000000..dee9f8a --- /dev/null +++ b/Html/apps/static/css/learning-path.css @@ -0,0 +1,281 @@ +:root { + --primary-blue: #6A9FB5; + --secondary-blue: #8BB4C5; + --light-blue: #E1F0F7; + --accent-blue: #4A7B9D; + --text-dark: #2C3E50; + --text-light: #7F8C8D; + --card-shadow: 0 4px 12px rgba(106, 159, 181, 0.15); +} + +/* 学习路径区域 */ +.learning-path-section { + background: linear-gradient(135deg, var(--light-blue), #D4E9F2); + padding: 2rem 0; + border-radius: 0 0 20px 20px; + margin-bottom: 2rem; +} + +.section-title { + color: var(--accent-blue); + font-weight: 600; + margin-bottom: 1.5rem; + position: relative; + padding-bottom: 0.5rem; + font-size: 28px; +} + +.section-title:after { + content: ''; + position: absolute; + bottom: 0; + left: 0; + width: 60px; + height: 3px; + background-color: var(--primary-blue); + border-radius: 2px; +} + +/* 专业选择器 */ +.major-selector { + position: relative; + margin-bottom: 2rem; +} + +.major-selector label { + font-weight: 600; + color: var(--accent-blue); + margin-bottom: 0.5rem; + display: block; +} + +.major-selector select { + appearance: none; + background-color: white; + border: 2px solid var(--primary-blue); + border-radius: 8px; + padding: 0.75rem 1.5rem; + font-size: 1rem; + color: var(--text-dark); + width: 100%; + max-width: 300px; + cursor: pointer; + transition: all 0.3s ease; +} + +.major-selector select:focus { + outline: none; + box-shadow: 0 0 0 3px rgba(106, 159, 181, 0.3); + border-color: var(--accent-blue); +} + +.major-selector::after { + content: '\f078'; + font-family: 'Font Awesome 5 Free'; + font-weight: 900; + position: absolute; + top: 50%; + right: 1rem; + transform: translateY(-50%); + pointer-events: none; + color: var(--primary-blue); +} + +/* 学习路径流程图 */ +.path-flow { + background-color: white; + border-radius: 12px; + padding: 2rem; + box-shadow: var(--card-shadow); + overflow-x: auto; + position: relative; +} + +.path-container { + display: flex; + min-width: 900px; + position: relative; +} + +.path-step { + flex: 1; + display: flex; + flex-direction: column; + align-items: center; + position: relative; + padding: 0 1rem; +} + +.step-connector { + position: absolute; + top: 40px; + left: -50%; + width: 100%; + height: 2px; + background-color: var(--primary-blue); + z-index: 1; +} + +.step-node { + width: 80px; + height: 80px; + border-radius: 50%; + background-color: var(--light-blue); + display: flex; + align-items: center; + justify-content: center; + margin-bottom: 1rem; + position: relative; + z-index: 2; + transition: all 0.3s ease; + cursor: pointer; +} + +.step-node:hover { + transform: scale(1.05); + background-color: var(--primary-blue); +} + +.step-node:hover .step-icon { + color: white; +} + +.step-icon { + font-size: 1.8rem; + color: var(--accent-blue); +} + +.step-content { + text-align: center; + width: 100%; +} + +.step-title { + font-weight: 600; + margin-bottom: 0.5rem; + color: var(--accent-blue); +} + +.step-courses { + font-size: 0.9rem; + color: var(--text-light); + margin-bottom: 0.5rem; +} + +.step-progress { + height: 6px; + background-color: #e9ecef; + border-radius: 3px; + overflow: hidden; + margin-bottom: 0.5rem; +} + +.step-progress-bar { + height: 100%; + background-color: var(--primary-blue); + border-radius: 3px; + transition: width 0.5s ease; +} + +.step-status { + font-size: 0.8rem; + color: var(--text-light); +} + +/* 阶段状态样式 */ +.step-completed .step-node { + background-color: var(--primary-blue); +} + +.step-completed .step-icon { + color: white; +} + +.step-active .step-node { + background-color: var(--accent-blue); + box-shadow: 0 0 0 4px rgba(74, 123, 157, 0.3); +} + +.step-active .step-icon { + color: white; +} + +/* 课程详情面板 */ +.course-panel { + display: none; + background-color: white; + border-radius: 12px; + padding: 1.5rem; + box-shadow: var(--card-shadow); + margin-top: 1.5rem; +} + +.course-panel.active { + display: block; +} + +.panel-header { + display: flex; + justify-content: space-between; + align-items: center; + margin-bottom: 1rem; + padding-bottom: 0.5rem; + border-bottom: 1px solid #e9ecef; +} + +.panel-title { + font-weight: 600; + color: var(--accent-blue); + margin: 0; +} + +.close-panel { + background: none; + border: none; + font-size: 1.2rem; + color: var(--text-light); + cursor: pointer; +} + +.course-list { + display: grid; + grid-template-columns: repeat(auto-fill, minmax(300px, 1fr)); + gap: 1rem; +} + +.course-item { + display: flex; + align-items: center; + padding: 0.75rem; + border-radius: 8px; + border: 1px solid #e9ecef; + transition: all 0.3s ease; +} + +.course-item:hover { + border-color: var(--primary-blue); + box-shadow: 0 2px 8px rgba(106, 159, 181, 0.15); +} + +.course-check { + margin-right: 0.75rem; + color: #28a745; +} + +.course-info { + flex: 1; +} + +.course-name { + font-weight: 500; + margin-bottom: 0.25rem; +} + +.course-duration { + font-size: 0.8rem; + color: var(--text-light); +} + +.course-action { + margin-left: 0.75rem; +} \ No newline at end of file diff --git a/Html/apps/static/css/navbar.css b/Html/apps/static/css/navbar.css index 78d2a0c..69c8e96 100644 --- a/Html/apps/static/css/navbar.css +++ b/Html/apps/static/css/navbar.css @@ -1,12 +1,8 @@ /* 页眉导航栏 */ .navbar { - display: flex; - justify-content: space-between; - align-items: center; - background-color: #2575fc; - color: rgb(235, 235, 235); - border-radius: 10px; - margin-bottom: 30px; + background: linear-gradient(135deg, var(--primary-blue), var(--accent-blue)); + box-shadow: 0 2px 10px rgba(0, 0, 0, 0.1); + padding: 0.8rem 1rem; } .navbar .logo h1 { diff --git a/Html/apps/static/js/learning-path.js b/Html/apps/static/js/learning-path.js new file mode 100644 index 0000000..bb6a9e6 --- /dev/null +++ b/Html/apps/static/js/learning-path.js @@ -0,0 +1,30 @@ +// 1. 点击学习阶段节点,显示对应课程面板 +document.querySelectorAll('.step-node').forEach((node) => { + node.addEventListener('click', function () { + // 隐藏所有面板 + document.querySelectorAll('.course-panel').forEach(panel => { + panel.classList.remove('active'); + }); + // 获取当前阶段名称,匹配面板ID + const stepTitle = this.closest('.path-step').querySelector('.step-title').textContent; + const panelId = stepTitle.toLowerCase().replace(' ', '-') + '-panel'; + const targetPanel = document.getElementById(panelId); + // 显示对应面板(若存在) + if (targetPanel) { + targetPanel.classList.add('active'); + } + }); +}); + +// 2. 关闭课程面板 +document.querySelectorAll('.close-panel').forEach(button => { + button.addEventListener('click', function () { + this.closest('.course-panel').classList.remove('active'); + }); +}); + +// 3. 切换专业方向(可扩展为动态更新学习路径) +document.getElementById('majorSelect').addEventListener('change', function () { + const selectedMajor = this.options[this.selectedIndex].text; + // 实际项目中可替换为AJAX请求,加载对应专业的学习路径 +}); \ No newline at end of file diff --git a/Html/apps/templates/dashboard.html b/Html/apps/templates/dashboard.html index c8e0e49..ca4e1a2 100644 --- a/Html/apps/templates/dashboard.html +++ b/Html/apps/templates/dashboard.html @@ -9,10 +9,12 @@ + {% include 'navbar.html' %} + {% include 'learning-path.html' %}
diff --git a/Html/apps/templates/learning-path.html b/Html/apps/templates/learning-path.html new file mode 100644 index 0000000..22c7a04 --- /dev/null +++ b/Html/apps/templates/learning-path.html @@ -0,0 +1,145 @@ + + +
+
+

学习路径

+ + +
+ + +
+ + +
+
+ +
+
+
+ +
+
+
编程基础
+
3门课程
+
+
+
+
已完成
+
+
+ + +
+
+
+ +
+
+
数据结构
+
2门课程
+
+
+
+
已完成
+
+
+ + +
+
+
+ +
+
+
算法设计
+
3门课程
+
+
+
+
进行中
+
+
+ + +
+
+
+ +
+
+
数据库原理
+
2门课程
+
+
+
+
未开始
+
+
+ + +
+
+
+ +
+
+
Web开发
+
5门课程
+
+
+
+
未开始
+
+
+
+ + +
+
+

算法设计 - 课程列表

+ +
+
+
+ +
+
算法基础与复杂度分析
+
12课时
+
+
+ +
+
+
+ +
+
排序与搜索算法
+
15课时
+
+
+ +
+
+
+ +
+
动态规划与贪心算法
+
18课时
+
+
+ +
+
+
+
+
+
+ +