可以跑了 准备做系统

This commit is contained in:
CakeCN
2024-12-28 17:11:24 +08:00
parent f3791850b0
commit 1280a978f5
24 changed files with 2053 additions and 324 deletions

158
Html/static/css/book.css Normal file
View File

@@ -0,0 +1,158 @@
/* Reset some default styles */
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
/* Body & Page Background */
body {
font-family: 'Arial', sans-serif;
background-color: #f5f5f5;
padding: 20px;
}
/* 页眉导航栏 */
.navbar {
display: flex;
justify-content: space-between;
align-items: center;
background-color: #2575fc;
padding: 10px 30px;
color: white;
border-radius: 10px;
margin-bottom: 30px;
}
.navbar .logo h1 {
font-size: 24px;
font-weight: bold;
}
.navbar-links a {
color: white;
text-decoration: none;
margin: 0 15px;
font-size: 16px;
transition: color 0.3s;
}
.navbar-links a:hover {
color: #f1c40f;
}
.navbar .avatar img {
width: 40px;
height: 40px;
border-radius: 50%;
border: 2px solid white;
}
/* 课程详情页面主体部分 */
.course-details {
max-width: 1200px;
margin: 0 auto;
}
/* 上半部分:课程封面和课程详情 */
.course-overview {
display: flex;
justify-content: space-between;
margin-bottom: 30px;
max-height: 200px;
height: 30%;
}
.course-cover {
width: 40%;
text-align: center;
}
.cover-image {
height: 100%;
width: auto;
border-radius: 10px;
box-shadow: 0 10px 20px rgba(0, 0, 0, 0.1);
}
.course-info {
width: 55%;
padding-left: 20px;
}
.course-title {
font-size: 32px;
font-weight: bold;
margin-bottom: 10px;
color: #333;
}
.course-author {
font-size: 16px;
color: #777;
margin-bottom: 20px;
}
.course-description {
font-size: 16px;
color: #555;
}
/* 下半部分:课程教案列表 */
.lesson-plans {
margin-top: 30px;
}
.lesson-plans h3 {
font-size: 24px;
font-weight: bold;
margin-bottom: 20px;
color: #333;
}
/* 课程教案卡片容器 */
.lesson-cards {
display: flex;
flex-wrap: wrap;
gap: 20px;
justify-content: space-around;
}
/* 课程教案卡片 */
.lesson-card {
width: 200px;
height: 300px;
background-color: white;
border-radius: 15px;
box-shadow: 0 10px 20px rgba(0, 0, 0, 0.1);
overflow: hidden;
transition: transform 0.3s;
}
.lesson-card:hover {
transform: translateY(-10px); /* 提升效果 */
}
.lesson-image {
width: 100%;
height: 150px;
object-fit: cover;
}
.lesson-info {
padding: 15px;
}
.lesson-title {
font-size: 18px;
font-weight: bold;
color: #333;
margin-bottom: 10px;
}
.lesson-description {
font-size: 14px;
color: #777;
}

View File

