<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>学生信息管理系统</title>
<!-- 外部资源引入 -->
<script src="https://cdn.jsdelivr.net/npm/jquery@3.7.1/dist/jquery.min.js"></script>
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/css/bootstrap.min.css" rel="stylesheet">
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap-icons@1.10.5/font/bootstrap-icons.css">
<!-- 样式模块:按功能划分 -->
<style>
/* 1. 全局基础样式 */
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
body {
font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
overflow-x: hidden;
background-color: #f8f9fa;
}
/* 2. 侧边栏样式 */
.sidebar {
position: fixed;
top: 0;
left: 0;
height: 100vh;
width: 220px;
background-color: #2c3e50;
color: #fff;
padding-top: 20px;
box-shadow: 2px 0 5px rgba(0,0,0,0.1);
transition: all 0.3s ease;
z-index: 1000;
}
.sidebar-header {
text-align: center;
padding: 0 20px 20px;
border-bottom: 1px solid #34495e;
margin-bottom: 20px;
}
.sidebar-header h2 {
font-size: 1.5rem;
color: #ecf0f1;
}
.nav-menu {
list-style: none;
}
.nav-item .nav-link {
display: flex;
align-items: center;
padding: 12px 20px;
color: #bdc3c7;
text-decoration: none;
transition: all 0.3s;
}
.nav-item .nav-link:hover,
.nav-item .nav-link.active {
background-color: #34495e;
color: #fff;
padding-left: 25px;
}
.nav-link i {
margin-right: 10px;
width: 20px;
text-align: center;
}
/* 3. 主内容区样式 */
.main-content {
margin-left: 220px;
padding: 30px;
transition: all 0.3s ease;
min-height: 100vh;
}
.content-header {
margin-bottom: 20px;
padding-bottom: 15px;
border-bottom: 1px solid #e9ecef;
}
.content-header h1 {
font-size: 1.8rem;
color: #2c3e50;
}
/* 4. 功能组件样式 */
.search-container {
margin-bottom: 20px;
display: flex;
align-items: center;
gap: 10px;
flex-wrap: wrap;
}
#searchInput {
flex-grow: 1;
max-width: 400px;
}
.operation-btn {
margin: 0 5px;
}
.debug-info {
margin-top: 20px;
padding: 15px;
background-color: #f8f9fa;
border-radius: 5px;
display: none;
border: 1px solid #e9ecef;
}
/* 5. 模态框样式 */
.modal {
display: none;
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
background: rgba(0,0,0,0.5);
z-index: 1050;
align-items: center;
justify-content: center;
}
.modal-content {
background: #fff;
padding: 25px;
width: 100%;
max-width: 500px;
border-radius: 8px;
box-shadow: 0 5px 15px rgba(0,0,0,0.2);
position: relative;
}
.close {
position: absolute;
top: 15px;
right: 20px;
font-size: 24px;
cursor: pointer;
color: #6c757d;
transition: color 0.2s;
}
.close:hover {
color: #dc3545;
}
/* 6. 提示消息样式 */
.status-message {
position: fixed;
top: 20px;
right: 20px;
padding: 15px 20px;
border-radius: 5px;
color: #fff;
z-index: 2000;
display: none;
box-shadow: 0 3px 10px rgba(0,0,0,0.2);
}
.status-success {
background-color: #28a745;
}
.status-error {
background-color: #dc3545;
}
/* 7. 表格样式 */
.table-responsive {
background-color: #fff;
border-radius: 8px;
box-shadow: 0 2px 5px rgba(0,0,0,0.05);
overflow: hidden;
}
/* 8. 响应式适配 */
@media (max-width: 768px) {
.sidebar {
width: 70px;
}
.sidebar-header h2,
.nav-link span {
display: none;
}
.nav-link {
justify-content: center;
padding: 15px 0 !important;
}
.nav-link i {
margin-right: 0;
font-size: 1.2rem;
}
.main-content {
margin-left: 70px;
padding: 15px;
}
}
</style>
</head>
<body>
<!-- 状态提示组件 -->
<div class="status-message" id="statusMessage"></div>
<!-- 侧边栏导航 -->
<div class="sidebar">
<div class="sidebar-header">
<h2>学生管理系统</h2>
</div>
<ul class="nav-menu">
<li class="nav-item">
<a href="#" class="nav-link active" data-page="student-list">
<i class="bi bi-people"></i>
<span>学生信息管理</span>
</a>
</li>
<li class="nav-item">
<a href="#" class="nav-link" data-page="statistics">
<i class="bi bi-bar-chart"></i>
<span>数据统计分析</span>
</a>
</li>
<li class="nav-item">
<a href="#" class="nav-link" data-page="settings">
<i class="bi bi-gear"></i>
<span>系统设置</span>
</a>
</li>
</ul>
</div>
<!-- 主内容区域 -->
<div class="main-content">
<div class="content-header">
<h1>学生信息列表</h1>
</div>
<!-- 搜索与操作按钮区 -->
<div class="search-container">
<input type="text" id="searchInput" class="form-control" placeholder="请输入学号或姓名搜索...">
<button id="searchBtn" class="btn btn-secondary">搜索</button>
<button id="resetBtn" class="btn btn-outline-secondary">重置</button>
<button id="addBtn" class="btn btn-primary ms-auto">新增学生</button>
<button id="toggleDebug" class="btn btn-info">显示调试</button>
</div>
<!-- 学生表格 -->
<div class="table-responsive">
<table class="table table-bordered table-striped">
<thead class="table-light">
<tr>
<th>学号</th>
<th>姓名</th>
<th>密码</th>
<th>年级</th>
<th>专业</th>
<th>电话</th>
<th>操作</th>
</tr>
</thead>
<tbody id="studentTable">
<!-- 数据通过JS动态渲染 -->
</tbody>
</table>
</div>
<!-- 调试信息区 -->
<div class="debug-info" id="debugInfo">
<h5 class="fw-bold">调试信息</h5>
<pre id="debugLog" class="mb-0"></pre>
</div>
</div>
<!-- 新增/编辑模态框 -->
<div id="studentModal" class="modal">
<div class="modal-content">
<span class="close">×</span>
<h3 id="modalTitle" class="mb-4">新增学生</h3>
<form id="studentForm">
<input type="hidden" id="studentId"> <!-- 隐藏ID,用于编辑 -->
<!-- 姓名输入 -->
<div class="mb-3">
<label for="stuname" class="form-label">姓名 <span class="text-danger">*</span></label>
<input type="text" class="form-control" id="stuname" required>
<div class="text-danger small mt-1" id="stunameError" style="display: none;">请输入姓名</div>
</div>
<!-- 密码输入 -->
<div class="mb-3">
<label for="password" class="form-label">密码 <span class="text-danger">*</span></label>
<input type="text" class="form-control" id="password" required>
<div class="text-danger small mt-1" id="passwordError" style="display: none;">请输入密码</div>
</div>
<!-- 年级输入 -->
<div class="mb-3">
<label for="grade" class="form-label">年级 <span class="text-danger">*</span></label>
<input type="text" class="form-control" id="grade" required placeholder="如:2023">
<div class="text-danger small mt-1" id="gradeError" style="display: none;">请输入年级</div>
</div>
<!-- 专业输入 -->
<div class="mb-3">
<label for="major" class="form-label">专业 <span class="text-danger">*</span></label>
<input type="text" class="form-control" id="major" required>
<div class="text-danger small mt-1" id="majorError" style="display: none;">请输入专业</div>
</div>
<!-- 电话输入 -->
<div class="mb-3">
<label for="phone" class="form-label">电话 <span class="text-danger">*</span></label>
<input type="tel" class="form-control" id="phone" required placeholder="如:13800138000">
<div class="text-danger small mt-1" id="phoneError" style="display: none;">请输入有效电话</div>
</div>
<!-- 提交按钮 -->
<button type="submit" class="btn btn-success w-100">保存</button>
</form>
</div>
</div>
<script>
// 1. 系统配置(集中管理,便于修改)
const SystemConfig = {
API_BASE_URL: "http://localhost:8080", // 后端接口根地址
ID_FIELD: "studentId", // 学生ID字段名(与后端一致)
STATUS_DURATION: 3000 // 提示消息显示时长(毫秒)
};
// 2. DOM元素缓存(避免重复查询DOM)
const DOM = {
// 表格相关
studentTable: $("#studentTable"),
searchInput: $("#searchInput"),
searchBtn: $("#searchBtn"),
resetBtn: $("#resetBtn"),
addBtn: $("#addBtn"),
// 模态框相关
studentModal: $("#studentModal"),
modalTitle: $("#modalTitle"),
studentForm: $("#studentForm"),
studentId: $("#studentId"),
stuname: $("#stuname"),
password: $("#password"),
grade: $("#grade"),
major: $("#major"),
phone: $("#phone"),
// 提示与调试
statusMessage: $("#statusMessage"),
toggleDebug: $("#toggleDebug"),
debugInfo: $("#debugInfo"),
debugLog: $("#debugLog"),
closeBtn: $(".close")
};
// 3. 工具函数(提取公共逻辑)
const Tool = {
/**
* 日志记录(控制台+页面调试区)
* @param {string} message - 日志内容
*/
log: function(message) {
const time = new Date().toLocaleTimeString();
const logText = `[${time}] ${message}\n`;
// 页面调试区显示
DOM.debugLog.prepend(logText);
// 控制台显示
console.log(`[调试] ${message}`);
},
/**
* 显示状态提示
* @param {string} message - 提示内容
* @param {boolean} isSuccess - 是否成功(true=绿色,false=红色)
*/
showStatus: function(message, isSuccess = true) {
DOM.statusMessage
.text(message)
.removeClass("status-success status-error")
.addClass(isSuccess ? "status-success" : "status-error")
.fadeIn(300);
// 自动隐藏
setTimeout(() => {
DOM.statusMessage.fadeOut(500);
}, SystemConfig.STATUS_DURATION);
},
/**
* AJAX错误统一处理
* @param {string} defaultMsg - 默认错误提示
* @returns {function} 错误处理函数
*/
handleAjaxError: function(defaultMsg) {
return function(xhr) {
let errorMsg = defaultMsg;
try {
const res = JSON.parse(xhr.responseText);
errorMsg = `${defaultMsg}:${res.message || res.msg || xhr.statusText}`;
} catch (e) {
errorMsg = `${defaultMsg}:${xhr.status} - ${xhr.statusText}`;
}
Tool.log(`AJAX错误:${errorMsg}`);
Tool.showStatus(errorMsg, false);
};
}
};
// 4. 业务逻辑(核心功能)
const StudentService = {
/**
* 初始化页面(入口函数)
*/
init: function() {
Tool.log("页面加载完成,开始初始化");
this.bindEvents(); // 绑定所有事件
this.loadStudents(); // 加载学生列表
},
/**
* 绑定所有页面事件
*/
bindEvents: function() {
// 导航栏切换
$(".nav-link").on("click", function(e) {
e.preventDefault();
$(".nav-link").removeClass("active");
$(this).addClass("active");
});
// 搜索按钮
DOM.searchBtn.on("click", () => this.searchStudents());
// 重置按钮
DOM.resetBtn.on("click", () => {
DOM.searchInput.val("");
this.loadStudents();
});
// 回车键搜索
DOM.searchInput.on("keypress", (e) => {
if (e.which === 13) this.searchStudents();
});
// 新增按钮
DOM.addBtn.on("click", () => this.openModalForAdd());
// 关闭模态框
DOM.closeBtn.on("click", () => this.closeModal());
// 点击模态框外部关闭
$(window).on("click", (e) => {
if (e.target === DOM.studentModal[0]) this.closeModal();
});
// 表单提交(新增/编辑)
DOM.studentForm.on("submit", (e) => {
e.preventDefault();
this.submitForm();
});
// 调试开关
DOM.toggleDebug.on("click", () => {
DOM.debugInfo.toggle();
});
// 表格操作按钮(动态渲染后绑定)
DOM.studentTable.on("click", ".edit-btn", (e) => {
const id = $(e.currentTarget).data("id");
this.openModalForEdit(id);
});
DOM.studentTable.on("click", ".delete-btn", (e) => {
const id = $(e.currentTarget).data("id");
this.deleteStudent(id);
});
},
/**
* 加载所有学生列表
*/
loadStudents: function() {
Tool.log("开始加载学生数据");
$.ajax({
url: `${SystemConfig.API_BASE_URL}/student`,
type: "GET",
dataType: "json",
success: (students) => {
Tool.log(`成功加载 ${students.length} 条学生数据`);
this.renderTable(students);
},
error: Tool.handleAjaxError("加载学生列表失败")
});
},
/**
* 搜索学生(按学号/姓名)
*/
searchStudents: function() {
const keyword = DOM.searchInput.val().trim();
Tool.log(`搜索关键词:${keyword}`);
if (!keyword) {
this.loadStudents();
return;
}
$.ajax({
url: `${SystemConfig.API_BASE_URL}/student/search`,
type: "GET",
data: { keyword },
dataType: "json",
success: (students) => {
Tool.log(`搜索到 ${students.length} 条匹配数据`);
this.renderTable(students);
},
error: Tool.handleAjaxError("搜索学生失败")
});
},
/**
* 渲染学生表格
* @param {Array} students - 学生数据数组
*/
renderTable: function(students) {
DOM.studentTable.empty();
// 空数据提示
if (students.length === 0) {
DOM.studentTable.append(`
<tr>
<td colspan="7" class="text-center py-3 text-muted">
没有找到匹配的学生信息
</td>
</tr>
`);
return;
}
// 渲染数据行
students.forEach(student => {
const id = student[SystemConfig.ID_FIELD] || "未知";
const row = `
<tr>
<td>${id}</td>
<td>${student.stuname || "未知"}</td>
<td>******</td> <!-- 密码脱敏 -->
<td>${student.grade || "未知"}</td>
<td>${student.major || "未知"}</td>
<td>${student.phone || "未知"}</td>
<td>
<button class="btn btn-warning btn-sm operation-btn edit-btn"
data-id="${id}">编辑</button>
<button class="btn btn-danger btn-sm operation-btn delete-btn"
data-id="${id}">删除</button>
</td>
</tr>
`;
DOM.studentTable.append(row);
});
},
/**
* 打开新增学生模态框
*/
openModalForAdd: function() {
Tool.log("打开新增学生模态框");
// 重置表单
DOM.studentForm[0].reset();
DOM.studentId.val("");
// 隐藏错误提示
this.hideAllErrors();
// 设置标题并显示
DOM.modalTitle.text("新增学生");
DOM.studentModal.css("display", "flex");
},
/**
* 打开编辑学生模态框
* @param {string} id - 学生ID
*/
openModalForEdit: function(id) {
if (!id || id === "未知") {
Tool.showStatus("学生ID无效", false);
return;
}
Tool.log(`打开编辑模态框,学生ID:${id}`);
$.ajax({
url: `${SystemConfig.API_BASE_URL}/student/${id}`,
type: "GET",
dataType: "json",
success: (student) => {
if (!student) {
Tool.showStatus(`未找到ID为${id}的学生`, false);
return;
}
// 填充表单数据
DOM.studentId.val(student[SystemConfig.ID_FIELD] || "");
DOM.stuname.val(student.stuname || "");
DOM.password.val(student.password || "");
DOM.grade.val(student.grade || "");
DOM.major.val(student.major || "");
DOM.phone.val(student.phone || "");
// 隐藏错误提示并显示模态框
this.hideAllErrors();
DOM.modalTitle.text("编辑学生");
DOM.studentModal.css("display", "flex");
},
error: Tool.handleAjaxError(`加载ID为${id}的学生数据失败`)
});
},
/**
* 关闭模态框
*/
closeModal: function() {
DOM.studentModal.css("display", "none");
},
/**
* 表单验证
* @returns {boolean} 验证结果(true=通过,false=不通过)
*/
validateForm: function() {
let isValid = true;
const stuname = DOM.stuname.val().trim();
const password = DOM.password.val().trim();
const grade = DOM.grade.val().trim();
const major = DOM.major.val().trim();
const phone = DOM.phone.val().trim();
// 姓名验证
if (!stuname) {
$("#stunameError").show();
isValid = false;
} else {
$("#stunameError").hide();
}
// 密码验证
if (!password) {
$("#passwordError").show();
isValid = false;
} else {
$("#passwordError").hide();
}
// 年级验证
if (!grade) {
$("#gradeError").show();
isValid = false;
} else {
$("#gradeError").hide();
}
// 专业验证
if (!major) {
$("#majorError").show();
isValid = false;
} else {
$("#majorError").hide();
}
// 电话验证(简单格式)
const phoneReg = /^1[3-9]\d{9}$/;
if (!phone || !phoneReg.test(phone)) {
$("#phoneError").text("请输入有效手机号");
$("#phoneError").show();
isValid = false;
} else {
$("#phoneError").hide();
}
return isValid;
},
/**
* 隐藏所有表单错误提示
*/
hideAllErrors: function() {
$("#stunameError, #passwordError, #gradeError, #majorError, #phoneError").hide();
},
/**
* 提交表单(新增/编辑)
*/
submitForm: function() {
Tool.log("开始提交表单");
// 表单验证
if (!this.validateForm()) {
Tool.log("表单验证失败");
return;
}
// 构建提交数据
const studentData = {
stuname: DOM.stuname.val().trim(),
password: DOM.password.val().trim(),
grade: DOM.grade.val().trim(),
major: DOM.major.val().trim(),
phone: DOM.phone.val().trim()
};
// 编辑模式:添加ID
const studentId = DOM.studentId.val().trim();
const isEdit = !!studentId;
if (isEdit) {
studentData[SystemConfig.ID_FIELD] = studentId;
}
// 发送请求
$.ajax({
url: `${SystemConfig.API_BASE_URL}/student`,
type: isEdit ? "PUT" : "POST",
contentType: "application/json",
data: JSON.stringify(studentData),
success: () => {
const msg = isEdit ? "学生信息更新成功" : "新学生添加成功";
Tool.log(msg);
Tool.showStatus(msg);
this.closeModal(); // 关闭模态框
this.loadStudents(); // 重新加载列表
},
error: Tool.handleAjaxError(isEdit ? "更新学生失败" : "新增学生失败")
});
},
/**
* 删除学生
* @param {string} id - 学生ID
*/
deleteStudent: function(id) {
if (!confirm("确定要删除这条学生记录吗?删除后不可恢复!")) {
return;
}
if (!id || id === "未知") {
Tool.showStatus("学生ID无效,删除失败", false);
return;
}
Tool.log(`开始删除学生,ID:${id}`);
$.ajax({
url: `${SystemConfig.API_BASE_URL}/student/${id}`,
type: "DELETE",
success: () => {
const msg = `ID为${id}的学生已删除`;
Tool.log(msg);
Tool.showStatus(msg);
this.loadStudents(); // 重新加载列表
},
error: Tool.handleAjaxError(`删除ID为${id}的学生失败`)
});
}
};
// 5. 页面加载完成后初始化
$(document).ready(() => {
StudentService.init();
});
</script>
</body>
</html>页面不显示,数据库显示,代码怎么修改