|
|
/*
|
|
|
filter 包:Java Web 中 Filter 用于过滤请求,处理编码、权限验证、XSS 防护等。比如图中的 AdminFilter、XSSFilter,分别做权限和防攻击。
|
|
|
javabean 包:存放实体类,封装数据,对应数据库表或业务数据。像 Admin、Manager 这些类,用于存储属性,遵循 JavaBean 规范,有 getter/setter 等。
|
|
|
servlet 包:处理客户端请求,接收参数,调用业务逻辑,返回响应。比如 ManagerLogin 处理登录请求,Announcement 相关的处理公告操作。
|
|
|
现在组织这些内容,分三个部分解释每个包的作用,确保清晰准确。
|
|
|
*/
|
|
|
///
|
|
|
// * * * CharacterEncondingFilter.java
|
|
|
/**
|
|
|
* 字符编码过滤器,用于统一设置请求与响应的字符编码为UTF-8,解决文本乱码问题
|
|
|
*/
|
|
|
public class CharacterEncodingFilter implements Filter {
|
|
|
|
|
|
/**
|
|
|
* 过滤器初始化方法,由容器调用,用于获取过滤器配置参数等初始化操作
|
|
|
* @param filterConfig 过滤器配置对象,可从中读取初始化参数
|
|
|
* @throws ServletException 初始化过程中发生异常时抛出
|
|
|
*/
|
|
|
public void init(FilterConfig filterConfig) throws ServletException {
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
* 执行过滤逻辑的核心方法,处理请求响应的编码设置
|
|
|
* @param servletRequest 客户端发送的请求对象
|
|
|
* @param servletResponse 服务器返回的响应对象
|
|
|
* @param filterChain 过滤链,用于将请求响应传递给后续处理组件
|
|
|
* @throws IOException 输入输出操作异常
|
|
|
* @throws ServletException Servlet处理过程异常
|
|
|
*/
|
|
|
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
|
|
|
// 设置请求编码为UTF-8,确保接收参数时字符编码统一
|
|
|
servletRequest.setCharacterEncoding("UTF-8");
|
|
|
// 设置响应编码为UTF-8,确保返回数据的字符编码统一
|
|
|
servletResponse.setCharacterEncoding("UTF-8");
|
|
|
// 将请求和响应传递给过滤链中的下一个组件(如其他过滤器或Servlet)
|
|
|
filterChain.doFilter(servletRequest, servletResponse);
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
* 过滤器销毁方法,由容器调用,用于释放过滤器占用的资源
|
|
|
* 当前过滤器无需要释放的资源,方法体为空
|
|
|
*/
|
|
|
public void destroy() {
|
|
|
}
|
|
|
}
|
|
|
// * * * ManagerFilter.java
|
|
|
package filter;
|
|
|
import java.io.IOException;
|
|
|
import javax.servlet.Filter;
|
|
|
import javax.servlet.FilterChain;
|
|
|
import javax.servlet.FilterConfig;
|
|
|
import javax.servlet.ServletException;
|
|
|
import javax.servlet.ServletRequest;
|
|
|
import javax.servlet.ServletResponse;
|
|
|
import javax.servlet.http.HttpServletRequest;
|
|
|
import javax.servlet.http.HttpServletResponse;
|
|
|
import javax.servlet.http.HttpSession;
|
|
|
// * 图书管理员过滤类,用于拦截请求并校验用户是否为登录状态的图书管理员* 实现Filter接口,完成请求过滤逻辑
|
|
|
public class ManagerFilter implements Filter {
|
|
|
// * 过滤器销毁方法,用于释放资源* 在过滤器生命周期结束时调用,此处暂无资源释放操作
|
|
|
public void destroy() {
|
|
|
}
|
|
|
/**
|
|
|
* 核心过滤方法,处理请求过滤逻辑
|
|
|
* @param request 客户端发送的请求对象
|
|
|
* @param response 服务器返回的响应对象
|
|
|
* @param chain 过滤器链,用于传递请求和响应
|
|
|
* @throws IOException IO异常
|
|
|
* @throws ServletException Servlet处理异常
|
|
|
*/
|
|
|
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
|
|
|
throws IOException, ServletException {
|
|
|
// 将通用请求对象转换为Http请求对象
|
|
|
HttpServletRequest req = (HttpServletRequest) request;
|
|
|
// 获取请求对应的HttpSession
|
|
|
HttpSession session = req.getSession();
|
|
|
// 检查session是否存在,以及session中是否存在标识管理员登录的"manager"属性
|
|
|
if (session == null || session.getAttribute("manager") == null) {
|
|
|
// 将通用响应对象转换为Http响应对象
|
|
|
HttpServletResponse rep = (HttpServletResponse) response;
|
|
|
// 重定向到管理员登录页面,阻止未登录用户访问受保护资源
|
|
|
rep.sendRedirect(req.getContextPath() + "/loginManager.html");
|
|
|
return; // 终止后续过滤逻辑
|
|
|
}
|
|
|
// 将请求和响应传递给过滤器链中的下一个组件(如其他过滤器或Servlet)
|
|
|
chain.doFilter(request, response);
|
|
|
}
|
|
|
|
|
|
// * 过滤器初始化方法,用于获取配置参数等初始化操作* @param fConfig 过滤器配置对象* @throws ServletException Servlet初始化异常
|
|
|
public void init(FilterConfig fConfig) throws ServletException {
|
|
|
}
|
|
|
}
|
|
|
// * XSS过滤器,用于过滤请求参数中的跨站脚本攻击代码(如 script、style 标签等),保护应用免受 XSS 攻击
|
|
|
public class XSSFilter implements Filter {
|
|
|
|
|
|
/**
|
|
|
* 过滤输入字符串中的 XSS 相关代码
|
|
|
* @param htmlStr 待过滤的字符串
|
|
|
* @return 过滤后的字符串,移除了 script、style、HTML 标签内容
|
|
|
*/
|
|
|
public String filter(String htmlStr) {
|
|
|
if (htmlStr == null) {
|
|
|
return null;
|
|
|
}
|
|
|
// 定义匹配 script 标签的正则表达式,不区分大小写
|
|
|
String regEx_script = "<script[^>]*?>[\\s\\S]*?<\\/script>";
|
|
|
// 定义匹配 style 标签的正则表达式,不区分大小写
|
|
|
String regEx_style = "<style[^>]*?>[\\s\\S]*?<\\/style>";
|
|
|
// 定义匹配 HTML 标签的正则表达式,不区分大小写
|
|
|
String regEx_html = "<[^>]+>";
|
|
|
|
|
|
// 编译 script 正则表达式为 Pattern 对象
|
|
|
Pattern p_script = Pattern.compile(regEx_script, Pattern.CASE_INSENSITIVE);
|
|
|
Matcher m_script = p_script.matcher(htmlStr);
|
|
|
// 替换所有匹配的 script 标签内容为空,即过滤掉 script 标签
|
|
|
htmlStr = m_script.replaceAll("");
|
|
|
|
|
|
// 编译 style 正则表达式为 Pattern 对象
|
|
|
Pattern p_style = Pattern.compile(regEx_style, Pattern.CASE_INSENSITIVE);
|
|
|
Matcher m_style = p_style.matcher(htmlStr);
|
|
|
// 替换所有匹配的 style 标签内容为空,即过滤掉 style 标签
|
|
|
htmlStr = m_style.replaceAll("");
|
|
|
|
|
|
// 编译 HTML 标签正则表达式为 Pattern 对象
|
|
|
Pattern p_html = Pattern.compile(regEx_html, Pattern.CASE_INSENSITIVE);
|
|
|
Matcher m_html = p_html.matcher(htmlStr);
|
|
|
// 替换所有匹配的 HTML 标签内容为空,即过滤掉 HTML 标签
|
|
|
htmlStr = m_html.replaceAll("");
|
|
|
|
|
|
return htmlStr.trim(); // 返回处理后去除首尾空白的字符串
|
|
|
}
|
|
|
//自定义请求包装类,重写参数获取方法以实现 XSS 过滤 继承 HttpServletRequestWrapper,包装 HttpServletRequest 对象
|
|
|
|
|
|
class Request extends HttpServletRequestWrapper {
|
|
|
|
|
|
public Request(HttpServletRequest request) {
|
|
|
super(request);
|
|
|
}
|
|
|
//重写获取多个参数值的方法,对每个参数值进行 XSS 过滤 ,@param name 参数名 ,@return 过滤后的参数值数组
|
|
|
@Override
|
|
|
public String getParameter(String name) {
|
|
|
// 获取原始参数值并进行过滤
|
|
|
return filter(super.getRequest().getParameter(name));
|
|
|
}
|
|
|
// * * * XSSFilter.java
|
|
|
//重写获取多个参数值的方法,对每个参数值进行 XSS 过滤 ,@param name 参数名 ,@return 过滤后的参数值数组
|
|
|
@Override
|
|
|
public String[] getParameterValues(String name) {
|
|
|
// 获取原始参数值数组
|
|
|
String[] values = super.getRequest().getParameterValues(name);
|
|
|
// 遍历数组,对每个参数值进行过滤
|
|
|
for (int i = 0; i < values.length; i++) {
|
|
|
values[i] = filter(values[i]);
|
|
|
}
|
|
|
return values;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
* 执行过滤逻辑的核心方法
|
|
|
* @param request 客户端请求对象
|
|
|
* @param response 服务器响应对象
|
|
|
* @param chain 过滤链,用于传递请求和响应
|
|
|
* @throws IOException IO 异常
|
|
|
* @throws ServletException Servlet 处理异常
|
|
|
*/
|
|
|
@Override
|
|
|
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
|
|
|
// 使用自定义的 Request 包装请求,实现参数过滤
|
|
|
request = new Request((HttpServletRequest) request);
|
|
|
// 将过滤后的请求传递给过滤链后续组件
|
|
|
chain.doFilter(request, response);
|
|
|
}
|
|
|
//过滤器销毁方法,用于释放资源(当前无资源释放操作)
|
|
|
@Override
|
|
|
public void destroy() {
|
|
|
}
|
|
|
}
|
|
|
|
|
|
// * * * src/main/java/javabean/base.java
|
|
|
package javabean;
|
|
|
|
|
|
import java.sql.Connection;
|
|
|
import java.sql.DriverManager;
|
|
|
import java.sql.PreparedStatement;
|
|
|
import java.sql.ResultSet;
|
|
|
import java.sql.SQLException;
|
|
|
|
|
|
/**
|
|
|
* 数据库操作基础类,封装数据库连接、查询、更新和资源释放的通用方法
|
|
|
* 依赖DBConstants类获取数据库连接配置
|
|
|
*/
|
|
|
public class Base {
|
|
|
// 数据库连接配置(从DBConstants类获取)
|
|
|
private static final String driver = DBConstants.driver;
|
|
|
private static final String url = DBConstants.url;
|
|
|
private static final String username = DBConstants.username;
|
|
|
private static final String password = DBConstants.password;
|
|
|
|
|
|
/**
|
|
|
* 获取数据库连接
|
|
|
* @return 数据库连接对象
|
|
|
* @throws ClassNotFoundException 数据库驱动未找到异常
|
|
|
*/
|
|
|
public static Connection getConnection() throws ClassNotFoundException {
|
|
|
Connection connection = null;
|
|
|
try {
|
|
|
// 加载数据库驱动
|
|
|
Class.forName(driver);
|
|
|
// 建立数据库连接
|
|
|
connection = (Connection) DriverManager.getConnection(url, username, password);
|
|
|
} catch (SQLException e) {
|
|
|
e.printStackTrace(); // 打印异常堆栈(实际项目建议日志记录)
|
|
|
}
|
|
|
return connection;
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
* 执行数据库查询操作
|
|
|
* @param connection 数据库连接(可复用)
|
|
|
* @param preparedStatement 预编译语句(可复用)
|
|
|
* @param resultSet 结果集(可复用)
|
|
|
* @param sql SQL语句
|
|
|
* @param params 参数数组(用于预编译语句的占位符)
|
|
|
* @return 查询结果集
|
|
|
* @throws SQLException SQL执行异常
|
|
|
*/
|
|
|
public static ResultSet executequery(Connection connection, PreparedStatement preparedStatement,
|
|
|
ResultSet resultSet, String sql, Object[] params) throws SQLException {
|
|
|
// 如果预编译语句为空,则创建新实例
|
|
|
if (preparedStatement == null) {
|
|
|
preparedStatement = (PreparedStatement) connection.prepareStatement(sql);
|
|
|
}
|
|
|
// 设置预编译语句参数
|
|
|
for (int i = 0; params != null && i < params.length; i++) {
|
|
|
preparedStatement.setObject(i + 1, params[i]);
|
|
|
}
|
|
|
// 执行查询并返回结果集
|
|
|
resultSet = preparedStatement.executeQuery();
|
|
|
return resultSet;
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
* 执行数据库更新操作(INSERT/UPDATE/DELETE)
|
|
|
* @param connection 数据库连接(可复用)
|
|
|
* @param preparedStatement 预编译语句(可复用)
|
|
|
* @param sql SQL语句
|
|
|
* @param params 参数数组(用于预编译语句的占位符)
|
|
|
* @return 受影响的行数
|
|
|
* @throws SQLException SQL执行异常
|
|
|
*/
|
|
|
public static int executeUpdate(Connection connection, PreparedStatement preparedStatement, String sql,
|
|
|
Object[] params) throws SQLException {
|
|
|
// 如果预编译语句为空,则创建新实例
|
|
|
if (preparedStatement == null) {
|
|
|
preparedStatement = (PreparedStatement) connection.prepareStatement(sql);
|
|
|
}
|
|
|
// 设置预编译语句参数
|
|
|
for (int i = 0; params != null && i < params.length; i++) {
|
|
|
preparedStatement.setObject(i + 1, params[i]);
|
|
|
}
|
|
|
// 执行更新并返回受影响的行数
|
|
|
int updateRows = preparedStatement.executeUpdate();
|
|
|
return updateRows;
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
* 释放数据库资源(结果集、预编译语句、连接)
|
|
|
* @param connection 数据库连接(可选)
|
|
|
* @param preparedStatement 预编译语句(可选)
|
|
|
* @param resultSet 结果集(可选)
|
|
|
* @return 资源释放成功标志
|
|
|
* @throws SQLException 资源释放异常
|
|
|
*/
|
|
|
public static boolean closeResource(Connection connection, PreparedStatement preparedStatement, ResultSet resultSet)
|
|
|
throws SQLException {
|
|
|
boolean flag = true;
|
|
|
// 按顺序关闭资源:结果集 → 预编译语句 → 连接
|
|
|
if (resultSet != null) {
|
|
|
try {
|
|
|
resultSet.close();
|
|
|
resultSet = null;
|
|
|
} catch (SQLException e) {
|
|
|
e.printStackTrace();
|
|
|
flag = false;
|
|
|
}
|
|
|
}
|
|
|
if (preparedStatement != null) {
|
|
|
try {
|
|
|
preparedStatement.close();
|
|
|
preparedStatement = null;
|
|
|
} catch (SQLException e) {
|
|
|
e.printStackTrace();
|
|
|
flag = false;
|
|
|
}
|
|
|
}
|
|
|
if (connection != null) {
|
|
|
try {
|
|
|
connection.close();
|
|
|
connection = null;
|
|
|
} catch (SQLException e) {
|
|
|
e.printStackTrace();
|
|
|
flag = false;
|
|
|
}
|
|
|
}
|
|
|
return flag;
|
|
|
}
|
|
|
}
|
|
|
// * * * src/main/java/javabean/DBConstants.java
|
|
|
package javabean;
|
|
|
/**
|
|
|
* 数据库连接配置类,存储数据库连接所需的常量参数
|
|
|
* 注意:实际项目中应避免硬编码密码,建议使用配置文件或环境变量
|
|
|
*/
|
|
|
public class DBConstants {
|
|
|
// MySQL JDBC驱动类(适用于MySQL Connector/J 8.0+版本)
|
|
|
public static final String driver = "com.mysql.cj.jdbc.Driver";
|
|
|
|
|
|
// 数据库连接URL
|
|
|
// 格式:jdbc:mysql://<主机>:<端口>/<数据库名>?参数
|
|
|
// 示例说明:
|
|
|
// - localhost:3306:本地MySQL服务,默认端口
|
|
|
// - library:数据库名称
|
|
|
// - useSSL=false:禁用SSL连接(生产环境建议启用)
|
|
|
// - serverTimezone=UTC:设置时区为UTC(与数据库保持一致)
|
|
|
// - useUnicode=true&characterEncoding=UTF-8:启用Unicode编码,字符集UTF-8
|
|
|
public static final String url = "jdbc:mysql://localhost:3306/library?&useSSL=false&serverTimezone=UTC&useUnicode=true&characterEncoding=UTF-8";
|
|
|
|
|
|
// 数据库用户名(通常为root或具有适当权限的用户)
|
|
|
public static final String username = "root";
|
|
|
|
|
|
// 数据库密码(注意:硬编码密码存在安全风险,建议使用配置文件或环境变量)
|
|
|
public static final String password = "123456";
|
|
|
}
|
|
|
// * * * src/main/java/javabean/JDBCBean.java
|
|
|
package javabean;
|
|
|
|
|
|
import java.sql.Connection;
|
|
|
import java.sql.DriverManager;
|
|
|
import java.sql.ResultSet;
|
|
|
import java.sql.Statement;
|
|
|
|
|
|
/**
|
|
|
* 数据库操作工具类,封装基本的JDBC操作(存在安全风险和性能问题,建议改进)
|
|
|
* 注意:直接使用Statement存在SQL注入风险,建议改用PreparedStatement
|
|
|
*/
|
|
|
public class JDBCBean {
|
|
|
// 数据库连接配置(从DBConstants类获取)
|
|
|
private static final String driver = DBConstants.driver;
|
|
|
private static final String url = DBConstants.url;
|
|
|
private static final String username = DBConstants.username;
|
|
|
private static final String password = DBConstants.password;
|
|
|
|
|
|
// 数据库连接和操作对象
|
|
|
private Connection conn = null;
|
|
|
private Statement stmt = null;
|
|
|
|
|
|
/**
|
|
|
* 构造方法:初始化数据库连接和Statement对象
|
|
|
* 注意:直接抛出异常到调用者,避免在构造方法中吞掉异常
|
|
|
* 潜在问题:每次实例化都会创建新连接,未使用连接池,影响性能
|
|
|
*/
|
|
|
public JDBCBean() {
|
|
|
try {
|
|
|
Class.forName(driver); // 加载数据库驱动
|
|
|
conn = DriverManager.getConnection(url, username, password); // 建立连接
|
|
|
stmt = conn.createStatement(); // 创建Statement对象(存在SQL注入风险)
|
|
|
System.out.println("成功与数据库建立连接!");
|
|
|
} catch (ClassNotFoundException | SQLException e) {
|
|
|
System.out.println("无法与数据库建立连接!");
|
|
|
e.printStackTrace(); // 打印异常堆栈(生产环境应使用日志记录)
|
|
|
}
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
* 执行数据库更新操作(INSERT/UPDATE/DELETE)
|
|
|
* @param s SQL语句(存在SQL注入风险)
|
|
|
* @return 受影响的行数
|
|
|
*/
|
|
|
public int executeUpdate(String s) {
|
|
|
int result = 0;
|
|
|
try {
|
|
|
System.out.println("执行SQL:" + s); // 调试输出,生产环境应移除
|
|
|
result = stmt.executeUpdate(s);
|
|
|
} catch (SQLException e) {
|
|
|
System.out.println("执行更新错误!");
|
|
|
e.printStackTrace();
|
|
|
}
|
|
|
return result;
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
* 执行数据库查询操作
|
|
|
* @param s SQL语句(存在SQL注入风险)
|
|
|
* @return 查询结果集(需要手动关闭)
|
|
|
*/
|
|
|
public ResultSet executeQuery(String s) {
|
|
|
ResultSet rs = null;
|
|
|
try {
|
|
|
rs = stmt.executeQuery(s);
|
|
|
} catch (SQLException e) {
|
|
|
System.out.println("执行查询错误!" + e.getMessage());
|
|
|
e.printStackTrace();
|
|
|
}
|
|
|
return rs;
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
* 关闭数据库资源(Statement和Connection)
|
|
|
* 注意:未正确处理异常,可能导致资源泄漏
|
|
|
* 建议:使用try-with-resources或在finally块中调用
|
|
|
*/
|
|
|
public void close() {
|
|
|
try {
|
|
|
if (stmt != null) stmt.close();
|
|
|
if (conn != null) conn.close();
|
|
|
} catch (SQLException e) {
|
|
|
e.printStackTrace();
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
// * * * src/main/java/javabean/Common.java
|
|
|
package javabean;
|
|
|
import java.sql.Connection;
|
|
|
import java.sql.PreparedStatement;
|
|
|
import java.sql.ResultSet;
|
|
|
import java.sql.SQLException;
|
|
|
import java.util.HashMap;
|
|
|
import java.util.TreeMap;
|
|
|
|
|
|
/**
|
|
|
* 通用数据库操作工具类,提供表行数统计和图书馆信息映射等功能
|
|
|
*/
|
|
|
public class Common {
|
|
|
|
|
|
/**
|
|
|
* 获取指定表的总记录数
|
|
|
* @param table 表名(不能为空)
|
|
|
* @return 记录总数(若表不存在或查询失败返回0)
|
|
|
* @throws ClassNotFoundException 数据库驱动未找到异常
|
|
|
* @throws SQLException SQL执行异常
|
|
|
*/
|
|
|
public static int getCount(String table) throws SQLException, ClassNotFoundException {
|
|
|
if (table == null || table.equals("")) {
|
|
|
return 0; // 表名为空直接返回0
|
|
|
}
|
|
|
|
|
|
Connection connection = null;
|
|
|
PreparedStatement pstmt = null;
|
|
|
ResultSet resultSet = null;
|
|
|
try {
|
|
|
connection = Base.getConnection(); // 获取数据库连接
|
|
|
// 构建查询总行数的SQL语句
|
|
|
pstmt = connection.prepareStatement("SELECT COUNT(*) AS count FROM " + table);
|
|
|
resultSet = pstmt.executeQuery(); // 执行查询
|
|
|
resultSet.next(); // 移动到结果集第一条记录
|
|
|
return resultSet.getInt("count"); // 返回总记录数
|
|
|
} catch (SQLException e) {
|
|
|
e.printStackTrace(); // 打印异常堆栈(实际项目建议日志记录)
|
|
|
return 0; // 查询失败返回0
|
|
|
} finally {
|
|
|
// 释放数据库资源
|
|
|
Base.closeResource(connection, pstmt, resultSet);
|
|
|
}
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
* 获取所有图书馆的ID-名称映射(按ID升序排列)
|
|
|
* @return TreeMap<图书馆ID, 图书馆名称>(若查询失败返回null)
|
|
|
* @throws SQLException SQL执行异常
|
|
|
*/
|
|
|
public static TreeMap<String, String> getLibraryMap() throws SQLException {
|
|
|
Connection connection = null;
|
|
|
PreparedStatement libraryPstmt = null;
|
|
|
ResultSet librarySet = null;
|
|
|
String librarySql = "SELECT id, name FROM library"; // 查询图书馆的SQL语句
|
|
|
|
|
|
TreeMap<String, String> map = new TreeMap<>(); // 使用TreeMap自动按键(ID)排序
|
|
|
|
|
|
try {
|
|
|
connection = Base.getConnection(); // 获取数据库连接
|
|
|
libraryPstmt = connection.prepareStatement(librarySql); // 创建预编译语句
|
|
|
librarySet = libraryPstmt.executeQuery(); // 执行查询
|
|
|
|
|
|
// 遍历结果集,填充TreeMap
|
|
|
while (librarySet.next()) {
|
|
|
String id = librarySet.getString("id");
|
|
|
String name = librarySet.getString("name");
|
|
|
map.put(id, name); // 键为ID,值为名称
|
|
|
}
|
|
|
} catch (ClassNotFoundException e) {
|
|
|
e.printStackTrace();
|
|
|
return null; // 驱动未找到返回null
|
|
|
} catch (SQLException e) {
|
|
|
e.printStackTrace();
|
|
|
return null; // SQL执行失败返回null
|
|
|
} finally {
|
|
|
// 释放数据库资源
|
|
|
Base.closeResource(connection, libraryPstmt, librarySet);
|
|
|
}
|
|
|
return map;
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
* 测试方法(实际项目建议删除)
|
|
|
* @param args 命令行参数
|
|
|
* @throws SQLException SQL执行异常
|
|
|
*/
|
|
|
public static void main(String[] args) throws SQLException {
|
|
|
System.out.println(Common.getLibraryMap()); // 打印图书馆映射
|
|
|
}
|
|
|
}
|
|
|
// * * * src/main/java/javabean/CompareDate.java
|
|
|
package javabean;
|
|
|
|
|
|
import java.text.ParseException;
|
|
|
import java.text.SimpleDateFormat;
|
|
|
import java.util.Date;
|
|
|
|
|
|
/**
|
|
|
* 日期比较工具类,提供计算两个日期字符串时间差的功能
|
|
|
*/
|
|
|
public class CompareDate {
|
|
|
|
|
|
/**
|
|
|
* 计算两个日期字符串之间的天数差(结束日期 - 开始日期)
|
|
|
* @param Str1 开始日期字符串(格式:yyyy-MM-dd HH:mm:ss)
|
|
|
* @param Str2 结束日期字符串(格式:yyyy-MM-dd HH:mm:ss)
|
|
|
* @return 相差的天数(可能为负数,表示结束日期早于开始日期)
|
|
|
* @throws ParseException 日期格式不正确时抛出(当前方法未处理,直接打印堆栈)
|
|
|
* @implNote 使用SimpleDateFormat进行日期解析,存在线程不安全问题
|
|
|
* @implNote 时间差计算为毫秒差除以一天的毫秒数(24*60*60*1000),结果为整数天数
|
|
|
*/
|
|
|
public static long show(String Str1, String Str2) {
|
|
|
long between = 0;
|
|
|
SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
|
|
|
try {
|
|
|
Date date1 = format.parse(Str1); // 解析开始日期
|
|
|
Date date2 = format.parse(Str2); // 解析结束日期
|
|
|
between = date2.getTime() - date1.getTime(); // 计算时间差(毫秒)
|
|
|
} catch (ParseException e) {
|
|
|
e.printStackTrace(); // 打印异常堆栈(实际项目应处理异常)
|
|
|
}
|
|
|
// 转换为天数(注意:直接除以一天的毫秒数可能导致精度丢失)
|
|
|
long days = between / (24 * 60 * 60 * 1000);
|
|
|
return days;
|
|
|
}
|
|
|
|
|
|
// 示例用法
|
|
|
public static void main(String[] args) {
|
|
|
long days = CompareDate.show("2023-01-01 00:00:00", "2023-01-03 23:59:59");
|
|
|
System.out.println("相差天数:" + days); // 输出:2
|
|
|
}
|
|
|
}
|
|
|
// * * * Manager.java
|
|
|
package javabean;
|
|
|
|
|
|
import java.sql.Connection;
|
|
|
import java.sql.PreparedStatement;
|
|
|
import java.sql.ResultSet;
|
|
|
import java.sql.SQLException;
|
|
|
|
|
|
/**
|
|
|
* 管理员业务逻辑处理类,封装管理员登录验证功能
|
|
|
*/
|
|
|
public class Manager {
|
|
|
|
|
|
/**
|
|
|
* 管理员登录验证方法
|
|
|
* @param user 管理员账号
|
|
|
* @param psw 管理员密码
|
|
|
* @return 验证结果:"1"表示成功,其他字符串表示失败原因
|
|
|
* @throws ClassNotFoundException 数据库驱动未找到异常
|
|
|
* @throws SQLException 数据库操作异常
|
|
|
*/
|
|
|
@SuppressWarnings("null") // 抑制空指针警告(resultSet在finally中已关闭)
|
|
|
public String login(String user, String psw) throws ClassNotFoundException, SQLException {
|
|
|
|
|
|
// 参数校验
|
|
|
if (user == null || user.trim().equals("")) {
|
|
|
return "账号不能为空";
|
|
|
} else if (psw == null || psw.trim().equals("")) {
|
|
|
return "密码不能为空";
|
|
|
}
|
|
|
|
|
|
Connection connection = null;
|
|
|
PreparedStatement pstmt = null;
|
|
|
ResultSet resultSet = null;
|
|
|
String sql = "select * from manager where ACCOUNT=? and PASSWORD=?";
|
|
|
|
|
|
try {
|
|
|
connection = Base.getConnection(); // 获取数据库连接
|
|
|
pstmt = connection.prepareStatement(sql); // 预编译SQL
|
|
|
pstmt.setString(1, user); // 绑定账号参数
|
|
|
pstmt.setString(2, psw); // 绑定密码参数
|
|
|
resultSet = pstmt.executeQuery(); // 执行查询
|
|
|
|
|
|
if (resultSet.next()) { // 若存在匹配记录
|
|
|
return "1"; // 返回成功标识
|
|
|
}
|
|
|
return "账号或密码错误"; // 查询无结果时返回错误信息
|
|
|
|
|
|
} finally {
|
|
|
// 释放数据库资源
|
|
|
Base.closeResource(connection, pstmt, resultSet);
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
// * * * java/servlet/announcement.java
|
|
|
package servlet.manager;
|
|
|
import java.io.IOException;
|
|
|
import java.io.PrintWriter;
|
|
|
import java.sql.Connection;
|
|
|
import java.sql.PreparedStatement;
|
|
|
import java.sql.ResultSet;
|
|
|
import java.sql.SQLException;
|
|
|
|
|
|
import javax.servlet.ServletException;
|
|
|
import javax.servlet.annotation.WebServlet;
|
|
|
import javax.servlet.http.HttpServlet;
|
|
|
import javax.servlet.http.HttpServletRequest;
|
|
|
import javax.servlet.http.HttpServletResponse;
|
|
|
|
|
|
import javabean.Base;
|
|
|
import javabean.Util;
|
|
|
import net.sf.json.JSONArray;
|
|
|
import net.sf.json.JSONObject;
|
|
|
|
|
|
/**
|
|
|
* 公告管理Servlet,处理公告查询请求
|
|
|
* 映射路径:/manager/announcement
|
|
|
* 仅响应GET请求,返回公告列表的JSON数据
|
|
|
*/
|
|
|
@WebServlet("/manager/announcement")
|
|
|
public class Announcement extends HttpServlet {
|
|
|
|
|
|
/**
|
|
|
* 处理GET请求,查询公告列表并返回JSON数据
|
|
|
* @param req HTTP请求对象
|
|
|
* @param resp HTTP响应对象
|
|
|
* @throws ServletException Servlet处理异常
|
|
|
* @throws IOException IO异常
|
|
|
*/
|
|
|
@Override
|
|
|
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
|
|
|
// 设置响应格式为JSON,字符集UTF-8
|
|
|
resp.setContentType("application/json; charset=utf8");
|
|
|
|
|
|
// 数据库操作变量
|
|
|
Connection connection = null;
|
|
|
PreparedStatement pstmt = null;
|
|
|
String sql = "";
|
|
|
ResultSet resultSet = null;
|
|
|
|
|
|
// 响应数据
|
|
|
int code = 1; // 状态码:1=失败,0=成功
|
|
|
String msg = "无数据"; // 状态描述
|
|
|
JSONObject jsonObject = new JSONObject(); // 单条公告JSON对象
|
|
|
JSONArray jsonArray = new JSONArray(); // 公告列表JSON数组
|
|
|
|
|
|
try {
|
|
|
// 获取数据库连接
|
|
|
connection = Base.getConnection();
|
|
|
// 查询所有公告的SQL语句
|
|
|
sql = "select * from announcement";
|
|
|
pstmt = connection.prepareStatement(sql);
|
|
|
resultSet = pstmt.executeQuery();
|
|
|
|
|
|
// 遍历结果集,封装为JSON格式
|
|
|
while (resultSet.next()) {
|
|
|
jsonObject.put("id", resultSet.getString("id")); // 公告ID
|
|
|
jsonObject.put("title", resultSet.getString("title")); // 公告标题
|
|
|
jsonObject.put("detail", resultSet.getString("detail")); // 公告详情
|
|
|
jsonObject.put("publish_date", resultSet.getString("publish_date")); // 发布日期
|
|
|
jsonArray.add(jsonObject); // 添加到公告列表
|
|
|
}
|
|
|
|
|
|
// 根据查询结果设置响应状态
|
|
|
if (!jsonArray.isEmpty()) {
|
|
|
code = 0;
|
|
|
msg = "查询成功";
|
|
|
} else {
|
|
|
msg = "数据为空";
|
|
|
}
|
|
|
|
|
|
} catch (ClassNotFoundException e) {
|
|
|
msg = "数据库驱动未找到";
|
|
|
} catch (SQLException e) {
|
|
|
msg = "SQL执行错误";
|
|
|
} finally {
|
|
|
// 释放数据库资源
|
|
|
try {
|
|
|
Base.closeResource(connection, pstmt, resultSet);
|
|
|
} catch (SQLException e) {
|
|
|
msg = "资源释放失败";
|
|
|
}
|
|
|
}
|
|
|
|
|
|
// 生成最终响应JSON
|
|
|
PrintWriter out = resp.getWriter();
|
|
|
out.print(Util.jsonResponse(code, msg, jsonArray.toString()));
|
|
|
}
|
|
|
}
|
|
|
// * * * java/servlet/announcementAdd.java
|
|
|
package servlet.manager;
|
|
|
import java.io.IOException;
|
|
|
import java.io.PrintWriter;
|
|
|
import java.sql.Connection;
|
|
|
import java.sql.PreparedStatement;
|
|
|
import java.sql.ResultSet;
|
|
|
import java.sql.SQLException;
|
|
|
|
|
|
import javax.servlet.ServletException;
|
|
|
import javax.servlet.annotation.WebServlet;
|
|
|
import javax.servlet.http.HttpServlet;
|
|
|
import javax.servlet.http.HttpServletRequest;
|
|
|
import javax.servlet.http.HttpServletResponse;
|
|
|
|
|
|
import javabean.Base;
|
|
|
import javabean.DateTime;
|
|
|
import net.sf.json.JSONArray;
|
|
|
import net.sf.json.JSONObject;
|
|
|
|
|
|
/**
|
|
|
* 公告添加Servlet,处理公告发布请求
|
|
|
* 映射路径:/manager/announcementAdd
|
|
|
* 仅响应POST请求,接收公告标题、内容并保存到数据库
|
|
|
*/
|
|
|
@WebServlet("/manager/announcementAdd")
|
|
|
public class AnnouncementAdd extends HttpServlet {
|
|
|
|
|
|
/**
|
|
|
* 处理POST请求,接收公告信息并插入数据库
|
|
|
* @param req HTTP请求对象(包含公告标题、内容参数)
|
|
|
* @param resp HTTP响应对象(返回操作结果JSON)
|
|
|
* @throws ServletException Servlet处理异常
|
|
|
* @throws IOException IO异常
|
|
|
*/
|
|
|
@Override
|
|
|
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
|
|
|
// 设置响应格式为JSON,字符集UTF-8
|
|
|
resp.setContentType("application/json; charset=utf8");
|
|
|
|
|
|
// 接收客户端提交的参数
|
|
|
String id = req.getParameter("id"); // 未使用的参数(可能为测试保留)
|
|
|
String tit = req.getParameter("title"); // 公告标题
|
|
|
String det = req.getParameter("detail"); // 公告内容
|
|
|
DateTime date = new DateTime(); // 获取当前时间
|
|
|
String time = date.show(); // 格式化时间字符串
|
|
|
|
|
|
// 数据库操作变量
|
|
|
Connection connection = null;
|
|
|
PreparedStatement pstmt = null;
|
|
|
ResultSet resultSet = null;
|
|
|
int result = 0; // 数据库操作影响的行数
|
|
|
int count = 0; // 未使用的计数器(可能为测试保留)
|
|
|
|
|
|
// 响应数据
|
|
|
int code = 1; // 状态码:1=失败,0=成功
|
|
|
String msg = ""; // 状态描述
|
|
|
JSONArray jsonArray = new JSONArray(); // 未使用的JSON数组(可能为测试保留)
|
|
|
JSONObject json = new JSONObject(); // 响应结果JSON对象
|
|
|
|
|
|
// SQL语句:插入公告信息(注意:id字段未包含,由数据库自增)
|
|
|
String sql = "insert into announcement(title, detail, publish_date) values(?,?,?)";
|
|
|
System.out.println(sql); // 控制台打印SQL语句(生产环境建议移除)
|
|
|
|
|
|
PrintWriter out = resp.getWriter(); // 获取响应输出流
|
|
|
|
|
|
try {
|
|
|
// 获取数据库连接
|
|
|
connection = Base.getConnection();
|
|
|
// 预编译SQL语句
|
|
|
pstmt = connection.prepareStatement(sql);
|
|
|
// 绑定参数:标题、内容、发布时间
|
|
|
pstmt.setString(1, tit);
|
|
|
pstmt.setString(2, det);
|
|
|
pstmt.setString(3, time);
|
|
|
// 执行插入操作
|
|
|
result = pstmt.executeUpdate();
|
|
|
|
|
|
} catch (SQLException e) {
|
|
|
// 捕获SQL异常(未处理具体错误信息,建议添加日志)
|
|
|
} catch (ClassNotFoundException e) {
|
|
|
e.printStackTrace(); // 打印驱动未找到异常堆栈
|
|
|
} finally {
|
|
|
// 释放数据库资源(结果集为null,无需关闭)
|
|
|
try {
|
|
|
Base.closeResource(connection, pstmt, null);
|
|
|
} catch (SQLException e) {
|
|
|
e.printStackTrace(); // 打印资源释放异常堆栈
|
|
|
}
|
|
|
}
|
|
|
|
|
|
// 根据操作结果生成响应JSON
|
|
|
if (result == 1) {
|
|
|
json.put("code", "0");
|
|
|
json.put("msg", "success");
|
|
|
} else {
|
|
|
json.put("code", "1");
|
|
|
json.put("msg", "error");
|
|
|
}
|
|
|
out.write(json.toString()); // 输出响应结果
|
|
|
}
|
|
|
}
|
|
|
|
|
|
// * * * java/servlet/announcementDel.java
|
|
|
package servlet.manager;
|
|
|
import java.io.IOException;
|
|
|
import java.io.PrintWriter;
|
|
|
import java.sql.Connection;
|
|
|
import java.sql.PreparedStatement;
|
|
|
import java.sql.ResultSet;
|
|
|
import java.sql.SQLException;
|
|
|
|
|
|
import javax.servlet.ServletException;
|
|
|
import javax.servlet.annotation.WebServlet;
|
|
|
import javax.servlet.http.HttpServlet;
|
|
|
import javax.servlet.http.HttpServletRequest;
|
|
|
import javax.servlet.http.HttpServletResponse;
|
|
|
|
|
|
import javabean.Base;
|
|
|
import javabean.Util;
|
|
|
|
|
|
/**
|
|
|
* 公告删除Servlet,处理公告删除请求
|
|
|
* 映射路径:/manager/announcementDel
|
|
|
* 仅响应GET请求,根据公告ID执行删除操作
|
|
|
*/
|
|
|
@WebServlet("/manager/announcementDel")
|
|
|
public class AnnouncementDel extends HttpServlet {
|
|
|
|
|
|
/**
|
|
|
* 处理GET请求,根据ID删除公告并返回JSON响应
|
|
|
* @param req HTTP请求对象(包含公告ID参数id)
|
|
|
* @param resp HTTP响应对象(返回删除结果JSON)
|
|
|
* @throws ServletException Servlet处理异常
|
|
|
* @throws IOException IO异常
|
|
|
*/
|
|
|
@Override
|
|
|
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
|
|
|
// 获取请求参数:公告ID
|
|
|
String id = req.getParameter("id");
|
|
|
|
|
|
// 数据库操作变量
|
|
|
String sql = ""; // SQL语句
|
|
|
Connection connection = null; // 数据库连接
|
|
|
PreparedStatement pstmt = null; // 预编译语句
|
|
|
ResultSet resultSet = null; // 结果集(未使用)
|
|
|
int result = 0; // 数据库操作影响的行数
|
|
|
|
|
|
// 响应数据
|
|
|
int code = 1; // 状态码:1=失败,0=成功
|
|
|
String msg = ""; // 状态描述
|
|
|
PrintWriter out = resp.getWriter(); // 响应输出流
|
|
|
|
|
|
try {
|
|
|
// 获取数据库连接
|
|
|
connection = Base.getConnection();
|
|
|
// 预编译删除SQL,使用占位符?防止SQL注入
|
|
|
sql = "delete from announcement where id=?";
|
|
|
pstmt = connection.prepareStatement(sql);
|
|
|
// 绑定参数:公告ID
|
|
|
pstmt.setString(1, id);
|
|
|
// 执行删除操作
|
|
|
result = pstmt.executeUpdate();
|
|
|
|
|
|
// 根据影响的行数判断操作结果
|
|
|
if (result == 1) {
|
|
|
code = 0;
|
|
|
msg = "删除成功";
|
|
|
} else {
|
|
|
msg = "删除失败(ID不存在或操作异常)";
|
|
|
}
|
|
|
|
|
|
} catch (ClassNotFoundException e) {
|
|
|
msg = "数据库驱动未找到";
|
|
|
} catch (SQLException e) {
|
|
|
msg = "SQL执行错误:" + e.getMessage(); // 建议记录详细错误日志
|
|
|
} finally {
|
|
|
// 释放数据库资源
|
|
|
try {
|
|
|
Base.closeResource(connection, pstmt, resultSet);
|
|
|
} catch (SQLException e) {
|
|
|
e.printStackTrace(); // 打印资源释放异常堆栈
|
|
|
}
|
|
|
}
|
|
|
|
|
|
// 生成JSON响应:状态码、消息、空数据
|
|
|
out.print(Util.jsonResponse(code, msg, null));
|
|
|
}
|
|
|
}
|
|
|
|
|
|
// * * * java/servlet/announcementEdit.java
|
|
|
package servlet.manager;
|
|
|
import java.io.IOException;
|
|
|
import java.io.PrintWriter;
|
|
|
import java.sql.Connection;
|
|
|
import java.sql.PreparedStatement;
|
|
|
import java.sql.ResultSet;
|
|
|
import java.sql.SQLException;
|
|
|
|
|
|
import javax.servlet.ServletException;
|
|
|
import javax.servlet.annotation.WebServlet;
|
|
|
import javax.servlet.http.HttpServlet;
|
|
|
import javax.servlet.http.HttpServletRequest;
|
|
|
import javax.servlet.http.HttpServletResponse;
|
|
|
|
|
|
import javabean.Base;
|
|
|
import javabean.Util;
|
|
|
import net.sf.json.JSONArray;
|
|
|
import net.sf.json.JSONObject;
|
|
|
|
|
|
/**
|
|
|
* 公告编辑Servlet,处理公告内容修改请求
|
|
|
* 映射路径:/manager/announcementEdit
|
|
|
* 仅响应POST请求,接收公告ID、新标题和内容并更新数据库
|
|
|
*/
|
|
|
@WebServlet("/manager/announcementEdit")
|
|
|
public class AnnouncementEdit extends HttpServlet {
|
|
|
|
|
|
/**
|
|
|
* 处理POST请求,执行公告内容修改并返回JSON响应
|
|
|
* @param req HTTP请求对象(包含公告ID、新标题和内容参数)
|
|
|
* @param resp HTTP响应对象(返回操作结果JSON)
|
|
|
* @throws ServletException Servlet处理异常
|
|
|
* @throws IOException IO异常
|
|
|
*/
|
|
|
@Override
|
|
|
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
|
|
|
// 设置响应格式为JSON,字符集UTF-8
|
|
|
resp.setContentType("application/json; charset=utf8");
|
|
|
|
|
|
// 接收客户端提交的参数
|
|
|
String id = req.getParameter("id"); // 公告ID(未校验非空)
|
|
|
String tit = req.getParameter("title"); // 新公告标题
|
|
|
String det = req.getParameter("detail"); // 新公告内容
|
|
|
|
|
|
// 数据库操作变量
|
|
|
String sql = ""; // SQL语句
|
|
|
Connection connection = null; // 数据库连接
|
|
|
PreparedStatement pstmt = null; // 预编译语句
|
|
|
ResultSet resultSet = null; // 结果集(未使用)
|
|
|
int result = 0; // 数据库操作影响的行数
|
|
|
|
|
|
// 响应数据
|
|
|
int code = 1; // 状态码:1=失败,0=成功
|
|
|
String msg = ""; // 状态描述
|
|
|
PrintWriter out = resp.getWriter(); // 响应输出流
|
|
|
JSONArray jsonArray = new JSONArray(); // 未使用的JSON数组(建议删除)
|
|
|
JSONObject jsonObject = new JSONObject(); // 未使用的JSON对象(建议删除)
|
|
|
|
|
|
// 参数校验:标题和内容不能为空
|
|
|
if (tit == null || tit.equals("") || det == null || det.equals("")) {
|
|
|
msg = "参数不能为空";
|
|
|
out.print(Util.jsonResponse(code, msg, null));
|
|
|
return; // 终止后续处理
|
|
|
}
|
|
|
|
|
|
try {
|
|
|
// 获取数据库连接
|
|
|
connection = Base.getConnection();
|
|
|
// 预编译更新SQL,使用占位符?防止SQL注入
|
|
|
sql = "update announcement set title=?, detail=? where id=?";
|
|
|
pstmt = connection.prepareStatement(sql);
|
|
|
// 绑定参数:新标题、新内容、公告ID
|
|
|
pstmt.setString(1, tit);
|
|
|
pstmt.setString(2, det);
|
|
|
pstmt.setString(3, id);
|
|
|
// 执行更新操作
|
|
|
result = pstmt.executeUpdate();
|
|
|
|
|
|
// 根据影响的行数判断操作结果
|
|
|
if (result == 1) {
|
|
|
code = 0;
|
|
|
msg = "修改成功";
|
|
|
} else {
|
|
|
msg = "修改失败(ID不存在或操作异常)";
|
|
|
}
|
|
|
|
|
|
} catch (ClassNotFoundException e) {
|
|
|
msg = "数据库驱动未找到";
|
|
|
} catch (SQLException e) {
|
|
|
msg = "SQL执行错误:" + e.getMessage(); // 建议记录详细错误日志
|
|
|
} finally {
|
|
|
// 释放数据库资源
|
|
|
try {
|
|
|
Base.closeResource(connection, pstmt, resultSet);
|
|
|
} catch (SQLException e) {
|
|
|
e.printStackTrace(); // 打印资源释放异常堆栈
|
|
|
}
|
|
|
}
|
|
|
|
|
|
// 生成JSON响应:状态码、消息、空数据
|
|
|
out.print(Util.jsonResponse(code, msg, null));
|
|
|
}
|
|
|
}
|
|
|
|
|
|
// * * * java/servlet/BorrowTable.java
|
|
|
package servlet.manager;
|
|
|
|
|
|
import java.io.IOException;
|
|
|
import java.io.PrintWriter;
|
|
|
import java.sql.Connection;
|
|
|
import java.sql.PreparedStatement;
|
|
|
import java.sql.ResultSet;
|
|
|
import java.sql.SQLException;
|
|
|
|
|
|
import javax.servlet.ServletException;
|
|
|
import javax.servlet.annotation.WebServlet;
|
|
|
import javax.servlet.http.HttpServlet;
|
|
|
import javax.servlet.http.HttpServletRequest;
|
|
|
import javax.servlet.http.HttpServletResponse;
|
|
|
|
|
|
import javabean.Base;
|
|
|
import net.sf.json.JSONArray;
|
|
|
import net.sf.json.JSONObject;
|
|
|
|
|
|
/**
|
|
|
* 借阅记录管理Servlet,处理分页查询和条件过滤请求
|
|
|
* 映射路径:/manager/borrowTable
|
|
|
* 仅响应GET请求,返回符合条件的借阅记录列表(JSON格式)
|
|
|
*/
|
|
|
@WebServlet("/manager/borrowTable")
|
|
|
public class BorrowTable extends HttpServlet {
|
|
|
|
|
|
/**
|
|
|
* 处理GET请求,执行分页查询并返回JSON数据
|
|
|
* @param req HTTP请求对象(包含分页参数和过滤条件)
|
|
|
* @param resp HTTP响应对象(返回查询结果JSON)
|
|
|
* @throws ServletException Servlet处理异常
|
|
|
* @throws IOException IO异常
|
|
|
*/
|
|
|
@Override
|
|
|
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
|
|
|
// 设置响应格式为JSON,字符集UTF-8
|
|
|
resp.setContentType("application/json; charset=utf8");
|
|
|
|
|
|
// 接收客户端参数
|
|
|
String limit = req.getParameter("limit"); // 每页显示数量
|
|
|
String page = req.getParameter("page"); // 当前页码
|
|
|
String condition = req.getParameter("condition"); // 过滤字段(如card_id)
|
|
|
String conditionValue = req.getParameter("conditionValue"); // 过滤值
|
|
|
|
|
|
// 初始化查询条件
|
|
|
String where = ""; // 无限制条件
|
|
|
if (page == null) page = "1"; // 默认页码1
|
|
|
if (limit == null) limit = "10"; // 默认每页10条
|
|
|
|
|
|
// 数据库操作变量
|
|
|
Connection connection = null;
|
|
|
PreparedStatement pstmt = null; // 数据查询语句
|
|
|
PreparedStatement countPstmt = null; // 总数查询语句
|
|
|
ResultSet resultSet = null;
|
|
|
ResultSet countSet = null;
|
|
|
String sql = "";
|
|
|
String countSql = "";
|
|
|
|
|
|
// 响应数据
|
|
|
int code = 1; // 状态码:1=失败,0=成功
|
|
|
String msg = "无数据"; // 状态描述
|
|
|
int count = 0; // 总记录数
|
|
|
JSONObject jsonData = new JSONObject(); // 单条记录JSON对象
|
|
|
JSONArray jsonArray = new JSONArray(); // 记录列表JSON数组
|
|
|
JSONObject jsonResult = new JSONObject(); // 最终响应JSON
|
|
|
|
|
|
try {
|
|
|
// 获取数据库连接
|
|
|
connection = Base.getConnection();
|
|
|
|
|
|
// 构建基础查询SQL(过滤manager_id不为null的记录)
|
|
|
sql = "select * from borrow_books where manager_id is not null";
|
|
|
// 拼接条件查询(注意:直接拼接字符串存在SQL注入风险)
|
|
|
if (condition != null && conditionValue != null
|
|
|
&& !condition.equals("") && !conditionValue.equals("")) {
|
|
|
where = " and " + condition + " like '%" + conditionValue + "%' ";
|
|
|
sql += where;
|
|
|
}
|
|
|
// 拼接分页参数(使用预编译占位符)
|
|
|
sql += " limit ?,?";
|
|
|
System.out.println("查询SQL:" + sql); // 调试用,生产环境建议移除
|
|
|
|
|
|
// 执行数据查询
|
|
|
pstmt = connection.prepareStatement(sql);
|
|
|
// 计算分页偏移量:(当前页-1)*每页数量
|
|
|
pstmt.setInt(1, (Integer.parseInt(page) - 1) * Integer.parseInt(limit));
|
|
|
pstmt.setInt(2, Integer.parseInt(limit));
|
|
|
resultSet = pstmt.executeQuery();
|
|
|
|
|
|
// 封装查询结果为JSON
|
|
|
while (resultSet.next()) {
|
|
|
jsonData.put("id", resultSet.getString("id")); // 记录ID
|
|
|
jsonData.put("card_id", resultSet.getString("card_id")); // 读者卡号
|
|
|
jsonData.put("book_id", resultSet.getString("book_id")); // 图书ID
|
|
|
jsonData.put("borrow_date", resultSet.getString("borrow_date")); // 借阅日期
|
|
|
jsonData.put("end_date", resultSet.getString("end_date")); // 应还日期
|
|
|
jsonData.put("return_date", resultSet.getString("return_date")); // 归还日期
|
|
|
jsonData.put("illegal", resultSet.getString("illegal")); // 违规状态
|
|
|
jsonData.put("manager_id", resultSet.getString("manager_id")); // 管理员ID
|
|
|
jsonArray.add(jsonData); // 添加到记录列表
|
|
|
}
|
|
|
|
|
|
// 执行总记录数查询
|
|
|
countSql = "select count(*) as count from borrow_books where manager_id is not null" + where;
|
|
|
countPstmt = connection.prepareStatement(countSql);
|
|
|
countSet = countPstmt.executeQuery();
|
|
|
if (countSet.next()) {
|
|
|
count = countSet.getInt("count"); // 获取总记录数
|
|
|
}
|
|
|
|
|
|
// 设置响应状态
|
|
|
if (!jsonArray.isEmpty()) {
|
|
|
code = 0;
|
|
|
msg = "查询成功";
|
|
|
}
|
|
|
|
|
|
} catch (ClassNotFoundException e) {
|
|
|
msg = "数据库驱动未找到";
|
|
|
} catch (SQLException e) {
|
|
|
msg = "SQL执行错误:" + e.getMessage();
|
|
|
} finally {
|
|
|
// 分批次释放资源
|
|
|
try {
|
|
|
Base.closeResource(null, pstmt, resultSet); // 关闭数据查询资源
|
|
|
Base.closeResource(connection, countPstmt, countSet); // 关闭总数查询资源
|
|
|
} catch (SQLException e) {
|
|
|
msg = "资源释放失败";
|
|
|
}
|
|
|
}
|
|
|
|
|
|
// 构建最终响应JSON
|
|
|
jsonResult.put("code", code);
|
|
|
jsonResult.put("count", count);
|
|
|
jsonResult.put("msg", msg);
|
|
|
jsonResult.put("data", jsonArray.toArray()); // 转换为JSON数组
|
|
|
|
|
|
// 输出响应
|
|
|
PrintWriter out = resp.getWriter();
|
|
|
out.print(jsonResult.toString());
|
|
|
}
|
|
|
}
|
|
|
|
|
|
// * * * java/servlet/ManagerLogin.java
|
|
|
package servlet.manager;
|
|
|
|
|
|
import java.io.IOException;
|
|
|
import java.io.PrintWriter;
|
|
|
import java.sql.SQLException;
|
|
|
import java.util.HashMap;
|
|
|
|
|
|
import javax.servlet.ServletException;
|
|
|
import javax.servlet.annotation.WebServlet;
|
|
|
import javax.servlet.http.HttpServlet;
|
|
|
import javax.servlet.http.HttpServletRequest;
|
|
|
import javax.servlet.http.HttpServletResponse;
|
|
|
import javax.servlet.http.HttpSession;
|
|
|
|
|
|
import javabean.Manager;
|
|
|
import net.sf.json.JSONObject;
|
|
|
|
|
|
/**
|
|
|
* 管理员登录Servlet,处理管理员登录请求
|
|
|
* 映射路径:/managerLogin
|
|
|
* 仅响应POST请求,验证账号密码并返回登录结果
|
|
|
*/
|
|
|
@WebServlet("/managerLogin")
|
|
|
public class ManagerLogin extends HttpServlet {
|
|
|
|
|
|
/**
|
|
|
* 处理GET请求(未使用,返回简单提示)
|
|
|
* @param request HTTP请求对象
|
|
|
* @param response HTTP响应对象
|
|
|
* @throws ServletException Servlet处理异常
|
|
|
* @throws IOException IO异常
|
|
|
*/
|
|
|
protected void doGet(HttpServletRequest request, HttpServletResponse response)
|
|
|
throws ServletException, IOException {
|
|
|
response.getWriter().append("Served at: ").append(request.getContextPath());
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
* 处理POST请求,执行管理员登录验证
|
|
|
* @param request HTTP请求对象(包含user和psw参数)
|
|
|
* @param response HTTP响应对象(返回JSON格式的登录结果)
|
|
|
* @throws ServletException Servlet处理异常
|
|
|
* @throws IOException IO异常
|
|
|
*/
|
|
|
protected void doPost(HttpServletRequest request, HttpServletResponse response)
|
|
|
throws ServletException, IOException {
|
|
|
// 设置响应格式为JSON,字符集UTF-8
|
|
|
response.setContentType("application/json; charset=utf8");
|
|
|
PrintWriter out = response.getWriter();
|
|
|
|
|
|
// 获取客户端提交的账号和密码
|
|
|
String user = request.getParameter("user"); // 管理员账号
|
|
|
String psw = request.getParameter("psw"); // 管理员密码
|
|
|
|
|
|
// 响应数据容器
|
|
|
HashMap<String, Object> hashMap = new HashMap<>();
|
|
|
|
|
|
// 调用业务逻辑层验证登录
|
|
|
Manager manager = new Manager();
|
|
|
String result = null;
|
|
|
try {
|
|
|
result = manager.login(user, psw); // 调用Manager类的登录方法
|
|
|
} catch (ClassNotFoundException | SQLException e) {
|
|
|
e.printStackTrace(); // 打印数据库相关异常堆栈(生产环境建议日志记录)
|
|
|
}
|
|
|
|
|
|
// 根据验证结果生成响应
|
|
|
if (result.equals("1")) { // 登录成功
|
|
|
HttpSession session = request.getSession();
|
|
|
session.setAttribute("manager", user); // 记录登录用户
|
|
|
session.setAttribute("manager_first", "1"); // 标记首次登录状态
|
|
|
hashMap.put("code", 0);
|
|
|
hashMap.put("msg", "登录成功");
|
|
|
// 返回跳转URL(前端根据此字段进行页面跳转)
|
|
|
hashMap.put("url", request.getContextPath() + "/manager/01nav.jsp");
|
|
|
} else { // 登录失败
|
|
|
hashMap.put("code", 1);
|
|
|
hashMap.put("msg", result); // 错误信息直接来自业务层
|
|
|
}
|
|
|
|
|
|
// 将响应数据转换为JSON并输出
|
|
|
JSONObject json = JSONObject.fromObject(hashMap);
|
|
|
out.write(json.toString());
|
|
|
}
|
|
|
}
|
|
|
// * * * java/servlet/Quit.java
|
|
|
package servlet.manager;
|
|
|
import java.io.IOException;
|
|
|
import javax.servlet.ServletException;
|
|
|
import javax.servlet.annotation.WebServlet;
|
|
|
import javax.servlet.http.HttpServlet;
|
|
|
import javax.servlet.http.HttpServletRequest;
|
|
|
import javax.servlet.http.HttpServletResponse;
|
|
|
import javax.servlet.http.HttpSession;
|
|
|
|
|
|
/**
|
|
|
* 管理员退出Servlet,处理管理员注销请求
|
|
|
* 映射路径:/manager/quit
|
|
|
* 仅响应GET请求,销毁用户会话并重定向到登录页面
|
|
|
*/
|
|
|
@WebServlet("/manager/quit")
|
|
|
public class Quit extends HttpServlet {
|
|
|
private static final long serialVersionUID = 1L;
|
|
|
|
|
|
/**
|
|
|
* 处理GET请求,执行管理员退出逻辑
|
|
|
* @param req HTTP请求对象
|
|
|
* @param resp HTTP响应对象
|
|
|
* @throws ServletException Servlet处理异常
|
|
|
* @throws IOException IO异常
|
|
|
*/
|
|
|
@Override
|
|
|
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
|
|
|
// 获取当前会话
|
|
|
HttpSession session = req.getSession();
|
|
|
|
|
|
// 检查会话中是否存在管理员登录标识
|
|
|
if (session.getAttribute("manager") != null) {
|
|
|
// 移除登录状态,终止会话
|
|
|
session.removeAttribute("manager");
|
|
|
}
|
|
|
|
|
|
// 重定向到管理员登录页面
|
|
|
resp.sendRedirect(req.getContextPath() + "/loginManager.html");
|
|
|
}
|
|
|
}
|
|
|
// * * * java/servlet/ReturnTable.java
|
|
|
package servlet.manager;
|
|
|
import java.io.IOException;
|
|
|
import java.io.PrintWriter;
|
|
|
import java.sql.Connection;
|
|
|
import java.sql.PreparedStatement;
|
|
|
import java.sql.ResultSet;
|
|
|
import java.sql.SQLException;
|
|
|
|
|
|
import javax.servlet.ServletException;
|
|
|
import javax.servlet.annotation.WebServlet;
|
|
|
import javax.servlet.http.HttpServlet;
|
|
|
import javax.servlet.http.HttpServletRequest;
|
|
|
import javax.servlet.http.HttpServletResponse;
|
|
|
|
|
|
import javabean.Base;
|
|
|
import net.sf.json.JSONArray;
|
|
|
import net.sf.json.JSONObject;
|
|
|
|
|
|
/**
|
|
|
* 待归还图书管理Servlet,处理分页查询和条件过滤请求
|
|
|
* 映射路径:/manager/returnTable
|
|
|
* 仅响应GET请求,返回未处理的借阅记录列表(JSON格式)
|
|
|
*/
|
|
|
@WebServlet("/manager/returnTable")
|
|
|
public class ReturnTable extends HttpServlet {
|
|
|
|
|
|
/**
|
|
|
* 处理GET请求,执行分页查询并返回JSON数据
|
|
|
* @param req HTTP请求对象(包含分页参数和过滤条件)
|
|
|
* @param resp HTTP响应对象(返回查询结果JSON)
|
|
|
* @throws ServletException Servlet处理异常
|
|
|
* @throws IOException IO异常
|
|
|
*/
|
|
|
@Override
|
|
|
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
|
|
|
// 设置响应格式为JSON,字符集UTF-8
|
|
|
resp.setContentType("application/json; charset=utf8");
|
|
|
|
|
|
// 接收客户端参数
|
|
|
String limit = req.getParameter("limit"); // 每页显示数量
|
|
|
String page = req.getParameter("page"); // 当前页码
|
|
|
String condition = req.getParameter("condition"); // 过滤字段(如card_id)
|
|
|
String conditionValue = req.getParameter("conditionValue"); // 过滤值
|
|
|
|
|
|
// 初始化查询条件
|
|
|
String where = ""; // 无限制条件
|
|
|
if (page == null) page = "1"; // 默认页码1
|
|
|
if (limit == null) limit = "10"; // 默认每页10条
|
|
|
|
|
|
// 数据库操作变量
|
|
|
Connection connection = null;
|
|
|
PreparedStatement pstmt = null; // 数据查询语句
|
|
|
PreparedStatement countPstmt = null; // 总数查询语句
|
|
|
ResultSet resultSet = null;
|
|
|
ResultSet countSet = null;
|
|
|
String sql = "";
|
|
|
String countSql = "";
|
|
|
|
|
|
// 响应数据
|
|
|
int code = 1; // 状态码:1=失败,0=成功
|
|
|
String msg = "无数据"; // 状态描述
|
|
|
int count = 0; // 总记录数
|
|
|
JSONObject jsonData = new JSONObject(); // 单条记录JSON对象
|
|
|
JSONArray jsonArray = new JSONArray(); // 记录列表JSON数组
|
|
|
JSONObject jsonResult = new JSONObject(); // 最终响应JSON
|
|
|
|
|
|
try {
|
|
|
// 获取数据库连接
|
|
|
connection = Base.getConnection();
|
|
|
|
|
|
// 构建基础查询SQL(过滤manager_id为null的记录)
|
|
|
sql = "select * from borrow_books where manager_id is null";
|
|
|
// 拼接条件查询(注意:直接拼接字符串存在SQL注入风险)
|
|
|
if (condition != null && conditionValue != null
|
|
|
&& !condition.equals("") && !conditionValue.equals("")) {
|
|
|
where = " and " + condition + " like '%" + conditionValue + "%' ";
|
|
|
sql += where;
|
|
|
}
|
|
|
// 拼接分页参数(使用预编译占位符)
|
|
|
sql += " limit ?,?";
|
|
|
System.out.println("查询SQL:" + sql); // 调试用,生产环境建议移除
|
|
|
|
|
|
// 执行数据查询
|
|
|
pstmt = connection.prepareStatement(sql);
|
|
|
// 计算分页偏移量:(当前页-1)*每页数量
|
|
|
pstmt.setInt(1, (Integer.parseInt(page) - 1) * Integer.parseInt(limit));
|
|
|
pstmt.setInt(2, Integer.parseInt(limit));
|
|
|
resultSet = pstmt.executeQuery();
|
|
|
|
|
|
// 封装查询结果为JSON
|
|
|
while (resultSet.next()) {
|
|
|
jsonData.put("id", resultSet.getString("id")); // 记录ID
|
|
|
jsonData.put("card_id", resultSet.getString("card_id")); // 读者卡号
|
|
|
jsonData.put("book_id", resultSet.getString("book_id")); // 图书ID
|
|
|
jsonData.put("borrow_date", resultSet.getString("borrow_date")); // 借阅日期
|
|
|
jsonData.put("end_date", resultSet.getString("end_date")); // 应还日期
|
|
|
jsonArray.add(jsonData); // 添加到记录列表
|
|
|
}
|
|
|
|
|
|
// 执行总记录数查询
|
|
|
countSql = "select count(*) as count from borrow_books where manager_id is null" + where;
|
|
|
countPstmt = connection.prepareStatement(countSql);
|
|
|
countSet = countPstmt.executeQuery();
|
|
|
if (countSet.next()) {
|
|
|
count = countSet.getInt("count"); // 获取总记录数
|
|
|
}
|
|
|
|
|
|
// 设置响应状态
|
|
|
if (!jsonArray.isEmpty()) {
|
|
|
code = 0;
|
|
|
msg = "查询成功";
|
|
|
}
|
|
|
|
|
|
} catch (ClassNotFoundException e) {
|
|
|
msg = "数据库驱动未找到";
|
|
|
} catch (SQLException e) {
|
|
|
msg = "SQL执行错误:" + e.getMessage();
|
|
|
} finally {
|
|
|
// 分批次释放资源
|
|
|
try {
|
|
|
Base.closeResource(null, pstmt, resultSet); // 关闭数据查询资源
|
|
|
Base.closeResource(connection, countPstmt, countSet); // 关闭总数查询资源
|
|
|
} catch (SQLException e) {
|
|
|
msg = "资源释放失败";
|
|
|
}
|
|
|
}
|
|
|
|
|
|
// 构建最终响应JSON
|
|
|
jsonResult.put("code", code);
|
|
|
jsonResult.put("count", count);
|
|
|
jsonResult.put("msg", msg);
|
|
|
jsonResult.put("data", jsonArray.toArray()); // 转换为JSON数组
|
|
|
|
|
|
// 输出响应
|
|
|
PrintWriter out = resp.getWriter();
|
|
|
out.print(jsonResult.toString());
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
* 处理POST请求(未使用)
|
|
|
* @param request HTTP请求对象
|
|
|
* @param response HTTP响应对象
|
|
|
* @throws ServletException Servlet处理异常
|
|
|
* @throws IOException IO异常
|
|
|
*/
|
|
|
protected void doPost(HttpServletRequest request, HttpServletResponse response)
|
|
|
throws ServletException, IOException {
|
|
|
// 未实现POST逻辑
|
|
|
}
|
|
|
}
|
|
|
|
|
|
// * * * 前端页面 jsp
|
|
|
|
|
|
// * * * 01nav.jsp
|
|
|
<body class="layui-layout-body">
|
|
|
<!-- 整体布局容器 -->
|
|
|
<div class="layui-layout layui-layout-admin">
|
|
|
|
|
|
<!-- 头部导航区域 -->
|
|
|
<div class="layui-header">
|
|
|
<div class="layui-logo">图书馆管理人员页面</div>
|
|
|
|
|
|
<!-- 左侧导航菜单 -->
|
|
|
<ul class="layui-nav layui-layout-left">
|
|
|
<li class="layui-nav-item">
|
|
|
<a href="javascript:;">其它系统</a>
|
|
|
<dl class="layui-nav-child">
|
|
|
<!-- 跳转到读者系统首页 -->
|
|
|
<dd><a href="../reader/04readerFrame.jsp" target="parent">图书馆首页</a></dd>
|
|
|
<!-- 跳转到系统管理员登录页面 -->
|
|
|
<dd><a href="../adminLogin.html" target="parent">系统管理员</a></dd>
|
|
|
</dl>
|
|
|
</li>
|
|
|
</ul>
|
|
|
|
|
|
<!-- 右侧用户信息和退出 -->
|
|
|
<ul class="layui-nav layui-layout-right">
|
|
|
<li class="layui-nav-item">
|
|
|
<a href="javascript:;">
|
|
|
<!-- 显示当前登录管理员用户名 -->
|
|
|
<%=session.getAttribute("manager") %>
|
|
|
</a>
|
|
|
<dl class="layui-nav-child">
|
|
|
<!-- 跳转到管理员个人资料页面 -->
|
|
|
<dd><a href="09managerSelf.jsp" target="content">基本资料</a></dd>
|
|
|
</dl>
|
|
|
</li>
|
|
|
<!-- 退出系统 -->
|
|
|
<li class="layui-nav-item"><a href="./quit" target="_parent">退出</a></li>
|
|
|
</ul>
|
|
|
</div>
|
|
|
|
|
|
<!-- 左侧功能菜单 -->
|
|
|
<div class="layui-side layui-bg-black">
|
|
|
<div class="layui-side-scroll">
|
|
|
<ul class="layui-nav layui-nav-tree" lay-filter="test">
|
|
|
<!-- 图书管理模块 -->
|
|
|
<li class="layui-nav-item layui-nav-itemed">
|
|
|
<a href="javascript:;">
|
|
|
<i class="layui-icon layui-icon-read" style="font-size: 20px; color: lightblue;"></i>
|
|
|
图书管理
|
|
|
</a>
|
|
|
<dl class="layui-nav-child">
|
|
|
<!-- 借阅图书页面 -->
|
|
|
<dd><a href="02borrow.jsp" target="content">借阅图书</a></dd>
|
|
|
<!-- 归还图书页面 -->
|
|
|
<dd><a href="04judge.jsp;" target="content">归还图书</a></dd>
|
|
|
</dl>
|
|
|
</li>
|
|
|
|
|
|
<!-- 报表管理模块 -->
|
|
|
<li class="layui-nav-item">
|
|
|
<a href="javascript:;">
|
|
|
<i class="layui-icon layui-icon-form" style="font-size: 20px; color: orange;"></i>
|
|
|
报表管理
|
|
|
</a>
|
|
|
<dl class="layui-nav-child">
|
|
|
<!-- 借书报表页面 -->
|
|
|
<dd><a href="06borrowTable.jsp" target="content">借书报表</a></dd>
|
|
|
<!-- 还书报表页面 -->
|
|
|
<dd><a href="07returnTable.jsp" target="content">还书报表</a></dd>
|
|
|
</dl>
|
|
|
</li>
|
|
|
|
|
|
<!-- 公告发布模块 -->
|
|
|
<li class="layui-nav-item">
|
|
|
<a href="08announcement.jsp" target="content">
|
|
|
<i class="layui-icon layui-icon-release" style="font-size: 20px; color: yellow;"></i>
|
|
|
发布公告
|
|
|
</a>
|
|
|
</li>
|
|
|
</ul>
|
|
|
</div>
|
|
|
</div>
|
|
|
|
|
|
<!-- 主体内容区域(通过iframe加载子页面) -->
|
|
|
<div class="layui-body">
|
|
|
<iframe src="02borrow.jsp" name="content" height="100%" width="100%" frameborder="0"></iframe>
|
|
|
</div>
|
|
|
|
|
|
<!-- 底部版权信息 -->
|
|
|
<div class="layui-footer">
|
|
|
© 图书管理系统
|
|
|
</div>
|
|
|
</div>
|
|
|
|
|
|
<!-- 初始化LayUI元素模块 -->
|
|
|
<script>
|
|
|
layui.use('element', function() {
|
|
|
var element = layui.element;
|
|
|
});
|
|
|
</script>
|
|
|
</body>
|
|
|
|
|
|
// * * 02borrow.jsp
|
|
|
<head>
|
|
|
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
|
|
|
<title>借阅图书</title>
|
|
|
<!-- 引入LayUI CSS样式 -->
|
|
|
<link rel="stylesheet" href="../public/layui/css/layui.css" media="all">
|
|
|
<!-- 引入LayUI核心JS库 -->
|
|
|
<script src="../public/layui/layui.js"></script>
|
|
|
<!-- 自定义样式:调整表单标签左边距 -->
|
|
|
<style>
|
|
|
.layui-form-label {
|
|
|
margin-left: 20%;
|
|
|
}
|
|
|
</style>
|
|
|
</head>
|
|
|
<body>
|
|
|
<!-- 页面标题 -->
|
|
|
<div align="center" style="margin-top: 2%;">
|
|
|
<h1>借阅图书</h1>
|
|
|
</div>
|
|
|
|
|
|
<!-- 主表单容器 -->
|
|
|
<div align="center" style="margin-left: 30%; margin-top: 5%; width: 40%;">
|
|
|
<!-- LayUI表单 -->
|
|
|
<form class="layui-form layui-form-pane" action="03borrowSus.jsp">
|
|
|
<!-- 借阅证号输入 -->
|
|
|
<div class="layui-form-item">
|
|
|
<label class="layui-form-label">借阅证号</label>
|
|
|
<div class="layui-input-inline">
|
|
|
<input type="text" name="userid" lay-verify="required"
|
|
|
placeholder="请输入借阅证号" autocomplete="off" class="layui-input">
|
|
|
</div>
|
|
|
</div>
|
|
|
|
|
|
<!-- 图书编号输入 -->
|
|
|
<div class="layui-form-item">
|
|
|
<label class="layui-form-label">图书编号</label>
|
|
|
<div class="layui-input-inline">
|
|
|
<input type="text" name="bookid" lay-verify="required"
|
|
|
placeholder="请输入图书编号" autocomplete="off" class="layui-input">
|
|
|
</div>
|
|
|
</div>
|
|
|
|
|
|
<!-- 借阅日期选择 -->
|
|
|
<div class="layui-form-item">
|
|
|
<label class="layui-form-label">借阅日期</label>
|
|
|
<div class="layui-input-inline">
|
|
|
<input type="text" name="date1" id="date1" autocomplete="off" class="layui-input">
|
|
|
</div>
|
|
|
</div>
|
|
|
|
|
|
<!-- 提交按钮 -->
|
|
|
<div class="layui-form-item" align="center">
|
|
|
<button class="layui-btn" lay-submit lay-filter="demo2">借阅</button>
|
|
|
</div>
|
|
|
</form>
|
|
|
|
|
|
<!-- LayUI初始化脚本 -->
|
|
|
<script>
|
|
|
layui.use(['form', 'laydate'], function() {
|
|
|
var form = layui.form,
|
|
|
laydate = layui.laydate;
|
|
|
|
|
|
// 初始化日期选择器(借阅日期)
|
|
|
laydate.render({
|
|
|
elem: '#date1', // 绑定输入框ID
|
|
|
type: 'datetime', // 日期时间模式
|
|
|
format: 'yyyy-M-d H:m:s',// 日期格式
|
|
|
value: new Date() // 默认值为当前时间
|
|
|
});
|
|
|
|
|
|
// 监听表单提交
|
|
|
form.on('submit(demo2)', function(data) {
|
|
|
// 实际项目中应移除alert,改为异步提交
|
|
|
layer.alert(JSON.stringify(data.field), { title: '提交数据' });
|
|
|
return false; // 阻止表单自动提交
|
|
|
});
|
|
|
});
|
|
|
</script>
|
|
|
</div>
|
|
|
</body>
|
|
|
|
|
|
// * * * 03borrowSus.jsp
|
|
|
<head>
|
|
|
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
|
|
|
<title>借阅图书处理</title>
|
|
|
</head>
|
|
|
<body>
|
|
|
<!-- 使用JDBCBean处理数据库操作 -->
|
|
|
<jsp:useBean id="borrow" scope="session" class="javabean.JDBCBean"></jsp:useBean>
|
|
|
<%
|
|
|
// 获取表单提交参数
|
|
|
String user = request.getParameter("userid"); // 借阅证号
|
|
|
String book = request.getParameter("bookid"); // 图书编号
|
|
|
String date1 = request.getParameter("date1"); // 借阅日期
|
|
|
|
|
|
// 查询借阅证信息
|
|
|
String sql1 = "select * from borrow_card where ID =" + user;
|
|
|
ResultSet rs1 = borrow.executeQuery(sql1);
|
|
|
|
|
|
// 管理员登录验证
|
|
|
if (session.getAttribute("manager") != null) {
|
|
|
if (rs1.next()) {
|
|
|
// 获取借阅证状态和规则ID
|
|
|
String rule = rs1.getString("rule_id");
|
|
|
int cardstatus = Integer.parseInt(rs1.getString("STATUS"));
|
|
|
|
|
|
// 查询借阅规则
|
|
|
String sql4 = "select * from rules where id = " + rule;
|
|
|
ResultSet rs4 = borrow.executeQuery(sql4);
|
|
|
int n = 0; // 借阅天数
|
|
|
String library = ""; // 可借阅图书馆
|
|
|
String[] libraryArray = {};
|
|
|
int num = 0; // 最大借阅数量
|
|
|
|
|
|
while (rs4.next()) {
|
|
|
n = rs4.getInt("limit_day");
|
|
|
library = rs4.getString("borrow_library");
|
|
|
libraryArray = library.split("、");
|
|
|
num = rs4.getInt("borrow_num");
|
|
|
}
|
|
|
|
|
|
// 计算应还日期
|
|
|
EndTime endtime = new EndTime();
|
|
|
String end = endtime.show(n);
|
|
|
|
|
|
// 借阅证状态检查
|
|
|
if (cardstatus != 0) {
|
|
|
// 查询图书信息
|
|
|
String sql2 = "select * from books where ID =" + book;
|
|
|
ResultSet rs2 = borrow.executeQuery(sql2);
|
|
|
|
|
|
if (rs2.next()) {
|
|
|
int status = Integer.parseInt(rs2.getString("STATUS")); // 图书状态
|
|
|
String lib = Integer.toString(rs2.getInt("library_id")); // 图书所在图书馆
|
|
|
|
|
|
// 检查图书是否在可借阅图书馆列表
|
|
|
boolean validLibrary = false;
|
|
|
for (int z = 0; z < libraryArray.length; z++) {
|
|
|
if (libraryArray[z].equals(lib)) {
|
|
|
validLibrary = true;
|
|
|
|
|
|
// 查询当前用户未处理的借阅数量
|
|
|
String countSql = "select count(*) as count from borrow_books where manager_id is null and card_id =" + user;
|
|
|
ResultSet rsSql = borrow.executeQuery(countSql);
|
|
|
int count = 0;
|
|
|
while (rsSql.next()) {
|
|
|
count = rsSql.getInt("count");
|
|
|
}
|
|
|
|
|
|
// 检查借阅数量限制
|
|
|
if (count < num) {
|
|
|
if (status == 1) { // 图书可用
|
|
|
// 执行借阅操作
|
|
|
String sql = "insert borrow_books(CARD_ID,BOOK_ID,BORROW_DATE,END_DATE) values('" + user + "','" + book + "','" + date1 + "','" + end + "')";
|
|
|
try {
|
|
|
int i = borrow.executeUpdate(sql);
|
|
|
if (i == 1) {
|
|
|
// 更新图书状态为已借出
|
|
|
borrow.executeUpdate("update books set STATUS=0 where ID=" + book);
|
|
|
%>
|
|
|
<script>
|
|
|
alert('借阅成功!');
|
|
|
window.location.href = "02borrow.jsp";
|
|
|
</script>
|
|
|
<%
|
|
|
} else {
|
|
|
%>
|
|
|
<script>
|
|
|
alert('借阅未成功!');
|
|
|
window.location.href = "02borrow.jsp";
|
|
|
</script>
|
|
|
<%
|
|
|
}
|
|
|
} catch (Exception e) {
|
|
|
%>
|
|
|
<script>
|
|
|
alert('借阅未成功!');
|
|
|
window.location.href = "02borrow.jsp";
|
|
|
</script>
|
|
|
<%
|
|
|
}
|
|
|
} else {
|
|
|
%>
|
|
|
<script>
|
|
|
alert('该图书已借出!');
|
|
|
window.location.href = "02borrow.jsp";
|
|
|
</script>
|
|
|
<%
|
|
|
}
|
|
|
} else {
|
|
|
%>
|
|
|
<script>
|
|
|
alert('该用户已达到可借阅数量!若需还书,请先归还!');
|
|
|
window.location.href = "02borrow.jsp";
|
|
|
</script>
|
|
|
<%
|
|
|
}
|
|
|
break;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
// 图书馆权限检查失败
|
|
|
if (!validLibrary) {
|
|
|
%>
|
|
|
<script>
|
|
|
alert('该图书未在可借阅的图书馆内!');
|
|
|
window.location.href = "02borrow.jsp";
|
|
|
</script>
|
|
|
<%
|
|
|
}
|
|
|
} else {
|
|
|
%>
|
|
|
<script>
|
|
|
alert('该图书不存在!');
|
|
|
window.location.href = "02borrow.jsp";
|
|
|
</script>
|
|
|
<%
|
|
|
}
|
|
|
} else {
|
|
|
%>
|
|
|
<script>
|
|
|
alert('借阅证已挂失!');
|
|
|
window.location.href = "02borrow.jsp";
|
|
|
</script>
|
|
|
<%
|
|
|
}
|
|
|
} else {
|
|
|
%>
|
|
|
<script>
|
|
|
alert('用户不存在!');
|
|
|
window.location.href = "02borrow.jsp";
|
|
|
</script>
|
|
|
<%
|
|
|
}
|
|
|
} else {
|
|
|
%>
|
|
|
<script>
|
|
|
alert('请先登录!');
|
|
|
window.parent.location.href = "../loginManager.html";
|
|
|
</script>
|
|
|
<%
|
|
|
}
|
|
|
%>
|
|
|
</body>
|
|
|
// * * * 04judge.jsp
|
|
|
<head>
|
|
|
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
|
|
|
<title>查询图书是否逾期</title>
|
|
|
<!-- 引入LayUI CSS样式 -->
|
|
|
<link rel="stylesheet" href="../public/layui/css/layui.css" media="all">
|
|
|
<!-- 引入LayUI核心JS库 -->
|
|
|
<script src="../public/layui/layui.js"></script>
|
|
|
<!-- 自定义样式:调整表单标签左边距 -->
|
|
|
<style>
|
|
|
.layui-form-label {
|
|
|
margin-left: 20%;
|
|
|
}
|
|
|
</style>
|
|
|
</head>
|
|
|
<body>
|
|
|
<!-- 页面标题 -->
|
|
|
<div align="center" style="margin-top: 2%;">
|
|
|
<h1>查询图书是否逾期</h1>
|
|
|
</div>
|
|
|
|
|
|
<!-- 主表单容器 -->
|
|
|
<div align="center" style="margin-left: 30%; margin-top: 5%; width: 40%;">
|
|
|
<!-- LayUI表单 -->
|
|
|
<form class="layui-form layui-form-pane" action="04judgeSus.jsp">
|
|
|
<!-- 图书编号输入 -->
|
|
|
<div class="layui-form-item">
|
|
|
<label class="layui-form-label">图书编号</label>
|
|
|
<div class="layui-input-inline">
|
|
|
<input type="text" name="bookid" lay-verify="required"
|
|
|
placeholder="请输入图书编号" autocomplete="off" class="layui-input">
|
|
|
</div>
|
|
|
</div>
|
|
|
|
|
|
<!-- 查询按钮 -->
|
|
|
<div class="layui-form-item" align="center">
|
|
|
<button class="layui-btn layui-btn-warm" lay-submit lay-filter="demo2">查询</button>
|
|
|
</div>
|
|
|
</form>
|
|
|
|
|
|
<!-- LayUI初始化脚本 -->
|
|
|
<script>
|
|
|
layui.use(['form', 'laydate'], function() {
|
|
|
var form = layui.form,
|
|
|
laydate = layui.laydate;
|
|
|
|
|
|
// 初始化日期选择器(未绑定到表单字段,可能为残留代码)
|
|
|
laydate.render({
|
|
|
elem: '#date1', // 页面中不存在该ID的输入框
|
|
|
type: 'datetime', // 日期时间模式
|
|
|
format: 'yyyy-M-d H:m:s',// 日期格式
|
|
|
min: 0, // 最小时间(当前时间)
|
|
|
max: 0, // 最大时间(当前时间)
|
|
|
value: new Date() // 默认值为当前时间
|
|
|
});
|
|
|
|
|
|
// 监听表单提交
|
|
|
form.on('submit(demo2)', function(data) {
|
|
|
// 实际项目中应使用异步提交(如AJAX)
|
|
|
layer.alert(JSON.stringify(data.field), { title: '提交数据' });
|
|
|
return false; // 阻止表单自动提交
|
|
|
});
|
|
|
});
|
|
|
</script>
|
|
|
</div>
|
|
|
</body>
|
|
|
|
|
|
// * * * 04judgeSus.jsp
|
|
|
<head>
|
|
|
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
|
|
|
<title>图书逾期查询处理</title>
|
|
|
</head>
|
|
|
<body>
|
|
|
<!-- 使用JDBCBean进行数据库操作-->
|
|
|
<jsp:useBean id="judge" scope="session" class="javabean.JDBCBean"></jsp:useBean>
|
|
|
<%
|
|
|
// 获取表单提交的图书编号
|
|
|
String book = request.getParameter("bookid");
|
|
|
session.setAttribute("book", book); // 将会话保存到session
|
|
|
|
|
|
// 管理员登录验证
|
|
|
if (session.getAttribute("manager") != null) {
|
|
|
DateTime date = new DateTime();
|
|
|
String now = date.show(); // 获取当前时间
|
|
|
String bookid = request.getParameter("bookid");
|
|
|
|
|
|
// 查询该图书的借阅记录
|
|
|
String sql = "select * from borrow_books where book_id = " + bookid;
|
|
|
ResultSet rs = judge.executeQuery(sql);
|
|
|
String end = ""; // 应还日期
|
|
|
String ret = ""; // 归还日期
|
|
|
String card = ""; // 借阅证号
|
|
|
|
|
|
while (rs.next()) {
|
|
|
end = rs.getString("end_date");
|
|
|
ret = rs.getString("return_date");
|
|
|
card = rs.getString("card_id");
|
|
|
}
|
|
|
|
|
|
if (ret == null) { // 图书未归还
|
|
|
// 计算逾期天数(now与end的时间差)
|
|
|
long n = CompareDate.show(now, end);
|
|
|
session.setAttribute("days", n); // 保存逾期天数
|
|
|
|
|
|
// 查询借阅证规则
|
|
|
String sql1 = "select * from borrow_card where id = " + card;
|
|
|
ResultSet rs1 = judge.executeQuery(sql1);
|
|
|
String rule = "";
|
|
|
while (rs1.next()) {
|
|
|
rule = rs1.getString("rule_id");
|
|
|
}
|
|
|
|
|
|
// 查询逾期费用规则
|
|
|
String sql2 = "select * from rules where id = " + rule;
|
|
|
ResultSet rs2 = judge.executeQuery(sql2);
|
|
|
String fee = "";
|
|
|
while (rs2.next()) {
|
|
|
fee = rs2.getString("overtime_fee");
|
|
|
}
|
|
|
session.setAttribute("fee", fee); // 保存逾期费用
|
|
|
|
|
|
// 跳转到图书归还页面
|
|
|
%>
|
|
|
<script>
|
|
|
window.location.href = "04return.jsp";
|
|
|
</script>
|
|
|
<%
|
|
|
} else { // 图书已归还
|
|
|
%>
|
|
|
<script>
|
|
|
alert("该书未借出或不存在!");
|
|
|
window.location.href = "04judge.jsp";
|
|
|
</script>
|
|
|
<%
|
|
|
}
|
|
|
} else { // 未登录处理
|
|
|
%>
|
|
|
<script>
|
|
|
alert('请先登录!');
|
|
|
window.parent.location.href = "../loginManager.html";
|
|
|
</script>
|
|
|
<%
|
|
|
}
|
|
|
%>
|
|
|
</body>
|
|
|
// * * * 04return.jsp
|
|
|
<head>
|
|
|
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
|
|
|
<title>归还图书</title>
|
|
|
<!-- 引入LayUI框架 -->
|
|
|
<link rel="stylesheet" href="../public/layui/css/layui.css" media="all">
|
|
|
<script src="../public/layui/layui.js"></script>
|
|
|
<!-- 自定义样式:调整表单标签左边距 -->
|
|
|
<style>
|
|
|
.layui-form-label {
|
|
|
margin-left: 20%;
|
|
|
}
|
|
|
</style>
|
|
|
</head>
|
|
|
<body>
|
|
|
<!-- 使用JDBCBean进行数据库操作 -->
|
|
|
<jsp:useBean id="judge" scope="session" class="javabean.JDBCBean"></jsp:useBean>
|
|
|
|
|
|
<!-- 页面标题 -->
|
|
|
<div align="center" style="margin-top: 2%;">
|
|
|
<h1>归还图书</h1>
|
|
|
</div>
|
|
|
|
|
|
<!-- 主表单容器 -->
|
|
|
<div align="center" style="margin-left: 30%; margin-top: 5%; width: 40%;">
|
|
|
<%
|
|
|
// 从会话中获取逾期天数、罚款金额和图书编号
|
|
|
Object days = session.getAttribute("days");
|
|
|
Object fee = session.getAttribute("fee");
|
|
|
String book = session.getAttribute("book").toString();
|
|
|
|
|
|
// 初始化提示信息
|
|
|
String mes = "";
|
|
|
String mes2 = "";
|
|
|
float sum = 0;
|
|
|
|
|
|
// 根据逾期天数计算罚款
|
|
|
if (days != null && fee != null) {
|
|
|
int d = Integer.parseInt(days.toString());
|
|
|
float f = Float.parseFloat(fee.toString());
|
|
|
if (d < 0) {
|
|
|
mes = "已逾期 " + (-d) + " 天";
|
|
|
sum = d * f * (-1); // 计算罚款总额
|
|
|
mes2 = "罚款金额:¥" + sum;
|
|
|
} else {
|
|
|
mes = "还剩 " + d + " 天";
|
|
|
}
|
|
|
// 将提示信息保存到会话中
|
|
|
session.setAttribute("mes", mes);
|
|
|
session.setAttribute("mes2", mes2);
|
|
|
}
|
|
|
%>
|
|
|
|
|
|
<!-- 表单 -->
|
|
|
<form class="layui-form layui-form-pane" action="05returnSus.jsp">
|
|
|
<!-- 逾期信息展示 -->
|
|
|
<div>
|
|
|
<blockquote class="layui-elem-quote layui-quote-nm">
|
|
|
<%= session.getAttribute("mes") %>
|
|
|
<br>
|
|
|
<%= session.getAttribute("mes2") %>
|
|
|
</blockquote>
|
|
|
</div>
|
|
|
|
|
|
<!-- 图书编号输入 -->
|
|
|
<div class="layui-form-item">
|
|
|
<label class="layui-form-label">图书编号</label>
|
|
|
<div class="layui-input-inline">
|
|
|
<input type="text" name="bookid" lay-verify="required"
|
|
|
value="<%= session.getAttribute("book") %>"
|
|
|
autocomplete="off" class="layui-input">
|
|
|
</div>
|
|
|
</div>
|
|
|
|
|
|
<!-- 截止日期显示 -->
|
|
|
<%
|
|
|
// 查询该图书的借阅记录(未归还)
|
|
|
String sql2 = "select * from borrow_books where return_date is null and book_id = " + book;
|
|
|
ResultSet rs2 = judge.executeQuery(sql2);
|
|
|
String endDate = "";
|
|
|
while (rs2.next()) {
|
|
|
endDate = rs2.getString("end_date");
|
|
|
%>
|
|
|
<div class="layui-form-item">
|
|
|
<label class="layui-form-label">截止日期</label>
|
|
|
<div class="layui-input-inline">
|
|
|
<input type="text" name="end" autocomplete="off"
|
|
|
class="layui-input" value="<%= endDate %>">
|
|
|
</div>
|
|
|
</div>
|
|
|
<% } %>
|
|
|
|
|
|
<!-- 归还日期选择 -->
|
|
|
<div class="layui-form-item">
|
|
|
<label class="layui-form-label">归还日期</label>
|
|
|
<div class="layui-input-inline">
|
|
|
<input type="text" name="date1" id="date1" autocomplete="off"
|
|
|
class="layui-input">
|
|
|
</div>
|
|
|
</div>
|
|
|
|
|
|
<!-- 违规信息输入 -->
|
|
|
<div class="layui-form-item">
|
|
|
<label class="layui-form-label">违规信息</label>
|
|
|
<div class="layui-input-inline">
|
|
|
<input type="text" name="ill"
|
|
|
placeholder="若无违规信息,则不填"
|
|
|
autocomplete="off" class="layui-input">
|
|
|
</div>
|
|
|
</div>
|
|
|
|
|
|
<!-- 管理员编号(自动填充,只读) -->
|
|
|
<div class="layui-form-item">
|
|
|
<label class="layui-form-label">管理员编号</label>
|
|
|
<div class="layui-input-inline">
|
|
|
<input type="text" name="managerid" readonly="readonly"
|
|
|
class="layui-input" value="<%= session.getAttribute("manager") %>">
|
|
|
</div>
|
|
|
</div>
|
|
|
|
|
|
<!-- 提交按钮 -->
|
|
|
<div class="layui-form-item" align="center">
|
|
|
<button class="layui-btn layui-btn-warm" lay-submit lay-filter="demo2">
|
|
|
归还
|
|
|
</button>
|
|
|
</div>
|
|
|
</form>
|
|
|
|
|
|
<!-- LayUI初始化脚本 -->
|
|
|
<script>
|
|
|
layui.use(['form', 'laydate'], function() {
|
|
|
var form = layui.form,
|
|
|
laydate = layui.laydate;
|
|
|
|
|
|
// 初始化日期选择器(仅当前时间可选)
|
|
|
laydate.render({
|
|
|
elem: '#date1',
|
|
|
type: 'datetime',
|
|
|
format: 'yyyy-MM-dd H:m:s',
|
|
|
min: 0,
|
|
|
max: 0,
|
|
|
value: new Date()
|
|
|
});
|
|
|
|
|
|
// 监听表单提交
|
|
|
form.on('submit(demo2)', function(data) {
|
|
|
// 实际项目中应使用异步提交(如AJAX)
|
|
|
layer.alert(JSON.stringify(data.field), { title: '提交数据' });
|
|
|
return false; // 阻止表单自动提交
|
|
|
});
|
|
|
});
|
|
|
</script>
|
|
|
</div>
|
|
|
</body>
|
|
|
// * * * 05returnSus.jsp
|
|
|
<head>
|
|
|
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
|
|
|
<title>图书归还处理</title>
|
|
|
</head>
|
|
|
<body>
|
|
|
<!-- 使用JDBCBean处理数据库操作 -->
|
|
|
<jsp:useBean id="ret" scope="session" class="javabean.JDBCBean"></jsp:useBean>
|
|
|
|
|
|
<%
|
|
|
// 获取表单提交参数
|
|
|
String book = request.getParameter("bookid"); // 图书编号
|
|
|
String date1 = request.getParameter("date1"); // 归还日期
|
|
|
String ill = request.getParameter("ill"); // 违规信息(可选)
|
|
|
String managerid = request.getParameter("managerid"); // 管理员编号
|
|
|
|
|
|
// 管理员登录验证
|
|
|
if (session.getAttribute("manager") != null) {
|
|
|
try {
|
|
|
// 查询图书当前状态
|
|
|
String sql2 = "select * from books where ID = " + book;
|
|
|
ResultSet rs2 = ret.executeQuery(sql2);
|
|
|
|
|
|
if (rs2.next()) {
|
|
|
int status = Integer.parseInt(rs2.getString("STATUS"));
|
|
|
|
|
|
// 图书状态检查(0表示已借出,1表示可借阅)
|
|
|
if (status == 0) {
|
|
|
// 更新借阅记录:设置归还日期、违规信息和处理管理员
|
|
|
String sql = "update borrow_books " +
|
|
|
"set RETURN_DATE = ?, ILLEGAL = ?, MANAGER_ID = ? " +
|
|
|
"where manager_id is null and BOOK_ID = ?";
|
|
|
|
|
|
// 执行更新操作
|
|
|
int i = ret.executeUpdate(sql, new Object[]{date1, ill, managerid, book});
|
|
|
|
|
|
// 更新图书状态为可借阅
|
|
|
ret.executeUpdate("update books set STATUS = 1 where ID = ?", new Object[]{book});
|
|
|
|
|
|
%>
|
|
|
<script>
|
|
|
alert('归还成功!');
|
|
|
window.location.href = "04judge.jsp";
|
|
|
</script>
|
|
|
<%
|
|
|
} else {
|
|
|
%>
|
|
|
<script>
|
|
|
alert('该图书未借出!');
|
|
|
window.location.href = "04judge.jsp";
|
|
|
</script>
|
|
|
<%
|
|
|
}
|
|
|
}
|
|
|
} catch (SQLException e) {
|
|
|
e.printStackTrace();
|
|
|
%>
|
|
|
<script>
|
|
|
alert('归还未成功!');
|
|
|
window.location.href = "04judge.jsp";
|
|
|
</script>
|
|
|
<%
|
|
|
}
|
|
|
} else {
|
|
|
%>
|
|
|
<script>
|
|
|
alert('请先登录!');
|
|
|
window.parent.location.href = "../loginManager.html";
|
|
|
</script>
|
|
|
<%
|
|
|
}
|
|
|
%>
|
|
|
</body>
|
|
|
//* * * 06borrwoTable.jsp
|
|
|
|
|
|
<head>
|
|
|
<meta charset="UTF-8">
|
|
|
<title>借阅记录</title>
|
|
|
<!-- 引入LayUI CSS样式 -->
|
|
|
<link rel="stylesheet" href="../public/layui/css/layui.css" media="all">
|
|
|
<!-- 自定义样式:调整表格边距 -->
|
|
|
<style>
|
|
|
.layui-table, .layui-table-view {
|
|
|
margin: 0 0px;
|
|
|
}
|
|
|
</style>
|
|
|
</head>
|
|
|
<body>
|
|
|
<!-- 引入LayUI核心JS库 -->
|
|
|
<script src="../public/layui/layui.js" charset="utf-8"></script>
|
|
|
|
|
|
<!-- 表格容器(初始隐藏) -->
|
|
|
<table class="layui-hide" id="cardTable" lay-filter="formFilter"></table>
|
|
|
|
|
|
<!-- 头部工具栏模板 -->
|
|
|
<script type="text/html" id="headBar">
|
|
|
条件搜索:
|
|
|
<div class="layui-inline">
|
|
|
<!-- 搜索条件下拉菜单 -->
|
|
|
<select id="condition" name="condition" lay-verify="required">
|
|
|
<option value=""></option>
|
|
|
<option value="card_id">借阅证号</option>
|
|
|
<option value="book_id">图书编号</option>
|
|
|
<option value ="borrow_date">借阅日期</option>
|
|
|
<option value="end_date">截止日期</option>
|
|
|
<option value="return_date">归还日期</option>
|
|
|
<option value="illegal">违章信息</option>
|
|
|
<option value="manager_id">处理人</option>
|
|
|
</select>
|
|
|
</div>
|
|
|
<div class="layui-inline">
|
|
|
<!-- 搜索值输入框 -->
|
|
|
<input class="layui-input" id="conditionValue" name="conditionValue" autocomplete="off">
|
|
|
</div>
|
|
|
<!-- 搜索按钮 -->
|
|
|
<button class="layui-btn" name="condition" data-type="reload" lay-event="search">搜索</button>
|
|
|
</script>
|
|
|
|
|
|
<script>
|
|
|
layui.use(['table', 'jquery'], function() {
|
|
|
var $ = layui.jquery;
|
|
|
var table = layui.table;
|
|
|
|
|
|
// 初始化表格渲染
|
|
|
var tableIns = table.render({
|
|
|
elem: '#cardTable', // 绑定表格容器ID
|
|
|
url: './borrowTable', // 数据接口(Servlet路径)
|
|
|
toolbar: '#headBar', // 绑定头部工具栏模板
|
|
|
cols: [[ // 表格列配置
|
|
|
{field: 'card_id', width: 180, title: '借阅证号', sort: true},
|
|
|
{field: 'book_id', width: 130, title: '图书编号', sort: true},
|
|
|
{field: 'borrow_date', width: 250, title: '借阅日期', sort: true},
|
|
|
{field: 'end_date', title: '截止日期', width: 250, sort: true},
|
|
|
{field: 'return_date', width: 250, title: '归还时间', sort: true},
|
|
|
{field: 'illegal', width: 180, title: '违章信息', sort: true, style: 'color: red;'},
|
|
|
{field: 'manager_id', minWidth: 80, title: '处理人'}
|
|
|
]],
|
|
|
page: true // 启用分页
|
|
|
});
|
|
|
|
|
|
// 头部工具栏事件处理
|
|
|
table.on('toolbar(formFilter)', function(obj) {
|
|
|
var checkStatus = table.checkStatus(obj.config.id);
|
|
|
switch (obj.event) {
|
|
|
case 'search':
|
|
|
// 获取搜索条件和值
|
|
|
var conditionValue = $('#conditionValue');
|
|
|
var condition = $('#condition');
|
|
|
// 重新加载表格数据
|
|
|
tableIns.reload({
|
|
|
where: {
|
|
|
"condition": condition.val(), // 过滤字段
|
|
|
"conditionValue": conditionValue.val() // 过滤值
|
|
|
},
|
|
|
page: {
|
|
|
curr: 1 // 重置为第一页
|
|
|
}
|
|
|
});
|
|
|
break;
|
|
|
case 'add':
|
|
|
// 打开添加借阅证弹窗(未实现)
|
|
|
var addCardLayer = layer.open({
|
|
|
type: 2,
|
|
|
title: '添加借书证',
|
|
|
area: ['800px', '500px'],
|
|
|
maxmin: true,
|
|
|
shadeClose: true,
|
|
|
content: 'cardadd.jsp'
|
|
|
});
|
|
|
break;
|
|
|
}
|
|
|
});
|
|
|
|
|
|
// 侧边工具栏事件处理(未实现)
|
|
|
table.on('tool(formFilter)', function(obj) {
|
|
|
var data = obj.data;
|
|
|
var layEvent = obj.event;
|
|
|
var tr = obj.tr;
|
|
|
switch (obj.event) {
|
|
|
case 'edit':
|
|
|
// 打开编辑弹窗(未实现)
|
|
|
layer.open({
|
|
|
type: 2,
|
|
|
title: '更改信息',
|
|
|
area: ['800px', '600px'],
|
|
|
maxmin: true,
|
|
|
shadeClose: true,
|
|
|
content: ''
|
|
|
});
|
|
|
break;
|
|
|
}
|
|
|
});
|
|
|
});
|
|
|
</script>
|
|
|
</body>
|
|
|
//* * * 07returnTable.jsp
|
|
|
<head>
|
|
|
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
|
|
|
<title>待归还图书列表</title>
|
|
|
<!-- 引入LayUI框架样式 -->
|
|
|
<link rel="stylesheet" href="../public/layui/css/layui.css" media="all">
|
|
|
<!-- 引入LayUI核心JS库 -->
|
|
|
<script src="../public/layui/layui.js" charset="utf-8"></script>
|
|
|
<!-- 自定义样式:调整表格边距 -->
|
|
|
<style>
|
|
|
.layui-table, .layui-table-view {
|
|
|
margin: 0 0px;
|
|
|
}
|
|
|
</style>
|
|
|
</head>
|
|
|
<body>
|
|
|
<!-- 表格容器(初始隐藏,通过LayUI动态渲染) -->
|
|
|
<table class="layui-hide" id="cardTable" lay-filter="formFilter"></table>
|
|
|
|
|
|
<!-- 头部工具栏模板 -->
|
|
|
<script type="text/html" id="headBar">
|
|
|
条件搜索:
|
|
|
<div class="layui-inline">
|
|
|
<!-- 搜索条件下拉菜单 -->
|
|
|
<select id="condition" name="condition" lay-verify="required">
|
|
|
<option value=""></option>
|
|
|
<option value="card_id">借阅证号</option>
|
|
|
<option value="book_id">图书编号</option>
|
|
|
<option value="borrow_date">借阅日期</option>
|
|
|
<option value="end_date">截止日期</option>
|
|
|
</select>
|
|
|
</div>
|
|
|
<div class="layui-inline">
|
|
|
<!-- 搜索值输入框 -->
|
|
|
<input class="layui-input" id="conditionValue" name="conditionValue" autocomplete="off">
|
|
|
</div>
|
|
|
<!-- 搜索按钮 -->
|
|
|
<button class="layui-btn" name="condition" data-type="reload" lay-event="search">搜索</button>
|
|
|
</script>
|
|
|
|
|
|
<script>
|
|
|
layui.use(['table', 'jquery'], function() {
|
|
|
var $ = layui.jquery;
|
|
|
var table = layui.table;
|
|
|
|
|
|
// 初始化表格渲染
|
|
|
var tableIns = table.render({
|
|
|
elem: '#cardTable', // 绑定表格容器ID
|
|
|
url: './returnTable', // 数据接口(Servlet路径)
|
|
|
toolbar: '#headBar', // 绑定头部工具栏模板
|
|
|
cols: [[ // 表格列配置
|
|
|
{field: 'card_id', width: 180, title: '借阅证号', sort: true},
|
|
|
{field: 'book_id', width: 130, title: '图书编号', sort: true},
|
|
|
{field: 'borrow_date', width: 250, title: '借阅日期', sort: true},
|
|
|
{field: 'end_date', title: '截止日期', width: 250, sort: true}
|
|
|
]],
|
|
|
page: true // 启用分页
|
|
|
});
|
|
|
|
|
|
// 头部工具栏事件处理
|
|
|
table.on('toolbar(formFilter)', function(obj) {
|
|
|
var checkStatus = table.checkStatus(obj.config.id);
|
|
|
switch (obj.event) {
|
|
|
case 'search':
|
|
|
// 获取搜索条件和值
|
|
|
var conditionValue = $('#conditionValue');
|
|
|
var condition = $('#condition');
|
|
|
// 重新加载表格数据
|
|
|
tableIns.reload({
|
|
|
where: {
|
|
|
"condition": condition.val(), // 过滤字段
|
|
|
"conditionValue": conditionValue.val() // 过滤值
|
|
|
},
|
|
|
page: {
|
|
|
curr: 1 // 重置为第一页
|
|
|
}
|
|
|
});
|
|
|
break;
|
|
|
case 'add':
|
|
|
// 打开添加借阅证弹窗(未实现)
|
|
|
var addCardLayer = layer.open({
|
|
|
type: 2,
|
|
|
title: '添加借书证',
|
|
|
area: ['800px', '500px'],
|
|
|
maxmin: true,
|
|
|
shadeClose: true,
|
|
|
content: 'cardadd.jsp'
|
|
|
});
|
|
|
break;
|
|
|
}
|
|
|
});
|
|
|
|
|
|
// 侧边工具栏事件处理(未实现)
|
|
|
table.on('tool(formFilter)', function(obj) {
|
|
|
var data = obj.data;
|
|
|
var layEvent = obj.event;
|
|
|
var tr = obj.tr;
|
|
|
switch (obj.event) {
|
|
|
case 'edit':
|
|
|
// 打开编辑弹窗(未实现)
|
|
|
layer.open({
|
|
|
type: 2,
|
|
|
title: '更改信息',
|
|
|
area: ['800px', '600px'],
|
|
|
maxmin: true,
|
|
|
shadeClose: true,
|
|
|
content: ''
|
|
|
});
|
|
|
break;
|
|
|
}
|
|
|
});
|
|
|
});
|
|
|
</script>
|
|
|
</body>
|
|
|
//* * * 08add.jsp
|
|
|
<head>
|
|
|
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
|
|
|
<title>发布公告</title>
|
|
|
<!-- 引入LayUI CSS样式 -->
|
|
|
<link rel="stylesheet" href="../public/layui/css/layui.css">
|
|
|
<!-- 引入LayUI核心JS库 -->
|
|
|
<script src="../public/layui/layui.js"></script>
|
|
|
</head>
|
|
|
<body>
|
|
|
<!-- 公告发布表单 -->
|
|
|
<form class="layui-form layui-form-pane" action="" lay-filter="formFilter">
|
|
|
<!-- 标题输入 -->
|
|
|
<div class="layui-form-item">
|
|
|
<label class="layui-form-label">标题</label>
|
|
|
<div class="layui-input-block">
|
|
|
<input type="text" name="title"
|
|
|
lay-verify="required" <!-- 启用LayUI必填验证 -->
|
|
|
required <!-- 浏览器原生必填验证 -->
|
|
|
autocomplete="off"
|
|
|
placeholder="请输入标题"
|
|
|
class="layui-input">
|
|
|
</div>
|
|
|
</div>
|
|
|
|
|
|
<!-- 公告内容输入 -->
|
|
|
<div class="layui-form-item" style="height:50%;">
|
|
|
<label class="layui-form-label">公告</label>
|
|
|
<div class="layui-input-block">
|
|
|
<textarea name="detail"
|
|
|
lay-verify="required"
|
|
|
placeholder="请输入公告"
|
|
|
autocomplete="off"
|
|
|
class="layui-input"
|
|
|
style="height:300px;"></textarea>
|
|
|
</div>
|
|
|
</div>
|
|
|
|
|
|
<!-- 提交按钮 -->
|
|
|
<div class="layui-form-item">
|
|
|
<div class="layui-input-block">
|
|
|
<button type="submit"
|
|
|
class="layui-btn"
|
|
|
lay-submit=""
|
|
|
lay-filter="submitButton">
|
|
|
<i class="layui-icon layui-icon-release"
|
|
|
style="font-size: 20px; color: yellow;"></i>
|
|
|
发布
|
|
|
</button>
|
|
|
</div>
|
|
|
</div>
|
|
|
</form>
|
|
|
|
|
|
<script>
|
|
|
layui.use(['form', 'jquery'], function() {
|
|
|
var $ = layui.jquery;
|
|
|
var form = layui.form;
|
|
|
var layer = layui.layer;
|
|
|
|
|
|
// 监听表单提交
|
|
|
form.on('submit(submitButton)', function(data) {
|
|
|
// 使用AJAX异步提交表单数据
|
|
|
$.ajax({
|
|
|
url: './announcementAdd', // 后端Servlet路径
|
|
|
method: 'post', // 请求方法
|
|
|
data: data.field, // 表单数据对象
|
|
|
dataType: 'json', // 期望返回JSON格式
|
|
|
success: function(response) {
|
|
|
if (response.code === "0") {
|
|
|
// 提交成功提示
|
|
|
parent.layer.msg("添加成功", {
|
|
|
icon: 6, // 成功图标
|
|
|
time: 500 // 提示持续时间(毫秒)
|
|
|
});
|
|
|
// 500ms后刷新父页面
|
|
|
setTimeout(function() {
|
|
|
parent.location.reload();
|
|
|
}, 500);
|
|
|
} else {
|
|
|
// 失败提示
|
|
|
layer.msg(response.msg);
|
|
|
}
|
|
|
}
|
|
|
});
|
|
|
return false; // 阻止表单默认提交行为
|
|
|
});
|
|
|
});
|
|
|
</script>
|
|
|
</body>
|
|
|
//* * *08edit.jsp
|
|
|
<head>
|
|
|
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
|
|
|
<link rel="stylesheet" href="../public/layui/css/layui.css">
|
|
|
<script src="../public/layui/layui.js"></script>
|
|
|
<title>公告编辑</title>
|
|
|
</head>
|
|
|
<body>
|
|
|
<!-- 使用JDBCBean进行数据库操作 -->
|
|
|
<jsp:useBean id="check" scope="session" class="javabean.JDBCBean"></jsp:useBean>
|
|
|
|
|
|
<%
|
|
|
// 获取URL参数中的公告ID
|
|
|
String id = request.getParameter("id");
|
|
|
|
|
|
// 数据库操作
|
|
|
Connection connection = null;
|
|
|
PreparedStatement pstmt = null;
|
|
|
ResultSet resultSet = null;
|
|
|
|
|
|
try {
|
|
|
connection = Base.getConnection();
|
|
|
// 使用预编译语句查询公告信息
|
|
|
String sql = "select * from announcement where id=?";
|
|
|
pstmt = connection.prepareStatement(sql);
|
|
|
pstmt.setString(1, id);
|
|
|
resultSet = pstmt.executeQuery();
|
|
|
|
|
|
// 移动到结果集第一条记录
|
|
|
if (resultSet.next()) {
|
|
|
// 页面后续会使用这些数据
|
|
|
}
|
|
|
} catch (SQLException e) {
|
|
|
e.printStackTrace();
|
|
|
} finally {
|
|
|
// 释放资源(此处未正确关闭,建议在finally中处理)
|
|
|
}
|
|
|
%>
|
|
|
|
|
|
<!-- 公告编辑表单 -->
|
|
|
<form class="layui-form layui-form-pane" action="" lay-filter="formFilter">
|
|
|
<!-- 隐藏字段:公告ID -->
|
|
|
<input type="text" name="id" value="<%=id %>"
|
|
|
lay-verify="required" required
|
|
|
autocomplete="off"
|
|
|
class="layui-input layui-hide">
|
|
|
|
|
|
<!-- 标题输入 -->
|
|
|
<div class="layui-form-item">
|
|
|
<label class="layui-form-label">标题</label>
|
|
|
<div class="layui-input-block">
|
|
|
<input type="text" name="title"
|
|
|
value="<%=resultSet.getString("title") %>"
|
|
|
lay-verify="required" required
|
|
|
autocomplete="off"
|
|
|
placeholder="请输入标题"
|
|
|
class="layui-input">
|
|
|
</div>
|
|
|
</div>
|
|
|
|
|
|
<!-- 公告内容输入 -->
|
|
|
<div class="layui-form-item">
|
|
|
<label class="layui-form-label">公告</label>
|
|
|
<div class="layui-input-block">
|
|
|
<input type="text" name="detail"
|
|
|
value="<%=resultSet.getString("detail") %>"
|
|
|
lay-verify="required"
|
|
|
placeholder="请输入公告"
|
|
|
autocomplete="off"
|
|
|
class="layui-input">
|
|
|
</div>
|
|
|
</div>
|
|
|
|
|
|
<!-- 提交按钮 -->
|
|
|
<div class="layui-form-item">
|
|
|
<div class="layui-input-block">
|
|
|
<button type="submit" class="layui-btn"
|
|
|
lay-submit lay-filter="submitButton">
|
|
|
立即提交
|
|
|
</button>
|
|
|
</div>
|
|
|
</div>
|
|
|
</form>
|
|
|
|
|
|
<script>
|
|
|
layui.use(['form', 'jquery'], function() {
|
|
|
var $ = layui.jquery;
|
|
|
var form = layui.form;
|
|
|
var layer = layui.layer;
|
|
|
|
|
|
// 监听表单提交
|
|
|
form.on('submit(submitButton)', function(data) {
|
|
|
// 使用AJAX异步提交表单数据
|
|
|
$.ajax({
|
|
|
url: './announcementEdit', // 后端Servlet路径
|
|
|
method: 'post', // 请求方法
|
|
|
data: data.field, // 表单数据对象
|
|
|
dataType: 'json', // 期望返回JSON格式
|
|
|
success: function(response) {
|
|
|
if (response.code === "0") {
|
|
|
// 提交成功提示
|
|
|
parent.layer.msg("修改成功", {
|
|
|
icon: 6, // 成功图标
|
|
|
time: 500 // 提示持续时间(毫秒)
|
|
|
});
|
|
|
// 500ms后刷新父页面
|
|
|
setTimeout(function() {
|
|
|
parent.location.reload();
|
|
|
}, 500);
|
|
|
} else {
|
|
|
// 失败提示
|
|
|
layer.msg(response.msg);
|
|
|
}
|
|
|
},
|
|
|
error: function(xhr, status, error) {
|
|
|
// 网络错误处理
|
|
|
layer.msg('网络请求失败,请检查网络连接');
|
|
|
}
|
|
|
});
|
|
|
return false; // 阻止表单默认提交行为
|
|
|
});
|
|
|
});
|
|
|
</script>
|
|
|
</body>
|
|
|
//* * *09managerSelf.jsp
|
|
|
|
|
|
<head>
|
|
|
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
|
|
|
<title>管理员个人资料</title>
|
|
|
<!-- 引入LayUI框架 -->
|
|
|
<link rel="stylesheet" href="../public/layui/css/layui.css" media="all">
|
|
|
<script src="../public/layui/layui.js"></script>
|
|
|
|
|
|
<!-- 引入Bootstrap框架 -->
|
|
|
<link href="../css/bootstrap.min.css" rel="stylesheet">
|
|
|
<script src="../js/jquery.min.js"></script>
|
|
|
<script src="../js/bootstrap.min.js"></script>
|
|
|
|
|
|
<!-- 引入自定义样式和动画库 -->
|
|
|
<link rel="stylesheet" type="text/css" href="../public/css/default.css" />
|
|
|
<link rel="stylesheet" type="text/css" href="../public/css/component.css" />
|
|
|
<script src="../public/js/modernizr.custom.js"></script>
|
|
|
|
|
|
<!-- 自定义样式 -->
|
|
|
<style>
|
|
|
body {
|
|
|
background-color: white !important;
|
|
|
color: black !important;
|
|
|
}
|
|
|
.md-content {
|
|
|
color: black;
|
|
|
background: white;
|
|
|
position: relative;
|
|
|
border-radius: 3px;
|
|
|
margin: 0 auto;
|
|
|
}
|
|
|
button {
|
|
|
background-color: #009688;
|
|
|
}
|
|
|
button:hover {
|
|
|
background-color: #5FB878;
|
|
|
}
|
|
|
.md-modal {
|
|
|
width: 35%;
|
|
|
}
|
|
|
</style>
|
|
|
</head>
|
|
|
<body>
|
|
|
<!-- 使用JDBCBean进行数据库操作 -->
|
|
|
<jsp:useBean id="gly" scope="session" class="javabean.JDBCBean"></jsp:useBean>
|
|
|
|
|
|
<!-- 管理员基本信息展示 -->
|
|
|
<fieldset class="layui-elem-field" style="width:30%; margin-left:30%; margin-top:5%; height:30%;">
|
|
|
<legend>管理员基本信息</legend>
|
|
|
<div class="layui-field-box" align="center" style="font-size:20px; font-family:YouYuan; margin-top:10%; margin-bottom:10%;">
|
|
|
<%
|
|
|
// 获取当前登录管理员账号
|
|
|
String manacc = session.getAttribute("manager").toString();
|
|
|
// 查询管理员信息(存在SQL注入风险!)
|
|
|
String sql = "select * from manager where ACCOUNT = '" + manacc + "';";
|
|
|
ResultSet rs = gly.executeQuery(sql);
|
|
|
while (rs.next()) {
|
|
|
%>
|
|
|
<!-- 展示基本信息 -->
|
|
|
<p>姓名:<%= rs.getString("name") %></p><br>
|
|
|
<p>账号:<%= rs.getString("account") %></p><br>
|
|
|
<p>邮箱:<%= rs.getString("email") %></p><br>
|
|
|
|
|
|
<!-- 模态框触发按钮 -->
|
|
|
<button class="md-trigger layui-btn layui-btn-radius" data-modal="modal-3">修改名字</button>
|
|
|
<button class="md-trigger layui-btn layui-btn-radius" data-modal="modal-13">修改密码</button>
|
|
|
<button class="md-trigger layui-btn layui-btn-radius" data-modal="modal-1">修改邮箱</button>
|
|
|
|
|
|
<% } %>
|
|
|
</div>
|
|
|
</fieldset>
|
|
|
|
|
|
<!-- 修改密码模态框 -->
|
|
|
<div class="md-modal md-effect-13" id="modal-13">
|
|
|
<div class="md-content">
|
|
|
<h3>修改密码</h3>
|
|
|
<form action="10updateManager.jsp" method="post" class="form-horizontal">
|
|
|
<div class="form-group" align="center" style="margin-left:3%;">
|
|
|
<br>
|
|
|
<label for="psw1" class="col-sm-2 control-label">新密码</label>
|
|
|
<div class="col-sm-10" align="center">
|
|
|
<input type="password" class="form-control" name="psw1" id="password1"
|
|
|
placeholder="请输入新密码" style="width:50%; margin-left:8%;">
|
|
|
</div>
|
|
|
</div>
|
|
|
<br>
|
|
|
<div class="form-group" align="center" style="margin-left:3%;">
|
|
|
<label for="psw2" class="col-sm-2 control-label">确认密码</label>
|
|
|
<div class="col-sm-10">
|
|
|
<input type="password" class="form-control" name="psw2" id="password2"
|
|
|
placeholder="请再次输入密码进行确认" style="width:50%; margin-left:8%;">
|
|
|
</div>
|
|
|
</div>
|
|
|
<div align="center">
|
|
|
<input type="submit" class="layui-btn layui-btn-radius" value="确认">
|
|
|
</div>
|
|
|
<br>
|
|
|
</form>
|
|
|
<button class="md-close layui-btn-radius" style="font-size:14px;">取消</button>
|
|
|
</div>
|
|
|
</div>
|
|
|
|
|
|
<!-- 修改邮箱模态框 -->
|
|
|
<div class="md-modal md-effect-13" id="modal-1">
|
|
|
<div class="md-content">
|
|
|
<h3>修改邮箱</h3>
|
|
|
<form action="10updateManager.jsp" method="post" class="form-horizontal">
|
|
|
<div class="form-group" align="center" style="margin-left:3%;">
|
|
|
<br>
|
|
|
<label for="email1" class="col-sm-2 control-label">新邮箱</label>
|
|
|
<div class="col-sm-10" align="center">
|
|
|
<input type="text" class="form-control" name="email1" id="password1"
|
|
|
placeholder="请输入新邮箱" style="width:50%; margin-left:8%;">
|
|
|
</div>
|
|
|
</div>
|
|
|
<br>
|
|
|
<div class="form-group" align="center" style="margin-left:3%;">
|
|
|
<label for="email2" class="col-sm-2 control-label">确认邮箱</label>
|
|
|
<div class="col-sm-10">
|
|
|
<input type="text" class="form-control" name="email2" id="password2"
|
|
|
placeholder="请再次输入邮箱进行确认" style="width:50%; margin-left:8%;">
|
|
|
</div>
|
|
|
</div>
|
|
|
<div align="center">
|
|
|
<input type="submit" class="layui-btn layui-btn-radius" value="确认">
|
|
|
</div>
|
|
|
<br>
|
|
|
</form>
|
|
|
<button class="md-close layui-btn-radius" style="font-size:14px;">取消</button>
|
|
|
</div>
|
|
|
</div>
|
|
|
|
|
|
<!-- 修改姓名模态框 -->
|
|
|
<div class="md-modal md-effect-13" id="modal-3">
|
|
|
<div class="md-content">
|
|
|
<h3>修改名字</h3>
|
|
|
<form action="10updateManager.jsp" method="post" class="form-horizontal">
|
|
|
<div class="form-group" align="center" style="margin-left:3%;">
|
|
|
<br>
|
|
|
<label for="name1" class="col-sm-2 control-label">新名字</label>
|
|
|
<div class="col-sm-10" align="center">
|
|
|
<input type="text" class="form-control" name="name1" id="password1"
|
|
|
placeholder="请输入新名字" style="width:50%; margin-left:8%;">
|
|
|
</div>
|
|
|
</div>
|
|
|
<br>
|
|
|
<div class="form-group" align="center" style="margin-left:3%;">
|
|
|
<label for="name2" class="col-sm-2 control-label">确认名字</label>
|
|
|
<div class="col-sm-10">
|
|
|
<input type="text" class="form-control" name="name2" id="password2"
|
|
|
placeholder="请再次输入名字进行确认" style="width:50%; margin-left:8%;">
|
|
|
</div>
|
|
|
</div>
|
|
|
<div align="center">
|
|
|
<input type="submit" class="layui-btn layui-btn-radius" value="确认">
|
|
|
</div>
|
|
|
<br>
|
|
|
</form>
|
|
|
<button class="md-close layui-btn-radius" style="font-size:14px;">取消</button>
|
|
|
</div>
|
|
|
</div>
|
|
|
|
|
|
<!-- 模态框遮罩层 -->
|
|
|
<div class="md-overlay"></div>
|
|
|
|
|
|
<!-- 模态框动画脚本 -->
|
|
|
<script src="../public/js/classie.js"></script>
|
|
|
<script src="../public/js/modalEffects.js"></script>
|
|
|
|
|
|
<!-- CSS滤镜兼容脚本 -->
|
|
|
<script>
|
|
|
var polyfilter_scriptpath = '/js/';
|
|
|
</script>
|
|
|
<script src="../public/js/cssParser.js"></script>
|
|
|
<script src="../public/js/css-filters-polyfill.js"></script>
|
|
|
</body>
|
|
|
//* * *updateManager.jsp
|
|
|
<head>
|
|
|
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
|
|
|
<title>管理员资料修改处理</title>
|
|
|
</head>
|
|
|
<body>
|
|
|
<!-- 使用JDBCBean进行数据库操作 -->
|
|
|
<jsp:useBean id="check" scope="session" class="javabean.JDBCBean"></jsp:useBean>
|
|
|
|
|
|
<%
|
|
|
// 获取表单提交的参数
|
|
|
String psw1 = request.getParameter("psw1"); // 新密码
|
|
|
String psw2 = request.getParameter("psw2"); // 确认密码
|
|
|
String email1 = request.getParameter("email1"); // 新邮箱
|
|
|
String email2 = request.getParameter("email2"); // 确认邮箱
|
|
|
String name1 = request.getParameter("name1"); // 新姓名
|
|
|
String name2 = request.getParameter("name2"); // 确认姓名
|
|
|
|
|
|
// 获取当前登录管理员账号
|
|
|
String id = session.getAttribute("manager").toString();
|
|
|
|
|
|
// 密码修改逻辑
|
|
|
if (psw1 != null && psw2 != null) {
|
|
|
// 验证密码一致性和非空
|
|
|
if (psw1.equals(psw2) && !psw1.trim().isEmpty() && !psw2.trim().isEmpty()) {
|
|
|
// 存在SQL注入风险!建议使用预编译语句
|
|
|
String sql = "update manager set PASSWORD = ? where ACCOUNT = ?";
|
|
|
try (Connection conn = check.getConnection();
|
|
|
PreparedStatement pstmt = conn.prepareStatement(sql)) {
|
|
|
pstmt.setString(1, psw1);
|
|
|
pstmt.setString(2, id);
|
|
|
int affectedRows = pstmt.executeUpdate();
|
|
|
|
|
|
if (affectedRows == 1) {
|
|
|
%>
|
|
|
<script>
|
|
|
alert('密码修改成功!');
|
|
|
window.location.href = "09managerSelf.jsp";
|
|
|
</script>
|
|
|
<%
|
|
|
} else {
|
|
|
%>
|
|
|
<script>
|
|
|
alert('密码修改失败!');
|
|
|
window.location.href = "09managerSelf.jsp";
|
|
|
</script>
|
|
|
<%
|
|
|
}
|
|
|
} catch (SQLException e) {
|
|
|
e.printStackTrace();
|
|
|
%>
|
|
|
<script>
|
|
|
alert('数据库操作失败!');
|
|
|
window.location.href = "09managerSelf.jsp";
|
|
|
</script>
|
|
|
<%
|
|
|
}
|
|
|
} else {
|
|
|
%>
|
|
|
<script>
|
|
|
alert('密码不一致或为空!');
|
|
|
window.location.href = "09managerSelf.jsp";
|
|
|
</script>
|
|
|
<%
|
|
|
}
|
|
|
}
|
|
|
// 邮箱修改逻辑
|
|
|
else if (email1 != null && email2 != null) {
|
|
|
// 验证邮箱一致性和非空
|
|
|
if (email1.equals(email2) && !email1.trim().isEmpty() && !email2.trim().isEmpty()) {
|
|
|
// 建议添加邮箱格式验证(正则表达式)
|
|
|
String sql = "update manager set EMAIL = ? where ACCOUNT = ?";
|
|
|
try (Connection conn = check.getConnection();
|
|
|
PreparedStatement pstmt = conn.prepareStatement(sql)) {
|
|
|
pstmt.setString(1, email1);
|
|
|
pstmt.setString(2, id);
|
|
|
int affectedRows = pstmt.executeUpdate();
|
|
|
|
|
|
if (affectedRows == 1) {
|
|
|
%>
|
|
|
<script>
|
|
|
alert('邮箱修改成功!');
|
|
|
window.location.href = "09managerSelf.jsp";
|
|
|
</script>
|
|
|
<%
|
|
|
} else {
|
|
|
%>
|
|
|
<script>
|
|
|
alert('邮箱修改失败!');
|
|
|
window.location.href = "09managerSelf.jsp";
|
|
|
</script>
|
|
|
<%
|
|
|
}
|
|
|
} catch (SQLException e) {
|
|
|
e.printStackTrace();
|
|
|
%>
|
|
|
<script>
|
|
|
alert('数据库操作失败!');
|
|
|
window.location.href = "09managerSelf.jsp";
|
|
|
</script>
|
|
|
<%
|
|
|
}
|
|
|
} else {
|
|
|
%>
|
|
|
<script>
|
|
|
alert('邮箱不一致或为空!');
|
|
|
window.location.href = "09managerSelf.jsp";
|
|
|
</script>
|
|
|
<%
|
|
|
}
|
|
|
}
|
|
|
// 姓名修改逻辑
|
|
|
else if (name1 != null && name2 != null) {
|
|
|
// 验证姓名一致性和非空
|
|
|
if (name1.equals(name2) && !name1.trim().isEmpty() && !name2.trim().isEmpty()) {
|
|
|
String sql = "update manager set NAME = ? where ACCOUNT = ?";
|
|
|
try (Connection conn = check.getConnection();
|
|
|
PreparedStatement pstmt = conn.prepareStatement(sql)) {
|
|
|
pstmt.setString(1, name1);
|
|
|
pstmt.setString(2, id);
|
|
|
int affectedRows = pstmt.executeUpdate();
|
|
|
|
|
|
if (affectedRows == 1) {
|
|
|
%>
|
|
|
<script>
|
|
|
alert('姓名修改成功!');
|
|
|
window.location.href = "09managerSelf.jsp";
|
|
|
</script>
|
|
|
<%
|
|
|
} else {
|
|
|
%>
|
|
|
<script>
|
|
|
alert('姓名修改失败!');
|
|
|
window.location.href = "09managerSelf.jsp";
|
|
|
</script>
|
|
|
<%
|
|
|
}
|
|
|
} catch (SQLException e) {
|
|
|
e.printStackTrace();
|
|
|
%>
|
|
|
<script>
|
|
|
alert('数据库操作失败!');
|
|
|
window.location.href = "09managerSelf.jsp";
|
|
|
</script>
|
|
|
<%
|
|
|
}
|
|
|
} else {
|
|
|
%>
|
|
|
<script>
|
|
|
alert('姓名不一致或为空!');
|
|
|
window.location.href = "09managerSelf.jsp";
|
|
|
</script>
|
|
|
<%
|
|
|
}
|
|
|
} else {
|
|
|
%>
|
|
|
<script>
|
|
|
alert('请选择要修改的内容!');
|
|
|
window.location.href = "09managerSelf.jsp";
|
|
|
</script>
|
|
|
<%
|
|
|
}
|
|
|
%>
|
|
|
</body>
|
|
|
// * * * loginManager.html
|
|
|
<head>
|
|
|
<meta charset="UTF-8">
|
|
|
<title>图书管理员登录页面</title>
|
|
|
<!-- 视口设置:适配移动端 -->
|
|
|
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no">
|
|
|
|
|
|
<!-- 引入jQuery库 -->
|
|
|
<script src="https://cdn.staticfile.org/jquery/2.1.1/jquery.min.js"></script>
|
|
|
|
|
|
<!-- Bootstrap框架样式 -->
|
|
|
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@3.3.7/dist/css/bootstrap.min.css">
|
|
|
<!-- Bootstrap核心脚本 -->
|
|
|
<script src="https://cdn.jsdelivr.net/npm/bootstrap@3.3.7/dist/js/bootstrap.min.js"></script>
|
|
|
<!-- 可选的Bootstrap主题 -->
|
|
|
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@3.3.7/dist/css/bootstrap-theme.min.css">
|
|
|
|
|
|
<!-- 自定义样式 -->
|
|
|
<link rel="stylesheet" href="./public/css/animate.css">
|
|
|
<link rel="stylesheet" href="./public/css/login.css">
|
|
|
</head>
|
|
|
<body>
|
|
|
<!-- 主容器 -->
|
|
|
<div class="container main">
|
|
|
<!-- 登录框容器,带淡入动画 -->
|
|
|
<div id="login" class="contain animated fadeInDown">
|
|
|
<h1>工作人员登录</h1>
|
|
|
<!-- 登录表单 -->
|
|
|
<form method="post">
|
|
|
<!-- 用户名输入框 -->
|
|
|
<input type="text" name="user" class="form-control my_input"
|
|
|
placeholder="请输入账号" required="required">
|
|
|
<!-- 密码输入框 -->
|
|
|
<input type="password" name="psw" class="form-control my_input"
|
|
|
placeholder="请输入密码" required="required">
|
|
|
<!-- 提交按钮,阻止默认表单提交 -->
|
|
|
<input type="submit" class="form-control" value="登录" onclick="javascript:void(0);">
|
|
|
</form>
|
|
|
</div>
|
|
|
</div>
|
|
|
|
|
|
<!-- 底部快捷链接 -->
|
|
|
<div style="position:fixed; bottom:0; right:0;">
|
|
|
<!-- 读者系统入口 -->
|
|
|
<a href="reader/04readerFrame.jsp" target="_blank">
|
|
|
<img src="public/image/reader.png" width="50px" height="50px">
|
|
|
</a>
|
|
|
<br>
|
|
|
<!-- 系统管理员入口 -->
|
|
|
<a href="adminLogin.html" target="_blank">
|
|
|
<img src="public/image/admin.png" width="50px" height="50px">
|
|
|
</a>
|
|
|
</div>
|
|
|
|
|
|
<!-- 弹出层插件 -->
|
|
|
<script src="./public/js/layer/layer.js"></script>
|
|
|
<script>
|
|
|
$(function() {
|
|
|
// 登录按钮点击事件
|
|
|
$("input[type=submit]").click(function() {
|
|
|
// 使用AJAX提交表单
|
|
|
$.ajax({
|
|
|
url: "./managerLogin", // 后端Servlet路径
|
|
|
type: "post", // 请求方法
|
|
|
data: $("form").serialize(), // 序列化表单数据
|
|
|
dataType: "json", // 期望返回JSON格式
|
|
|
success: function(data) {
|
|
|
if (data.code === 0) {
|
|
|
// 登录成功提示
|
|
|
layer.msg("登录成功", {
|
|
|
icon: 6, // 成功图标
|
|
|
time: 1000 // 提示持续时间(毫秒)
|
|
|
}, function() {
|
|
|
// 跳转至目标页面
|
|
|
location.href = data.url;
|
|
|
});
|
|
|
} else {
|
|
|
// 登录失败提示
|
|
|
layer.open({
|
|
|
title: "登录失败",
|
|
|
content: data.msg,
|
|
|
icon: 5, // 错误图标
|
|
|
anim: 6 // 动画效果
|
|
|
});
|
|
|
}
|
|
|
}
|
|
|
});
|
|
|
return false; // 阻止表单默认提交行为
|
|
|
});
|
|
|
});
|
|
|
</script>
|
|
|
</body>
|
|
|
// * * * src/main/webapp/index.jsp
|
|
|
|
|
|
<head>
|
|
|
<meta charset="UTF-8">
|
|
|
<title>Insert title here</title>
|
|
|
</head>
|
|
|
<body>
|
|
|
<%
|
|
|
// 使用response.sendRedirect方法将页面重定向到指定的URL
|
|
|
// 这里将页面重定向到名为04readerFrame.jsp的页面,该页面位于reader目录下
|
|
|
response.sendRedirect("./reader/04readerFrame.jsp");
|
|
|
%>
|
|
|
</body>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|