@@ -0,0 +1,185 @@
/* Reset some default styles */
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
/* Body & Page Background */
body {
font-family: 'Arial', sans-serif;
background-color: #f5f5f5;
padding: 20px;
}
/* 页眉导航栏 */
.navbar {
display: flex;
justify-content: space-between;
align-items: center;
background-color: #2575fc;
padding: 10px 30px;
color: white;
border-radius: 10px;
margin-bottom: 30px;
}
.navbar .logo h1 {
font-size: 24px;
font-weight: bold;
}
.navbar-links a {
color: white;
text-decoration: none;
margin: 0 15px;
font-size: 16px;
transition: color 0.3s;
}
.navbar-links a:hover {
color: #f1c40f;
}
.navbar .avatar img {
width: 40px;
height: 40px;
border-radius: 50%;
border: 2px solid white;
}
/* Dashboard 主体部分 */
.dashboard {
max-width: 1200px;
margin: 0 auto;
}
.dashboard-title {
font-size: 28px;
font-weight: bold;
margin-bottom: 20px;
text-align: center;
}
/* 课程卡片容器 */
.course-cards {
display: flex;
flex-wrap: wrap;
gap: 20px;
justify-content: center;
}
/* 课程卡片 */
.course-card {
width: 300px;
height: 500px;
background-color: white;
border-radius: 15px;
box-shadow: 0 10px 30px rgba(0, 0, 0, 0.1);
overflow: hidden;
position: relative;
transition: transform 0.3s;
}
.course-card:hover {
transform: translateY(-10px); /* 提升效果 */
}
.course-image {
width: 100%;
height: 200px;
object-fit: cover;
}
.course-info {
padding: 20px;
}
.course-name {
font-size: 22px;
font-weight: bold;
color: #333;
}
.course-description {
font-size: 14px;
color: #777;
margin-top: 10px;
}
/* 右侧滑出进度卡片样式 */
.course-progress {
position: fixed;
top: 0;
right: -400px; /* 初始时在屏幕外 */
width: 400px;
height: 100%;
background-color: #fff;
box-shadow: -2px 0 5px rgba(0, 0, 0, 0.1);
padding: 30px;
transition: right 0.3s ease;
z-index: 9999;
border-radius: 15px; /* 添加圆角 */
}
.course-progress.open {
right: 0; /* 打开时显示 */
}
.progress-header {
display: flex;
justify-content: space-between;
align-items: center;
font-size: 20px;
margin-bottom: 20px;
}
.close-btn {
background: none;
border: none;
font-size: 24px;
cursor: pointer;
}
/* 章节和子章节样式 */
.chapter-list {
list-style-type: none;
padding-left: 0;
}
.chapter-item {
margin: 5px 0;
padding: 5px;
cursor: pointer;
}
.chapter-item .chapter-title {
font-size: 16px;
font-weight: bold;
}
.chapter-item .sub-chapter-list {
display: none; /* 初始状态下子章节隐藏 */
padding-left: 20px;
}
.chapter-item.open .sub-chapter-list {
display: block; /* 展开时显示子章节 */
}
.chapter-item:hover {
background-color: #f1f1f1;
border-radius: 5px;
}
/* 子章节的样式 */
.sub-chapter-item {
margin: 3px 0;
padding: 3px;
font-size: 14px;
}
.sub-chapter-item:hover {
background-color: #e8e8e8;
}

213
Html/static/css/desktop.css Normal file
View File

@@ -0,0 +1,213 @@
/* 左右两侧的页面内容 */
.sidebar {
background-color: #f0f0f0;
padding: 20px;
height: 100%;
}
body {
font-family: Arial, sans-serif;
display: flex;
flex-direction: column;
height: 100vh;
margin: 0;
}
.chatbox {
flex-grow: 1;
padding: 20px;
height: 75%;
overflow-y: auto;
border: 1px solid #ccc;
background-color: #f9f9f9;
}
.chat-message {
max-width: 70%;
padding: 10px 15px;
border-radius: 20px;
margin-bottom: 10px;
}
.user-message {
background-color: #d1e7dd;
text-align: right;
margin-left: auto;
}
.server-message {
background-color: #f1f1f1;
text-align: left;
margin-right: auto;
}
textarea {
flex-grow: 1;
padding: 10px;
border: 1px solid #ccc;
border-radius: 4px;
resize: none;
}
button {
padding: 10px 20px;
margin-left: 10px;
background-color: #28a745;
color: white;
border: none;
border-radius: 4px;
cursor: pointer;
}
pre {
background-color: #eee;
padding: 10px;
border-radius: 4px;
}
code {
font-family: monospace;
}
/* 让父容器为flex布局 */
.maxcontainer {
display: flex;
flex-grow: 1;
height: 100%;
position: relative;
}
/* 中间的拖拽条 */
.resizer {
width: 5px;
background-color: #ccc;
cursor: ew-resize;
position: relative;
}
.chatbox-header {
padding: 10px;
background-color: #f1f1f1;
display: flex;
justify-content: space-between;
align-items: center;
border-bottom: 1px solid #ddd;
}
.input-area {
display: flex;
gap: 10px;
margin-top: 15px;
padding: 10px;
background-color: #f1f1f1;
border-top: 1px solid #ddd;
}
.slider-container, .language-toggle {
display: flex;
align-items: center;
}
.slider-container input[type="range"] {
width: 70%;
margin-left: 10px;
}
.btn-group-toggle .btn {
padding: 5px 10px;
}
#leftSidebar, .vscode-web, #rightSidebar {
height: 100vh;
overflow: auto;
}
#dragbar, #dragbar2 {
background-color: #ccc;
cursor: col-resize;
}
/* 主容器,使用 grid 布局 */
#maxcontainer {
display: grid;
grid-template-columns: 1fr 5px 3fr 5px 1fr; /* 默认宽度比例 */
height: 100vh;
}
/* 各区域基础样式 */
.sidebar {
overflow: auto; /* 确保内容可以滚动 */
}
.vscode-web {
width: 100%;
height: 100%;
border: none;
}
.resizer {
background-color: #ccc;
cursor: col-resize;
width: 5px; /* 设置拖动条宽度 */
}
.gutter {
background-color: #ccc; /* 分隔条颜色 */
cursor: col-resize;
}#container {
display: grid;
grid-template-columns: 1fr 5px 3fr 5px 1fr; /* 初始比例 */
height: 100vh;
}
#leftSidebar, #vscodeWeb, #rightSidebar {
overflow: auto;
}
#dragbar, #dragbar2 {
background-color: #ccc;
cursor: col-resize;
}
/* 设置每个子框的基本样式 */
.progress-box {
height: 100%; /* 高度为 100%,撑满容器 */
display: flex;
flex-direction: row; /* 使子框横向排列 */
justify-content: flex-start;
}
.progress-title {
height: 60px; /* 每个进度节点的高度 */
text-align: center;
line-height: 60px; /* 垂直居中 */
margin: 2px; /* 水平方向上的间隔 */
border: 1px solid #ddd;
transition: background-color 0.3s ease;
position: relative;
}
.green {
background-color: green;
color: white;
}
.white {
background-color: white;
color: black;
}
.progress-box > .progress-title:last-child {
margin-bottom: 0; /* 防止最后一个子框出现多余的间距 */
}
/* 进度条详细信息的样式 */
#progress-detail {
position: absolute;
top: 0;
left: 0;
display: none;
padding: 10px;
background-color: rgba(0, 0, 0, 0.7);
color: white;
border-radius: 5px;
max-width: 200px;
}

