一.前端代码
addClass.html
<!DOCTYPE html>:指定这是一个HTML5文档类型的页面。
<html lang="zh-CN" xmlns:th="http://www.thymeleaf.org">:HTML页面的根元素,lang属性定义了文档语言为中文,xmlns:th定义了thymeleaf命名空间。
<head th:replace="adminCommon::common-header"></head>:页面的头部,使用th:replace指令引用了名为adminCommon::common-header的模板。
<body class="sb-nav-fixed">:页面的主体,定义了一个样式类sb-nav-fixed。
<nav th:replace="adminCommon::common-navbar"></nav>:页面的导航栏,使用th:replace指令引用了名为adminCommon::common-navbar的模板。
<div id="layoutSidenav">:整个页面的布局容器。
<div th:replace="adminCommon::common-sidenav"></div>:页面的侧边栏,使用th:replace指令引用了名为adminCommon::common-sidenav的模板。
<div id="layoutSidenav_content">:页面内容的主要容器。
<main>:页面的主要内容。
<!-- 这是一个包含添加课程表单的页面 -->
<div class="container-fluid px-4">
<!-- 页面标题 -->
<h1 class="mt-4">添加课程</h1>
<!-- 面包屑导航栏,用于指示当前页面所处的位置 -->
<ol class="breadcrumb mb-4">
<li class="breadcrumb-item"><a th:href="@{/toAdminMain}">主页</a></li>
<li class="breadcrumb-item"><a th:href="@{/class/selClass}">课程管理</a></li>
<li class="breadcrumb-item active">添加课程</li>
</ol>
<!-- 添加课程的表单 -->
<div class="card mb-4">
<!-- 表单提交时调用 beforeSubmit() 函数进行校验 -->
<form th:action="@{/class/addClass}" method="post" name="addForm" onsubmit="return beforeSubmit(this)">
<!-- 课程信息表格 -->
<table class="table table-hover">
<!-- 编号输入框 -->
<tr>
<td text-align="center">编号:</td>
<td><input type="text" class="form-control" placeholder="4位编号" name="classId"></td>
</tr>
<!-- 名称输入框 -->
<tr>
<td text-align="center">名称:</td>
<td><input type="text" class="form-control" placeholder="课程名称" name="className"></td>
</tr>
<!-- 时间输入框 -->
<tr>
<td text-align="center">时间:</td>
<td><input type="text" class="form-control" placeholder="xxxx年xx月xx日 00:00" name="classBegin"></td>
</tr>
<!-- 时长输入框 -->
<tr>
<td text-align="center">时长:</td>
<td><input type="text" class="form-control" placeholder="xx分钟" name="classTime"></td>
</tr>
<!-- 教练输入框 -->
<tr>
<td text-align="center">教练:</td>
<td><input type="text" class="form-control" placeholder="教练" name="coach"></td>
</tr>
</table>
<!-- 提交按钮 -->
<div style="text-align:center;margin-top:20px;margin-bottom:20px">
<input type="submit" class="btn btn-outline-success" value="添加">
</div>
</form>
</div>
</div>
<!-- 页面底部 -->
<main role="main" class="flex-shrink-0">
<footer th:replace="adminCommon::common-footer"></footer>
</main>
<!-- 通用的脚本文件 -->
<div th:include="adminCommon::common-scripts"></div>
<!-- JavaScript 校验函数 -->
<script type="text/javascript">
function beforeSubmit(addForm) {
// 检查各个输入框是否为空
if (addForm.classId.value == "") {
alert("请输入课程编号!")
return false;
}
if (addForm.className.value == "") {
alert("请输入课程名称!")
return false;
}
if (addForm.classBegin.value == "") {
alert("请输入课程时间!")
return false;
}
if (addForm.classTime.value == "") {
alert("请输入课程时长!")
return false;
}
if (addForm.coach.value == "") {
alert("请输入教练!")
return false;
}
return true;
}
</script>
</body>
</html>
部分代码解析如下
1.<html lang="zh-CN" xmlns:th="http://www.thymeleaf.org">
这是一个HTML页面的开头,其中定义了两个属性: "lang" 和 "xmlns:th"。
"lang" 属性用于指定当前页面的语言,这里是 "zh-CN",表示该页面使用中文语言。
"xmlns:th" 属性是为了支持 Thymeleaf 模板引擎。它定义了一个命名空间 "http://www.thymeleaf.org",使得在 HTML 页面中可以使用 Thymeleaf 提供的特定语法和功能,例如使用 th:text 属性来动态绑定文本内容。该命名空间定义后,需要在后续使用 Thymeleaf 的标签或属性时,添加该命名空间前缀 "th:",以示区别。
2.<head th:replace="adminCommon::common-header"></head>
这是 Thymeleaf 模板引擎中的语法,用于将指定页面片段(片段通常是一组 HTML 元素)插入到当前 HTML 页面的<head>标签中。
在这个例子中,th:replace 属性指定了要插入的页面片段的位置和名称,即 adminCommon::common-header。其中 adminCommon 是指定该片段所在的模板,common-header 是该模板中一个命名为 common-header 的片段。
当 Thymeleaf 引擎解析这个页面时,它将在指定的位置插入该片段,即将 adminCommon 模板中的 common-header 片段的 HTML 内容插入到当前 HTML 页面的<head>标签中。这通常用于在不同页面中共享一些公共的 HTML 元素或代码,避免重复编写和维护。
3.<nav th:replace="adminCommon::common-navbar"></nav>
这是 Thymeleaf 模板引擎中的语法,用于将指定页面片段(片段通常是一组 HTML 元素)插入到当前 HTML 页面的<nav>标签中。
在这个例子中,th:replace 属性指定了要插入的页面片段的位置和名称,即 adminCommon::common-navbar。其中 adminCommon 是指定该片段所在的模板,common-navbar 是该模板中一个命名为 common-navbar 的片段。
当 Thymeleaf 引擎解析这个页面时,它将在指定的位置插入该片段,即将 adminCommon 模板中的 common-navbar 片段的 HTML 内容插入到当前 HTML 页面的<nav>标签中。这通常用于在不同页面中共享一些公共的 HTML 元素或代码,避免重复编写和维护。在这个例子中,common-navbar 片段可能包含了整个网站的导航栏的 HTML 内容。
4.<div th:replace="adminCommon::common-sidenav"></div>
这是 Thymeleaf 模板引擎中的语法,用于将指定页面片段(片段通常是一组 HTML 元素)插入到当前 HTML 页面的<div>标签中。
在这个例子中,th:replace 属性指定了要插入的页面片段的位置和名称,即 adminCommon::common-sidenav。其中 adminCommon 是指定该片段所在的模板,common-sidenav 是该模板中一个命名为 common-sidenav 的片段。
当 Thymeleaf 引擎解析这个页面时,它将在指定的位置插入该片段,即将 adminCommon 模板中的 common-sidenav 片段的 HTML 内容插入到当前 HTML 页面的<div>标签中。这通常用于在不同页面中共享一些公共的 HTML 元素或代码,避免重复编写和维护。在这个例子中,common-sidenav 片段可能包含了整个网站的侧边栏的 HTML 内容。
5.<li class="breadcrumb-item"><a th:href="@{/toAdminMain}">
这是一个 HTML 页面中的一段代码,它是一个面包屑导航的一部分,用于在页面中展示当前页面的层级结构和访问路径。
在这个例子中,<li>标签表示一个列表项,class="breadcrumb-item" 表示该列表项是面包屑导航中的一个项,会根据样式表的设置来展示样式。其中,breadcrumb 是一个类,用于定义面包屑导航的样式。
在该列表项内部,<a>标签用于定义链接,th:href="@{/toAdminMain}" 表示该链接的地址,这个地址是使用 Thymeleaf 的 URL 模板语法来生成的。它将生成一个相对于应用程序根路径的 URL,其中 /toAdminMain 是一个控制器的映射路径,表示该链接将会访问到控制器的 toAdminMain() 方法。
当用户点击这个链接时,会跳转到 toAdminMain() 方法对应的页面或操作。而面包屑导航的作用是让用户知道他们当前所在的位置,以及可以从当前位置回到前面的位置。
6.<form th:action="@{/class/addClass}" method="post" name="addForm" οnsubmit="return beforeSubmit(this)">
这是一个 HTML 表单的一部分,用于在前端页面中收集用户输入的数据,并将数据提交到服务器。
在这个例子中,th:action="@{/class/addClass}" 表示表单的提交地址,这个地址是使用 Thymeleaf 的 URL 模板语法来生成的。它将生成一个相对于应用程序根路径的 URL,其中 /class/addClass 是一个控制器的映射路径,表示该表单将会提交到控制器的 addClass() 方法进行处理。
method="post" 表示表单数据将会以 POST 方法提交到服务器,这通常用于提交敏感数据或大量数据,以避免将数据暴露在 URL 参数中。
name="addForm" 表示该表单的名称,可以用 JavaScript 或其他脚本语言访问和操作表单的各个元素和数据。
οnsubmit="return beforeSubmit(this)" 表示在表单提交之前将会执行 beforeSubmit() 方法,这个方法通常用于对用户输入的数据进行验证和处理,以确保数据的有效性和合法性。如果 beforeSubmit() 方法返回 false,表单将不会提交到服务器。
7.<input type="text" class="form-control" placeholder="4位编号" name="classId">
这是一个HTML的<input>元素,它用于在前端界面中显示一个文本框。该文本框被定义为一个类为"form-control"的样式,这通常用于在Bootstrap框架中实现一个简洁的文本框。
这个文本框有一个"placeholder"属性,用于在文本框中显示一个占位符文本,这里是"4位编号"。当用户点击文本框并开始输入时,占位符文本将自动消失。
"name"属性用于为此文本框指定一个名称,以便在提交表单时可以获取和处理文本框中的值。在这个例子中,名称为"classId",这意味着在提交表单时,您可以使用"classId"名称来访问这个文本框的值。
8. <div style="text-align:center;margin-top:20px;margin-bottom:20px">
<input type="submit" class="btn btn-outline-success" value="添加">
</div>
这是一个 HTML 表单的一部分,它包含一个提交按钮,用于提交用户在表单中输入的数据到服务器。
在这个例子中,<div> 标签定义了一个带有居中样式和上下间距的容器,<input> 标签定义了一个提交按钮,type="submit" 表示这是一个提交按钮,当用户点击这个按钮时,表单数据将会被提交到服务器。
class="btn btn-outline-success" 表示这是一个样式类,它用于定义按钮的外观和行为。在这个例子中,btn 是用于定义按钮样式的一个类,btn-outline-success 则是一个颜色类,用于将按钮的颜色设置为绿色。
value="添加" 表示按钮的显示文本,即当用户在页面上看到这个按钮时,它所显示的文本内容为“添加”。当用户点击这个按钮时,表单将被提交到表单中指定的地址,即 th:action="@{/class/addClass}" 中定义的地址。
9. <main role="main" class="flex-shrink-0">
<footer th:replace="adminCommon::common-footer"></footer>
</main>
这是一个 HTML 页面的一部分,它包含一个主要内容区域和一个页脚部分。
在这个例子中,<main> 标签用于定义主要内容区域,role="main" 表示该标签的角色是主要内容区域,class="flex-shrink-0" 则是一个样式类,用于控制元素的弹性收缩行为。
<footer> 标签用于定义页脚部分,th:replace="adminCommon::common-footer" 表示该页脚部分是通过 Thymeleaf 模板引擎来生成的,它将会被替换为 adminCommon::common-footer 模板中的内容。
页脚部分通常包含一些版权信息、链接、社交媒体图标等内容,用于提供一些有用的信息或方便用户进行相关操作。
10.<div th:include="adminCommon::common-scripts"></div>
这是一个 HTML 页面的一部分,它引用了一个 Thymeleaf 模板文件 adminCommon::common-scripts 中的内容。
Thymeleaf 是一个服务器端的 Java 模板引擎,它可以将模板文件中的标记、属性和表达式等转换为最终的 HTML 页面,同时还能在模板中嵌入动态数据和逻辑处理。
在这个例子中,<div> 标签用于定义一个容器元素,th:include="adminCommon::common-scripts" 表示该容器元素会包含在 adminCommon::common-scripts 模板文件中定义的内容。
通常,这种技术可以用于将一些通用的代码块和脚本文件抽象出来,以便于在多个页面之间复用和管理。
而 "::" 符号则表示这里使用的是 Thymeleaf 的语法规则,用于将相对路径转换为绝对路径。通常情况下,相对路径会被解析为相对于当前模板文件的路径,而使用 "::" 符号可以将路径从当前模板文件的上级目录开始解析。
11.<script type="text/javascript">
function beforeSubmit(addForm) {
// 检查各个输入框是否为空
if (addForm.classId.value == "") {
alert("请输入课程编号!")
return false;
}
if (addForm.className.value == "") {
alert("请输入课程名称!")
return false;
}
if (addForm.classBegin.value == "") {
alert("请输入课程时间!")
return false;
}
if (addForm.classTime.value == "") {
alert("请输入课程时长!")
return false;
}
if (addForm.coach.value == "") {
alert("请输入教练!")
return false;
}
return true;
}
</script>
这是一个 JavaScript 脚本,用于在提交表单之前进行输入验证。
在这个例子中,该脚本定义了一个名为 beforeSubmit 的函数。当表单提交时,该函数会被调用,它会首先检查各个输入框的值是否为空,如果有任何一个输入框的值为空,就会弹出一个警告框提示用户输入相应的内容,并返回 false 阻止表单提交。
如果所有输入框都不为空,则函数返回 true,表单提交可以继续进行。
这种技术可以提高表单的可靠性和安全性,防止用户输入无效或恶意的数据。同时,它也可以提供更友好的用户体验,使用户可以更轻松地发现和纠正错误。
addEmployee.html
<!DOCTYPE html>
<html lang="zh-CN" xmlns:th="http://www.thymeleaf.org">
<head th:replace="adminCommon::common-header"> <!-- 页面头部引入公共头部页面 -->
</head>
<body class="sb-nav-fixed">
<nav th:replace="adminCommon::common-navbar"></nav> <!-- 导航栏引入公共导航栏页面 -->
<div id="layoutSidenav">
<div th:replace="adminCommon::common-sidenav"></div> <!-- 侧边栏引入公共侧边栏页面 -->
<div id="layoutSidenav_content">
<main>
<div class="container-fluid px-4">
<h1 class="mt-4">添加员工</h1> <!-- 页面主标题 -->
<ol class="breadcrumb mb-4">
<li class="breadcrumb-item"><a th:href="@{/toAdminMain}">主页</a></li> <!-- 面包屑导航,跳转到主页 -->
<li class="breadcrumb-item"><a th:href="@{/employee/selEmployee}">员工管理</a></li>
<!-- 面包屑导航,跳转到员工管理页面 -->
<li class="breadcrumb-item active">添加员工</li> <!-- 面包屑导航,当前页面为添加员工 -->
</ol>
<div class="card mb-4">
<!-- 表单提交,提交到addEmployee处理 -->
<form th:action="@{/employee/addEmployee}" method="post" name="addForm"
onsubmit="return beforeSubmit(this)">
<table class="table table-hover">
<tr>
<td text-align="center">工号:</td>
<!-- 工号自动生成,设置为只读状态 -->
<td><input type="text" class="form-control" placeholder="工号由系统自动生成"
name="employeeAccount" disabled="disabled"></td>
</tr>
<tr>
<td text-align="center">姓名:</td>
<td><input type="text" class="form-control" placeholder="姓名" name="employeeName"></td>
</tr>
<tr>
<td text-align="center">性别:</td>
<td><input type="text" class="form-control" placeholder="性别" name="employeeGender"></td>
</tr>
<tr>
<td text-align="center">年龄:</td>
<td><input type="text" class="form-control" placeholder="年龄" name="employeeAge"></td>
</tr>
<tr>
<td text-align="center">职务:</td>
<td><input type="text" class="form-control" placeholder="职务" name="staff"></td>
</tr>
<tr>
<td text-align="center">备注信息:</td>
<td><input type="text" class="form-control" placeholder="备注信息" name="employeeMessage">
</td>
</tr>
</table>
<div style="text-align:center;margin-top:20px;margin-bottom:20px">
<input type="submit" class="btn btn-outline-success" value="添加"> <!-- 提交按钮 -->
</div>
</form>
</div>
</div>
</main>
<!-- 引入页脚模板 -->
<footer th:replace="adminCommon::common-footer"></footer>
</div>
</div>
<!-- 引入公共脚本模板 -->
<div th:include="adminCommon::common-scripts"></div>
<!-- 客户端JavaScript代码 -->
<script type="text/javascript">
// 声明一个函数beforeSubmit,用于在提交表单前进行数据校验
function beforeSubmit(addForm) {
// 如果姓名为空,弹出提示框并返回false
if (addForm.employeeName.value == "") {
alert("请输入姓名!")
return false;
}
// 如果性别为空,弹出提示框并返回false
if (addForm.employeeGender.value == "") {
alert("请输入性别!")
return false;
}
// 如果年龄为空,弹出提示框并返回false
if (addForm.employeeAge.value == "") {
alert("请输入年龄!")
return false;
}
// 如果职务为空,弹出提示框并返回false
if (addForm.staff.value == "") {
alert("请输入职务!")
return false;
}
// 如果数据校验通过,返回true
return true;
}
</script>
</body>
</html>
1. <form th:action="@{/employee/addEmployee}" method="post" name="addForm"
onsubmit="return beforeSubmit(this)">
这是一个 HTML 表单,用于向服务器提交数据。在这个例子中,该表单定义了以下属性:
th:action="@{/employee/addEmployee}":表示表单提交时将数据发送到服务器上的 /employee/addEmployee URL,这通常是一个处理表单数据的后端控制器。
method="post":表示使用 POST 请求方式提交表单数据,这意味着数据将被包含在 HTTP 请求体中发送给服务器。name="addForm":为表单元素定义了一个名称,以便在 JavaScript 脚本中引用。
οnsubmit="return beforeSubmit(this)":表示在提交表单之前将调用名为 beforeSubmit 的 JavaScript 函数,以进行输入验证和数据处理。通常,HTML 表单是 Web 应用程序中收集和处理用户输入的主要方式之一。在提交表单之前,通常需要对输入数据进行验证和处理,以确保它们符合要求并可以被正确处理。
2.<tr>
<td text-align="center">工号:</td>
<!-- 工号自动生成,设置为只读状态 -->
<td><input type="text" class="form-control" placeholder="工号由系统自动生成"
name="employeeAccount" disabled="disabled"></td>
</tr>
这段 HTML 代码包含一个表格行,用于在一个 HTML 表格中显示员工的工号。该表格行包含了两个表格单元格。第一个表格单元格包含了 "工号:" 文本,该文本将被显示在表格中。它还使用了 text-align 属性来设置单元格内容的水平对齐方式为居中。第二个表格单元格包含了一个输入框,用于显示自动生成的员工工号。该输入框使用了 form-control 类,使其在外观上与其他输入框一致。它还包含了一个 placeholder 属性,用于在输入框中显示提示文本,帮助用户理解输入框的用途。由于工号是系统自动生成的,该输入框被设置为只读状态,并且它的 disabled 属性被设置为 "disabled"。这样用户就不能在此输入框中输入任何内容,只能查看工号的值。
3. <div style="text-align:center;margin-top:20px;margin-bottom:20px">
<input type="submit" class="btn btn-outline-success" value="添加"> <!-- 提交按钮 -->
</div>
这段 HTML 代码包含一个按钮,用于提交表单并将数据发送到服务器进行处理。该按钮被包含在一个 div 元素中,该元素使用了 text-align 属性将按钮设置为居中显示,并且在顶部和底部各留出了一些空白间距,以增加其在视觉上的吸引力。
该按钮使用了 input 元素,类型为 submit,表示它是一个提交按钮。按钮的文本为 "添加",使用了 btn 和 btn-outline-success 类,使其在外观上与其他按钮一致。用户点击该按钮后,浏览器将自动将表单数据发送到 th:action 属性指定的服务器 URL 进行处理。
4. <footer th:replace="adminCommon::common-footer"></footer>
这段 HTML 代码包含了一个 footer 元素,使用了 th:replace 属性来替换为 adminCommon::common-footer 模板片段的内容。这意味着 footer 元素的实际内容将从指定的模板片段中获取,并将其插入到页面中。
这种模板技术可以使网站的开发更加模块化和可重用,因为您可以将不同页面中的相同元素抽象为一个模板,并在需要使用它们的地方引用它们。在这种情况下,adminCommon::common-footer 可能包含网站的版权信息、联系方式或其他类似的内容,因此可以在整个网站的各个页面中重用。
5. <!-- 客户端JavaScript代码 -->
<script type="text/javascript">
// 声明一个函数beforeSubmit,用于在提交表单前进行数据校验
function beforeSubmit(addForm) {
// 如果姓名为空,弹出提示框并返回false
if (addForm.employeeName.value == "") {
alert("请输入姓名!")
return false;
}
// 如果性别为空,弹出提示框并返回false
if (addForm.employeeGender.value == "") {
alert("请输入性别!")
return false;
}
// 如果年龄为空,弹出提示框并返回false
if (addForm.employeeAge.value == "") {
alert("请输入年龄!")
return false;
}
// 如果职务为空,弹出提示框并返回false
if (addForm.staff.value == "") {
alert("请输入职务!")
return false;
}
// 如果数据校验通过,返回true
return true;
}
</script>
这段代码是一段客户端JavaScript代码,用于在前端页面中对表单提交前进行数据校验。代码中声明了一个名为beforeSubmit的函数,该函数的参数为一个表单对象addForm,表示待提交的表单。在该函数中,使用if语句对表单中的各个输入框进行判断,若某个输入框为空,则弹出一个提示框提醒用户,然后返回false以阻止表单提交。若所有输入框都不为空,则返回true,表单可以提交。这样做的目的是为了避免用户在提交表单时漏填了某些必填项,从而保证数据的完整性和准确性。
addEquipment.html
<!DOCTYPE html> <!--文档类型定义为HTML-->
<html lang="zh-CN" xmlns:th="http://www.thymeleaf.org"> <!--定义语言和thymeleaf命名空间-->
<head th:replace="adminCommon::common-header"></head> <!--引用共同的头部信息-->
<body class="sb-nav-fixed"> <!--添加类名,便于样式控制-->
<nav th:replace="adminCommon::common-navbar"></nav> <!--引用共同的导航栏-->
<div id="layoutSidenav"> <!--定义整个页面的布局-->
<div th:replace="adminCommon::common-sidenav"></div> <!--引用共同的侧边栏-->
<div id="layoutSidenav_content"> <!--定义页面主要内容的区域-->
<main>
<div class="container-fluid px-4"> <!--定义内容的容器-->
<h1 class="mt-4">添加器材</h1> <!--页面标题-->
<ol class="breadcrumb mb-4"> <!--面包屑导航-->
<li class="breadcrumb-item"><a th:href="@{/toAdminMain}">主页</a></li>
<li class="breadcrumb-item"><a th:href="@{/equipment/selEquipment}">器材管理</a></li>
<li class="breadcrumb-item active">添加器材</li>
</ol>
<div class="card mb-4"> <!--定义卡片样式-->
<form th:action="@{/equipment/addEquipment}" method="post" name="addForm"
onsubmit="return beforeSubmit(this)"> <!--定义表单,设置提交动作和提交前的函数-->
<table class="table table-hover"> <!--定义表格样式-->
<tr>
<td text-align="center">器材名称:</td> <!--表格行,设置文本内容和样式-->
<td><input type="text" class="form-control" placeholder="名称" name="equipmentName"></td>
<!--表格行,定义文本输入框,设置样式和属性-->
</tr>
<tr>
<td text-align="center">器材位置:</td>
<td><input type="text" class="form-control" placeholder="x号房间" name="equipmentLocation">
</td>
</tr>
<tr>
<td text-align="center">器材状态:</td>
<td><input type="text" class="form-control" placeholder="状态" name="equipmentStatus">
</td>
</tr>
<tr>
<td text-align="center">备注信息:</td>
<td><input type="text" class="form-control" placeholder="备注" name="equipmentMessage">
</td>
</tr>
</table>
<div style="text-align:center;margin-top:20px;margin-bottom:20px"> <!--设置样式-->
<input type="submit" class="btn btn-outline-success" value="添加"> <!--定义提交按钮,设置样式和属性-->
</div>
</form>
</div>
</div>
</main>
<footer th:replace="adminCommon::common-footer"></footer> <!--引用共同的页脚信息-->
</div>
</div>
<!-- 引入公共脚本文件 -->
<div th:include="adminCommon::common-scripts"></div>
<!-- 定义JavaScript函数,用于在提交表单前进行验证 -->
<script type="text/javascript">
function beforeSubmit(addForm) {
// 如果器材名称为空,则提示用户输入器材名称并返回false
if (addForm.equipmentName.value == "") {
alert("请输入器材名称!")
return false;
}
// 如果器材位置为空,则提示用户输入器材位置并返回false
if (addForm.equipmentLocation.value == "") {
alert("请输入器材位置!")
return false;
}
// 如果器材状态为空,则提示用户输入器材状态并返回false
if (addForm.equipmentStatus.value == "") {
alert("请输入器材状态!")
return false;
}
// 如果备注信息为空,则提示用户输入备注信息并返回false
if (addForm.equipmentMessage.value == "") {
alert("请输入备注信息!")
return false;
}
// 如果所有字段都不为空,则返回true,允许提交表单数据
return true;
}
</script>
</body>
</html>
1. <ol class="breadcrumb mb-4"> <!--面包屑导航-->
<li class="breadcrumb-item"><a th:href="@{/toAdminMain}">主页</a></li>
<li class="breadcrumb-item"><a th:href="@{/equipment/selEquipment}">器材管理</a></li>
<li class="breadcrumb-item active">添加器材</li>
</ol>
这段前端代码主要是用于展示一个添加器材的表单页面,包含了以下元素:
表单的action属性为/equipment/addEquipment,表示提交表单后数据将被发送到/equipment/addEquipment的路由上。
表单的method属性为post,表示提交表单时使用POST方法。
表单有一个名为addForm的标识符。
表单中包含多个输入框和标签,如器材编号、器材名称、器材数量、器材价格等。
表单还有一个提交按钮,点击后触发表单提交操n表单的提交按钮还绑定了一个名为beforeSubmit的JavaScript函数,该函数用于在表单提交前进行数据校验,如果校验不通过则阻止表单的提交,并在页面上弹出提示框。
此外,还包含了一些使用Thymeleaf模板引擎的语法,如使用th:replace指令引入其他模板中的代码块,使用th:action指令指定表单提交的路由,使用th:each指令遍历一个列表等。
2. <div style="text-align:center;margin-top:20px;margin-bottom:20px"> <!--设置样式-->
<input type="submit" class="btn btn-outline-success" value="添加"> <!--定义提交按钮,设置样式和属性-->
</div>
这段前端代码定义了一个包含提交按钮的 div 元素,并设置了居中、上边距和下边距的样式。
在这个 div 中,定义了一个 input 元素作为提交按钮,它的类型是 submit,类名为 btn btn-outline-success。其中,btn 表示这个元素是一个按钮,btn-outline-success 表示按钮的样式为轮廓式绿色成功样式。该按钮的值为“添加”,即在表单提交时,将调用名为 addForm 的表单的 th:action 属性指定的地址提交表单数据。
3. <script type="text/javascript">
function beforeSubmit(addForm) {
// 如果器材名称为空,则提示用户输入器材名称并返回false
if (addForm.equipmentName.value == "") {
alert("请输入器材名称!")
return false;
}
// 如果器材位置为空,则提示用户输入器材位置并返回false
if (addForm.equipmentLocation.value == "") {
alert("请输入器材位置!")
return false;
}
// 如果器材状态为空,则提示用户输入器材状态并返回false
if (addForm.equipmentStatus.value == "") {
alert("请输入器材状态!")
return false;
}
// 如果备注信息为空,则提示用户输入备注信息并返回false
if (addForm.equipmentMessage.value == "") {
alert("请输入备注信息!")
return false;
}
// 如果所有字段都不为空,则返回true,允许提交表单数据
return true;
}
</script>
该前端代码是一个客户端JavaScript函数,用于在表单提交前对用户输入的数据进行校验,以确保数据的完整性和正确性。具体实现如下:
当表单提交时,会调用名为beforeSubmit的JavaScript函数,函数参数为表单对象addForm。
函数中,首先检查用户输入的器材名称、位置、状态和备注信息是否为空,如果为空,则使用alert方法提示用户输入相应信息,并返回false,表示校验失败。
如果所有字段都不为空,则返回true,表示校验通过,允许提交表单数据。
这样就可以通过客户端JavaScript代码实现简单的表单数据校验功能,提高数据录入的准确性和完整性。
addMember.html
<!-- 注释1:会员添加表单,使用Bootstrap样式 -->
<div class="card mb-4">
<!-- 注释2:会员添加表单提交,使用Thymeleaf模板引擎生成URL -->
<form th:action="@{/member/addMember}" method="post" name="addForm" onsubmit="return beforeSubmit(this)">
<!-- 注释3:会员添加表单,使用Bootstrap表格样式 -->
<table class="table table-hover">
<!-- 注释4:会员账号/卡号栏,禁用输入框并由系统自动生成 -->
<tr>
<td text-align="center">会员账号/卡号:</td>
<td>
<input type="text" class="form-control" placeholder="卡号由系统自动生成" name="memberAccount"
disabled="disabled">
</td>
</tr>
<!-- 注释5:姓名栏 -->
<tr>
<td text-align="center">姓名:</td>
<td>
<input type="text" class="form-control" placeholder="姓名" name="memberName">
</td>
</tr>
<!-- 注释6:密码栏,禁用输入框并使用初始密码123456 -->
<tr>
<td text-align="center">密码:</td>
<td>
<input type="text" class="form-control" placeholder="初始密码123456" name="memberPassword"
disabled="disabled">
</td>
</tr>
<!-- 注释7:性别栏 -->
<tr>
<td text-align="center">性别:</td>
<td>
<input type="text" class="form-control" placeholder="性别" name="memberGender">
</td>
</tr>
<!-- 注释8:年龄栏 -->
<tr>
<td text-align="center">年龄:</td>
<td>
<input type="text" class="form-control" placeholder="年龄" name="memberAge">
</td>
</tr>
<!-- 注释9:联系方式栏 -->
<tr>
<td text-align="center">联系方式:</td>
<td>
<input type="text" class="form-control" placeholder="11位手机号" name="memberPhone">
</td>
</tr>
<!-- 注释10:身高栏 -->
<tr>
<td text-align="center">身高:</td>
<td>
<input type="text" class="form-control" placeholder="cm" name="memberHeight">
</td>
</tr>
<!-- 注释11:体重栏 -->
<tr>
<td text-align="center">体重:</td>
<td>
<input type="text" class="form-control" placeholder="kg" name="memberWeight">
</td>
</tr>
<!-- 注释12:购买课时栏 -->
<tr>
<td text-align="center">购买课时:</td>
<td>
<input type="text" class="form-control" placeholder="购买课时" name="cardClass">
</td>
</tr>
</table>
<div style="text-align:center;margin-top:20px;margin-bottom:20px">
<!-- 创建一个居中对齐的div,并设置其上下边距 -->
<input type="submit" class="btn btn-outline-success" value="添加">
<!-- 创建一个提交按钮,并为其添加一个样式类,用于美化按钮的外观 -->
</div>
</form>
<!-- 结束一个表单 -->
</div>
</div>
</main>
<!-- 结束主要内容区域 -->
<footer th:replace="adminCommon::common-footer"></footer>
<!-- 引用一个公共的页脚模板 -->
</div>
</div>
<div th:include="adminCommon::common-scripts"></div>
<!-- 引用一个公共的JavaScript脚本 -->
<script type="text/javascript">
function beforeSubmit(addForm) {
// 定义一个变量,并使用正则表达式设置手机号的验证规则
let phone = /^[1][3,4,5,7,8,9][0-9]{9}$/;
// 如果姓名为空,则弹出提示框并返回false
if (addForm.memberName.value == "") {
alert("请输入姓名!")
return false;
}
// 如果性别为空,则弹出提示框并返回false
if (addForm.memberGender.value == "") {
alert("请输入性别!")
return false;
}
// 如果年龄为空,则弹出提示框并返回false
if (addForm.memberAge.value == "") {
alert("请输入年龄!")
return false;
}
// 如果手机号码不符合规则,则弹出提示框并返回false
if (!phone.test(addForm.memberPhone.value)) {
alert("手机号码错误!");
return false;
}
// 如果身高为空,则弹出提示框并返回false
if (addForm.memberHeight.value == "") {
alert("请输入身高!")
return false;
}
// 如果体重为空,则弹出提示框并返回false
if (addForm.memberWeight.value == "") {
alert("请输入体重!")
return false;
}
// 如果购买课时为空,则弹出提示框并返回false
if (addForm.cardClass.value == "") {
alert("请输入购买课时!")
return false;
}
// 如果以上所有条件都满足,则返回true
return true;
}
</script>
</body>
</html>
1. <tr>
<td text-align="center">会员账号/卡号:</td>
<td>
<input type="text" class="form-control" placeholder="卡号由系统自动生成" name="memberAccount"
disabled="disabled">
</td>
</tr>
这段前端代码是一个HTML表格(table)的一行(row)代码片段,包含两列(column)。第一列是一个居中对齐的表格单元格(table cell),内容是“会员账号/卡号:”。第二列是一个表单输入框,其中placeholder属性指定了输入框内灰色字体提示的文本,“卡号由系统自动生成”,而disabled属性禁用了输入框,使其无法编辑,只能在程序中由系统自动生成。最后,该输入框的name属性被设为“memberAccount”,在提交表单时,该值将被用作数据的键名(key)。
2. <!-- 注释6:密码栏,禁用输入框并使用初始密码123456 -->
<tr>
<td text-align="center">密码:</td>
<td>
<input type="text" class="form-control" placeholder="初始密码123456" name="memberPassword"
disabled="disabled">
</td>
</tr>
这段前端代码定义了一个表格行(<tr>)用于显示“密码”信息。具体来说,它包含了两个表格单元格(<td>),第一个单元格中显示了“密码”文本,第二个单元格则包含了一个文本输入框(<input type="text">)用于输入密码。
输入框具有以下属性:
class="form-control":使用样式类 form-control,用于美化输入框的外观。
placeholder="初始密码123456":在输入框中显示占位符文本“初始密码123456”,用于提示用户输入密码的格式。
name="memberPassword":设置输入框的名称为 memberPassword,用于在提交表单时将输入的密码值发送到后端处理。
另外,该输入框还包含了一个属性 disabled="disabled",它会将输入框设置为禁用状态,从而使用户无法直接在输入框中输入密码。而是使用初始密码“123456”。
3. <div style="text-align:center;margin-top:20px;margin-bottom:20px">
<!-- 创建一个居中对齐的div,并设置其上下边距 -->
<input type="submit" class="btn btn-outline-success" value="添加">
<!-- 创建一个提交按钮,并为其添加一个样式类,用于美化按钮的外观 -->
</div>
该前端代码是一个表单提交按钮,包含一个居中对齐的 div 元素和一个 input 元素。在该 div 元素中,设置了居中对齐和上下边距的样式,以便将按钮放置在页面的中心位置并使其看起来更美观。该 input 元素是一个 type 为 "submit" 的按钮,当点击时会触发表单的提交操作。它还有一个样式类 "btn btn-outline-success",这些样式类用于应用 Bootstrap 框架中的预定义样式来美化该按钮。
4. <script type="text/javascript">
function beforeSubmit(addForm) {
// 定义一个变量,并使用正则表达式设置手机号的验证规则
let phone = /^[1][3,4,5,7,8,9][0-9]{9}$/;
// 如果姓名为空,则弹出提示框并返回false
if (addForm.memberName.value == "") {
alert("请输入姓名!")
return false;
}
// 如果性别为空,则弹出提示框并返回false
if (addForm.memberGender.value == "") {
alert("请输入性别!")
return false;
}
// 如果年龄为空,则弹出提示框并返回false
if (addForm.memberAge.value == "") {
alert("请输入年龄!")
return false;
}
// 如果手机号码不符合规则,则弹出提示框并返回false
if (!phone.test(addForm.memberPhone.value)) {
alert("手机号码错误!");
return false;
}
// 如果身高为空,则弹出提示框并返回false
if (addForm.memberHeight.value == "") {
alert("请输入身高!")
return false;
}
// 如果体重为空,则弹出提示框并返回false
if (addForm.memberWeight.value == "") {
alert("请输入体重!")
return false;
}
// 如果购买课时为空,则弹出提示框并返回false
if (addForm.cardClass.value == "") {
alert("请输入购买课时!")
return false;
}
// 如果以上所有条件都满足,则返回true
return true;
}
</script>
这段代码定义了一个JavaScript函数 beforeSubmit(addForm),它接受一个参数 addForm,表示一个表单元素。该函数的作用是在表单提交之前,对表单中的输入进行验证,确保输入的数据符合要求。
具体来说,该函数首先使用正则表达式定义了一个变量 phone,表示手机号码的验证规则。然后,它分别检查了表单中姓名、性别、年龄、手机号码、身高、体重、购买课时这几个输入框是否为空,如果为空,则弹出一个提示框,并返回false。如果手机号码不符合规则,则同样弹出一个提示框,并返回false。如果以上所有条件都满足,则返回true,允许表单提交。
需要注意的是,这里使用了 test() 方法来检查手机号码是否符合规则。该方法接受一个参数,表示要匹配的字符串,如果匹配成功,则返回true,否则返回false。在本例中,我们通过 ! 运算符将 phone.test(addForm.memberPhone.value) 的结果取反,即在手机号码不符合规则时返回false。
这个正则表达式可以用来匹配中国大陆的手机号码格式,其中:
- ^ 表示匹配字符串的开头
- [1] 表示第一位必须是数字1
- [3,4,5,7,8,9] 表示第二位可以是数字3、4、5、7、8或9中的任意一个
- [0-9]{9} 表示后面跟着9个数字,共计11位
- $ 表示匹配字符串的结尾
因此,这个正则表达式可以匹配符合中国大陆手机号码格式的字符串,例如:
- 13912345678
- 18888888888
- 17398765432
但是不能匹配以下情况:
- 22345678901(不是以1开头)
- 12412345678(第二位不是3、4、5、7、8或9中的一个)
- 1391234567(不够11位)
- 139123456789(超过11位)
adminCommon.html
<!DOCTYPE html> <!-- 声明文档类型为HTML5 -->
<html lang="zh-CN" xmlns:th="http://www.thymeleaf.org"> <!-- 定义HTML文档的基本结构 -->
<head th:fragment="common-header"> <!-- 头部信息的片段,可以在其他HTML页面中重复使用 -->
<!-- 设置字符集为UTF-8 -->
<meta charset="UTF-8"/>
<!-- 告诉浏览器使用最新的IE内核 -->
<meta http-equiv="X-UA-Compatible" content="IE=edge"/>
<!-- 定义视口,用于移动端响应式布局 -->
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no"/>
<!-- 设置网页的描述信息 -->
<meta name="description" content="gym-management-system"/>
<!-- 设置网页作者 -->
<meta name="author" content="ZhangMing"/>
<!-- 设置网页标题 -->
<title>健身房管理系统-管理员</title>
<!-- 引入 Simple Datatables 的样式文件 -->
<link href="https://cdn.jsdelivr.net/npm/simple-datatables@latest/dist/style.css" rel="stylesheet"/>
<!-- 引入自定义的 CSS 样式文件 -->
<link href="/static/css/styles.css" th:href="@{/css/styles.css}" rel="stylesheet"/>
<!-- 引入 Font Awesome 的 JS 文件 -->
<script src="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.15.3/js/all.min.js" crossorigin="anonymous"></script>
</head>
<body>
<!-- 导航栏 -->
<nav class="sb-topnav navbar navbar-expand navbar-dark bg-dark" th:fragment="common-navbar">
<!-- 导航栏品牌 -->
<a class="navbar-brand ps-3">健身房管理系统</a>
<!-- 侧边栏开关按钮 -->
<button class="btn btn-link btn-sm order-1 order-lg-0 me-4 me-lg-0" id="sidebarToggle" href="#!"><i class="fas fa-bars"></i></button>
<!-- 导航栏搜索框 -->
<form class="d-none d-md-inline-block form-inline ms-auto me-0 me-md-3 my-2 my-md-0">
<div class="input-group">
<input class="form-control" type="text" placeholder="搜索" aria-label="搜索" aria-describedby="btnNavbarSearch"/>
<button class="btn btn-primary" id="btnNavbarSearch" type="button"><i class="fas fa-search"></i></button>
</div>
</form>
<!-- 导航栏右侧菜单 -->
<ul class="navbar-nav ms-auto ms-md-0 me-3 me-lg-4">
<li class="nav-item dropdown">
<!-- 用户菜单 -->
<a class="nav-link dropdown-toggle" id="navbarDropdown" href="#" role="button" data-bs-toggle="dropdown" aria-expanded="false"><i class="fas fa-user fa-fw"></i></a>
<ul class="dropdown-menu dropdown-menu-end" aria-labelledby="navbarDropdown">
<!-- 退出登录选项 -->
<li><a class="dropdown-item" th:href="@{/}"><i class="fas fa-sign-out-alt"></i> 退出登录</a></li>
</ul>
</li>
</ul>
</nav>
<!--侧边栏-->
<div id="layoutSidenav_nav" th:fragment="common-sidenav">
<!-- 创建一个带有折叠效果的侧边栏 -->
<nav class="sb-sidenav accordion sb-sidenav-light" id="sidenavAccordion">
<div class="sb-sidenav-menu">
<div class="nav">
<!--快速查询区域-->
<!-- 显示"快速查询"标题 -->
<div class="sb-sidenav-menu-heading">快速查询</div>
<!-- 创建一个"会员卡查询"链接,th:href用于Thymeleaf模板引擎解析,sb-nav-link-icon是导航栏图标,i标签表示使用Font Awesome图标-->
<a class="nav-link" th:href="@{/member/toSelByCard}">
<div class="sb-nav-link-icon"><i class="fas fa-id-card"></i></div>
会员卡查询
</a>
<!--管理区域-->
<!-- 显示"管理"标题 -->
<div class="sb-sidenav-menu-heading">管理</div>
<!-- 创建一个"会员管理"链接 -->
<a class="nav-link" th:href="@{/member/selMember}">
<div class="sb-nav-link-icon"><i class="fas fa-user"></i></div>
会员管理
</a>
<!-- 创建一个"员工管理"链接 -->
<a class="nav-link" th:href="@{/employee/selEmployee}">
<div class="sb-nav-link-icon"><i class="fas fa-user-tie"></i></div>
员工管理
</a>
<!-- 创建一个"器材管理"链接 -->
<a class="nav-link" th:href="@{/equipment/selEquipment}">
<div class="sb-nav-link-icon"><i class="fas fa-table-tennis"></i></div>
器材管理
</a>
<!-- 创建一个"课程管理"链接 -->
<a class="nav-link" th:href="@{/class/selClass}">
<div class="sb-nav-link-icon"><i class="fas fa-calendar-alt"></i></div>
课程管理
</a>
<!--链接区域-->
<!-- 显示"链接"标题 -->
<div class="sb-sidenav-menu-heading">链接</div>
<!-- 创建一个"注意事项"链接,使用外部链接 -->
<a class="nav-link" href="https://zhuanlan.zhihu.com/p/440751809">
<div class="sb-nav-link-icon"><i class="fab fa-github"></i></div>
注意事项
</a>
</div>
</div>
</nav>
<footer class="py-4 bg-light mt-auto" th:fragment="common-footer">
<!-- py-4:添加上下内边距为4个单位的空白 -->
<!-- bg-light:添加浅色背景 -->
<!-- mt-auto:将该元素的上边距设置为自动,以便它在父元素中垂直居中 -->
<div class="container-fluid px-4">
<!-- container-fluid:使用全宽容器 -->
<!-- px-4:添加左右内边距为4个单位的空白 -->
<div class="d-flex align-items-center justify-content-between small">
<!-- d-flex:使用 Flexbox 布局 -->
<!-- align-items-center:垂直居中元素 -->
<!-- justify-content-between:在容器中分别对齐元素 -->
<!-- small:添加更小的字体 -->
<div class="text-muted">
<!-- text-muted:使用浅色字体 -->
Copyright © chenfuhai 2023
<!-- 版权信息 -->
</div>
</div>
</div>
</footer>
<div th:fragment="common-scripts">
<!-- 引入Bootstrap框架的JS文件 -->
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.0.2/dist/js/bootstrap.bundle.min.js"
crossorigin="anonymous"></script>
<!-- 引入自定义的脚本文件 -->
<script src="/static/js/scripts.js" th:src="@{/js/scripts.js}"></script>
<!-- 引入Chart.js图表库的JS文件 -->
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.8.0/Chart.min.js" crossorigin="anonymous"></script>
<!-- 引入使用Chart.js库的演示脚本文件 -->
<script src="/static/assets/demo/chart-area-demo.js" th:src="@{/assets/demo/chart-area-demo.js}"></script>
<!-- 引入使用Chart.js库的演示脚本文件 -->
<script src="/static/assets/demo/chart-bar-demo.js" th:src="@{/assets/demo/chart-bar-demo.js}"></script>
<!-- 引入Simple Datatables插件的JS文件 -->
<script src="https://cdn.jsdelivr.net/npm/simple-datatables@latest" crossorigin="anonymous"></script>
<!-- 引入使用Simple Datatables插件的演示脚本文件 -->
<script src="/static/js/datatables-simple-demo.js" th:src="@{/js/datatables-simple-demo.js}"></script>
</div>
</body>
</html>
1. <button class="btn btn-link btn-sm order-1 order-lg-0 me-4 me-lg-0" id="sidebarToggle" href="#!"><i class="fas fa-bars"></i></button>
这段前端代码定义了一个按钮元素,使用了Bootstrap的样式类,包括"btn"和"btn-link",并指定了按钮的大小为"btn-sm",使用了flex布局,设置该按钮在小屏幕设备中排列顺序为1,大屏幕设备中排列顺序为0,也就是在大屏幕中默认隐藏,显示一个带有"fa-bars"图标的汉堡菜单按钮。
该按钮的id属性为"sidebarToggle",但由于该按钮没有设置具体的链接地址,所以href属性设置为"#!",表示空链接。
2. <ul class="navbar-nav ms-auto ms-md-0 me-3 me-lg-4">
<li class="nav-item dropdown">
<!-- 用户菜单 -->
<a class="nav-link dropdown-toggle" id="navbarDropdown" href="#" role="button" data-bs-toggle="dropdown" aria-expanded="false"><i class="fas fa-user fa-fw"></i></a>
<ul class="dropdown-menu dropdown-menu-end" aria-labelledby="navbarDropdown">
<!-- 退出登录选项 -->
<li><a class="dropdown-item" th:href="@{/}"><i class="fas fa-sign-out-alt"></i> 退出登录</a></li>
</ul>
</li>
</ul>
这段代码是一个Bootstrap导航栏中的用户菜单,包括一个下拉菜单和一个退出登录选项。具体解释如下:
<ul>:定义一个无序列表,使用了Bootstrap提供的样式类navbar-nav,表示该列表作为导航栏的一部分。
<li>:定义一个列表项,表示用户菜单,使用了Bootstrap提供的样式类nav-item dropdown,表示该列表项是一个下拉菜单。
<a>:定义一个锚元素,作为用户菜单的触发器,使用了Bootstrap提供的样式类nav-link dropdown-toggle,表示该锚元素是一个带下拉菜单的链接,并设置了相关属性:data-bs-toggle为"dropdown",aria-expanded为"false",用于定义下拉菜单的行为。
<ul>:定义一个下拉菜单,使用了Bootstrap提供的样式类dropdown-menu dropdown-menu-end,表示该菜单为一个下拉菜单,并将其位置设置为右侧。
<li>:定义一个列表项,表示退出登录选项,使用了Bootstrap提供的样式类dropdown-item,表示该列表项为下拉菜单中的一个选项。
<a>:定义一个锚元素,作为退出登录选项的链接,并设置了相关属性:th:href为"@{/}",表示点击该链接将跳转到应用程序的根路径;<i>元素中使用了Font Awesome提供的图标样式,用于显示“退出登录”图标。
3. <nav class="sb-sidenav accordion sb-sidenav-light" id="sidenavAccordion">
这段前端代码定义了一个导航菜单(navigation menu),其样式为“sb-sidenav”和“sb-sidenav-light”,并且给它设置了一个id属性“sidenavAccordion”。
该导航菜单通常用于响应式布局,可以根据设备的屏幕尺寸和方向来自动适应。它可能包含多个链接和子菜单,并且可以随着用户的交互而展开或折叠。具体而言,这段代码可能还包含其他HTML元素或JavaScript代码,用于定义菜单中的具体内容和行为。
4. <a class="nav-link" th:href="@{/member/toSelByCard}">
<div class="sb-nav-link-icon"><i class="fas fa-id-card"></i></div>
会员卡查询
</a>
这段前端代码是一个超链接,使用了Thymeleaf模板引擎的语法,th:href="@{/member/toSelByCard}"表示在点击这个超链接时,会跳转到名为toSelByCard的请求处理方法。在超链接里还嵌套了一个<div>元素和一个图标<i>元素,<i>元素中使用了Font Awesome提供的图标样式用于显示一个带图标的导航栏菜单项,具体来说:
• class="nav-link"指定了该超链接应用了Bootstrap框架中的nav-link样式,使其具有一定的样式特征;
• th:href="@{/member/toSelByCard}"中的@{...}语法表示使用Thymeleaf模板引擎的URL重写功能,将名为/member/toSelByCard的请求路径转换为实际可用的URL路径,以便在点击链接时能够正确访问到对应的请求处理方法;
• <div class="sb-nav-link-icon"><i class="fas fa-id-card"></i></div>用于显示一个带图标的菜单项,其中<div>元素应用了sb-nav-link-icon样式,用于设置该菜单项图标的样式特征,<i>元素则使用了Font Awesome字体库中的fa-id-card图标,用于显示一个名为"会员卡查询"的菜单项。
adminLogin.html
<!DOCTYPE html>
<html lang="zh-CN" xmlns:th="http://www.thymeleaf.org">
<!--本段head代码在HTML文档的<head>标签中,包含了网页的元信息、CSS文件和JavaScript函数等。-->
<head>
<!-- 设置字符编码 -->
<meta charset="UTF-8"/>
<!-- 设置IE兼容模式 -->
<meta http-equiv="X-UA-Compatible" content="IE=edge"/>
<!-- 设置视口宽度和缩放比例 -->
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no"/>
<!-- 设置网页描述信息 -->
<meta name="description" content="gym-management-system"/>
<!-- 设置作者信息 -->
<meta name="author" content="ZhangMing"/>
<!-- 设置网页标题 -->
<title>健身房管理系统-管理员登录</title>
<!-- 引入CSS文件 -->
<link href="/static/css/styles.css" th:href="@{css/styles.css}" rel="stylesheet"/>
<!-- 引入FontAwesome图标库 -->
<script src="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.15.3/js/all.min.js"
crossorigin="anonymous"></script>
<!-- 定义JavaScript函数,用于检查表单输入是否合法 -->
<script type="text/javascript">
function checkSubmit(loginForm) {
if (loginForm.adminAccount.value == '') {
alert("请输入账号");
loginForm.adminAccount.focus();
return false;
}
if (loginForm.adminPassword.value == '') {
alert("请输入密码");
loginForm.adminPassword.focus();
return false;
}
return true;
}
</script>
</head>
<!-- 设置页面背景为蓝色,并设置背景图片为/img/background.jpeg -->
<body class="bg-primary" th:style="'background-image: url(/img/background.jpeg);background-size: 100%, 100%'">
<!-- 管理员登录页面的主体内容,使用Bootstrap的布局 -->
<div id="layoutAuthentication">
<div id="layoutAuthentication_content">
<main>
<!-- 设置容器宽度为父容器宽度的居中容器 -->
<div class="container">
<!-- 将子元素水平居中 -->
<div class="row justify-content-center">
<!-- 设置列的宽度为12格的5格,占据了居中容器的一半 -->
<div class="col-lg-5">
<!-- 卡片式面板,使用Bootstrap的样式,并设置阴影、无边框、圆角等属性 -->
<div class="card shadow-lg border-0 rounded-lg mt-5">
<!-- 卡片面板的头部 -->
<div class="card-header">
<!-- 设置标题,使用Bootstrap的样式,并居中显示、设置字体粗细、设置上下外边距 -->
<h3 class="text-center font-weight-light my-4">管理员登录</h3>
</div>
<!-- 卡片面板的主体部分 -->
<div class="card-body">
<!-- 表单,使用POST方法提交数据,并设置表单名为loginForm,提交时调用JS函数进行验证 -->
<form th:action="@{/adminLogin}" method="post" name="loginForm"
onsubmit="return checkSubmit(this)">
<!-- 账号输入框,使用Bootstrap的样式,并设置为浮动标签,输入时仅允许输入数字,设置placeholder提示信息 -->
<div class="form-floating mb-3">
<input class="form-control" id="inputAccount" name="adminAccount" type="account"
placeholder="Account"
onkeypress="return event.keyCode>=48&&event.keyCode<=57"/>
<label for="inputAccount">账号</label>
</div>
<!-- 密码输入框,使用Bootstrap的样式,并设置为浮动标签,设置placeholder提示信息 -->
<div class="form-floating mb-3">
<input class="form-control" id="inputPassword" name="adminPassword"
type="password"
placeholder="Password"/>
<label for="inputPassword">密码</label>
</div>
<!-- 记住密码复选框,使用Bootstrap的样式,并设置标签信息 -->
<div class="form-check mb-3">
<input class="form-check-input" id="inputRememberPassword" type="checkbox"
value=""/>
<label class="form-check-label" for="inputRememberPassword">记住密码</label>
</div>
<!-- 按钮容器,使用Flex布局,设置两个按钮 -->
<div class="d-flex align-items-center justify-content-between mt-4 mb-0">
<!-- 登录按钮,使用Bootstrap的样式,并设置按钮颜色、字体粗细、宽度等属性 -->
<input type="submit" class="btn btn-success" value="登录">
<a class="btn btn-primary" th:href="@{/toUserLogin}">转到会员登录</a>
</div>
</form>
<div th:text="${msg}" style="margin-top: 20px;text-align: center;color: red"></div>
</div>
</div>
</div>
</div>
</div>
</main>
</div>
</div>
<!--这段代码script是在HTML中引入了两个JavaScript脚本文件。第一个文件是从CDN中加载的Bootstrap框架,用于提供Web页面的样式和交互效果。-->
<!--第二个文件是在本地服务器上的一个自定义JavaScript脚本,用于在页面加载时执行一些自定义代码,包括对页面元素进行操作、对用户输入-->
<!--进行验证、与服务器进行数据交互等。这里使用了Thymeleaf的语法,以便在服务器端动态地生成正确的URL。 crossorigin属性是用来设置-->
<!--请求的跨域资源是否需要使用凭证(如cookie、HTTP认证等)来验证的。-->
<!-- 引入Bootstrap的JS库 -->
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.0.2/dist/js/bootstrap.bundle.min.js"
crossorigin="anonymous"></script>
<!-- 引入自定义的JavaScript脚本 -->
<script src="/static/js/scripts.js" th:src="@{js/scripts.js}"></script>
</body>
</html>
1.<input class="form-control" id="inputAccount" name="adminAccount" type="account"
placeholder="Account"
οnkeypress="return event.keyCode>=48&&event.keyCode<=57"/>
input
:指定了要创建一个文本输入框,即生成一个用户可以在其中输入文本的元素。class="form-control"
:指定了该输入框样式的 class 名称。form-control
是 Bootstrap 框架中定义的一种样式,可以让输入框的样式保持一致。id="inputAccount"
:指定了该输入框的 ID 名称为inputAccount
。该 ID 可以用于 JavaScript 或 CSS 等代码中进行操作。name="adminAccount"
:指定了该输入框的名称,可在提交表单时使用该名称。type="account"
:指定了该输入框的类型,该类型并非标准的 HTML 输入框类型,因此该类型在实际应用中并不实用。placeholder="Account"
:指定了在用户未输入任何内容时在输入框中显示的文本。onkeypress="return event.keyCode>=48&&event.keyCode<=57"
:指定了当用户在输入框中按键时触发的 JavaScript 代码。该代码用于限制用户只能输入数字字符,event.keyCode>=48&&event.keyCode<=57
这段代码是一个用于检测按键事件的 JavaScript 条件语句。它的作用是在接收到按键事件时,判断用户是否按下了数字键(0 到 9)。如果用户按下的是数字键,则该条件语句将返回 true 值。具体来说,event.keyCode 是一个保存按键事件的 JavaScript 对象,它包含了各种属性和方法,以便开发者可以对按键事件进行处理。在这个条件语句中,我们检查 event.keyCode 是否大于等于 48(对应数字 '0' 的 ASCII 码)且小于等于 57(对应数字 '9' 的 ASCII 码)。如果是,说明用户按下的是一个数字键,条件语句将返回 true 值,否则返回 false 值
2. <script src="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.15.3/js/all.min.js"
crossorigin="anonymous"></script>
这段前端代码是引入了 Font Awesome 图标库中的 JS 文件,地址为 "https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.15.3/js/all.min.js"。Font Awesome 是一款开源的图标字体库,提供了众多的矢量图标,可以直接在 HTML 中使用。通过引入这个 JS 文件,可以在页面中使用 Font Awesome 中的图标。
3. <script type="text/javascript">
function checkSubmit(loginForm) {
if (loginForm.adminAccount.value == '') {
alert("请输入账号");
loginForm.adminAccount.focus();
return false;
}
if (loginForm.adminPassword.value == '') {
alert("请输入密码");
loginForm.adminPassword.focus();
return false;
}
return true;
}
</script>
这段代码定义了一个函数checkSubmit,用于检查管理员登录表单的输入是否合法。函数接受一个参数loginForm,表示管理员登录表单的DOM对象。在函数内部,首先判断账号输入框的值是否为空,如果为空,则弹出提示框并返回false。接着判断密码输入框的值是否为空,如果为空,则弹出提示框并返回false。如果以上两个条件都满足,则返回true,表示表单输入合法。这个函数一般会绑定到表单的onsubmit事件上,在管理员提交表单时被调用,用于验证管理员输入的账号和密码是否合法。
4.<div class="form-check mb-3"> <input class="form-check-input" id="inputRememberPassword" type="checkbox" value=""/> <label class="form-check-label" for="inputRememberPassword">记住密码</label> </div>
这段代码是一个 HTML 的表单元素,用于显示一个复选框,用户可以勾选或取消勾选该复选框。
具体来说,这个表单元素包含了一个 div 标签,使用了 Bootstrap 框架中的 form-check 和 mb-3 类来美化表单样式。在 div 中包含了一个 input 元素和一个 label 元素。input 元素使用了 form-check-input 类,并设置了 id、type、value 属性。这里 type 属性设置为 'checkbox',表示该表单元素是一个复选框。当用户勾选复选框时,该元素的 value 属性将被设置为 "on",否则该属性为空字符串。label 元素使用了 form-check-label 类,并设置了 for 属性,以便与相应的 input 元素建立联系。
总的来说,这个表单元素的作用是让用户选择是否记住密码。当用户勾选该复选框时,相关的 JavaScript 代码将可以通过检查 input 元素的 checked 属性来确定用户是否要求记住密码。
5.<a class="btn btn-primary" th:href="@{/toUserLogin}">转到会员登录</a>
这段代码是一个 HTML 的超链接元素,用于在用户点击该链接时跳转到指定的页面。
具体来说,超链接元素使用了 Bootstrap 框架中的 btn 和 btn-primary 类来美化按钮样式。该元素有一个 th:href 属性,这个属性使用了 Thymeleaf 模板引擎的语法,其中 @{...} 表示对地址进行解析和处理。在本例中,@{/toUserLogin} 表示将相对路径 /toUserLogin 解析为绝对路径,然后将其设置为该超链接的目标地址。这通常用于在 Web 应用程序中实现页面之间的跳转。
总的来说,这个超链接元素的作用是让用户可以通过点击跳转到会员登录页面,以便登录应用程序的会员账号。
6.<div th:text="${msg}" style="margin-top: 20px;text-align: center;color: red"></div>
这段代码是一个 HTML 的 div 元素,用于在 Web 页面中显示一条消息。具体来说,div 元素使用了 Thymeleaf 模板引擎的语法,其中 th:text="${msg}" 表示将服务器端传递过来的名为 "msg" 的变量值设置为该元素的文本内容。当页面被渲染时,如果 "msg" 变量具有有效值,则该 div 元素将显示该值,否则该元素将不显示任何内容。这通常用于在 Web 应用程序中向用户展示一些提示信息或错误消息。此外,该 div 元素还设置了 style 属性,其中 margin-top: 20px 表示将该元素顶部与其父元素顶部之间的距离设置为 20 像素,text-align: center 表示将该元素的文本居中对齐,color: red 表示将该元素的文字颜色设置为红色。这些样式属性和值用于美化该元素的外观和布局。
总的来说,这个 div 元素的作用是在 Web 页面中显示一个指定格式的消息,以便向用户传达相应的信息。
7.<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.0.2/dist/js/bootstrap.bundle.min.js" crossorigin="anonymous"></script>
这段代码是一个用于加载 Bootstrap 框架 JavaScript 脚本的 HTML 代码。具体来说,这里使用了 CDN(内容分发网络)技术,将一个由 Bootstrap 官方提供的 JavaScript 文件从远程服务器上加载到本地客户端。
其中, script 标签的 src 属性指定了该 JavaScript 文件的地址,即 https://cdn.jsdelivr.net/npm/bootstrap@5.0.2/dist/js/bootstrap.bundle.min.js。在这个地址中,npm 表示 Node.js 包管理器,bootstrap@5.0.2 表示需要下载的 Bootstrap 版本,dist/js/bootstrap.bundle.min.js 表示从该版本的发布目录中下载相应的 JavaScript 文件。
此外,该 script 标签还设置了 crossorigin="anonymous" 属性,表示该文件可以匿名加载,不会向服务端发送用户信息或其他敏感数据。这有利于保护用户的隐私和安全。
总的来说,这段代码的作用是通过加载 Bootstrap 框架的 JavaScript 文件,为 Web 应用程序添加一些预定义的样式、交互效果和组件,以便提升用户体验和开发效率。
8.<script src="/static/js/scripts.js" th:src="@{js/scripts.js}"></script>
这段代码是一个 HTML 的 script 标签,用于引入 JavaScript 脚本文件,并且使用了 Thymeleaf 模板引擎的语法。
具体来说,script 标签包含两个属性,分别是 src 和 th:src。其中,src 表示该标签要引入的 JavaScript 文件路径,即 /static/js/scripts.js。这个路径应该是相对于当前 HTML 页面的根目录而言的。而 th:src 属性使用了 Thymeleaf 模板引擎中的语法,通过 @{...} 解析为绝对路径,这里 @{js/scripts.js} 表示将相对路径 /js/scripts.js 解析为绝对路径。在运行时,Thymeleaf 将自动替换这个属性值为计算得到的 URL,以便浏览器正确加载 JavaScript 文件。
总的来说,这段代码的作用是在 HTML 页面中引入一个名为 scripts.js 的 JavaScript 文件,以实现一些前端交互效果或业务逻辑。同时,使用了 Thymeleaf 的语法,可以更加灵活地管理和组织 HTML 与 JavaScript 代码。
adminMain.html
<!DOCTYPE html>
<html lang="zh-CN" xmlns:th="http://www.thymeleaf.org">
<!--该代码head 片段使用了Thymeleaf模板引擎的语法,它会将名为"adminCommon::common-header"的片段替换掉整个<head>元素。 -->
<!-- 具体而言,它将从名为"adminCommon"的模板中引用名为"common-header"的片段,并将其替换为当前位置的<head>元素。-->
<!-- 因此,该片段实际上是在引用模板中定义的一些公共的头部内容。-->
<head th:replace="adminCommon::common-header"></head>
<body class="sb-nav-fixed"> <!-- 固定导航栏 -->
<nav th:replace="adminCommon::common-navbar"></nav> <!-- 引入导航栏模板 -->
<div id="layoutSidenav"> <!-- 整个页面的布局 -->
<div th:replace="adminCommon::common-sidenav"></div> <!-- 引入侧边栏模板 -->
<div id="layoutSidenav_content"> <!-- 页面主体部分 -->
<main>
<div class="container-fluid px-4"> <!-- 页面主体内容 -->
<h1 class="mt-4">管理员主页</h1> <!-- 页面标题 -->
<ol class="breadcrumb mb-4"> <!-- 面包屑导航 -->
<li class="breadcrumb-item active">主页</li>
</ol>
<div class="row">
<div class="col-xl-3 col-md-6">
<div class="card bg-primary text-white mb-4">
<div class="card-body">健身房总人数</div>
<div class="card-footer d-flex align-items-center justify-content-between">
<span class="small text-white" th:text="${humanTotal} + '人'"></span> <!-- 健身房总人数 -->
</div>
</div>
</div>
<div class="col-xl-3 col-md-6">
<div class="card bg-warning text-white mb-4">
<div class="card-body">员工人数</div>
<div class="card-footer d-flex align-items-center justify-content-between">
<span class="small text-white" th:text="${employeeTotal} + '人'"></span> <!-- 员工人数 -->
</div>
</div>
</div>
<div class="col-xl-3 col-md-6">
<div class="card bg-success text-white mb-4">
<div class="card-body">会员人数</div>
<div class="card-footer d-flex align-items-center justify-content-between">
<span class="small text-white" th:text="${memberTotal} + '人'"></span> <!-- 会员人数 -->
</div>
</div>
</div>
<div class="col-xl-3 col-md-6">
<div class="card bg-danger text-white mb-4">
<div class="card-body">器材数</div>
<div class="card-footer d-flex align-items-center justify-content-between">
<span class="small text-white" th:text="${equipmentTotal} + '件'"></span> <!-- 器材数 -->
</div>
</div>
</div>
</div>
<div class="row">
<div class="col-xl-6">
<div class="card mb-4">
<div class="card-header">
<i class="fas fa-chart-area me-1"></i>
Area Chart Example
</div>
<div class="card-body">
<canvas id="myAreaChart" width="100%" height="40"></canvas> <!-- 绘制区域图 -->
</div>
</div>
</div>
<!--<!–下面这段代码是一个包含一个柱形图的卡片,用于展示管理员主页上的数据可视化。–>-->
<!-- 具体来说:-->
<!-- <div>元素设置了一个宽度为“col-xl-6”,表示该卡片的宽度为50%。-->
<!-- class="card mb-4"添加了Bootstrap的card类和“mb-4”类,使卡片具有卡片样式和底部边距。-->
<!-- <div class="card-header">定义卡片头,包含一个名为“Bar Chart Example”的标题,以及一个使用Font Awesome图标的元素。-->
<!-- <div class="card-body">定义卡片的主体部分,其中包含一个canvas元素,用于展示柱形图。-->
<!-- <canvas>元素的id设置为“myBarChart”,以便在脚本中引用该元素。其宽度设置为100%,以使其在其父容器内占用所有可用空间。高度设置为“40”,以避免元素完全折叠。-->
<!-- 此卡片显示了一个柱形图,但需要使用JavaScript或其他前端库来渲染数据和实现交互。-->
<div class="col-xl-6">
<div class="card mb-4">
<div class="card-header">
<i class="fas fa-chart-bar me-1"></i>
Bar Chart Example
</div>
<div class="card-body">
<canvas id="myBarChart" width="100%" height="40"></canvas>
</div>
</div>
</div>
</div>
</div>
</main>
<footer th:replace="adminCommon::common-footer"></footer>
<!-- 这段代码是一个页面底部的HTML标记,使用了Thymeleaf的语法,引用了一个
<!--名为"adminCommon::common-footer"的HTML片段,用于在管理后台的页面底部显示一些通用的内容,例如版权声明、联系方式等。–>-->
</div>
</div>
<!--这行代码使用Thymeleaf的语法,它将另一个HTML模板引入当前页面中。这个模板文件名
为“adminCommon::common-scripts”,它可能是一个独立的HTML文件或者是片段,具体取
决于它的实现方式。这个模板可能包含与脚本相关的HTML、CSS或JavaScript文件,可以在当
前页面中使用。
-->
<div th:include="adminCommon::common-scripts"></div>
</body>
</html>
1. <div class="col-xl-3 col-md-6">
<div class="card bg-primary text-white mb-4">
<div class="card-body">健身房总人数</div>
<div class="card-footer d-flex align-items-center justify-content-between">
<span class="small text-white" th:text="${humanTotal} + '人'"></span> <!-- 健身房总人数 -->
</div>
</div>
</div>
这段前端代码展示了一个用于显示健身房总人数的卡片。该卡片包含一个背景颜色为蓝色的div,div内部有一个显示“健身房总人数”的文本,以及一个位于卡片底部的div,用于显示健身房总人数的具体数字。具体数字通过Thymeleaf表达式${humanTotal}动态地从后端传递进来,并与文本“人”一起显示在卡片底部。
2. <div class="col-xl-6">
<div class="card mb-4">
<div class="card-header">
<i class="fas fa-chart-area me-1"></i>
Area Chart Example
</div>
<div class="card-body">
<canvas id="myAreaChart" width="100%" height="40"></canvas> <!-- 绘制区域图 -->
</div>
</div>
</div>
这段前端代码创建了一个卡片(card)元素,并在其中嵌套了一个绘制区域图的画布元素。卡片的标题为“Area Chart Example”,左侧有一个表示区域图的图标,宽度为卡片容器的50%。整个卡片元素被包含在一个占据半行宽度的列元素中,这意味着该卡片元素将与另一个占据剩余宽度的列元素并排显示在同一行。该区域图可通过JavaScript动态地更新和绘制数据。
3. <div class="col-xl-6">
<div class="card mb-4">
<div class="card-header">
<i class="fas fa-chart-bar me-1"></i>
Bar Chart Example
</div>
<div class="card-body">
<canvas id="myBarChart" width="100%" height="40"></canvas>
</div>
</div>
</div>
这段前端代码是一个展示柱状图的示例,其中包含一个 <canvas> 标签,它将用于绘制图表。<canvas> 是 HTML5 新增的标签,它是一个画布,可以使用 JavaScript 在其中绘制各种图形。
在这个例子中,这个 <canvas> 的 ID 为 myBarChart。通过在 JavaScript 中使用 Chart.js 库(需要在页面中引用),可以轻松地在 <canvas> 中绘制出柱状图。这个图表可以用于展示各种数据,例如产品销售数据、访问量统计等等。
4. <div th:include="adminCommon::common-scripts"></div>
这段前端代码是使用Thymeleaf模板引擎的语法,在HTML页面中包含名为“adminCommon::common-scripts”的Thymeleaf片段,这个片段可能包含了一些常用的前端脚本文件和样式文件,以便在多个页面中复用。这样可以提高代码的复用性和维护性。
selectByMemberAccount.html
<!DOCTYPE html>
<html lang="zh-CN" xmlns:th="http://www.thymeleaf.org">
<head th:replace="adminCommon::common-header"></head>
<!-- 设置body的class为"sb-nav-fixed",并固定导航栏 -->
<body class="sb-nav-fixed">
<!-- 引入名为"adminCommon::common-navbar"的Thymeleaf片段,替换当前位置 -->
<nav th:replace="adminCommon::common-navbar"></nav>
<!-- id为"layoutSidenav"的div,分为两部分:侧边栏和主要内容区域 -->
<div id="layoutSidenav">
<div th:replace="adminCommon::common-sidenav"></div> <!-- 引入侧边栏的Thymeleaf片段,替换当前位置 -->
<!-- id为"layoutSidenav_content"的div,主要内容区域 -->
<div id="layoutSidenav_content">
<main>
<!-- 容器,用于包含页面主要内容 -->
<div class="container-fluid px-4">
<!-- 标题 -->
<h1 class="mt-4">会员卡查询</h1>
<!-- 面包屑导航 -->
<ol class="breadcrumb mb-4">
<li class="breadcrumb-item"><a th:href="@{/toAdminMain}">主页</a></li>
<li class="breadcrumb-item active">会员卡查询</li>
</ol>
<!-- 卡片 -->
<div class="card mb-4">
<div class="card-header">
<i class="fas fa-table me-1"></i> <!-- 用FontAwesome图标显示一个表格图标 -->
会员卡查询
</div>
<div class="card-body">
<div>
<!-- 表单,提交方式为post,目标地址为"/member/selByCard" -->
<form th:action="@{/member/selByCard}" method="post">
<!-- 嵌套div,用于水平排列两个元素 -->
<div style="width: 310px;margin-bottom: 15px">
<!-- 左侧元素,输入框 -->
<div align="left" style="float:left">
<!-- 输入框类型为text,限制只能输入数字,不能输入字母 -->
<input type="text" class="form-control"
onkeypress="return event.keyCode>=48&&event.keyCode<=57"
ng-pattern="/[^a-zA-Z]/"
name="memberAccount">
</div>
<!-- 右侧元素,提交按钮 -->
<div align="right">
<input type="submit" class="btn btn-outline-success" value="查询">
</div>
</div>
</form>
</div>
<!-- 表格 -->
<table class="table table-hover">
<thead class="bg-light">
<tr>
<th scope="col" class="border-0">会员账号/卡号</th>
<th scope="col" class="border-0">姓名</th>
<th scope="col" class="border-0">办卡时间</th>
<th scope="col" class="border-0">性别</th>
<th scope="col" class="border-0">年龄</th>
<th scope="col" class="border-0">联系方式</th>
<th scope="col" class="border-0">身高</th>
<th scope="col" class="border-0">体重</th>
<th scope="col" class="border-0">购买课时</th>
<th scope="col" class="border-0">剩余课时</th>
<th scope="col" class="border-0">操作</th>
</tr>
</thead>
<tbody>
<!-- 遍历memberList,生成表格每一行的内容 -->
<tr th:each="mem:${memberList}">
<td th:text="${mem.memberAccount}">会员账号/卡号</td> <!-- 会员账号/卡号 -->
<td th:text="${mem.memberName}">姓名</td> <!-- 姓名 -->
<td th:text="${mem.cardTime}">办卡时间</td> <!-- 办卡时间 -->
<td th:text="${mem.memberGender}">性别</td> <!-- 性别 -->
<td th:text="${mem.memberAge}">年龄</td> <!-- 年龄 -->
<td th:text="${mem.memberPhone}">联系方式</td> <!-- 联系方式 -->
<td th:text="${mem.memberHeight}">身高</td> <!-- 身高 -->
<td th:text="${mem.memberWeight}">体重</td> <!-- 体重 -->
<td th:text="${mem.cardClass}">购买课时</td> <!-- 购买课时 -->
<td th:text="${mem.cardNextClass}">剩余课时</td> <!-- 剩余课时 -->
<td>
<a th:href="@{/member/toUpdateMember(memberAccount=${mem.memberAccount})}">
<input type="button" class="btn btn-sm btn-outline-primary" value="编辑">
</a> <!-- 编辑按钮 -->
</td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
</main>
<footer th:replace="adminCommon::common-footer"></footer>
</div>
</div>
<div th:include="adminCommon::common-scripts"></div>
</body>
</html>
1. <input type="text" class="form-control"
onkeypress="return event.keyCode>=48&&event.keyCode<=57"
ng-pattern="/[^a-zA-Z]/"
name="memberAccount">
这段前端代码展示了一个文本输入框,用于输入会员账号。其中:
class="form-control" 表示使用 Bootstrap 的表单样式。
οnkeypress="return event.keyCode>=48&&event.keyCode<=57" 表示只允许输入数字(ASCII码 4857 表示数字 09),其他字符将无法输入。
ng-pattern="/[^a-zA-Z]/" 表示使用 AngularJS 的表单验证,只允许输入字母以外的字符,即不能输入字母。
name="memberAccount" 表示该输入框的名称为 memberAccount,用于在提交表单时获取输入的值。
2. <input type="submit" class="btn btn-outline-success" value="查询">
这是一个HTML代码,展示了一个查询按钮。该按钮是一个提交表单的按钮,它被定义为input元素类型为“submit”。按钮的类名为“btn btn-outline-success”,这意味着它具有一个轮廓边框、背景为白色,字体颜色为绿色的按钮样式。按钮的显示文本为“查询”。
3. <thead class="bg-light">
<tr>
<th scope="col" class="border-0">会员账号/卡号</th>
<th scope="col" class="border-0">姓名</th>
<th scope="col" class="border-0">办卡时间</th>
<th scope="col" class="border-0">性别</th>
<th scope="col" class="border-0">年龄</th>
<th scope="col" class="border-0">联系方式</th>
<th scope="col" class="border-0">身高</th>
<th scope="col" class="border-0">体重</th>
<th scope="col" class="border-0">购买课时</th>
<th scope="col" class="border-0">剩余课时</th>
<th scope="col" class="border-0">操作</th>
</tr>
</thead>
这段代码是一个表格的表头部分,使用了Bootstrap框架的样式。其中,每个表头的<th>标签指定了表头的文本内容,如“会员账号/卡号”、“姓名”等等。每个<th>标签中的class属性为“border-0”,表示去掉边框,使表格更美观。最终,这些表头会被用在一个表格的<thead>标签中,表示这是表格的头部分。
selectClass.html
<!DOCTYPE html>
<html lang="zh-CN" xmlns:th="http://www.thymeleaf.org">
<head th:replace="adminCommon::common-header"></head>
<body class="sb-nav-fixed">
<nav th:replace="adminCommon::common-navbar"></nav>
<div id="layoutSidenav"> <!-- 创建一个包含左侧导航栏和右侧主要内容区域的布局 -->
<div th:replace="adminCommon::common-sidenav"></div> <!-- 嵌入左侧导航栏HTML文件 -->
<div id="layoutSidenav_content"> <!-- 右侧主要内容区域 -->
<main>
<div class="container-fluid px-4">
<h1 class="mt-4">课程管理</h1> <!-- 页面标题 -->
<ol class="breadcrumb mb-4"> <!-- 面包屑导航 -->
<li class="breadcrumb-item"><a th:href="@{/toAdminMain}">主页</a></li> <!-- 面包屑导航第一部分 -->
<li class="breadcrumb-item active">课程管理</li> <!-- 面包屑导航第二部分,表示当前所在页面 -->
</ol>
<div class="card mb-4"> <!-- 显示课程信息的卡片 -->
<div class="card-header"> <!-- 卡片标题 -->
<i class="fas fa-table me-1"></i>
课程信息表
</div>
<div class="card-body"> <!-- 卡片内容 -->
<table id="datatablesSimple"> <!-- 显示课程信息的表格 -->
<thead>
<tr>
<th>编号</th>
<th>名称</th>
<th>时间</th>
<th>时长</th>
<th>教练</th>
<th>操作</th>
</tr>
</thead>
<tbody>
<!-- 使用th:each迭代classList中的每个class对象,生成一行表格 -->
<tr th:each="class:${classList}">
<!-- 显示classId属性的值,如果为空则显示“编号” -->
<td th:text="${class.classId}">编号</td>
<!-- 显示className属性的值,如果为空则显示“名称” -->
<td th:text="${class.className}">名称</td>
<!-- 显示classBegin属性的值,如果为空则显示“时间” -->
<td th:text="${class.classBegin}">时间</td>
<!-- 显示classTime属性的值,如果为空则显示“时长” -->
<td th:text="${class.classTime}">时长</td>
<!-- 显示coach属性的值,如果为空则显示“教练” -->
<td th:text="${class.coach}">教练</td>
<td>
<!-- 使用th:href设置链接地址,当点击链接时会调用selClassOrder方法,传入参数classId -->
<a th:href="@{/class/selClassOrder(classId=${class.classId})}" style="text-decoration: none">
<!-- 显示“报名信息”按钮 -->
<input type="button" class="btn btn-sm btn-outline-secondary" value="报名信息">
</a>
<!-- 使用th:href设置链接地址,当点击链接时会调用delClass方法,传入参数classId -->
<a th:href="@{/class/delClass(classId=${class.classId})}" style="text-decoration: none">
<!-- 显示“删除”按钮,并设置onclick事件,调用del方法 -->
<input type="button" class="btn btn-sm btn-outline-danger" onclick="return del()" value="删除">
</a>
</td>
</tr>
</tbody>
</table>
</div>
</div>
<!-- 这是一个居中对齐的 div 元素,上下各留出 20px 的外边距 -->
<div style="text-align:center;margin-top:20px;margin-bottom:20px">
<!-- 这是一个跳转到添加课程信息页面的链接 -->
<a th:href="@{/class/toAddClass}">
<!-- 这是一个用 Bootstrap 样式的按钮,颜色为绿色,样式为边框,按钮文字为“添加课程信息” -->
<input type="button" class="btn btn-outline-success" value="添加课程信息">
</a>
</div>
</div>
</main>
<footer th:replace="adminCommon::common-footer"></footer>
</div>
</div>
<div th:include="adminCommon::common-scripts"></div>
<script>
// 定义名为del的函数
function del() {
// 设置确认框的提示信息
let msg = "确定要删除吗?";
// 如果用户点击确认,则返回true
if (confirm(msg) == true) {
return true;
}
// 如果用户点击取消,则返回false
else {
return false;
}
}
</script>
<!--这段代码是一个JavaScript函数,用于在用户点击“删除”按钮时弹出一个确认框,让用户确认是否真的要删除该条数据。-->
</body>
</html>
1. <a th:href="@{/class/selClassOrder(classId=${class.classId})}" style="text-decoration: none">
这段代码是一个超链接,使用Thymeleaf模板引擎的语法生成URL,并且将classId作为参数传递给selClassOrder方法。具体解释如下:
th:href:是Thymeleaf模板引擎的语法,用于生成URL。
@{/class/selClassOrder(classId=${class.classId})}:是URL的模板,其中/class/selClassOrder是URL的路径,classId=${class.classId}是URL的参数,${class.classId}是一个Thymeleaf的表达式,用于动态生成classId参数的值。
style="text-decoration: none":是CSS样式,用于去掉超链接的下划线。
因此,这段代码的作用是生成一个带有参数的超链接,点击后将跳转到/class/selClassOrder路径,并且classId参数的值是当前class对象的classId属性值。
2. <script>
// 定义名为del的函数
function del() {
// 设置确认框的提示信息
let msg = "确定要删除吗?";
// 如果用户点击确认,则返回true
if (confirm(msg) == true) {
return true;
}
// 如果用户点击取消,则返回false
else {
return false;
}
}
</script>
框,提示用户是否确定要删除。如果用户点击“确认”,则返回true;如果用户点击“取消”,则返回false。该函数通常被绑定在删除按钮的onclick事件上,用于对用户的删除操作进行确认,避免误删或误操作。
selectClassOrder.html
<!DOCTYPE html>
<html lang="zh-CN" xmlns:th="http://www.thymeleaf.org">
<head th:replace="adminCommon::common-header"></head>
<body class="sb-nav-fixed">
<nav th:replace="adminCommon::common-navbar"></nav>
<div id="layoutSidenav_content">
<main>
<!-- 容器 -->
<div class="container-fluid px-4">
<!-- 标题 -->
<h1 class="mt-4">报名信息</h1>
<!-- 面包屑导航 -->
<ol class="breadcrumb mb-4">
<li class="breadcrumb-item"><a th:href="@{/toAdminMain}">主页</a></li>
<li class="breadcrumb-item"><a th:href="@{/class/selClass}">课程管理</a></li>
<li class="breadcrumb-item active">报名信息</li>
</ol>
<!-- 卡片容器 -->
<div class="card mb-4">
<!-- 当classOrderList为空(该课程无人报名)时显示 -->
<div th:if="${#lists.isEmpty(classOrderList)}">
<table class="table table-hover">
<tr>
<td align="center">暂无报名信息!</td>
</tr>
</table>
</div>
<!-- 当classOrderList不为空(该课程已有人报名)时显示 -->
<div th:if="${not #lists.isEmpty(classOrderList)}">
<table class="table table-hover">
<tr>
<td text-align="center">课程编号:</td>
<td th:text="${classOrderList[0].classId}">课程编号</td>
</tr>
<tr>
<td text-align="center">课程名称:</td>
<td th:text="${classOrderList[0].className}">课程名称</td>
</tr>
<tr>
<td text-align="center">开课时间:</td>
<td th:text="${classOrderList[0].classBegin}">开课时间</td>
</tr>
<tr>
<td colspan="2"></td>
</tr>
<tr>
<td colspan="2"><strong>报名会员:</strong></td>
</tr>
<!-- 循环遍历classOrderList中的报名会员信息 -->
<tr th:each="order:${classOrderList}">
<td th:text="${order.memberAccount}">无</td>
<td th:text="${order.memberName}">无</td>
</tr>
</table>
</div>
<!-- 返回按钮 -->
<a th:href="@{/class/selClass}" style="text-align:center;margin-top:10px;margin-bottom:20px">
<input type="submit" class="btn btn-outline-secondary" value="返回">
</a>
</div>
</div>
</main>
<!-- 页脚 -->
<footer th:replace="adminCommon::common-footer"></footer>
</div>
</div>
<div th:include="adminCommon::common-scripts"></div>
</body>
</html>
1. <div th:if="${#lists.isEmpty(classOrderList)}">
<table class="table table-hover">
<tr>
<td align="center">暂无报名信息!</td>
</tr>
</table>
</div>
这段前端代码使用了Thymeleaf模板引擎的语法,用于在网页上根据条件判断是否显示暂无报名信息的提示。具体解释如下:
th:if 属性用于判断条件是否成立,如果成立则显示包裹在这个标签内的内容,否则不显示。
${#lists.isEmpty(classOrderList)} 是一个Thymeleaf内置的工具类方法,用于判断 classOrderList 是否为空,如果为空则返回 true,否则返回 false。
在条件成立时,会在网页上显示一个表格,表格中只有一个单元格,其中的文字为“暂无报名信息!”。如果条件不成立,则不显示这个表格。
2. <a th:href="@{/class/selClass}" style="text-align:center;margin-top:10px;margin-bottom:20px">
<input type="submit" class="btn btn-outline-secondary" value="返回">
这段代码是一个超链接,其中使用了Thymeleaf模板引擎的语法。当用户点击该链接时,会跳转到地址为/class/selClass的页面。该链接中包含一个按钮,按钮的文本为“返回”,样式为浅灰色的边框按钮。在该按钮之上还添加了一些上下外边距,使其在页面中居中且与其他元素有一定的间距。
selectEmployee.html
<!DOCTYPE html>
<html lang="zh-CN" xmlns:th="http://www.thymeleaf.org">
<head th:replace="adminCommon::common-header"></head>
<body class="sb-nav-fixed">
<nav th:replace="adminCommon::common-navbar"></nav>
<div id="layoutSidenav">
<div th:replace="adminCommon::common-sidenav"></div> <!-- 侧边栏模板,显示在左侧,使用Thymeleaf模板引擎 -->
<div id="layoutSidenav_content">
<main>
<div class="container-fluid px-4">
<h1 class="mt-4">员工管理</h1> <!-- 标题,显示在页面最上方 -->
<ol class="breadcrumb mb-4">
<li class="breadcrumb-item"><a th:href="@{/toAdminMain}">主页</a></li> <!-- 面包屑导航,显示在页面上方,帮助用户快速定位到当前页面的上一级页面 -->
<li class="breadcrumb-item active">员工管理</li>
</ol>
<div class="card mb-4">
<div class="card-header">
<i class="fas fa-table me-1"></i>
员工信息表
</div>
<div class="card-body">
<table id="datatablesSimple"> <!-- 一个表格,用于显示员工信息 -->
<thead>
<tr>
<th>工号</th>
<th>姓名</th>
<th>性别</th>
<th>年龄</th>
<th>入职时间</th>
<th>职务</th>
<th>备注信息</th>
<th>操作</th>
</tr>
</thead>
<tbody>
<!-- 遍历员工列表,为每个员工生成一行数据 -->
<tr th:each="emp:${employeeList}">
<!-- 显示员工的工号 -->
<td th:text="${emp.employeeAccount}">工号</td>
<!-- 显示员工的姓名 -->
<td th:text="${emp.employeeName}">姓名</td>
<!-- 显示员工的性别 -->
<td th:text="${emp.employeeGender}">性别</td>
<!-- 显示员工的年龄 -->
<td th:text="${emp.employeeAge}">年龄</td>
<!-- 显示员工的入职时间 -->
<td th:text="${emp.entryTime}">入职时间</td>
<!-- 显示员工的职务 -->
<td th:text="${emp.staff}">职务</td>
<!-- 显示员工的备注信息 -->
<td th:text="${emp.employeeMessage}">备注信息</td>
<!-- 显示操作按钮,包括编辑和解雇 -->
<td>
<!-- 编辑员工信息的按钮 -->
<a th:href="@{/employee/toUpdateEmployee(employeeAccount=${emp.employeeAccount})}"
style="text-decoration: none">
<input type="button" class="btn btn-sm btn-outline-primary" value="编辑">
</a>
<!-- 解雇员工的按钮 -->
<a th:href="@{/employee/delEmployee(employeeAccount=${emp.employeeAccount})}"
style="text-decoration: none">
<input type="button" class="btn btn-sm btn-outline-danger"
onclick="return del()" value="解雇">
</a>
</td>
</tr>
</tbody>
</table>
</div>
</div>
<div style="text-align:center;margin-top:20px;margin-bottom:20px">
<!-- 样式为居中对齐,顶部间距为20px,底部间距也为20px -->
<a th:href="@{/employee/toAddEmployee}">
<!-- th:href是Spring Boot Thymeleaf模板引擎的语法,表示跳转到员工信息添加页面 -->
<input type="button" class="btn btn-outline-success" value="添加员工信息">
<!-- 添加员工信息按钮,样式为绿色边框的成功按钮 -->
</a>
</div>
</div>
</main>
<footer th:replace="adminCommon::common-footer"></footer>
</div>
</div>
<div th:include="adminCommon::common-scripts"></div>
<script>
function del() {
let msg = "确定要解雇吗?";
if (confirm(msg) == true) {
return true;
} else {
return false;
}
}
</script>
这段代码是一个JavaScript脚本,其中定义了一个名为del的函数。当用户点击“解雇”按钮时,这个函数会被调用。该函数首先创建一个包含“确定要解雇吗?”消息的字符串变量msg,然后调用JavaScript内置的confirm()函数来显示一个包含该消息和确定和取消按钮的对话框。如果用户单击“确定”按钮,则函数返回true,否则返回false。根据返回值,调用该函数的HTML元素上的点击事件可能会继续执行或被取消。在这个例子中,点击“解雇”按钮时,如果用户单击“确定”按钮,则将调用后端代码解雇该员工;如果用户单击“取消”按钮,则不会进行任何操作。
</body>
</html>
1. <a th:href="@{/employee/toUpdateEmployee(employeeAccount=${emp.employeeAccount})}"
style="text-decoration: none">
<input type="button" class="btn btn-sm btn-outline-primary" value="编辑">
</a>
这是一个按钮元素,用于在单击时跳转到编辑员工信息的页面。其中,th:href属性用于设置页面跳转的地址,${emp.employeeAccount}是Thymeleaf模板引擎中的表达式语言,表示引用当前员工对象中的employeeAccount属性值。style属性用于设置按钮样式,text-decoration: none用于去除按钮文本的下划线。class属性用于设置按钮的CSS类,btn、btn-sm、btn-outline-primary分别表示按钮的基础样式、大小样式和颜色样式。value属性用于设置按钮文本。
selectEquipment.html
<!DOCTYPE html>
<html lang="zh-CN" xmlns:th="http://www.thymeleaf.org">
<head th:replace="adminCommon::common-header"></head>
<body class="sb-nav-fixed">
<nav th:replace="adminCommon::common-navbar"></nav>
<div id="layoutSidenav">
<!-- 左侧导航栏 -->
<div th:replace="adminCommon::common-sidenav"></div>
<!-- 主要内容区域 -->
<div id="layoutSidenav_content">
<main>
<div class="container-fluid px-4">
<!-- 页面标题 -->
<h1 class="mt-4">器材管理</h1>
<!-- 面包屑导航 -->
<ol class="breadcrumb mb-4">
<li class="breadcrumb-item"><a th:href="@{/toAdminMain}">主页</a></li>
<li class="breadcrumb-item active">器材管理</li>
</ol>
<!-- 显示器材信息的表格 -->
<div class="card mb-4">
<div class="card-header">
<i class="fas fa-table me-1"></i>
器材信息表
</div>
<div class="card-body">
<table id="datatablesSimple">
<thead>
<tr>
<th>器材id</th>
<th>名称</th>
<th>位置</th>
<th>状态</th>
<th>备注信息</th>
<th>操作</th>
</tr>
</thead>
<tbody>
<!-- 遍历器材信息列表 -->
<tr th:each="equ:${equipmentList}">
<td th:text="${equ.equipmentId}">id</td>
<td th:text="${equ.equipmentName}">name</td>
<td th:text="${equ.equipmentLocation}">location</td>
<td th:text="${equ.equipmentStatus}">status</td>
<td th:text="${equ.equipmentMessage}">message</td>
<td>
<!-- 编辑器材信息 -->
<a th:href="@{/equipment/toUpdateEquipment(equipmentId=${equ.equipmentId})}"
style="text-decoration: none">
<input type="button" class="btn btn-sm btn-outline-primary" value="编辑">
</a>
<!-- 删除器材信息 -->
<a th:href="@{/equipment/delEquipment(equipmentId=${equ.equipmentId})}"
style="text-decoration: none">
<input type="button" class="btn btn-sm btn-outline-danger"
onclick="return del()" value="删除">
</a>
</td>
</tr>
</tbody>
</table>
</div>
</div>
<!-- 添加器材信息的按钮 -->
<div style="text-align:center;margin-top:20px;margin-bottom:20px">
<a th:href="@{/equipment/toAddEquipment}">
<input type="button" class="btn btn-outline-success" value="添加器材信息">
</a>
</div>
</div>
</main>
<!-- 页脚 -->
<footer th:replace="adminCommon::common-footer"></footer>
</div>
</div>
<div th:include="adminCommon::common-scripts"></div>
<script>
function del() {
let msg = "确定要删除吗?";
if (confirm(msg) == true) { // 弹出确认对话框,如果用户点击确认,则返回true;否则返回false
return true;
} else {
return false;
}
}
</script>
</body>
</html>
1. <ol class="breadcrumb mb-4">
<li class="breadcrumb-item"><a th:href="@{/toAdminMain}">主页</a></li>
<li class="breadcrumb-item active">器材管理</li>
</ol>
这是一个由Bootstrap提供的面包屑组件这段代码是一个面包屑导航,用于显示当前页面在网站的位置和层次结构。它由两个列表项组成,分别是“主页”和“器材管理”。点击“主页”列表项可以返回到网站的主页,而“器材管理”则表示当前所在的页面是器材管理页面。使用面包屑导航可以让用户更好地理解当前页面的位置和关系,方便用户进行页面导航和操作。
2. <tr th:each="equ:${equipmentList}">
<td th:text="${equ.equipmentId}">id</td>
<td th:text="${equ.equipmentName}">name</td>
<td th:text="${equ.equipmentLocation}">location</td>
<td th:text="${equ.equipmentStatus}">status</td>
<td th:text="${equ.equipmentMessage}">message</td>
<td>
<!-- 编辑器材信息 -->
<a th:href="@{/equipment/toUpdateEquipment(equipmentId=${equ.equipmentId})}"
style="text-decoration: none">
<input type="button" class="btn btn-sm btn-outline-primary" value="编辑">
</a>
<!-- 删除器材信息 -->
<a th:href="@{/equipment/delEquipment(equipmentId=${equ.equipmentId})}"
style="text-decoration: none">
<input type="button" class="btn btn-sm btn-outline-danger"
onclick="return del()" value="删除">
</a>
</td>
</tr>
这段前端代码使用Thymeleaf模板引擎进行动态渲染,展示了一个器材列表。其中,通过th:each指令循环遍历器材列表,将每个器材的各个属性渲染到页面上的表格中,包括器材id、名称、位置、状态和备注信息。每个器材的最后一列包含编辑和删除按钮,点击编辑按钮会跳转到编辑器材信息的页面,点击删除按钮会弹出确认对话框,确认后会执行删除操作。在删除按钮上添加了一个onclick事件,该事件会调用名为del()的JavaScript函数来弹出确认对话框并返回用户的确认结果。
3. <script>
function del() {
let msg = "确定要删除吗?";
if (confirm(msg) == true) { // 弹出确认对话框,如果用户点击确认,则返回true;否则返回false
return true;
} else {
return false;
}
}
</script>
这是一个JavaScript脚本,定义了一个名为del的函数。该函数的作用是在用户点击删除按钮时弹出确认对话框,询问用户是否确认删除操作。如果用户点击确认,则返回true;否则返回false。这个函数通常用于配合删除按钮,确保用户意图明确,避免误删。在HTML中,可以通过onclick属性将这个函数与删除按钮关联起来,例如:<input type="button" οnclick="return del()" value="删除">。
selectMember.html
<!DOCTYPE html>
<html lang="zh-CN" xmlns:th="http://www.thymeleaf.org">
<head th:replace="adminCommon::common-header"></head>
<body class="sb-nav-fixed">
<nav th:replace="adminCommon::common-navbar"></nav>
<!-- 定义整个页面的左右结构,左侧为导航栏,右侧为内容 -->
<div id="layoutSidenav">
<!-- 引入名为adminCommon::common-sidenav的thymeleaf模板,渲染出导航栏的内容 -->
<div th:replace="adminCommon::common-sidenav"></div>
<!-- 右侧内容区域 -->
<div id="layoutSidenav_content">
<main>
<!-- 页面内容以一个容器为基础进行布局 -->
<div class="container-fluid px-4">
<!-- 标题 -->
<h1 class="mt-4">会员管理</h1>
<!-- 面包屑导航 -->
<ol class="breadcrumb mb-4">
<li class="breadcrumb-item"><a th:href="@{/toAdminMain}">主页</a></li>
<li class="breadcrumb-item active">会员管理</li>
</ol>
<!-- 信息表格的卡片 -->
<div class="card mb-4">
<!-- 卡片标题 -->
<div class="card-header">
<i class="fas fa-table me-1"></i>
会员信息表
</div>
<!-- 卡片主体内容 -->
<div class="card-body">
<!-- 表格 -->
<table id="datatablesSimple">
<!-- 表格头部,包含表格列名 -->
<thead>
<tr>
<th>会员账号/卡号</th>
<th>姓名</th>
<th>办卡时间</th>
<th>性别</th>
<th>年龄</th>
<th>联系方式</th>
<th>身高</th>
<th>体重</th>
<th>购买课时</th>
<th>剩余课时</th>
<th>操作</th>
</tr>
</thead>
<tbody>
<!-- 遍历会员信息列表 -->
<tr th:each="mem:${memberList}">
<!-- 显示会员账号/卡号 -->
<td th:text="${mem.memberAccount}">会员账号/卡号</td>
<!-- 显示会员姓名 -->
<td th:text="${mem.memberName}">姓名</td>
<!-- 显示会员办卡时间 -->
<td th:text="${mem.cardTime}">办卡时间</td>
<!-- 显示会员性别 -->
<td th:text="${mem.memberGender}">性别</td>
<!-- 显示会员年龄 -->
<td th:text="${mem.memberAge}">年龄</td>
<!-- 显示会员联系方式 -->
<td th:text="${mem.memberPhone}">联系方式</td>
<!-- 显示会员身高 -->
<td th:text="${mem.memberHeight}">身高</td>
<!-- 显示会员体重 -->
<td th:text="${mem.memberWeight}">体重</td>
<!-- 显示会员购买课时 -->
<td th:text="${mem.cardClass}">购买课时</td>
<!-- 显示会员剩余课时 -->
<td th:text="${mem.cardNextClass}">剩余课时</td>
<td>
<!-- 编辑会员信息按钮 -->
<a th:href="@{/member/toUpdateMember(memberAccount=${mem.memberAccount})}"
style="text-decoration: none">
<input type="button" class="btn btn-sm btn-outline-primary" value="编辑">
</a>
<!-- 删除会员信息按钮 -->
<a th:href="@{/member/delMember(memberAccount=${mem.memberAccount})}"
style="text-decoration: none">
<input type="button" class="btn btn-sm btn-outline-danger"
onclick="return del()" value="删除">
</a>
</td>
</tr>
</tbody>
</table>
</div>
</div>
<!-- 在页面中央添加一个居中对齐的按钮 -->
<div style="text-align:center;margin-top:20px;margin-bottom:20px">
<!-- 创建一个超链接,链接到添加会员信息的页面 -->
<a th:href="@{/member/toAddMember}">
<!-- 创建一个绿色轮廓按钮,上面写着"添加会员信息" -->
<input type="button" class="btn btn-outline-success" value="添加会员信息">
</a>
</div>
</div>
</main>
<footer th:replace="adminCommon::common-footer"></footer>
</div>
</div>
<div th:include="adminCommon::common-scripts"></div>
<script>
function del() {
let msg = "确定要删除吗?";
if (confirm(msg) == true) {
return true;
} else {
return false;
}
}
</script>
</body>
</html>
updateEmployee.html
<!DOCTYPE html>
<html lang="zh-CN" xmlns:th="http://www.thymeleaf.org">
<head th:replace="adminCommon::common-header"></head>
<body class="sb-nav-fixed">
<nav th:replace="adminCommon::common-navbar"></nav>
<!--这是一个HTML页面的代码,主要用于显示一个编辑会员信息的表单页面-->
<div id="layoutSidenav">
<div th:replace="adminCommon::common-sidenav"></div>
<!-- 侧边栏代码,使用了Thymeleaf模板引擎进行渲染 -->
<div id="layoutSidenav_content">
<main>
<div class="container-fluid px-4">
<h1 class="mt-4">编辑会员</h1>
<!-- 标题 -->
<ol class="breadcrumb mb-4">
<li class="breadcrumb-item"><a th:href="@{/toAdminMain}">主页</a></li>
<li class="breadcrumb-item"><a th:href="@{/member/selMember}">会员管理</a></li>
<li class="breadcrumb-item active">编辑会员</li>
</ol>
<!-- 面包屑导航,用于提示用户当前所在的位置 -->
<div class="card mb-4">
<form th:action="@{/member/updateMember}" method="post" name="updateForm"
onsubmit="return beforeSubmit(this)">
<!-- 提交表单,使用了Thymeleaf的表单绑定功能,绑定了表单提交的URL和请求方法,同时指定表单的name属性和提交时的验证方法 -->
<div th:each="mem:${memberList}">
<!-- 创建一个类为table和table-hover的HTML表格 -->
<table class="table table-hover">
<!-- 创建一个包含会员账号/卡号的表格行 -->
<tr>
<!-- 创建表格单元格,其中包含“会员账号/卡号”文本 -->
<td text-align="center">会员账号/卡号:</td>
<!-- 创建表格单元格,其中包含一个只读的输入框,用于显示会员账号/卡号 -->
<td>
<input type="text" class="form-control" readonly="readonly" th:value="${mem.memberAccount}" name="memberAccount">
</td>
</tr>
<!-- 创建一个包含姓名的表格行 -->
<tr>
<!-- 创建表格单元格,其中包含“姓名”文本 -->
<td text-align="center">姓名:</td>
<!-- 创建表格单元格,其中包含一个输入框,用于显示和修改会员姓名 -->
<td>
<input type="text" class="form-control" th:value="${mem.memberName}" name="memberName">
</td>
</tr>
<!-- 创建一个包含密码的表格行 -->
<tr>
<!-- 创建表格单元格,其中包含“密码”文本 -->
<td text-align="center">密码:</td>
<!-- 创建表格单元格,其中包含一个只读的输入框,用于显示会员密码 -->
<td>
<input type="text" class="form-control" readonly="readonly" th:value="${mem.memberPassword}" name="memberPassword">
</td>
</tr>
<!-- 创建一个包含性别的表格行 -->
<tr>
<!-- 创建表格单元格,其中包含“性别”文本 -->
<td text-align="center">性别:</td>
<!-- 创建表格单元格,其中包含一个输入框,用于显示和修改会员性别 -->
<td>
<input type="text" class="form-control" th:value="${mem.memberGender}" name="memberGender">
</td>
</tr>
<!-- 创建一个包含年龄的表格行 -->
<tr>
<!-- 创建表格单元格,其中包含“年龄”文本 -->
<td text-align="center">年龄:</td>
<!-- 创建表格单元格,其中包含一个输入框,用于显示和修改会员年龄 -->
<td>
<input type="text" class="form-control" th:value="${mem.memberAge}" name="memberAge">
</td>
</tr>
<!-- 创建一个包含联系方式的表格行 -->
<tr>
<!-- 创建表格单元格,其中包含“联系方式”文本 -->
<td text-align="center">联系方式:</td>
<!-- 创建表格单元格,其中包含一个输入框,用于显示和修改会员联系方式 -->
<td>
<input type="text" class="form-control" th:value="${mem.memberPhone}" name="memberPhone">
</td>
</tr>
<!-- 表格中的一行,显示会员身高信息 -->
<tr>
<td text-align="center">身高:</td>
<td>
<!-- 输入框,显示会员身高信息 -->
<input type="text" class="form-control" th:value="${mem.memberHeight}" name="memberHeight">
</td>
</tr>
<!-- 表格中的一行,显示会员体重信息 -->
<tr>
<td text-align="center">体重:</td>
<td>
<!-- 输入框,显示会员体重信息 -->
<input type="text" class="form-control" th:value="${mem.memberWeight}" name="memberWeight">
</td>
</tr>
<!-- 表格中的一行,显示会员购买课时信息 -->
<tr>
<td text-align="center">购买课时:</td>
<td>
<!-- 输入框,显示会员购买课时信息 -->
<input type="text" class="form-control" th:value="${mem.cardClass}" name="cardClass">
</td>
</tr>
<!-- 表格中的一行,显示会员剩余课时信息 -->
<tr>
<td text-align="center">剩余课时:</td>
<td>
<!-- 输入框,显示会员剩余课时信息 -->
<input type="text" class="form-control" th:value="${mem.cardNextClass}" name="cardNextClass">
</td>
</tr>
</table>
<!-- 以下是一个用于居中的div,设置了底部外边距为15像素 -->
<div style="text-align:center;margin-bottom:15px">
<!-- 以下是一个提交按钮,样式为轮廓性绿色按钮,文本为“确认修改” -->
<input type="submit" class="btn btn-outline-success" value="确认修改">
</div>
</div>
</form>
</div>
</div>
</main>
<footer th:replace="adminCommon::common-footer"></footer>
</div>
</div>
<div th:include="adminCommon::common-scripts"></div>
<script type="text/javascript">
// 定义一个名为beforeSubmit的函数,该函数用于在提交表单前进行验证
function beforeSubmit(updateForm) {
// 定义一个手机号码的正则表达式
let phone = /^[1][3,4,5,7,8,9][0-9]{9}$/;//设置手机号正则表达式 // 如果手机号码格式不正确,弹出提示信息并返回false
if (!phone.test(updateForm.memberPhone.value)) {
alert("手机号码错误!");
return false;
} // 如果手机号码格式正确,返回true
return true;
}
</script>
</body>
</html>
1. <ol class="breadcrumb mb-4">
<li class="breadcrumb-item"><a th:href="@{/toAdminMain}">主页</a></li> <!-- 面包屑导航 -->
<li class="breadcrumb-item"><a th:href="@{/employee/selEmployee}">员工管理</a></li>
<li class="breadcrumb-item active">编辑员工</li>
</ol>
这段代码是一个面包屑导航,用于帮助用户定位当前页面的位置和路径。其中,ol表示有序列表,class为“breadcrumb mb-4”表示面包屑的样式;每个li标签表示一个面包屑导航项,其中,第一个li表示回到主页,第二个li表示员工管理,第三个li表示当前页面是编辑员工。使用th:href属性可以让用户点击面包屑导航项后跳转到相应的页面。
2. <div th:each="emp:${employeeList}">
这是一个Thymeleaf模板引擎中的指令,用于在HTML页面中循环渲染多个元素,每个元素对应employeeList中的一个对象,对象的属性可以通过Thymeleaf的属性绑定方式在页面中显示。其中“emp”是迭代时当前对象的别名,可以在循环内部使用。
3. <tr>
<td text-align="center">工号:</td> <!-- 工号 -->
<td><input type="text" class="form-control" readonly="readonly"
th:value="${emp.employeeAccount}" name="employeeAccount">
</td>
</tr>
这段代码展示了一个表格中的一行,该行显示了员工的工号。具体解释如下:
<tr> 表示表格的一行。
<td text-align="center">工号:</td> 表示一列,文本居中,显示“工号:”。
<td> 表示一列,其中包含一个输入框,用于显示员工的工号。
<input type="text" class="form-control" readonly="readonly" th:value="${emp.employeeAccount}" name="employeeAccount"> 表示输入框的具体属性:
type="text" 表示该输入框为文本输入框。
class="form-control" 表示该输入框使用 form-control 样式,通常用于 Bootstrap 框架。
readonly="readonly" 表示该输入框只读,即不能编辑。
th:value="${emp.employeeAccount}" 表示该输入框的值来自于 Thymeleaf 模板引擎中的 emp.employeeAccount 属性。
name="employeeAccount" 表示该输入框的名称为 employeeAccount。
updateEquipment.html
<!DOCTYPE html>
<html lang="zh-CN" xmlns:th="http://www.thymeleaf.org">
<head th:replace="adminCommon::common-header"></head>
<body class="sb-nav-fixed">
<nav th:replace="adminCommon::common-navbar"></nav>
<div id="layoutSidenav">
<div th:replace="adminCommon::common-sidenav"></div> <!-- 包含侧边栏的模板片段 -->
<div id="layoutSidenav_content">
<main>
<div class="container-fluid px-4">
<h1 class="mt-4">编辑器材</h1> <!-- 页面标题 -->
<ol class="breadcrumb mb-4">
<li class="breadcrumb-item"><a th:href="@{/toAdminMain}">主页</a></li> <!-- 面包屑导航:跳转到管理员主页 -->
<li class="breadcrumb-item"><a th:href="@{/equipment/selEquipment}">器材管理</a></li> <!-- 面包屑导航:跳转到器材管理页面 -->
<li class="breadcrumb-item active">编辑器材</li> <!-- 面包屑导航:当前页面 -->
</ol>
<div class="card mb-4">
<form th:action="@{/equipment/updateEquipment}" method="post"> <!-- 表单提交地址和方法 -->
<div th:each="equ:${equipmentList}"> <!-- 遍历器材列表,展示当前要编辑的器材信息 -->
<table class="table table-hover">
<tr>
<td text-align="center">器材id:</td>
<td><input type="text" class="form-control" readonly="readonly"
th:value="${equ.equipmentId}" name="equipmentId"> <!-- 器材id,只读 -->
</td>
</tr>
<tr>
<td text-align="center">器材名称:</td>
<td><input type="text" class="form-control" th:value="${equ.equipmentName}"
name="equipmentName"></td> <!-- 器材名称,可编辑 -->
</tr>
<tr>
<td text-align="center">器材位置:</td>
<td><input type="text" class="form-control" th:value="${equ.equipmentLocation}"
name="equipmentLocation">
</td> <!-- 器材位置,可编辑 -->
</tr>
<tr>
<td text-align="center">器材状态:</td>
<td><input type="text" class="form-control" th:value="${equ.equipmentStatus}"
name="equipmentStatus">
</td> <!-- 器材状态,可编辑 -->
</tr>
<tr>
<td text-align="center">器材备注信息:</td>
<td><input type="text" class="form-control" th:value="${equ.equipmentMessage}"
name="equipmentMessage">
</td> <!-- 器材备注信息,可编辑 -->
</tr>
</table>
<div style="text-align:center;margin-bottom:15px">
<input type="submit" class="btn btn-outline-success" value="确认修改"> <!-- 提交修改按钮 -->
</div>
</div>
</form>
</div>
</div>
</main>
<footer th:replace="adminCommon::common-footer"></footer> <!-- 包含页脚的模板片段 -->
</div>
</div>
<div th:include="adminCommon::common-scripts"></div>
</body>
</html>
updateMember.html
<!DOCTYPE html>
<html lang="zh-CN" xmlns:th="http://www.thymeleaf.org">
<head th:replace="adminCommon::common-header"></head>
<body class="sb-nav-fixed">
<nav th:replace="adminCommon::common-navbar"></nav>
<!--这是一个HTML页面的代码,主要用于显示一个编辑会员信息的表单页面-->
<div id="layoutSidenav">
<div th:replace="adminCommon::common-sidenav"></div>
<!-- 侧边栏代码,使用了Thymeleaf模板引擎进行渲染 -->
<div id="layoutSidenav_content">
<main>
<div class="container-fluid px-4">
<h1 class="mt-4">编辑会员</h1>
<!-- 标题 -->
<ol class="breadcrumb mb-4">
<li class="breadcrumb-item"><a th:href="@{/toAdminMain}">主页</a></li>
<li class="breadcrumb-item"><a th:href="@{/member/selMember}">会员管理</a></li>
<li class="breadcrumb-item active">编辑会员</li>
</ol>
<!-- 面包屑导航,用于提示用户当前所在的位置 -->
<div class="card mb-4">
<form th:action="@{/member/updateMember}" method="post" name="updateForm"
onsubmit="return beforeSubmit(this)">
<!-- 提交表单,使用了Thymeleaf的表单绑定功能,绑定了表单提交的URL和请求方法,同时指定表单的name属性和提交时的验证方法 -->
<div th:each="mem:${memberList}">
<!-- 创建一个类为table和table-hover的HTML表格 -->
<table class="table table-hover">
<!-- 创建一个包含会员账号/卡号的表格行 -->
<tr>
<!-- 创建表格单元格,其中包含“会员账号/卡号”文本 -->
<td text-align="center">会员账号/卡号:</td>
<!-- 创建表格单元格,其中包含一个只读的输入框,用于显示会员账号/卡号 -->
<td>
<input type="text" class="form-control" readonly="readonly" th:value="${mem.memberAccount}" name="memberAccount">
</td>
</tr>
<!-- 创建一个包含姓名的表格行 -->
<tr>
<!-- 创建表格单元格,其中包含“姓名”文本 -->
<td text-align="center">姓名:</td>
<!-- 创建表格单元格,其中包含一个输入框,用于显示和修改会员姓名 -->
<td>
<input type="text" class="form-control" th:value="${mem.memberName}" name="memberName">
</td>
</tr>
<!-- 创建一个包含密码的表格行 -->
<tr>
<!-- 创建表格单元格,其中包含“密码”文本 -->
<td text-align="center">密码:</td>
<!-- 创建表格单元格,其中包含一个只读的输入框,用于显示会员密码 -->
<td>
<input type="text" class="form-control" readonly="readonly" th:value="${mem.memberPassword}" name="memberPassword">
</td>
</tr>
<!-- 创建一个包含性别的表格行 -->
<tr>
<!-- 创建表格单元格,其中包含“性别”文本 -->
<td text-align="center">性别:</td>
<!-- 创建表格单元格,其中包含一个输入框,用于显示和修改会员性别 -->
<td>
<input type="text" class="form-control" th:value="${mem.memberGender}" name="memberGender">
</td>
</tr>
<!-- 创建一个包含年龄的表格行 -->
<tr>
<!-- 创建表格单元格,其中包含“年龄”文本 -->
<td text-align="center">年龄:</td>
<!-- 创建表格单元格,其中包含一个输入框,用于显示和修改会员年龄 -->
<td>
<input type="text" class="form-control" th:value="${mem.memberAge}" name="memberAge">
</td>
</tr>
<!-- 创建一个包含联系方式的表格行 -->
<tr>
<!-- 创建表格单元格,其中包含“联系方式”文本 -->
<td text-align="center">联系方式:</td>
<!-- 创建表格单元格,其中包含一个输入框,用于显示和修改会员联系方式 -->
<td>
<input type="text" class="form-control" th:value="${mem.memberPhone}" name="memberPhone">
</td>
</tr>
<!-- 表格中的一行,显示会员身高信息 -->
<tr>
<td text-align="center">身高:</td>
<td>
<!-- 输入框,显示会员身高信息 -->
<input type="text" class="form-control" th:value="${mem.memberHeight}" name="memberHeight">
</td>
</tr>
<!-- 表格中的一行,显示会员体重信息 -->
<tr>
<td text-align="center">体重:</td>
<td>
<!-- 输入框,显示会员体重信息 -->
<input type="text" class="form-control" th:value="${mem.memberWeight}" name="memberWeight">
</td>
</tr>
<!-- 表格中的一行,显示会员购买课时信息 -->
<tr>
<td text-align="center">购买课时:</td>
<td>
<!-- 输入框,显示会员购买课时信息 -->
<input type="text" class="form-control" th:value="${mem.cardClass}" name="cardClass">
</td>
</tr>
<!-- 表格中的一行,显示会员剩余课时信息 -->
<tr>
<td text-align="center">剩余课时:</td>
<td>
<!-- 输入框,显示会员剩余课时信息 -->
<input type="text" class="form-control" th:value="${mem.cardNextClass}" name="cardNextClass">
</td>
</tr>
</table>
<!-- 以下是一个用于居中的div,设置了底部外边距为15像素 -->
<div style="text-align:center;margin-bottom:15px">
<!-- 以下是一个提交按钮,样式为轮廓性绿色按钮,文本为“确认修改” -->
<input type="submit" class="btn btn-outline-success" value="确认修改">
</div>
</div>
</form>
</div>
</div>
</main>
<footer th:replace="adminCommon::common-footer"></footer>
</div>
</div>
<div th:include="adminCommon::common-scripts"></div>
<script type="text/javascript">
// 定义一个名为beforeSubmit的函数,该函数用于在提交表单前进行验证
function beforeSubmit(updateForm) {
// 定义一个手机号码的正则表达式
let phone = /^[1][3,4,5,7,8,9][0-9]{9}$/;//设置手机号正则表达式 // 如果手机号码格式不正确,弹出提示信息并返回false
if (!phone.test(updateForm.memberPhone.value)) {
alert("手机号码错误!");
return false;
} // 如果手机号码格式正确,返回true
return true;
}
</script>
</body>
</html>
1. <form th:action="@{/member/updateMember}" method="post" name="updateForm"
onsubmit="return beforeSubmit(this)">
这是一个HTML表单,通过th:action属性指定了表单提交的目标URL为“/member/updateMember”,提交方法为POST。同时,表单有一个名为“updateForm”的名称。其中,onsubmit属性指定了一个JavaScript函数“beforeSubmit(this)”,该函数在提交表单之前执行。如果该函数返回false,则表单不会被提交。
2. <div th:each="mem:${memberList}">
面包屑导航:用于标识当前页面所处的位置,包含一个或多个链接,方便用户在网站中进行导航。
th:each:用于遍历集合中的每个元素,可以在模板中循环生成相应的 HTML 代码。
工号:员工的工作编号。
input:用于在表单中输入数据的 HTML 元素。
form:用于创建包含表单控件的 HTML 表单,通常用于向服务器提交数据。
th:action:用于指定表单提交的目标 URL。
method:指定表单提交时使用的 HTTP 方法。
onsubmit:指定在表单提交之前要执行的 JavaScript 函数。
beforeSubmit:自定义的 JavaScript 函数,用于在表单提交之前进行数据验证等操作。
updateUserInformation.html
<!DOCTYPE html>
<html lang="zh-CN" xmlns:th="http://www.thymeleaf.org">
<head th:replace="userCommon::common-header"></head>
<body class="sb-nav-fixed">
<nav th:replace="userCommon::common-navbar"></nav>
<div id="layoutSidenav"> <!-- 整个页面的主要布局 -->
<div th:replace="userCommon::common-sidenav"></div> <!-- 引入侧边栏模板 -->
<div id="layoutSidenav_content"> <!-- 右侧主要内容区域 -->
<main>
<div class="container-fluid px-4">
<h1 class="mt-4">编辑个人信息</h1> <!-- 页面标题 -->
<ol class="breadcrumb mb-4"> <!-- 面包屑导航,提示用户当前位置 -->
<li class="breadcrumb-item"><a th:href="@{/toUserMain}">主页</a></li>
<li class="breadcrumb-item"><a th:href="@{/user/toUserInfo}">个人信息</a></li>
<li class="breadcrumb-item active">编辑个人信息</li>
</ol>
<div class="card mb-4"> <!-- 使用 Bootstrap 样式渲染卡片 -->
<form th:action="@{/user/updateInfo}" method="post" name="updateForm"
onsubmit="return beforeSubmit(this)"> <!-- 提交表单,并在提交前执行 JavaScript 函数 beforeSubmit() -->
<table class="table table-hover">
<!-- 第一行,包含会员账号/卡号 -->
<tr>
<td text-align="center">会员账号/卡号:</td>
<td>
<!-- 会员账号/卡号输入框,设置为只读,并将当前会员的账号/卡号值作为初始值 -->
<input type="text" class="form-control" readonly="readonly" th:value="${member.memberAccount}" name="memberAccount">
</td>
</tr>
<!-- 第二行,包含会员姓名 -->
<tr>
<td text-align="center">姓名:</td>
<td>
<!-- 会员姓名输入框,将当前会员的姓名作为初始值 -->
<input type="text" class="form-control" th:value="${member.memberName}" name="memberName">
</td>
</tr>
<!-- 第三行,包含会员密码 -->
<tr>
<td text-align="center">密码:</td>
<td>
<!-- 会员密码输入框,将当前会员的密码作为初始值 -->
<input type="text" class="form-control" th:value="${member.memberPassword}" name="memberPassword">
</td>
</tr>
<!-- 第四行,包含会员性别 -->
<tr>
<td text-align="center">性别:</td>
<td>
<!-- 会员性别输入框,将当前会员的性别作为初始值 -->
<input type="text" class="form-control" th:value="${member.memberGender}" name="memberGender">
</td>
</tr>
<!-- 第五行,包含会员年龄 -->
<tr>
<td text-align="center">年龄:</td>
<td>
<!-- 会员年龄输入框,将当前会员的年龄作为初始值 -->
<input type="text" class="form-control" th:value="${member.memberAge}" name="memberAge">
</td>
</tr>
<!-- 第六行,包含会员联系方式 -->
<tr>
<td text-align="center">联系方式:</td>
<td>
<!-- 会员联系方式输入框,将当前会员的联系方式作为初始值 -->
<input type="text" class="form-control" th:value="${member.memberPhone}" name="memberPhone">
</td>
</tr>
<!-- 第七行,包含会员身高 -->
<tr>
<td text-align="center">身高:</td>
<td>
<!-- 会员身高输入框,将当前会员的身高作为初始值 -->
<input type="text" class="form-control" th:value="${member.memberHeight}" name="memberHeight">
</td>
</tr>
<tr>
<td text-align="center">体重:</td>
<td><input type="text" class="form-control" th:value="${member.memberWeight}"
name="memberWeight">
</td>
</tr>
</table>
<!--创建一个 div 元素,样式为居中对齐和底部 margin 15px-->
<div style="text-align:center;margin-bottom:15px">
<!--创建一个提交按钮-->
<input type="submit"
class="btn btn-outline-success" <!--添加按钮样式,以显示为绿色轮廓按钮-->
value="确认修改"> <!--按钮显示文本为“确认修改”-->
</div>
</form>
</div>
</div>
</main>
<footer th:replace="userCommon::common-footer"></footer>
</div>
</div>
<div th:include="userCommon::common-scripts"></div>
<!--使用 script 标签定义一个 JavaScript 函数,该函数用于提交表单之前的验证-->
<script type="text/javascript">
<script type="text/javascript">
function beforeSubmit(updateForm) {
let phone = /^[1][3,4,5,7,8,9][0-9]{9}$/;//设置手机号正则表达式
//如果手机号码不符合正则表达式,则弹出错误提示并返回 false,表示表单验证不通过
if (!phone.test(updateForm.memberPhone.value)) {
alert("手机号码错误!");
return false;
}
return true;
}
</script>
</body>
</html>
script代码解释:
这段代码定义了一个名为 beforeSubmit
的 JavaScript 函数,该函数将在提交表单之前对表单进行验证。具体注释如下:
function beforeSubmit(updateForm)
:定义了一个名为beforeSubmit
的函数,该函数将接收一个名为updateForm
的参数,该参数表示待验证的表单对象。let phone = /^[1][3,4,5,7,8,9][0-9]{9}$/;
:定义了一个名为phone
的变量,该变量存储了一个手机号码的正则表达式,该正则表达式限定了手机号码的格式必须以 1 开头,第二位为 3、4、5、7、8 或 9,后面必须跟着 9 个数字。if (!phone.test(updateForm.memberPhone.value))
:如果待验证的表单中名为memberPhone
的表单元素的值不符合手机号码正则表达式,则执行下面的代码块。alert("手机号码错误!");
:弹出一个提示框,显示错误信息“手机号码错误!”。return false;
:返回 false,表示表单验证不通过。return true;
:如果手机号码符合正则表达式,则返回 true,表示表单验证通过。
userApplyClass.html
<!DOCTYPE html>
<html lang="zh-CN" xmlns:th="http://www.thymeleaf.org">
<head th:replace="userCommon::common-header"></head>
<body class="sb-nav-fixed">
<nav th:replace="userCommon::common-navbar"></nav>
<!--使用 id 属性定义一个容器-->
<div id="layoutSidenav">
<!--在容器内部引入一个名为 "userCommon::common-sidenav" 的 Thymeleaf 片段-->
<div th:replace="userCommon::common-sidenav"></div>
<!--使用 id 属性定义另一个容器-->
<div id="layoutSidenav_content">
<!--定义一个主体内容区域-->
<main>
<!--定义一个容器,设置其样式-->
<div class="container-fluid px-4">
<!--定义一个标题-->
<h1 class="mt-4">报名选课</h1>
<!--定义一个面包屑导航,用于展示当前页面的位置信息-->
<ol class="breadcrumb mb-4">
<li class="breadcrumb-item"><a th:href="@{/toUserMain}">主页</a></li>
<li class="breadcrumb-item active">报名选课</li>
</ol>
<!--定义一个卡片容器-->
<div class="card mb-4">
<!--定义卡片容器的标题-->
<div class="card-header">
<i class="fas fa-table me-1"></i>
课程信息表
</div>
<!--定义卡片容器的主体内容-->
<div class="card-body">
<!--定义一个表格,使用 id 属性进行标识-->
<table id="datatablesSimple">
<!--定义表格的列名-->
<thead>
<tr>
<th>编号</th>
<th>名称</th>
<th>时间</th>
<th>时长</th>
<th>教练</th>
<th>操作</th>
</tr>
</thead>
<!--定义表格的内容-->
<tbody>
<!--使用 th:each 指令遍历课程列表-->
<tr th:each="class:${classList}">
<!--展示课程编号-->
<td th:text="${class.classId}">编号</td>
<!--展示课程名称-->
<td th:text="${class.className}">名称</td>
<!--展示课程时间-->
<td th:text="${class.classBegin}">时间</td>
<!--展示课程时长-->
<td th:text="${class.classTime}">时长</td>
<!--展示课程教练-->
<td th:text="${class.coach}">教练</td>
<!--在操作列中添加一个报名按钮-->
<td>
<a th:href="@{/user/applyClass(classId=${class.classId})}"
style="text-decoration: none">
<input type="button" class="btn btn-sm btn-outline-primary" value="报名">
</a>
</td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
</main>
<!--在主体内容区域下方引入一个名为 "userCommon::common-footer" 的 Thymeleaf 片段-->
<footer th:replace="userCommon::common-footer"></footer>
</div>
</div>
<div th:include="userCommon::common-scripts"></div>
</body>
</html>
1. <tr th:each="class:${classList}">
该代码使用了Thymeleaf模板引擎中的th:each属性来遍历classList列表中的元素,并将每个元素赋值给变量class。在HTML表格中,每次循环都会生成一个<tr>标签,表示一行数据。
2. <td th:text="${class.classId}">编号</td>
这行代码用于显示每个班级的编号。其中${class.classId}是使用Thymeleaf模板引擎表达式,用于获取当前循环中班级对象的classId属性的值,并将其设置为该表格单元格的文本内容。如果class对象中的classId属性值为空,则该单元格的文本内容将默认为“编号”。
3. <a th:href="@{/user/applyClass(classId=${class.classId})}"
style="text-decoration: none">
<input type="button" class="btn btn-sm btn-outline-primary" value="报名">
</a>
这段代码是一个HTML中的链接元素,当用户点击这个链接时,会向服务器发送一个请求来报名参加某个课程。
具体来说,这个链接的目标地址是/user/applyClass,其中classId=${class.classId}是一个Thymeleaf表达式,表示classId参数的值是当前循环到的class对象的classId属性。这样,在用户点击链接时,就会将对应的classId值作为参数一起发送给服务器。
该链接还定义了一个按钮元素,当用户点击该按钮时,会触发链接的点击事件。这个按钮的样式是一个蓝色的小按钮,按钮上显示了“报名”两个字。同时,也通过CSS样式去除了链接的下划线和按钮的默认样式。
userClass.html
<!DOCTYPE html>
<html lang="zh-CN" xmlns:th="http://www.thymeleaf.org">
<head th:replace="userCommon::common-header"></head>
<body class="sb-nav-fixed">
<nav th:replace="userCommon::common-navbar"></nav>
<div id="layoutSidenav">
<!-- 引入公共侧边栏 -->
<div th:replace="userCommon::common-sidenav"></div>
<div id="layoutSidenav_content">
<main>
<div class="container-fluid px-4">
<h1 class="mt-4">我的课程</h1>
<ol class="breadcrumb mb-4">
<li class="breadcrumb-item"><a th:href="@{/toUserMain}">主页</a></li>
<li class="breadcrumb-item active">我的课程</li>
</ol>
<!-- 课程信息表卡片 -->
<div class="card mb-4">
<div class="card-header">
<i class="fas fa-table me-1"></i>
课程信息表
</div>
<div class="card-body">
<!-- 使用datatables库展示数据 -->
<table id="datatablesSimple">
<thead>
<!-- 表头 -->
<tr>
<th>编号</th>
<th>名称</th>
<th>时间</th>
<th>教练</th>
<th>操作</th>
</tr>
</thead>
<tbody>
<!-- 循环展示课程列表 -->
<tr th:each="class:${classOrderList}">
<!-- 课程编号 -->
<td th:text="${class.classId}">编号</td>
<!-- 课程名称 -->
<td th:text="${class.className}">名称</td>
<!-- 课程开始时间 -->
<td th:text="${class.classBegin}">时间</td>
<!-- 课程教练 -->
<td th:text="${class.coach}">教练</td>
<!-- 操作按钮列 -->
<td>
<!-- 退课按钮 -->
<a th:href="@{/user/delUserClass(classOrderId=${class.classOrderId})}"
style="text-decoration: none">
<input type="button" class="btn btn-sm btn-outline-danger"
onclick="return del()" value="退课">
</a>
</td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
</main>
<!-- 引入公共页脚 -->
<footer th:replace="userCommon::common-footer"></footer>
</div>
</div>
<div th:include="userCommon::common-scripts"></div>
<script>
function del() {
let msg = "确定要退课吗?";
if (confirm(msg) == true) {
return true;
} else {
return false;
}
}
</script>
</body>
</html>
1. <table id="datatablesSimple">
这是一个HTML表格元素,使用了id为“datatablesSimple”。这个ID可能用于在JavaScript代码中选择和操作这个表格。
2. <a th:href="@{/user/delUserClass(classOrderId=${class.classOrderId})}"
style="text-decoration: none">
<input type="button" class="btn btn-sm btn-outline-danger"
onclick="return del()" value="退课">
</a>
这是一个超链接,它指向一个URL路径,并设置了一个th:href属性值,这个属性值使用了Spring Boot框架的URL路径匹配语法。当用户点击这个链接时,浏览器会向服务器发起一个HTTP请求,请求的URL路径是th:href属性指定的路径。同时,这个链接中嵌套了一个input标签,它是一个按钮元素,当用户点击这个按钮时,会触发onclick事件,调用del()函数来提示用户确认是否退课。如果用户点击确认,则会执行退课操作,否则什么都不会发生。
3. <script>
function del() {
let msg = "确定要退课吗?";
if (confirm(msg) == true) {
return true;
} else {
return false;
}
}
</script>
这是一个JavaScript脚本,用于在用户点击退课按钮时弹出确认对话框。该对话框会显示一个消息,询问用户是否确定要退课。如果用户点击“确定”按钮,则返回true;如果用户点击“取消”按钮,则返回false。在这个例子中,该函数被绑定到一个按钮的onclick事件上,以便在用户点击该按钮时执行。
userCommon.html
<!DOCTYPE html>
<html lang="zh-CN" xmlns:th="http://www.thymeleaf.org">
<head th:fragment="common-header">
<!-- 设置页面的字符集 -->
<meta charset="UTF-8"/>
<!-- 兼容IE浏览器的最新文档模式 -->
<meta http-equiv="X-UA-Compatible" content="IE=edge"/>
<!-- 定义视口以支持响应式布局 -->
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no"/>
<!-- 页面的描述信息 -->
<meta name="description" content="gym-management-system"/>
<!-- 页面的作者信息 -->
<meta name="author" content="ZhangMing"/>
<!-- 页面标题 -->
<title>健身房管理系统-用户</title>
<!-- 导入 Simple DataTables 样式 -->
<link href="https://cdn.jsdelivr.net/npm/simple-datatables@latest/dist/style.css" rel="stylesheet"/>
<!-- 导入自定义样式 -->
<link href="/static/css/styles.css" th:href="@{/css/styles.css}" rel="stylesheet"/>
<!-- 导入 Font Awesome 图标 -->
<script src="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.15.3/js/all.min.js"
crossorigin="anonymous"></script>
</head>
<body>
<!--导航栏-->
<nav class="sb-topnav navbar navbar-expand navbar-dark bg-dark" th:fragment="common-navbar">
<!-- Navbar Brand-->
<a class="navbar-brand ps-3">健身房管理系统</a>
<!-- Sidebar Toggle-->
<button class="btn btn-link btn-sm order-1 order-lg-0 me-4 me-lg-0" id="sidebarToggle" href="#!"><i
class="fas fa-bars"></i></button>
<!-- Navbar Search-->
<form class="d-none d-md-inline-block form-inline ms-auto me-0 me-md-3 my-2 my-md-0">
<div class="input-group">
<input class="form-control" type="text" placeholder="搜索" aria-label="搜索"
aria-describedby="btnNavbarSearch"/>
<button class="btn btn-primary" id="btnNavbarSearch" type="button"><i class="fas fa-search"></i></button>
</div>
</form>
<!-- Navbar-->
<ul class="navbar-nav ms-auto ms-md-0 me-3 me-lg-4">
<li class="nav-item dropdown">
<a class="nav-link dropdown-toggle" id="navbarDropdown" href="#" role="button" data-bs-toggle="dropdown"
aria-expanded="false"><i class="fas fa-user fa-fw"></i></a>
<ul class="dropdown-menu dropdown-menu-end" aria-labelledby="navbarDropdown">
<li><a class="dropdown-item" th:href="@{/toUserLogin}"><i class="fas fa-sign-out-alt"></i> 退出登录</a></li>
</ul>
</li>
</ul>
</nav>
<!--侧边栏-->
<div id="layoutSidenav_nav" th:fragment="common-sidenav">
<nav class="sb-sidenav accordion sb-sidenav-light" id="sidenavAccordion">
<div class="sb-sidenav-menu">
<div class="nav">
<!--管理区域-->
<div class="sb-sidenav-menu-heading">管理</div>
<a class="nav-link" th:href="@{/user/toUserInfo}">
<div class="sb-nav-link-icon"><i class="fas fa-user"></i></div>
个人信息
</a>
<a class="nav-link collapsed" href="#" data-bs-toggle="collapse" data-bs-target="#collapseLayouts" aria-expanded="false" aria-controls="collapseLayouts">
<div class="sb-nav-link-icon"><i class="fas fa-calendar-alt"></i></div>
课程管理
<div class="sb-sidenav-collapse-arrow"><i class="fas fa-angle-down"></i></div>
</a>
<div class="collapse" id="collapseLayouts" aria-labelledby="headingOne" data-bs-parent="#sidenavAccordion">
<nav class="sb-sidenav-menu-nested nav">
<a class="nav-link" th:href="@{/user/toApplyClass}">报名选课</a>
<a class="nav-link" th:href="@{/user/toUserClass}">我的课程</a>
</nav>
</div>
<!--链接区域-->
<div class="sb-sidenav-menu-heading">链接</div>
<a class="nav-link" href="https://zhuanlan.zhihu.com/p/440751809">
<div class="sb-nav-link-icon"><i class="fab fa-github"></i></div>
注意事项
</a>
</div>
</div>
<div class="sb-sidenav-footer">
<div class="small">你好!</div>
尊敬的会员
</div>
</nav>
</div>
<!--页脚-->
<footer class="py-4 bg-light mt-auto" th:fragment="common-footer">
<div class="container-fluid px-4">
<div class="d-flex align-items-center justify-content-between small">
<div class="text-muted">Copyright © chenfuhai 2023</div>
</div>
</div>
</footer>
<div th:fragment="common-scripts">
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.0.2/dist/js/bootstrap.bundle.min.js"
crossorigin="anonymous"></script>
<script src="/static/js/scripts.js" th:src="@{/js/scripts.js}"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.8.0/Chart.min.js" crossorigin="anonymous"></script>
<script src="/static/assets/demo/chart-area-demo.js" th:src="@{/assets/demo/chart-area-demo.js}"></script>
<script src="/static/assets/demo/chart-bar-demo.js" th:src="@{/assets/demo/chart-bar-demo.js}"></script>
<script src="https://cdn.jsdelivr.net/npm/simple-datatables@latest" crossorigin="anonymous"></script>
<script src="/static/js/datatables-simple-demo.js" th:src="@{/js/datatables-simple-demo.js}"></script>
</div>
</body>
</html>
1. <ul class="navbar-nav ms-auto ms-md-0 me-3 me-lg-4">
<li class="nav-item dropdown">
<a class="nav-link dropdown-toggle" id="navbarDropdown" href="#" role="button" data-bs-toggle="dropdown"
aria-expanded="false"><i class="fas fa-user fa-fw"></i></a>
<ul class="dropdown-menu dropdown-menu-end" aria-labelledby="navbarDropdown">
<li><a class="dropdown-item" th:href="@{/toUserLogin}"><i class="fas fa-sign-out-alt"></i> 退出登录</a></li>
</ul>
</li>
</ul>
这段代码是一个导航栏的用户登录信息部分,它包含一个下拉菜单,其中包含一个"退出登录"选项。具体来说,这个导航栏有一个右对齐的用户信息部分,其中包含一个带有用户头像图标的下拉按钮。当用户点击这个按钮时,会弹出一个下拉菜单,其中只有一个选项,即"退出登录"。这个选项是一个链接,指向一个用Thymeleaf模板语言编写的页面。
head:
这段代码是HTML页面的头部内容,主要包含以下内容:
- 设置页面的字符集为 UTF-8。
- 设置文档模式为 IE 最新版本。
- 定义视口以支持响应式布局。
- 定义页面的描述信息和作者信息。
- 设置页面标题为 "健身房管理系统-用户"。
- 导入 Simple DataTables 样式,用于显示表格。
- 导入自定义样式,用于美化页面。
- 导入 Font Awesome 图标,用于显示图标。
<!--导航栏-->:
- 一个显示“健身房管理系统”的导航栏品牌。
- 一个切换侧边栏的按钮。
- 一个搜索框,用户可以输入关键字进行搜索。
- 一个下拉菜单,展示当前用户信息和“退出登录”选项。
代码中包含以下具体的HTML标签和CSS类:
<nav>
标签定义导航栏。navbar
和navbar-expand
类指定导航栏的样式。navbar-dark bg-dark
类指
div id:
id="layoutSidenav_nav"
:定义一个具有唯一标识符的<div>
元素,这个标识符可以在其他页面中使用,通常用来定义导航栏、侧边栏等。th:fragment="common-sidenav"
:指定了一个名为common-sidenav
的片段,在其他页面中可以通过这个名字引用这个片段。<nav>
:定义导航栏。class="sb-sidenav accordion sb-sidenav-light" id="sidenavAccordion"
:添加了一些样式和一个唯一标识符,使导航栏具有折叠功能。<div class="sb-sidenav-menu">
:定义导航栏的主体部分。<div class="nav">
:定义导航栏的链接部分,即导航栏的具体内容。<!--管理区域-->
:注释,用于提高代码的可读性,这里注释了这个区域是用于管理。<div class="sb-sidenav-menu-heading">管理</div>
:定义一个标题,表示这里是管理区域。<a class="nav-link" th:href="@{/user/toUserInfo}">
:定义一个链接
<!--页脚-->:
这段代码是一个网页的页脚部分,包含一个底部区域,用于显示版权信息等。
<footer>
标签定义了一个页面的底部区域。class="py-4 bg-light mt-auto"
是 Bootstrap 的类,用于设置样式。th:fragment="common-footer"
是 Thymeleaf 的语法,用于定义一个页面片段。<div class="container-fluid px-4">
定义一个包含内容的容器。<div class="d-flex align-items-center justify-content-between small">
定义一个具有弹性的 div 元素,它包含内容并使用 justify-content 和 align-items 属性将其垂直和水平居中对齐。<div class="text-muted">
定义一个文本元素,用于显示版权信息等。©
是 HTML 实体字符,表示版权符号。chenfuhai 2023
是网站的版权信息。
<div th:fragment="common-scripts">:
这段代码是一个Thymeleaf的片段,用于在HTML页面中引入需要的JavaScript文件。具体的解释如下:
-
<div th:fragment="common-scripts">
: 这个div定义了一个Thymeleaf片段,名称为"common-scripts"。 -
src="https://cdn.jsdelivr.net/npm/bootstrap@5.0.2/dist/js/bootstrap.bundle.min.js" crossorigin="anonymous"
:从jsdelivr CDN引入Bootstrap框架的JS文件,crossorigin属性设置为"anonymous"表示跨域请求时不会发送cookie等敏感信息。 -
<script src="/static/js/scripts.js" th:src="@{/js/scripts.js}"></script>
:引入自定义的JS文件,th:src属性中的@{/js/scripts.js}表示使用Thymeleaf的URL表达式引用该文件,即在使用Thymeleaf模板时会自动替换为正确的URL路径。 -
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.8.0/Chart.min.js" crossorigin="anonymous"></script>
:引入Chart.js库的JS文件,同样设置crossorigin属性为"anonymous"。 -
<script src="/static/assets/demo/chart-area-demo.js" th:src="@{/assets/demo/chart-area-demo.js}"></script>
:引入自定义的图表JS文件,同样使用Thymeleaf URL表达式引用。 -
<script src="/static/assets/demo/chart-bar-demo.js" th:src="@{/assets/demo/chart-bar-demo.js}"></script>
:引入另一个自定义的图表JS文件,同样使用Thymeleaf URL表达式引用。 -
<script src="https://cdn.jsdelivr.net/npm/simple-datatables@latest" crossorigin="anonymous"></script>
:引入简单数据表格插件的JS文件,同样设置crossorigin属性为"anonymous"。 -
<script src="/static/js/datatables-simple-demo.js" th:src="@{/js/datatables-simple-demo.js}"></script>
:引入自定义的使用简单数据表格插件的JS文件,同样使用Thymeleaf URL表达式引用。
这段代码的作用是引入需要的JavaScript文件,以支持页面的各种交互和功能。
userInformation.html
<!DOCTYPE html>
<html lang="zh-CN" xmlns:th="http://www.thymeleaf.org">
<head th:replace="userCommon::common-header"></head>
<body class="sb-nav-fixed">
<nav th:replace="userCommon::common-navbar"></nav>
<div id="layoutSidenav"> <!-- 创建一个 ID 为 layoutSidenav 的 div 元素,用于页面布局 -->
<div th:replace="userCommon::common-sidenav"></div> <!-- 引用 common-sidenav 模板 -->
<div id="layoutSidenav_content"> <!-- 创建一个 ID 为 layoutSidenav_content 的 div 元素,用于页面布局 -->
<main> <!-- 主要内容部分,通常用于显示页面的主体信息 -->
<div class="container-fluid px-4"> <!-- 创建一个 container-fluid 类型的 div 元素,用于创建一个静态容器 -->
<h1 class="mt-4">个人信息</h1> <!-- 标题,用于页面内容的头部展示 -->
<ol class="breadcrumb mb-4"> <!-- 创建一个包含导航栏的 ol 元素,用于用户快速定位页面所在位置 -->
<li class="breadcrumb-item"><a th:href="@{/toUserMain}">主页</a></li> <!-- 第一个导航栏的内容 -->
<li class="breadcrumb-item active">个人信息</li> <!-- 第二个导航栏的内容,active 标识当前页 -->
</ol>
<div class="card mb-4"> <!-- 创建一个 card 类型的 div 元素,用于包含个人信息表格 -->
<table class="table table-hover"> <!-- 创建一个表格用于展示用户信息 -->
<tr> <!-- 第一行,展示会员账号/卡号 -->
<td text-align="center">会员账号/卡号:</td>
<td th:text="${member.memberAccount}"></td> <!-- 获取数据库中的会员账号/卡号数据并展示 -->
</tr>
<tr> <!-- 第二行,展示姓名 -->
<td text-align="center">姓名:</td>
<td th:text="${member.memberName}"></td> <!-- 获取数据库中的姓名数据并展示 -->
</tr>
<tr> <!-- 第三行,展示性别 -->
<td text-align="center">性别:</td>
<td th:text="${member.memberGender}"></td> <!-- 获取数据库中的性别数据并展示 -->
</tr>
<tr> <!-- 第四行,展示年龄 -->
<td text-align="center">年龄:</td>
<td th:text="${member.memberAge}"></td> <!-- 获取数据库中的年龄数据并展示 -->
</tr>
<tr> <!-- 第五行,展示联系方式 -->
<td text-align="center">联系方式:</td>
<td th:text="${member.memberPhone}"></td> <!-- 获取数据库中的联系方式数据并展示 -->
</tr>
<tr> <!-- 第六行,展示身高 -->
<td text-align="center">身高:</td>
<td th:text="${member.memberHeight}"></td> <!-- 获取数据库中的身高数据并展示 -->
</tr>
<tr> <!-- 第七行,展示体重 -->
<td text-align="center">体重:</td>
<td th:text="${member.memberWeight}"></td> <!-- 获取数据库中的体重数据并展示 -->
</tr>
<tr>
<td text-align="center">办卡时间:</td>
<td th:text="${member.cardTime}"></td>
</tr>
<tr>
<td text-align="center">剩余课时:</td>
<td th:text="${member.cardNextClass}"></td>
</tr>
</table>
<div style="text-align:center;margin-bottom:15px"> <!-- 编辑按钮的容器 -->
<a th:href="@{/user/toUpdateInfo}"> <!-- 编辑按钮链接 -->
<input type="button" class="btn btn-outline-primary" value="编辑个人信息">
</a>
</div>
</div>
</div>
</main>
<footer th:replace="userCommon::common-footer"></footer> <!-- 引用名为common-footer的模板片段 -->
</div>
</div>
<div th:include="userCommon::common-scripts"></div>
</body>
</html>
userLogin.html
<!DOCTYPE html>
<html lang="zh-CN" xmlns:th="http://www.thymeleaf.org">
<head>
<!-- 定义文档字符编码为UTF-8 -->
<meta charset="UTF-8"/>
<!-- 指定页面应该采用的浏览器版本 -->
<meta http-equiv="X-UA-Compatible" content="IE=edge"/>
<!-- 告诉浏览器页面应该自动缩放到合适的大小 -->
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no"/>
<!-- 页面的描述信息 -->
<meta name="description" content="gym-management-system"/>
<!-- 页面的作者信息 -->
<meta name="author" content="ZhangMing"/>
<!-- 页面标题 -->
<title>健身房管理系统-会员登录</title>
<!-- 引用外部样式表文件 -->
<link href="/static/css/styles.css" th:href="@{css/styles.css}" rel="stylesheet"/>
<!-- 引用外部脚本文件 -->
<script src="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.15.3/js/all.min.js" crossorigin="anonymous"></script>
<!-- 定义一个 JavaScript 函数,用于检查表单提交前的数据是否合法 -->
<script type="text/javascript">
function checkSubmit(loginForm) {
if (loginForm.memberAccount.value == '') {
alert("请输入账号");
loginForm.memberAccount.focus();
return false;
}
if (loginForm.memberPassword.value == '') {
alert("请输入密码");
loginForm.memberPassword.focus();
return false;
}
return true;
}
</script>
</head>
<body class="bg-primary" th:style="'background-image: url(/img/background.jpeg);background-size: 100%, 100%'">
<!-- 设置背景颜色为primary,背景图片为background.jpeg,并且全屏显示 -->
<div id="layoutAuthentication">
<div id="layoutAuthentication_content">
<main>
<div class="container">
<div class="row justify-content-center">
<div class="col-lg-5">
<div class="card shadow-lg border-0 rounded-lg mt-5">
<div class="card-header"><h3 class="text-center font-weight-light my-4">会员登录</h3></div>
<div class="card-body">
<form th:action="@{/userLogin}" method="post" name="loginForm"
onsubmit="return checkSubmit(this)">
<!-- 用户名输入框 -->
<div class="form-floating mb-3">
<input class="form-control" id="inputAccount" name="memberAccount" type="account"
placeholder="Account"
onkeypress="return event.keyCode>=48&&event.keyCode<=57"/>
<label for="inputAccount">账号</label>
</div>
<!-- 密码输入框 -->
<div class="form-floating mb-3">
<input class="form-control" id="inputPassword" name="memberPassword"
type="password"
placeholder="Password"/>
<label for="inputPassword">密码</label>
</div>
<!-- 记住密码复选框 -->
<div class="form-check mb-3">
<input class="form-check-input" id="inputRememberPassword" type="checkbox"
value=""/>
<label class="form-check-label" for="inputRememberPassword">记住密码</label>
</div>
<!-- 登录和转到管理员登录按钮 -->
<div class="d-flex align-items-center justify-content-between mt-4 mb-0">
<input type="submit" class="btn btn-success" value="登录">
<a class="btn btn-primary" th:href="@{/}">转到管理员登录</a>
</div>
</form>
<!-- 错误信息 -->
<div th:text="${msg}" style="margin-top: 20px;text-align: center;color: red"></div>
</div>
</div>
</div>
</div>
</div>
</main>
</div>
</div>
<!-- 引入Bootstrap的js文件和自定义的js文件 -->
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.0.2/dist/js/bootstrap.bundle.min.js"
crossorigin="anonymous"></script>
<script src="/static/js/scripts.js" th:src="@{js/scripts.js}"></script>
</body>
</html>
1. <script type="text/javascript">
function checkSubmit(loginForm) {
if (loginForm.memberAccount.value == '') {
alert("请输入账号");
loginForm.memberAccount.focus();
return false;
}
if (loginForm.memberPassword.value == '') {
alert("请输入密码");
loginForm.memberPassword.focus();
return false;
}
return true;
}
</script>
这是一个 JavaScript 脚本,包含了一个名为 checkSubmit 的函数。该函数的作用是在用户提交登录表单前,检查表单中的账号和密码是否都已填写。如果账号或密码未填写,则会弹出提示框,提示用户输入对应的信息,并使相应的输入框获得焦点。如果账号和密码都已填写,则函数返回 true,允许表单提交;否则返回 false,阻止表单提交。这种检查用户输入的方式可以提高用户体验,避免因为错误的输入而导致登录失败或其他问题。
2. <form th:action="@{/userLogin}" method="post" name="loginForm"
onsubmit="return checkSubmit(this)">
这是一个用于用户登录的表单,其中包含以下属性:
th:action="@{/userLogin}":指定表单的提交地址为/userLogin,即登录页面的后端处理地址。
method="post":指定表单的提交方式为POST。
name="loginForm":为表单指定一个名称loginForm。
οnsubmit="return checkSubmit(this)":当用户在提交表单时会触发该函数,函数会检查账号和密码是否为空,如果为空则弹出提示框提示用户输入,并将光标聚焦到相应的输入框中。
该表单用于收集用户登录所需的信息,包括用户名和密码,并将其发送到后端进行验证。
3. <div class="form-floating mb-3">
<input class="form-control" id="inputAccount" name="memberAccount" type="account"
placeholder="Account"
onkeypress="return event.keyCode>=48&&event.keyCode<=57"/>
<label for="inputAccount">账号</label>
</div>
这段代码是一个表单输入框,使用Bootstrap框架的form-floating类,表示该输入框浮动于上方的标签,方便用户输入。输入框的id为"inputAccount",表单提交时对应的参数名为"memberAccount"。输入框类型为account,使用了一个onkeypress事件,限制输入的字符为数字。占位符为"Account",在输入框中未输入内容时会显示该占位符,提示用户需要输入的内容。
4. <!-- 记住密码复选框 -->
<div class="form-check mb-3">
<input class="form-check-input" id="inputRememberPassword" type="checkbox"
value=""/>
<label class="form-check-label" for="inputRememberPassword">记住密码</label>
</div>
这是一个HTML代码片段,表示一个记住密码的复选框。当用户选中这个复选框时,浏览器会在用户下一次登录时记住密码,自动填入账号和密码。用户可以通过取消勾选复选框来取消记住密码。
5. <div class="d-flex align-items-center justify-content-between mt-4 mb-0">
<input type="submit" class="btn btn-success" value="登录">
<a class="btn btn-primary" th:href="@{/}">转到管理员登录</a>
</div>
这段代码是一个登录表单,包含一个账号输入框、一个密码输入框和一个登录按钮,以及一个转到管理员登录页面的按钮。当用户点击登录按钮时,会提交表单到服务器进行登录验证。如果账号和密码验证通过,则会登录到用户主页,否则会弹出相应的提示信息。如果用户勾选了记住密码复选框,则浏览器会记住用户的登录信息,下次访问时不需要重新输入账号和密码。
6. <!-- 错误信息 -->
<div th:text="${msg}" style="margin-top: 20px;text-align: center;color: red"></div>
该代码段包含一个HTML <div>元素,用于显示错误信息。该元素使用了Thymeleaf模板引擎的语法,其中th:text属性将会动态绑定一个名为msg的模型属性的值,该属性存储着错误信息的文本内容。此外,该元素还包含了一些CSS样式,用于控制错误信息的显示效果。具体来说,它将显示在顶部,有20px的上边距,水平居中对齐,文本颜色为红色。
7. <!-- 引入Bootstrap的js文件和自定义的js文件 -->
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.0.2/dist/js/bootstrap.bundle.min.js"
crossorigin="anonymous"></script>
<script src="/static/js/scripts.js" th:src="@{js/scripts.js}"></script>
这段代码是用来引入Bootstrap框架的JS文件和自定义的JS文件的。Bootstrap是一个流行的前端框架,包括HTML、CSS和JS,用于创建响应式、移动设备友好的网站。在这段代码中,通过CDN引入Bootstrap的js文件,并且通过thymeleaf的语法引用自定义的js文件。自定义的js文件通常用于实现特定的功能或交互效果。
userMain.html
<!DOCTYPE html> <!-- 声明文档类型为 HTML5 -->
<html lang="zh-CN" xmlns:th="http://www.thymeleaf.org"> <!-- 标记文档语言为中文,并引用 Thymeleaf 命名空间 -->
<head th:replace="userCommon::common-header"></head> <!-- 插入公共头部信息 -->
<body class="sb-nav-fixed"> <!-- 设定导航栏固定 -->
<nav th:replace="userCommon::common-navbar"></nav> <!-- 插入公共导航栏 -->
<div id="layoutSidenav"> <!-- 开始布局 -->
<div th:replace="userCommon::common-sidenav"></div> <!-- 插入公共侧边栏 -->
<div id="layoutSidenav_content">
<main>
<div class="container-fluid px-4">
<h1 class="mt-4" th:text="${member.memberName} + '的主页'"></h1> <!-- 以 member.memberName 的值为标题 -->
<ol class="breadcrumb mb-4">
<li class="breadcrumb-item active">主页</li> <!-- 显示当前为主页 -->
</ol>
</div>
</main>
<footer th:replace="userCommon::common-footer"></footer> <!-- 插入公共页脚 -->
</div>
</div>
<div th:include="userCommon::common-scripts"></div> <!-- 引用公共 JavaScript 文件 -->
</body>
</html>
二.后端代码
Admin.java
package com.milotnt.pojo;
/**
* 管理员实体类
*/
public class Admin {
// 管理员账号,使用Integer类型
private Integer adminAccount;
// 管理员密码,使用String类型
private String adminPassword;
// get方法:获取管理员账号
public Integer getAdminAccount() {
return adminAccount;
}
// set方法:设置管理员账号
public void setAdminAccount(Integer adminAccount) {
this.adminAccount = adminAccount;
}
// get方法:获取管理员密码
public String getAdminPassword() {
return adminPassword;
}
// set方法:设置管理员密码
public void setAdminPassword(String adminPassword) {
this.adminPassword = adminPassword;
}
// 重写toString方法:输出管理员账号和密码
@Override
public String toString() {
return "Admin{" +
"adminAccount=" + adminAccount +
", adminPassword='" + adminPassword + '\'' +
'}';
}
}
这是一个Java类文件,包名为"com.milotnt.pojo"。
该类为"Admin"实体类,有两个属性,分别为"adminAccount"和"adminPassword",对应管理员的账号和密码。提供了对这两个属性的getter和setter方法。
同时还重写了toString方法,用于输出该实体类的对象内容。
这是一个名为Admin
的Java类,用于表示管理员对象。下面是该类的属性和方法:
adminAccount
,Integer类型,表示管理员账号;adminPassword
,String类型,表示管理员密码;getAdminAccount()
方法,返回adminAccount
属性的值;setAdminAccount(Integer adminAccount)
方法,将参数adminAccount
的值设置给adminAccount
属性;getAdminPassword()
方法,返回adminPassword
属性的值;setAdminPassword(String adminPassword)
方法,将参数adminPassword
的值设置给adminPassword
属性;toString()
方法,用于返回包含adminAccount
和adminPassword
属性的字符串表示形式。
ClassOrder.java
package com.milotnt.pojo;
/**
* ClassOrder 类是一个 POJO(Plain Old Java Object),用于表示一个课程预约订单。
* POJO 是一种简单的 Java 对象,通常用于表示业务实体,不包含业务逻辑。此类用于存储课程预约订单的相关信息。
*
* ClassOrder 类有 7 个成员变量,分别表示课程预约订单的 ID,课程 ID,课程名称,教练,会员姓名,会员账号和上课时间。
* 其中前 6 个成员变量的类型分别为 Integer 或 String,classBegin 的类型为 String,用于存储时间字符串。
* 此外,该类还包含默认构造方法和带参构造方法,以及相应的 getter 和 setter 方法。
*/
public class ClassOrder {
// 课程订单编号
private Integer classOrderId;
// 课程编号
private Integer classId;
// 课程名
private String className;
// 教练名
private String coach;
// 会员名
private String memberName;
// 会员账号
private Integer memberAccount;
// 上课时间
private String classBegin;
// 无参构造方法
public ClassOrder() {
}
/**
* 带参构造方法,用于创建一个包含课程预约订单信息的 ClassOrder 对象。
* @param classId 课程 ID
* @param className 课程名称
* @param coach 教练
* @param memberName 会员姓名
* @param memberAccount 会员账号
* @param classBegin 上课时间
*/
// 有参构造方法
public ClassOrder(Integer classId, String className, String coach, String memberName, Integer memberAccount, String classBegin) {
this.classId = classId;
this.className = className;
this.coach = coach;
this.memberName = memberName;
this.memberAccount = memberAccount;
this.classBegin = classBegin;
}
// getter和setter方法
public Integer getClassOrderId() {
return classOrderId;
}
public void setClassOrderId(Integer classOrderId) {
this.classOrderId = classOrderId;
}
public Integer getClassId() {
return classId;
}
public void setClassId(Integer classId) {
this.classId = classId;
}
public String getClassName() {
return className;
}
public void setClassName(String className) {
this.className = className;
}
public String getCoach() {
return coach;
}
public void setCoach(String coach) {
this.coach = coach;
}
public String getMemberName() {
return memberName;
}
public void setMemberName(String memberName) {
this.memberName = memberName;
}
public Integer getMemberAccount() {
return memberAccount;
}
public void setMemberAccount(Integer memberAccount) {
this.memberAccount = memberAccount;
}
public String getClassBegin() {
return classBegin;
}
public void setClassBegin(String classBegin) {
this.classBegin = classBegin;
}
// 重写toString方法
@Override
public String toString() {
return "ClassOrder{" +
"classOrderId=" + classOrderId +
", classId=" + classId +
", className='" + className + '\'' +
", coach='" + coach + '\'' +
", memberName='" + memberName + '\'' +
", memberAccount=" + memberAccount +
", classBegin='" + classBegin + '\'' +
'}';
}
}
以上是对课程订单类的详细注释,包括每个属性的含义,构造方法、getter和setter方法的作用,以及重写的toString方法的实现。
ClassTable.java
package com.milotnt.pojo;
/**
* 表示课程表的类
*/
public class ClassTable {
// 课程id
private Integer classId;
// 课程名称
private String className;
// 课程开始时间
private String classBegin;
// 课程持续时间
private String classTime;
// 教练名称
private String coach;
/**
* 获取课程id
* @return 课程id
*/
public Integer getClassId() {
return classId;
}
/**
* 设置课程id
* @param classId 课程id
*/
public void setClassId(Integer classId) {
this.classId = classId;
}
/**
* 获取课程名称
* @return 课程名称
*/
public String getClassName() {
return className;
}
/**
* 设置课程名称
* @param className 课程名称
*/
public void setClassName(String className) {
this.className = className;
}
/**
* 获取课程开始时间
* @return 课程开始时间
*/
public String getClassBegin() {
return classBegin;
}
/**
* 设置课程开始时间
* @param classBegin 课程开始时间
*/
public void setClassBegin(String classBegin) {
this.classBegin = classBegin;
}
/**
* 获取课程持续时间
* @return 课程持续时间
*/
public String getClassTime() {
return classTime;
}
/**
* 设置课程持续时间
* @param classTime 课程持续时间
*/
public void setClassTime(String classTime) {
this.classTime = classTime;
}
/**
* 获取教练名称
* @return 教练名称
*/
public String getCoach() {
return coach;
}
/**
* 设置教练名称
* @param coach 教练名称
*/
public void setCoach(String coach) {
this.coach = coach;
}
/**
* 重写toString方法,返回类的信息
* @return 类的信息
*/
@Override
public String toString() {
return "ClassTable{" +
"classId=" + classId +
", className='" + className + '\'' +
", classBegin='" + classBegin + '\'' +
", classTime='" + classTime + '\'' +
", coach='" + coach + '\'' +
'}';
}
}
这是一个表示课程表的Java类,其中包含了课程id、课程名称、课程开始时间、课程持续时间和教练名称等属性。此外,这个类还包含了一些方法,如获取和设置属性的方法,以及重写的toString方法来返回这个类的信息。
Employee.java
package com.milotnt.pojo;
/**
* 员工实体类
*/
public class Employee {
//员工账号
private Integer employeeAccount;
//员工姓名
private String employeeName;
//员工性别
private String employeeGender;
//员工年龄
private Integer employeeAge;
//员工入职时间
private String entryTime;
//员工职位
private String staff;
//员工信息
private String employeeMessage;
//空构造方法
public Employee() {
}
/**
* 带参数构造方法
* @param employeeAccount 员工账号
* @param employeeName 员工姓名
* @param employeeGender 员工性别
* @param employeeAge 员工年龄
* @param entryTime 员工入职时间
* @param staff 员工职位
* @param employeeMessage 员工信息
*/
public Employee(Integer employeeAccount, String employeeName, String employeeGender, Integer employeeAge, String entryTime, String staff, String employeeMessage) {
//为对象的各个属性赋值
this.employeeAccount = employeeAccount;
this.employeeName = employeeName;
this.employeeGender = employeeGender;
this.employeeAge = employeeAge;
this.entryTime = entryTime;
this.staff = staff;
this.employeeMessage = employeeMessage;
}
//以下为Getter和Setter方法
public Integer getEmployeeAccount() {
return employeeAccount;
}
public void setEmployeeAccount(Integer employeeAccount) {
this.employeeAccount = employeeAccount;
}
public String getEmployeeName() {
return employeeName;
}
public void setEmployeeName(String employeeName) {
this.employeeName = employeeName;
}
public String getEmployeeGender() {
return employeeGender;
}
public void setEmployeeGender(String employeeGender) {
this.employeeGender = employeeGender;
}
public Integer getEmployeeAge() {
return employeeAge;
}
public void setEmployeeAge(Integer employeeAge) {
this.employeeAge = employeeAge;
}
public String getEntryTime() {
return entryTime;
}
public void setEntryTime(String entryTime) {
this.entryTime = entryTime;
}
public String getStaff() {
return staff;
}
public void setStaff(String staff) {
this.staff = staff;
}
public String getEmployeeMessage() {
return employeeMessage;
}
public void setEmployeeMessage(String employeeMessage) {
this.employeeMessage = employeeMessage;
}
/**
* 重写toString方法,用于输出员工对象的字符串表示形式
*/
@Override
public String toString() {
return "Employee{" +
"employeeAccount=" + employeeAccount +
", employeeName='" + employeeName + '\'' +
", employeeGender='" + employeeGender + '\'' +
", employeeAge=" + employeeAge +
", entryTime='" + entryTime + '\'' +
", staff='" + staff + '\'' +
", employeeMessage='" + employeeMessage + '\'' +
'}';
}
}
Equipment.java.java
package com.milotnt.pojo;
/**
* 设备实体类
*/
public class Equipment {
//设备ID
private Integer equipmentId;
//设备名称
private String equipmentName;
//设备位置
private String equipmentLocation;
//设备状态
private String equipmentStatus;
//设备信息
private String equipmentMessage;
//空构造方法
public Equipment() {
}
/**
* 带参数构造方法
* @param equipmentId 设备ID
* @param equipmentName 设备名称
* @param equipmentLocation 设备位置
* @param equipmentStatus 设备状态
* @param equipmentMessage 设备信息
*/
public Equipment(Integer equipmentId, String equipmentName, String equipmentLocation, String equipmentStatus, String equipmentMessage) {
this.equipmentId = equipmentId;
this.equipmentName = equipmentName;
this.equipmentLocation = equipmentLocation;
this.equipmentStatus = equipmentStatus;
this.equipmentMessage = equipmentMessage;
}
//以下为Getter和Setter方法
public Integer getEquipmentId() {
return equipmentId;
}
public void setEquipmentId(Integer equipmentId) {
this.equipmentId = equipmentId;
}
public String getEquipmentName() {
return equipmentName;
}
public void setEquipmentName(String equipmentName) {
this.equipmentName = equipmentName;
}
public String getEquipmentLocation() {
return equipmentLocation;
}
public void setEquipmentLocation(String equipmentLocation) {
this.equipmentLocation = equipmentLocation;
}
public String getEquipmentStatus() {
return equipmentStatus;
}
public void setEquipmentStatus(String equipmentStatus) {
this.equipmentStatus = equipmentStatus;
}
public String getEquipmentMessage() {
return equipmentMessage;
}
public void setEquipmentMessage(String equipmentMessage) {
this.equipmentMessage = equipmentMessage;
}
/**
* 重写toString方法
*/
@Override
public String toString() {
return "Equipment{" +
"equipmentId=" + equipmentId +
", equipmentName='" + equipmentName + '\'' +
", equipmentLocation='" + equipmentLocation + '\'' +
", equipmentStatus='" + equipmentStatus + '\'' +
", equipmentMessage='" + equipmentMessage + '\'' +
'}';
}
}
注释涵盖了类的定义、字段的说明、构造方法、Getter和Setter方法以及重写的toString方法
Member.java
package com.milotnt.pojo;
/**
* 会员类
* 包含会员信息
*
* @author ZhangMing [1157038410@qq.com]
* @date 2021/8/10
*/
public class Member {
private Integer memberAccount; //会员账号
private String memberPassword; //会员密码
private String memberName; //会员姓名
private String memberGender; //会员性别
private Integer memberAge; //会员年龄
private Integer memberHeight; //会员身高
private Integer memberWeight; //会员体重
private Long memberPhone; //会员电话
private String cardTime; //会员办卡时间
private Integer cardClass; //会员卡种类
private Integer cardNextClass; //会员下一次预约的课程种类
public Integer getMemberAccount() {
return memberAccount;
}
public void setMemberAccount(Integer memberAccount) {
this.memberAccount = memberAccount;
}
public String getMemberPassword() {
return memberPassword;
}
public void setMemberPassword(String memberPassword) {
this.memberPassword = memberPassword;
}
public String getMemberName() {
return memberName;
}
public void setMemberName(String memberName) {
this.memberName = memberName;
}
public String getMemberGender() {
return memberGender;
}
public void setMemberGender(String memberGender) {
this.memberGender = memberGender;
}
public Integer getMemberAge() {
return memberAge;
}
public void setMemberAge(Integer memberAge) {
this.memberAge = memberAge;
}
public Integer getMemberHeight() {
return memberHeight;
}
public void setMemberHeight(Integer memberHeight) {
this.memberHeight = memberHeight;
}
public Integer getMemberWeight() {
return memberWeight;
}
public void setMemberWeight(Integer memberWeight) {
this.memberWeight = memberWeight;
}
public Long getMemberPhone() {
return memberPhone;
}
public void setMemberPhone(Long memberPhone) {
this.memberPhone = memberPhone;
}
public String getCardTime() {
return cardTime;
}
public void setCardTime(String cardTime) {
this.cardTime = cardTime;
}
public Integer getCardClass() {
return cardClass;
}
public void setCardClass(Integer cardClass) {
this.cardClass = cardClass;
}
public Integer getCardNextClass() {
return cardNextClass;
}
public void setCardNextClass(Integer cardNextClass) {
this.cardNextClass = cardNextClass;
}
@Override
public String toString() {
return "Member{" +
", memberAccount=" + memberAccount +
", memberPassword='" + memberPassword + '\'' +
", memberName='" + memberName + '\'' +
", memberGender='" + memberGender + '\'' +
", memberAge=" + memberAge +
", memberHeight=" + memberHeight +
", memberWeight=" + memberWeight +
", memberPhone=" + memberPhone +
", cardTime='" + cardTime + '\'' +
", cardClass=" + cardClass +
", cardNextClass=" + cardNextClass +
'}';
}
}
GymManagementSystemApplication.java
//这是一个Spring Boot的启动类,用于启动整个项目,以下是每行代码的作用解释:
package com.milotnt;
//声明包名,该类所属的包名为com.milotnt。
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
//导入Spring Boot相关的类。
//@SpringBootApplication是一个组合注解,包含了@Configuration、@EnableAutoConfiguration
//和@ComponentScan三个注解。
//@Configuration和@ComponentScan这两个注解不需要我们自己添加,Spring Boot会自动为我们添
//加。
//@EnableAutoConfiguration是自动配置注解,用于自动配置Spring Boot项目所需的配置信息。
@SpringBootApplication
public class GymManagementSystemApplication {
//声明一个公共类GymManagementSystemApplication,用于Spring Boot应用的启动。
public static void main(String[] args) {
SpringApplication.run(GymManagementSystemApplication.class, args);
}
}
//该类的主方法,用于启动整个Spring Boot应用。SpringApplication.run()方法会自动启动整个Spring //Boot应用,并加载自动配置信息和应用配置信息。args是传入的启动参数。
这段代码是一个 Spring Boot 应用程序的主入口,它包含了一个 main 方法。该应用程序使用了 Spring Boot 框架,通过 @SpringBootApplication 注解来启用 Spring Boot 自动配置功能,包括自动配置应用程序所需的各种组件,如数据源、事务管理、Web MVC 等等。该注解是一个复合注解,包含了 @Configuration、@EnableAutoConfiguration 和 @ComponentScan 这三个注解。
在 main 方法中,使用 SpringApplication 类的 run 方法启动 Spring Boot 应用程序,它会自动执行 Spring Boot 的自动配置,并根据需要创建所需的 Bean。如果在启动时需要传递命令行参数,可以将这些参数传递给 run 方法的 args 参数。
该应用程序的主要作用是管理健身房系统,因此可以在该应用程序中添加管理健身房系统所需的各种业务逻辑和功能。
三.接口
AdminMapper.java
package com.milotnt.mapper;
import com.milotnt.pojo.Admin;
import org.apache.ibatis.annotations.Mapper;
@Mapper
public interface AdminMapper {
Admin selectByAccountAndPassword(Admin admin);
}
这段代码定义了一个AdminMapper
接口,它使用MyBatis框架来与数据库进行交互。以下是每行代码的作用:
package com.milotnt.mapper;
: 定义了该接口所在的包名。import com.milotnt.pojo.Admin;
: 导入了Admin
类,这个类是管理员实体类。import org.apache.ibatis.annotations.Mapper;
: 导入了MyBatis的@Mapper
注解,该注解将会告诉Spring Boot这是一个MyBatis的Mapper接口,需要在启动时生成相应的实现类。@Mapper
: 这是一个注解,用于告诉Spring Boot将该接口注册为MyBatis的Mapper接口。public interface AdminMapper {
: 定义了AdminMapper
接口。Admin selectByAccountAndPassword(Admin admin);
: 定义了一个抽象方法,用于查询符合给定账户和密码的管理员。
ClassOrderMapper.java
package com.milotnt.mapper;
import com.milotnt.pojo.ClassOrder;
import org.apache.ibatis.annotations.*;
import java.util.List;
@Mapper
public interface ClassOrderMapper {
//查询所有报名表信息
List<ClassOrder> findAll();
//添加报名信息
Boolean insertClassOrder(ClassOrder classOrder);
//根据会员账号查询个人报名课表
List<ClassOrder> selectClassOrderByMemberAccount(Integer memberAccount);
//删除已预约的课程
Boolean deleteByClassOrderId(Integer classOrderId);
//查询会员是否报名该课程
ClassOrder selectMemberByClassIdAndMemberAccount(Integer classId, Integer memberAccount);
//根据课程id查询所有报名的会员
List<ClassOrder> selectMemberOrderList(Integer classId);
}
这是一个名为 ClassOrderMapper
的 Java 接口,其主要功能是定义数据库操作相关的方法。
@Mapper
注解表示这是一个 MyBatis Mapper 接口,用于进行数据库操作映射。List<ClassOrder> findAll()
:查询所有报名表信息,返回类型为List<ClassOrder>
。Boolean insertClassOrder(ClassOrder classOrder)
:添加报名信息,参数类型为ClassOrder
,返回值为Boolean
,表示添加是否成功。List<ClassOrder> selectClassOrderByMemberAccount(Integer memberAccount)
:根据会员账号查询个人报名课表,参数类型为Integer
,返回类型为List<ClassOrder>
。Boolean deleteByClassOrderId(Integer classOrderId)
:删除已预约的课程,参数类型为Integer
,返回值为Boolean
,表示删除是否成功。ClassOrder selectMemberByClassIdAndMemberAccount(Integer classId, Integer memberAccount)
:查询会员是否报名该课程,参数类型为Integer
,返回类型为ClassOrder
。List<ClassOrder> selectMemberOrderList(Integer classId)
:根据课程id查询所有报名的会员,参数类型为Integer
,返回类型为List<ClassOrder>
。
ClassTableMapper.java
package com.milotnt.mapper;
import com.milotnt.pojo.ClassTable;
import org.apache.ibatis.annotations.Mapper;
import java.util.List;
@Mapper
public interface ClassTableMapper {
//查询所有课程
List<ClassTable> findAll();
//根据id删除课程
Boolean deleteClassByClassId(Integer classId);
//添加课程
Boolean insertClass(ClassTable classTable);
//根据id查询课表
ClassTable selectByClassId(Integer classId);
//根据id删除已预约的课程
Boolean deleteOrderByClassId(Integer classId);
}
这是一个名为ClassTableMapper
的Java接口,定义了与课程表相关的数据库操作方法。
@Mapper
注解表示这是一个MyBatis的Mapper接口。List<ClassTable> findAll()
方法:查询所有课程信息,返回一个ClassTable
对象的列表。Boolean deleteClassByClassId(Integer classId)
方法:根据课程id删除课程,返回一个布尔值表示是否删除成功。Boolean insertClass(ClassTable classTable)
方法:添加一门新的课程,返回一个布尔值表示是否添加成功。ClassTable selectByClassId(Integer classId)
方法:根据课程id查询对应的课程信息,返回一个ClassTable
对象。Boolean deleteOrderByClassId(Integer classId)
方法:根据课程id删除已预约该课程的所有会员,返回一个布尔值表示是否删除成功。
EmployeeMapper.java
package com.milotnt.mapper;
import com.milotnt.pojo.Employee;
import org.apache.ibatis.annotations.Mapper;
import java.util.List;
@Mapper
public interface EmployeeMapper {
//查询所有员工
List<Employee> findAll();
//根据员工账号删除员工
Boolean deleteByEmployeeAccount(Integer employeeAccount);
//添加新员工
Boolean insertEmployee(Employee employee);
//根据员工账号修改会员信息
Boolean updateMemberByEmployeeAccount(Employee employee);
//根据员工账号查询员工
List<Employee> selectByEmployeeAccount(Integer employeeAccount);
//查询员工数
Integer selectTotalCount();
}
这是一个员工管理相关的Mapper接口,下面是对每个方法的注释说明:
-
findAll()
: 查询所有员工的信息并返回一个员工列表(List<Employee>)。 -
deleteByEmployeeAccount(Integer employeeAccount)
: 根据员工账号删除一个员工,并返回一个Boolean类型的值表示操作是否成功。 -
insertEmployee(Employee employee)
: 插入一个新的员工记录,并返回一个Boolean类型的值表示操作是否成功。 -
updateMemberByEmployeeAccount(Employee employee)
: 根据员工账号修改员工信息,并返回一个Boolean类型的值表示操作是否成功。 -
selectByEmployeeAccount(Integer employeeAccount)
: 根据员工账号查询一个员工,并返回一个员工列表(List<Employee>)。 -
selectTotalCount()
: 查询员工总数,并返回一个Integer类型的值表示员工总数。
EmployeeMapper.java
package com.milotnt.mapper;
import com.milotnt.pojo.Employee;
import org.apache.ibatis.annotations.Mapper;
import java.util.List;
@Mapper
public interface EmployeeMapper {
//查询所有员工
List<Employee> findAll();
//根据员工账号删除员工
Boolean deleteByEmployeeAccount(Integer employeeAccount);
//添加新员工
Boolean insertEmployee(Employee employee);
//根据员工账号修改会员信息
Boolean updateMemberByEmployeeAccount(Employee employee);
//根据员工账号查询员工
List<Employee> selectByEmployeeAccount(Integer employeeAccount);
//查询员工数
Integer selectTotalCount();
}
这是一个名为EmployeeMapper
的Java接口,它定义了访问员工数据的一组方法。接口中的方法主要用于查询、删除、添加和修改员工的信息。
@Mapper
注解表示这是MyBatis框架中的Mapper接口,用于将SQL语句映射到Java方法中。
接口中的方法包括:
findAll()
:查询所有员工信息;deleteByEmployeeAccount(Integer employeeAccount)
:根据员工账号删除员工;insertEmployee(Employee employee)
:添加新员工;updateMemberByEmployeeAccount(Employee employee)
:根据员工账号修改员工信息;selectByEmployeeAccount(Integer employeeAccount)
:根据员工账号查询员工信息;selectTotalCount()
:查询员工总数。
EmployeeMapper.java
package com.milotnt.mapper;
import com.milotnt.pojo.Member;
import org.apache.ibatis.annotations.*;
import java.util.List;
@Mapper
public interface MemberMapper {
//查询会员信息
List<Member> findAll();
//新增会员信息
Boolean insertMember(Member member);
//根据会员账号修改会员信息
Boolean updateMemberByMemberAccount(Member member);
//查询会员账号密码
Member selectByAccountAndPassword(Member member);
//根据会员账号删除会员信息
Boolean deleteByMemberAccount(Integer memberAccount);
//查询会员数
Integer selectTotalCount();
//根据会员账号查询会员
List<Member> selectByMemberAccount(Integer memberAccount);
}
在这个Mapper中,每个方法都是针对会员信息的操作,包括查询、新增、修改和删除等。其中,还有一些特殊的方法,比如查询会员总数和根据会员账号和密码查询会员信息等。这些方法都是为了满足系统的需求而设计的,能够方便快捷地对会员信息进行操作。
controller
ClassController.java
package com.milotnt.controller;
import com.milotnt.pojo.ClassOrder;
import com.milotnt.pojo.ClassTable;
import com.milotnt.service.ClassOrderService;
import com.milotnt.service.ClassTableService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import java.util.List;
/**
* @author ZhangMing [1157038410@qq.com]
* @date 2021/8/19
*/
@Controller
@RequestMapping("/class")
public class ClassController {
@Autowired
private ClassTableService classTableService;
@Autowired
private ClassOrderService classOrderService;
//查询课程
@RequestMapping("/selClass")
public String selectClass(Model model) {
List<ClassTable> classList = classTableService.findAll();
model.addAttribute("classList", classList);
return "selectClass";
}
//跳转新增课程页面
@RequestMapping("/toAddClass")
public String toAddClass() {
return "addClass";
}
//新增课程
@RequestMapping("/addClass")
public String addClass(ClassTable classTable) {
classTableService.insertClass(classTable);
return "redirect:selClass";
}
//删除课程
@RequestMapping("/delClass")
public String deleteClass(Integer classId) {
classTableService.deleteClassByClassId(classId);
classTableService.deleteOrderByClassId(classId);
return "redirect:selClass";
}
//查询课程报名信息
@RequestMapping("/selClassOrder")
public String selectClassOrder(Integer classId, Model model) {
List<ClassOrder> classOrderList = classOrderService.selectMemberOrderList(classId);
model.addAttribute("classOrderList", classOrderList);
return "selectClassOrder";
}
}
这是一个Java代码文件,其中包含了一个名为ClassController的控制器类。该类使用Spring MVC框架进行开发,通过注解@RequestMapping指定了与课程相关的访问路径。同时,该类使用@Autowired注解来实现自动装配,将两个服务类ClassTableService和ClassOrderService注入到该类中。
该类提供了以下请求处理方法:
-
selectClass: 用于查询所有的课程信息,并通过model传递给selectClass视图页面进行展示。
-
toAddClass: 用于跳转到新增课程页面。
-
addClass: 用于在数据库中插入一条新的课程记录,并重定向到selectClass请求,以展示所有课程信息。
-
deleteClass: 用于删除一条课程记录以及相关联的报名信息,然后重定向到selClass请求,以展示所有课程信息。
-
selectClassOrder: 用于根据课程ID查询课程报名信息,并通过model传递给selectClassOrder视图页面进行展示。
以上的请求处理方法都通过@RequestMapping注解进行路径映射,以接收相应的HTTP请求并处理返回结果。
EmployeeController.java
package com.milotnt.controller;
import com.milotnt.pojo.Employee;
import com.milotnt.service.EmployeeService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;
import java.util.Random;
/**
* @author ZhangMing [1157038410@qq.com]
* @date 2021/8/18
*/
@Controller
@RequestMapping("/employee")
public class EmployeeController {
@Autowired
private EmployeeService employeeService;
//查询员工
@RequestMapping("/selEmployee")
public String selectEmployee(Model model) {
List<Employee> employeeList = employeeService.findAll();
model.addAttribute("employeeList", employeeList);
return "selectEmployee";
}
//跳转新增员工页面
@RequestMapping("/toAddEmployee")
public String toAddEmployee() {
return "addEmployee";
}
//新增员工
@RequestMapping("/addEmployee")
public String addEmployee(Employee employee) {
//工号随机生成
Random random = new Random();
String account1 = "1010";
for (int i = 0; i < 5; i++) {
account1 += random.nextInt(10);
}
Integer account = Integer.parseInt(account1);
//获取当前日期
Date date = new Date();
SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd");
String nowDay = simpleDateFormat.format(date);
employee.setEmployeeAccount(account);
employee.setEntryTime(nowDay);
employeeService.insertEmployee(employee);
return "redirect:selEmployee";
}
//删除员工
@RequestMapping("/delEmployee")
public String deleteEmployee(Integer employeeAccount) {
employeeService.deleteByEmployeeAccount(employeeAccount);
return "redirect:selEmployee";
}
//跳转员工修改页面
@RequestMapping("/toUpdateEmployee")
public String toUpdateEmployee(Integer employeeAccount, Model model) {
List<Employee> employeeList = employeeService.selectByEmployeeAccount(employeeAccount);
model.addAttribute("employeeList", employeeList);
return "updateEmployee";
}
//修改员工信息
@RequestMapping("/updateEmployee")
public String updateEmployee(Employee employee) {
employeeService.updateMemberByEmployeeAccount(employee);
return "redirect:selEmployee";
}
}
这是一个Java代码文件,其中包含了一个名为EmployeeController的控制器类。该类使用Spring MVC框架进行开发,通过注解@RequestMapping指定了与员工信息相关的访问路径。同时,该类使用@Autowired注解来实现自动装配,将一个服务类EmployeeService注入到该类中。
该类提供了以下请求处理方法:
-
selectEmployee: 用于查询所有员工的信息,并通过model传递给selectEmployee视图页面进行展示。
-
toAddEmployee: 用于跳转到新增员工页面。
-
addEmployee: 用于在数据库中插入一条新的员工记录,并重定向到selectEmployee请求,以展示所有员工信息。该方法中还实现了工号随机生成和获取当前日期的功能。
-
deleteEmployee: 用于删除一条员工记录,然后重定向到selEmployee请求,以展示所有员工信息。
-
toUpdateEmployee: 用于跳转到修改员工信息页面,并根据员工工号查询员工信息。查询结果通过model传递给updateEmployee视图页面进行展示。
-
updateEmployee: 用于更新员工信息,并重定向到selEmployee请求,以展示所有员工信息。
以上的请求处理方法都通过@RequestMapping注解进行路径映射,以接收相应的HTTP请求并处理返回结果。
EquipmentController.java
package com.milotnt.controller;
import com.milotnt.pojo.Equipment;
import com.milotnt.service.EquipmentService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import javax.servlet.http.HttpSession;
import java.util.List;
/**
* @author ZhangMing [1157038410@qq.com]
* @date 2021/8/15
*/
@Controller
@RequestMapping("/equipment")
public class EquipmentController {
@Autowired
private EquipmentService equipmentService;
//查询器材
@RequestMapping("/selEquipment")
public String selectEquipment(Model model, HttpSession session) {
List<Equipment> equipmentList = equipmentService.findAll();
session.setAttribute("equipmentList", equipmentList);
model.addAttribute("equipmentList", equipmentList);
return "selectEquipment";
}
//删除器材
@RequestMapping("/delEquipment")
public String deleteEquipment(Integer equipmentId) {
equipmentService.deleteByEquipmentId(equipmentId);
return "redirect:selEquipment";
}
//跳转修改器材页面
@RequestMapping("/toUpdateEquipment")
public String toUpdateEquipment(Integer equipmentId, Model model) {
List<Equipment> equipmentList = equipmentService.selectByEquipmentId(equipmentId);
model.addAttribute("equipmentList", equipmentList);
return "updateEquipment";
}
//修改器材
@RequestMapping("/updateEquipment")
public String updateEquipment(Equipment equipment) {
equipmentService.updateEquipmentByEquipmentId(equipment);
return "redirect:selEquipment";
}
//跳转新增器材页面
@RequestMapping("/toAddEquipment")
public String toAddEquipment() {
return "addEquipment";
}
//新增器材
@RequestMapping("/addEquipment")
public String addEquipment(Equipment equipment) {
equipmentService.insertEquipment(equipment);
return "redirect:selEquipment";
}
}
这是一个Java代码文件,其中包含了一个名为EquipmentController的控制器类。该类使用Spring MVC框架进行开发,通过注解@RequestMapping指定了与器材相关的访问路径。同时,该类使用@Autowired注解来实现自动装配,将一个服务类EquipmentService注入到该类中。
该类提供了以下请求处理方法:
-
selectEquipment: 用于查询所有器材的信息,并通过session和model传递给selectEquipment视图页面进行展示。
-
deleteEquipment: 用于删除一条器材记录,然后重定向到selEquipment请求,以展示所有器材信息。
-
toUpdateEquipment: 用于跳转到修改器材信息页面,并根据器材ID查询器材信息。查询结果通过model传递给updateEquipment视图页面进行展示。
-
updateEquipment: 用于更新器材信息,并重定向到selEquipment请求,以展示所有器材信息。
-
toAddEquipment: 用于跳转到新增器材页面。
-
addEquipment: 用于在数据库中插入一条新的器材记录,并重定向到selEquipment请求,以展示所有器材信息。
以上的请求处理方法都通过@RequestMapping注解进行路径映射,以接收相应的HTTP请求并处理返回结果。其中,为了避免多次查询数据库造成性能损耗,在查询所有器材信息时使用了session缓存器材列表数据,并将其同时传递给view层与model中。
LoginController.java
package com.milotnt.controller;
import com.milotnt.pojo.Admin;
import com.milotnt.pojo.Member;
import com.milotnt.service.AdminService;
import com.milotnt.service.EmployeeService;
import com.milotnt.service.EquipmentService;
import com.milotnt.service.MemberService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import javax.servlet.http.HttpSession;
/**
* @author ZhangMing [1157038410@qq.com]
* @date 2021/8/20
*/
@Controller
public class LoginController {
@Autowired
private MemberService memberService;
@Autowired
private AdminService adminService;
@Autowired
private EmployeeService employeeService;
@Autowired
private EquipmentService equipmentService;
//主页、跳转管理员登录页面
@RequestMapping("/")
public String toAdminLogin() {
return "adminLogin";
}
//跳转会员登录页面
@RequestMapping("/toUserLogin")
public String toUserLogin() {
return "userLogin";
}
//管理员登录
@RequestMapping("/adminLogin")
public String adminLogin(Admin admin, Model model, HttpSession session) {
Admin admin1 = adminService.adminLogin(admin);
if (admin1 != null) {
//会员人数
Integer memberTotal = memberService.selectTotalCount();
model.addAttribute("memberTotal", memberTotal);
session.setAttribute("memberTotal", memberTotal);
//员工人数
Integer employeeTotal = employeeService.selectTotalCount();
model.addAttribute("employeeTotal", employeeTotal);
session.setAttribute("employeeTotal", employeeTotal);
//健身房总人数
Integer humanTotal = memberTotal + employeeTotal;
model.addAttribute("humanTotal", humanTotal);
session.setAttribute("humanTotal", humanTotal);
//器材数
Integer equipmentTotal = equipmentService.selectTotalCount();
model.addAttribute("equipmentTotal", equipmentTotal);
session.setAttribute("equipmentTotal", equipmentTotal);
return "adminMain";
}
model.addAttribute("msg", "您输入的账号或密码有误,请重新输入!");
return "adminLogin";
}
//会员登录
@RequestMapping("/userLogin")
public String userLogin(Member member, Model model, HttpSession session) {
Member member1 = memberService.userLogin(member);
if (member1 != null) {
model.addAttribute("member", member1);
session.setAttribute("user", member1);
return "userMain";
}
model.addAttribute("msg", "您输入的账号或密码有误,请重新输入!");
return "userLogin";
}
//跳转管理员主页
@RequestMapping("/toAdminMain")
public String toAdminMain(Model model, HttpSession session) {
Integer memberTotal = (Integer) session.getAttribute("memberTotal");
Integer employeeTotal = (Integer) session.getAttribute("employeeTotal");
Integer humanTotal = (Integer) session.getAttribute("humanTotal");
Integer equipmentTotal = (Integer) session.getAttribute("equipmentTotal");
model.addAttribute("memberTotal", memberTotal);
model.addAttribute("employeeTotal", employeeTotal);
model.addAttribute("humanTotal", humanTotal);
model.addAttribute("equipmentTotal", equipmentTotal);
return "adminMain";
}
//跳转会员主页
@RequestMapping("/toUserMain")
public String toUserMain(Model model, HttpSession session) {
Member member = (Member) session.getAttribute("user");
model.addAttribute("member", member);
return "userMain";
}
}
这是一个Java代码文件,其中包含了一个名为LoginController的控制器类。该类使用Spring MVC框架进行开发,通过注解@RequestMapping指定了与登录相关的访问路径。同时,该类使用@Autowired注解来实现自动装配,将四个服务类AdminService、MemberService、EmployeeService和EquipmentService注入到该类中。
该类提供了以下请求处理方法:
-
toAdminLogin: 用于跳转到管理员登录页面。
-
toUserLogin: 用于跳转到会员登录页面。
-
adminLogin: 用于管理员身份验证,并在验证通过后跳转到管理员主页。在验证过程中,会统计会员人数、员工人数、健身房总人数和器材数,并分别通过session和model传递给adminMain视图页面进行展示。
-
userLogin: 用于会员身份验证,并在验证通过后跳转到会员主页。
-
toAdminMain: 用于跳转到管理员主页,并将之前统计的会员人数、员工人数、健身房总人数和器材数从session中取出并传递给adminMain视图页面进行展示。
-
toUserMain: 用于跳转到会员主页,并将当前用户信息(即member)通过model传递给userMain视图页面进行展示。
以上的请求处理方法都通过@RequestMapping注解进行路径映射,以接收相应的HTTP请求并处理返回结果。其中,为了在管理员身份验证后统计相关信息并传递给adminMain视图页面,使用了session和model两种方式进行数据传递。同时,在会员登录成功后将用户信息存储在session中,方便后续的使用。
MemberController.java
package com.milotnt.controller;
import com.milotnt.pojo.Member;
import com.milotnt.service.MemberService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;
import java.util.Random;
/**
* @author ZhangMing [1157038410@qq.com]
* @date 2021/8/16
*/
@Controller
@RequestMapping("/member")
public class MemberController {
@Autowired
private MemberService memberService;
//查询会员
@RequestMapping("/selMember")
public String selectMember(Model model) {
List<Member> memberList = memberService.findAll();
model.addAttribute("memberList", memberList);
return "selectMember";
}
//跳转新增会员页面
@RequestMapping("/toAddMember")
public String toAddMember() {
return "addMember";
}
//新增会员
@RequestMapping("/addMember")
public String addMember(Member member) {
//会员账号&卡号随机生成
Random random = new Random();
String account1 = "2021";
for (int i = 0; i < 5; i++) {
account1 += random.nextInt(10);
}
Integer account = Integer.parseInt(account1);
//初始密码
String password = "123456";
//获取当前日期
Date date = new Date();
SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd");
String nowDay = simpleDateFormat.format(date);
Integer nextClass = member.getCardClass();
member.setMemberAccount(account);
member.setMemberPassword(password);
member.setCardTime(nowDay);
member.setCardNextClass(nextClass);
memberService.insertMember(member);
return "redirect:selMember";
}
//删除会员
@RequestMapping("/delMember")
public String deleteMember(Integer memberAccount) {
memberService.deleteByMemberAccount(memberAccount);
return "redirect:selMember";
}
//跳转会员修改页面
@RequestMapping("/toUpdateMember")
public String toUpdateMember(Integer memberAccount, Model model) {
List<Member> memberList = memberService.selectByMemberAccount(memberAccount);
model.addAttribute("memberList", memberList);
return "updateMember";
}
//修改会员信息
@RequestMapping("/updateMember")
public String updateMember(Member member) {
memberService.updateMemberByMemberAccount(member);
return "redirect:selMember";
}
//跳转会员卡查询页面
@RequestMapping("/toSelByCard")
public String toSelectByCardId() {
return "selectByMemberAccount";
}
//根据会员卡号查询
@RequestMapping("/selByCard")
public String selectByCardId(Model model, Integer memberAccount) {
List<Member> memberList = memberService.selectByMemberAccount(memberAccount);
if (memberList != null) {
model.addAttribute("memberList", memberList);
} else {
String message = "会员卡号不存在!";
model.addAttribute("noMessage", message);
}
return "selectByMemberAccount";
}
}
UserController.java
package com.milotnt.controller;
import com.milotnt.pojo.ClassOrder;
import com.milotnt.pojo.ClassTable;
import com.milotnt.pojo.Member;
import com.milotnt.service.ClassOrderService;
import com.milotnt.service.ClassTableService;
import com.milotnt.service.MemberService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import javax.servlet.http.HttpSession;
import java.util.List;
@Controller
@RequestMapping("/user")
public class UserController {
@Autowired
private ClassTableService classTableService;
@Autowired
private MemberService memberService;
@Autowired
private ClassOrderService classOrderService;
//跳转个人信息页面
@RequestMapping("/toUserInfo")
public String toUserInformation(Model model, HttpSession session) {
Member member = (Member) session.getAttribute("user");
model.addAttribute("member", member);
return "userInformation";
}
//跳转修改个人信息页面
@RequestMapping("/toUpdateInfo")
public String toUpdateUserInformation(HttpSession session, Model model) {
Member member = (Member) session.getAttribute("user");
model.addAttribute("member", member);
return "updateUserInformation";
}
//修改个人信息
@RequestMapping("/updateInfo")
public String updateUserInformation(HttpSession session, Member member) {
Member member1 = (Member) session.getAttribute("user");
member.setMemberAccount(member1.getMemberAccount());
member.setCardClass(member1.getCardClass());
member.setCardTime(member1.getCardTime());
member.setCardNextClass(member1.getCardNextClass());
memberService.updateMemberByMemberAccount(member);
return "userInformation";
}
//跳转我的课程页面
@RequestMapping("/toUserClass")
public String toUserClass(Model model, HttpSession session) {
Member member = (Member) session.getAttribute("user");
model.addAttribute("member", member);
Integer memberAccount = member.getMemberAccount();
List<ClassOrder> classOrderList = classOrderService.selectClassOrderByMemberAccount(memberAccount);
model.addAttribute("classOrderList", classOrderList);
return "userClass";
}
//退课
@RequestMapping("delUserClass")
public String deleteUserClass(Integer classOrderId) {
classOrderService.deleteByClassOrderId(classOrderId);
return "redirect:toUserClass";
}
//跳转报名选课页面
@RequestMapping("/toApplyClass")
public String toUserApplyClass(Model model, HttpSession session) {
Member member = (Member) session.getAttribute("user");
List<ClassTable> classList = classTableService.findAll();
model.addAttribute("member", member);
model.addAttribute("classList", classList);
return "userApplyClass";
}
//报名选课
@RequestMapping("/applyClass")
public String userApplyClass(Integer classId, Model model, HttpSession session) {
ClassTable classTable = classTableService.selectByClassId(classId);
Member member = (Member) session.getAttribute("user");
Integer classId1 = classTable.getClassId();
String className = classTable.getClassName();
String coach = classTable.getCoach();
String classBegin = classTable.getClassBegin();
String memberName = member.getMemberName();
Integer memberAccount = member.getMemberAccount();
ClassOrder classOrder = new ClassOrder(classId1, className, coach, memberName, memberAccount, classBegin);
Integer memberAccount1 = member.getMemberAccount();
ClassOrder classOrder1 = classOrderService.selectMemberByClassIdAndMemberAccount(classId1, memberAccount1);
if (classOrder1 == null) {
classOrderService.insertClassOrder(classOrder);
}
return "redirect:toUserClass";
}
}