View File

@@ -1,162 +1,156 @@
/* 页眉导航栏 */
.navbar {
display: flex;
justify-content: space-between;
align-items: center;
background-color: #2575fc;
padding: 10px 30px;
color: white;
border-radius: 10px;
margin-bottom: 30px;
}
/* 左右两侧的页面内容 */
.sidebar {
background-color: #f0f0f0;
padding: 20px;
height: 100%;
}
.navbar .logo h1 {
font-size: 24px;
font-weight: bold;
}
body {
font-family: Arial, sans-serif;
display: flex;
flex-direction: column;
height: 100vh;
margin: 0;
}
.chatbox {
flex-grow: 1;
padding: 20px;
height: 75%;
overflow-y: auto;
border: 1px solid #ccc;
background-color: #f9f9f9;
}
.navbar-links a {
color: white;
text-decoration: none;
margin: 0 15px;
font-size: 16px;
transition: color 0.3s;
}
.chat-message {
max-width: 70%;
padding: 10px 15px;
border-radius: 20px;
margin-bottom: 10px;
}
.user-message {
background-color: #d1e7dd;
text-align: right;
margin-left: auto;
}
.server-message {
background-color: #f1f1f1;
text-align: left;
margin-right: auto;
}
textarea {
flex-grow: 1;
padding: 10px;
border: 1px solid #ccc;
border-radius: 4px;
resize: none;
}
button {
padding: 10px 20px;
margin-left: 10px;
background-color: #28a745;
color: white;
border: none;
border-radius: 4px;
cursor: pointer;
}
pre {
background-color: #eee;
padding: 10px;
border-radius: 4px;
}
code {
font-family: monospace;
}
/* 让父容器为flex布局 */
.maxcontainer {
display: flex;
flex-grow: 1;
height: 100%;
position: relative;
}
/* 中间的拖拽条 */
.resizer {
width: 5px;
background-color: #ccc;
cursor: ew-resize;
position: relative;
}
.chatbox-header {
padding: 10px;
background-color: #f1f1f1;
display: flex;
justify-content: space-between;
align-items: center;
border-bottom: 1px solid #ddd;
}
.navbar-links a:hover {
color: #f1c40f;
}
.navbar .avatar img {
width: 40px;
height: 40px;
border-radius: 50%;
border: 2px solid white;
}
/* General reset */
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
.input-area {
display: flex;
gap: 10px;
margin-top: 15px;
padding: 10px;
background-color: #f1f1f1;
border-top: 1px solid #ddd;
}
/* Body & Page Background */
body {
font-family: 'Arial', sans-serif;
background-color: #f5f5f5;
padding: 20px;
}
.slider-container, .language-toggle {
display: flex;
align-items: center;
}
/* Header styles */
header {
background-color: #2575fc;
padding: 20px;
color: white;
}
.slider-container input[type="range"] {
width: 70%;
margin-left: 10px;
}
.header-container {
display: flex;
justify-content: space-between;
align-items: center;
}
.btn-group-toggle .btn {
padding: 5px 10px;
}
#leftSidebar, .vscode-web, #rightSidebar {
height: 100vh;
overflow: auto;
}
#dragbar, #dragbar2 {
background-color: #ccc;
cursor: col-resize;
}
/* 主容器,使用 grid 布局 */
#maxcontainer {
display: grid;
grid-template-columns: 1fr 5px 3fr 5px 1fr; /* 默认宽度比例 */
height: 100vh;
}
/* 各区域基础样式 */
.sidebar {
overflow: auto; /* 确保内容可以滚动 */
}
.vscode-web {
width: 100%;
height: 100%;
border: none;
}
.resizer {
background-color: #ccc;
cursor: col-resize;
width: 5px; /* 设置拖动条宽度 */
}
.gutter {
background-color: #ccc; /* 分隔条颜色 */
cursor: col-resize;
}#container {
display: grid;
grid-template-columns: 1fr 5px 3fr 5px 1fr; /* 初始比例 */
height: 100vh;
}
#leftSidebar, #vscodeWeb, #rightSidebar {
overflow: auto;
}
#dragbar, #dragbar2 {
background-color: #ccc;
cursor: col-resize;
}
.site-name h1 {
font-size: 24px;
}
.nav ul {
list-style-type: none;
display: flex;
gap: 20px;
}
.nav ul li {
display: inline;
}
.nav ul li a {
color: white;
text-decoration: none;
font-size: 16px;
}
.user-avatar img {
width: 40px;
height: 40px;
border-radius: 50%;
}
/* Main content styles */
main {
padding: 20px;
}
.course-selection h2 {
font-size: 28px;
margin-bottom: 20px;
}
.course-list {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(300px, 1fr));
gap: 20px;
}
.course-card {
background-color: white;
border-radius: 8px;
width: 300px;
height: 400px;
box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1);
overflow: hidden;
transition: transform 0.3s ease;
}
.course-card img {
width: 100%;
height: 261px;
object-fit: cover;
}
.course-card h3 {
padding: 15px;
font-size: 20px;
color: #2575fc;
}
.course-card p {
padding: 0 15px;
font-size: 14px;
color: #555;
}
.select-button {
display: block;
width: 100%;
padding: 10px;
background-color: #2575fc;
color: white;
border: none;
cursor: pointer;
font-size: 16px;
}
.select-button:hover {
background-color: #113c86;
}
/* Footer styles */
footer {
background-color: #333;
color: white;
text-align: center;
padding: 10px;
margin-top: 20px;
}

136
Html/static/css/login.css Normal file
View File

@@ -0,0 +1,136 @@
/* Reset some default styles */
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
/* Body & Page background */
body {
font-family: 'Arial', sans-serif;
background: linear-gradient(135deg, #70ff88, #e6d05f); /* 美丽的渐变背景 */
height: 100vh;
display: flex;
justify-content: center;
align-items: center;
padding: 20px;
}
.login-container {
display: flex;
justify-content: center;
align-items: center;
height: 100%;
width: 40%;
}
.login-card {
background-color: white;
padding: 40px;
border-radius: 15px;
box-shadow: 0 10px 30px rgba(0, 0, 0, 0.1);
width: 100%;
max-width: 500px;
text-align: center;
}
.login-title {
font-size: 28px;
font-weight: bold;
color: #333;
margin-bottom: 20px;
}
.login-form {
display: flex;
flex-direction: column;
gap: 20px;
}
.input-group {
display: flex;
flex-direction: column;
align-items: flex-start;
}
.input-group label {
font-size: 14px;
color: #555;
margin-bottom: 5px;
}
.input-group input {
width: 100%;
padding: 12px;
border-radius: 8px;
border: 1px solid #ddd;
font-size: 16px;
transition: border-color 0.3s;
}
.input-group input:focus {
border-color: #2575fc;
outline: none;
}
.login-btn {
background-color: #2575fc;
color: white;
padding: 14px;
font-size: 16px;
border: none;
border-radius: 8px;
cursor: pointer;
transition: background-color 0.3s;
}
.login-btn:hover {
background-color: #6a11cb;
}
.forgot-password {
margin-top: 10px;
}
.forgot-password a {
color: #2575fc;
font-size: 14px;
text-decoration: none;
}
.forgot-password a:hover {
text-decoration: underline;
}
.social-login {
margin-top: 20px;
}
.social-btn {
width: 100%;
padding: 12px;
margin: 5px 0;
font-size: 16px;
border: none;
border-radius: 8px;
cursor: pointer;
transition: background-color 0.3s;
}
.social-btn.google {
background-color: #db4437;
color: white;
}
.social-btn.google:hover {
background-color: #c1351d;
}
.social-btn.facebook {
background-color: #3b5998;
color: white;
}
.social-btn.facebook:hover {
background-color: #2d4373;
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 912 KiB

View File

@@ -3,7 +3,7 @@ var socket;
document.addEventListener('DOMContentLoaded', function() {
data = window.appData;
console.log(data);
socket = io('http://localhost:5000/agent?username='+data.username+'&folder='+data.folder);
socket = io('/agent?username='+data.username+'&folder='+data.folder);
socket.on('connect', function() {
console.log('Connected to server');
socket.emit('login',JSON.stringify(data));
@@ -18,6 +18,49 @@ document.addEventListener('DOMContentLoaded', function() {
// 滚动到最新消息
document.getElementById('chatbox').scrollTop = document.getElementById('chatbox').scrollHeight;
});
socket.on('request_function', function(data){
try {
console.log("request_function", data);
if (typeof data === 'string') {
data = JSON.parse(data);
}
for (let i = 0; i < data.length; i++) {
const element = data[i]
const requestMessage = document.createElement('div');
requestMessage.className = 'chat-message server-message';
const approveButton = document.createElement('button');
approveButton.innerText = '批准';
approveButton.data = element;
approveButton.onclick = function(event) {
console.log(element)
socket.emit('message', JSON.stringify({type:'function', data:element}));
event.currentTarget.disabled = true;
};
// 将按钮添加到消息气泡中
requestMessage.innerHTML = `<b>Function:</b> ${element.name}(${JSON.stringify(element.arguments)})<br>`;
requestMessage.appendChild(approveButton);
document.getElementById('chatbox').appendChild(requestMessage);
document.getElementById('chatbox').scrollTop = document.getElementById('chatbox').scrollHeight;
}
} catch (error) {
console.log(error)
}
});
socket.on('next_chapter', function(data){
next_chapter(data);
});
socket.on('chapter_score',function(data){
if (typeof data === 'string'){
data = JSON.parse(data);
}
console.log(data)
const scoreMessage = document.createElement('div');
scoreMessage.className = 'chat-message server-message';
scoreMessage.innerHTML = `<b>Chapter ${data.chapter_id} Score:</b> ${data.data}`;
document.getElementById('chatbox').appendChild(scoreMessage);
document.getElementById('chatbox').scrollTop = document.getElementById('chatbox').scrollHeight;
})
});
@@ -33,19 +76,32 @@ fontSizeSlider.addEventListener('input', function() {
// 语言切换按钮
const englishRadio = document.getElementById('english');
const chineseRadio = document.getElementById('chinese');
let language = 'en'; // 默认语言
const englishLabel = document.getElementById('label_for_en');
const chineseLabel = document.getElementById('label_for_zh');
let language = 'zh'; // 默认语言
// 切换语言事件
englishRadio.addEventListener('change', function() {
if (englishRadio.checked) language = 'en';
if (englishRadio.checked) {
language = 'en';
englishLabel.classList.add('active');
chineseLabel.classList.remove('active');
}
socket.emit('language',language);
});
chineseRadio.addEventListener('change', function() {
if (chineseRadio.checked) language = 'zn';
if (chineseRadio.checked) {
language = 'zh';
chineseLabel.classList.add('active');
englishLabel.classList.remove('active');
}
socket.emit('language',language);
});
// 发送消息
function sendMessage() {
const input = document.getElementById('messageInput').value;
@@ -60,7 +116,7 @@ function sendMessage() {
document.getElementById('chatbox').appendChild(userMessage);
// 发送消息到服务器
socket.emit('message', input);
socket.emit('message', JSON.stringify({data: input, type:'text'}));
// 清空输入框
document.getElementById('messageInput').value = '';
@@ -69,3 +125,95 @@ function sendMessage() {
document.getElementById('chatbox').scrollTop = document.getElementById('chatbox').scrollHeight;
}
let currentChapterIndex = -1;
function next_chapter(data) {
// 获取所有的 h3 元素
var iframe = document.getElementById('markdown-content-iframe');
// 访问 iframe 的文档对象
var iframeDocument = iframe.contentDocument || iframe.contentWindow.document;
var titles = []
var h3Elements = iframeDocument.querySelectorAll('h3');
console.log("h3Elements next")
if (currentChapterIndex >= h3Elements.length) {
return; // 如果已经到了最后一个章节,则不进行任何操作
}
// 隐藏当前章节及其后的内容
for (let i = 0; i < h3Elements.length; i++) {
h3Elements[i].style.display = 'none';
titles.push(h3Elements[i].innerText)
let nextSibling = h3Elements[i].nextElementSibling;
while (nextSibling && nextSibling.tagName !== 'H3') {
nextSibling.style.display = 'none';
nextSibling = nextSibling.nextElementSibling;
}
}
// 显示下一个章节及其后的内容直到再下一个h3元素或结束
if (currentChapterIndex + 1 < h3Elements.length) {
h3Elements[currentChapterIndex + 1].style.display = 'block';
let nextSibling = h3Elements[currentChapterIndex + 1].nextElementSibling;
while (nextSibling && nextSibling.tagName !== 'H3') {
nextSibling.style.display = 'block';
nextSibling = nextSibling.nextElementSibling;
}
}
currentChapterIndex++;
generateProgressBar(h3Elements.length, currentChapterIndex, titles);
}
function generateProgressBar(N, idx, titles) {
const container = document.getElementById('markdown-content-process');
container.innerHTML = ''; // 清空内容
// 创建进度条的外框
const progressBox = document.createElement('div');
progressBox.className = 'progress-box';
// 获取详细信息容器
const detailBox = document.getElementById('progress-detail');
// 根据N值动态调整每个进度节点的宽度
const nodeWidth = 100 / N; // 每个节点的宽度为 100% / N
// 根据N值生成子框并设置颜色
for (let i = 0; i < N; i++) {
const titleBox = document.createElement('div');
titleBox.className = 'progress-title';
// 设置进度条的颜色
if (i < idx) {
titleBox.classList.add('green'); // 已完成部分
} else {
titleBox.classList.add('white'); // 未完成部分
}
// 设置每个子框的标题
titleBox.innerHTML = titles[i] || `Step ${i + 1}`;
// 设置每个进度节点的宽度
titleBox.style.width = `${nodeWidth}%`;
// 监听鼠标移入事件来显示详情
titleBox.addEventListener('mouseenter', function() {
detailBox.innerHTML = `Step ${i + 1}: ${titles[i] || "No title"}`;// - Additional details here...`;
detailBox.style.display = 'block';
// 根据进度条位置显示详情
const rect = titleBox.getBoundingClientRect();
detailBox.style.top = `${rect.top + window.scrollY - 100}px`; // 微调位置
detailBox.style.left = `${rect.left + window.scrollX + rect.width / 2 - detailBox.offsetWidth / 2}px`;
});
// 监听鼠标移出事件来隐藏详情
titleBox.addEventListener('mouseleave', function() {
detailBox.style.display = 'none';
});
progressBox.appendChild(titleBox);
}
// 将生成的进度条添加到容器中
container.appendChild(progressBox);
}

123
Html/static/js/dashboard.js Normal file
View File

@@ -0,0 +1,123 @@
// dashboard.js
function openCourseProgress(courseId) {
const courseData = {
'algorithm': {
title: '算法分析与设计',
progress: '50%',
chapters: [
{
title: '第一章: 算法基础',
subChapters: [
{ title: '子章节1: 算法介绍', path: 'introduction' },
{ title: '子章节2: 时间复杂度分析', path: 'time-complexity' }
]
},
{
title: '第二章: 排序与查找',
subChapters: [
{ title: '子章节1: 排序算法', path: 'sorting-algorithms' },
{ title: '子章节2: 查找算法', path: 'searching-algorithms' }
]
},
{
title: '第三章: 图算法',
subChapters: [
{ title: '子章节1: 图的表示', path: 'graph-representation' },
{ title: '子章节2: DFS 与 BFS', path: 'dfs-bfs' }
]
}
]
},
'data-structures': {
title: '数据结构与算法',
progress: '30%',
chapters: [
{
title: '第一章: 数组与链表',
subChapters: [
{ title: '子章节1: 数组基础', path: 'array-basics' },
{ title: '子章节2: 链表实现', path: 'linked-list' }
]
},
{
title: '第二章: 栈与队列',
subChapters: [
{ title: '子章节1: 栈的实现', path: 'stack-implementation' },
{ title: '子章节2: 队列的应用', path: 'queue-application' }
]
},
{
title: '第三章: 二叉树',
subChapters: [
{ title: '子章节1: 二叉树的遍历', path: 'binary-tree-traversal' },
{ title: '子章节2: 二叉查找树', path: 'binary-search-tree' }
]
}
]
}
// 可以继续添加其他课程的数据
};
// 获取对应课程的数据
const course = courseData[courseId];
if (!course) return;
// 更新右侧滑出卡片的内容
document.getElementById('course-title').textContent = course.title;
document.getElementById('progress').textContent = course.progress;
// 更新章节列表
const chapterList = document.getElementById('chapter-list');
chapterList.innerHTML = ''; // 清空之前的章节
course.chapters.forEach(chapter => {
const chapterItem = document.createElement('li');
chapterItem.classList.add('chapter-item');
const chapterTitle = document.createElement('div');
chapterTitle.classList.add('chapter-title');
chapterTitle.textContent = chapter.title;
chapterItem.appendChild(chapterTitle);
// 创建子章节
if (chapter.subChapters && chapter.subChapters.length > 0) {
const subChapterList = document.createElement('ul');
subChapterList.classList.add('sub-chapter-list');
chapter.subChapters.forEach(subChapter => {
const subChapterItem = document.createElement('li');
subChapterItem.classList.add('sub-chapter-item');
subChapterItem.textContent = subChapter.title;
// 添加点击事件跳转到学习页面
subChapterItem.addEventListener('click', () => {
const userId = 'userid'; // 这里可以动态传入当前用户ID
const courseName = encodeURIComponent(course.title); // 对课程名称进行编码
const subChapterPath = subChapter.path; // 子章节路径
const url = `/desktop/${userId}/${courseName}/${subChapterPath}`;
window.location.href = url; // 跳转到该学习页面
});
subChapterList.appendChild(subChapterItem);
});
chapterItem.appendChild(subChapterList);
// 添加点击事件切换子章节显示
chapterItem.addEventListener('click', () => {
chapterItem.classList.toggle('open');
});
}
chapterList.appendChild(chapterItem);
});
// 打开滑出卡片
document.getElementById('courseProgress').classList.add('open');
}
function closeCourseProgress() {
// 关闭滑出卡片
document.getElementById('courseProgress').classList.remove('open');
}

60
Html/static/js/login.js Normal file
View File

@@ -0,0 +1,60 @@
document.addEventListener('DOMContentLoaded', function() {
// 获取登录表单及按钮
const loginForm = document.querySelector('.login-form');
const loginButton = document.querySelector('.login-btn');
const usernameInput = document.getElementById('username');
const passwordInput = document.getElementById('password');
// 在点击登录按钮时提交表单
loginButton.addEventListener('click', function(event) {
event.preventDefault(); // 防止表单的默认提交行为
// 获取输入框的值
const username = usernameInput.value.trim();
const password = passwordInput.value.trim();
// 检查输入框是否为空
if (!username || !password) {
alert('用户名和密码不能为空');
return;
}
// 显示加载提示
loginButton.innerHTML = '登录中...';
loginButton.disabled = true;
// 创建一个请求对象
const data = {
username: username,
password: password
};
// 使用 Fetch API 发送 POST 请求到 Flask 后端
fetch('/login_post', {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify(data) // 将数据转换为 JSON 格式发送
})
.then(response => response.json()) // 解析响应数据
.then(data => {
if (data.success) {
// 登录成功,跳转到主页
window.location.href = '/dashboard'; // 根据需要修改跳转的路径
} else {
// 登录失败,提示错误信息
alert('登录失败: ' + data.message);
}
})
.catch(error => {
console.error('Error:', error);
alert('登录请求失败,请稍后重试');
})
.finally(() => {
// 恢复按钮状态
loginButton.innerHTML = '登录';
loginButton.disabled = false;
});
});
});