酒店管理系统

使用html+Servlet+数据库的方式完成一个简单的酒店管理系统。

项目整体分为客户端那u和管理员端。

客户端:

1.用户登录功能:用户登录功能

2.入住房间:在可以入住的房间之上进行操作,进行入住。

管理员端:

管理员可以直接根据系统默认的用户名密码登录,进行房间和旅客的信息管理。

信息展示和操作:

  1. 旅客信息展示:展示全部的旅客信息并配合操作
  2. 房间信息展示:展示全部的房间信息并配合操作

 工作日志:

日期:4月3日

任务:数据库的构建以及用户登陆功能的实现

数据库:

考虑到项目仅实现了,用户的登陆和入住功能以及管理员对用户和房间的增删改查功能。决定使用两张表,分别是users、rooms。代码如下:

CREATE TABLE `users` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `name` varchar(50) COLLATE utf8mb4_bin NOT NULL,
  `password` varchar(50) COLLATE utf8mb4_bin NOT NULL,
  `phone` varchar(20) COLLATE utf8mb4_bin NOT NULL,
  `id_card` varchar(20) COLLATE utf8mb4_bin NOT NULL,
  `status` enum('入住','未入住') COLLATE utf8mb4_bin DEFAULT NULL,
  PRIMARY KEY (`id`),
  UNIQUE KEY `phone` (`phone`),
  UNIQUE KEY `id_card` (`id_card`)
) ENGINE=InnoDB AUTO_INCREMENT=6 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin;


CREATE TABLE `rooms` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `room_number` varchar(10) COLLATE utf8mb4_bin NOT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=17 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin;


用户表字段分别是 用户id、用户姓名、用户密码、用户手机号、用户id_card。(管理员的id为1)

房间表字段分别是 房间id、房间号码。

前端页面:

<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <title>客户端登录</title>
    <script src='js/jquery-3.7.1.min.js'></script>
    <script src="js/jquery.cookie.min.js"></script>
    <script src='js/login.js' defer></script>
    <style>
        body {
            font-family: Arial, sans-serif;
            background-color: #f5f5f5;
            display: flex;
            justify-content: center;
            align-items: center;
            height: 100vh;
            margin: 0;
        }
        
        #loginForm {
            background-color: white;
            padding: 30px;
            border-radius: 8px;
            box-shadow: 0 0 20px rgba(0,0,0,0.1);
            width: 300px;
        }
        
        h1 {
            text-align: center;
            color: #4CAF50;
            margin-bottom: 20px;
        }
        
        label {
            display: block;
            margin-bottom: 8px;
            color: #555;
        }
        
        input[type="text"], input[type="password"] {
            width: 100%;
            padding: 10px;
            margin-bottom: 20px;
            border: 1px solid #ddd;
            border-radius: 4px;
            box-sizing: border-box;
        }
        
        input[type="button"] {
            width: 100%;
            background-color: #4CAF50;
            color: white;
            padding: 12px;
            border: none;
            border-radius: 4px;
            cursor: pointer;
            font-size: 16px;
        }
        
        input[type="button"]:hover {
            background-color: #45a049;
        }
    </style>
</head>
<body>
    <form id="loginForm">
        <h1>客户端登录</h1>
        <label for="phone">手机号:</label>
        <input type="text" class="phone" id="phone"><br>
        <label for="password">密码:</label>
        <input type="password" class="password" id="password"><br>
        <input type="button" value="登录" class='login'>
    </form>
</body>
</html>

login.js代码如下: 

$(".login").click(function(){
	var phone=$(".phone").val().trim();
	var password=$(".password").val().trim();
    if (phone === "") {
        alert("姓名不能为空");
        return;
    }
    if (password === "") {
        alert("性别不能为空");
        return;
    }
	
    $.ajax({
        url: "login",
        type: "post", 
        data: { phone,password },
        success: function (value) {

            if (value.data.length != 0) {
            	console.log(value.data[0].id)
            	if (value.data[0].id==1){
            		window.location.href = 'users.html';
            	}
            	 else {
             window.location.href = 'check_in.html';}
            } else {
                alert('登录失败');
                }
        },
        error: function () {
            alert("出错啦");
        }
    });
});
	
	
	

用户输入手机号和密码后经校验进入入住页面。为区分管理员和用户的进入的页面,对返回的value.data[0].id进行判断。

时间:4月4日

任务:新增check_in表。用户入住页面。数据的展示。入住按钮的绑定以及对入住情况的判断。

因为要考虑用户的入住之后不能再入住,以及其他用户不能入住已经入住的房间。添加check_in表来做记录。

CREATE TABLE `check_ins` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `user_id` int(11) NOT NULL,
  `room_id` int(11) NOT NULL,
  `check_in_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
  `check_out_time` timestamp NULL DEFAULT NULL,
  PRIMARY KEY (`id`),
  KEY `user_id` (`user_id`),
  KEY `room_id` (`room_id`)
) ENGINE=InnoDB AUTO_INCREMENT=51 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin;

CREATE DEFINER=`skip-grants user`@`skip-grants host` TRIGGER before_insert_check_in
BEFORE INSERT ON check_ins
FOR EACH ROW
BEGIN
    -- 检查用户是否已有未退房记录
    IF EXISTS (
        SELECT 1 FROM check_ins 
        WHERE user_id = NEW.user_id 
        AND check_out_time IS NULL
    ) THEN
        SIGNAL SQLSTATE '45000' 
        SET MESSAGE_TEXT = '用户已入住,不可重复入住';
    END IF;
END;

对与入住页面会展示房间id、房间号以及房间此时的状态还有入住和退房的操作。

对于数据的查询,在入住页面的回显。

 html代码如下:

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>入住管理</title>
<script src='js/jquery-3.7.1.min.js'></script>
<script src="js/jquery.cookie.min.js"></script>
<script src='js/client.js' defer></script>
<script>

function checkOut() {
    var userId = $.cookie("user_id");
    if (!userId) {
        alert("请先登录");
        return;
    }
    $.ajax({
        url: "CheckOutServlet",
        type: "post",
        data: { user_id: userId },
        success: function(response) {
        	console.log(response.status)
            if (response.status === "success") {
                alert("退房成功");
                location.reload();
            } else {
                alert("退房失败");
            }
        },
        error: function() {
            alert("请求失败");
        }
    });
}
</script>
<style>
body {
    font-family: Arial, sans-serif;
    margin: 20px;
    background-color: #f5f5f5;
}

table {
    width: 100%;
    border-collapse: collapse;
    margin-bottom: 20px;
    box-shadow: 0 0 10px rgba(0,0,0,0.1);
}

th, td {
    padding: 12px 15px;
    text-align: left;
    border-bottom: 1px solid #ddd;
}

th {
    background-color: #4CAF50;
    color: white;
}

tr:hover {
    background-color: #f5f5f5;
}

tr:nth-child(even) {
    background-color: #f2f2f2;
}
</style>
</head>
<body>
    <table>
        <thead></thead>
        <tbody>
            <tr>
                <th>id</th>
                <th>房间号</th>
                <th>状态</th>
                <th>操作</th>
               
            </tr>
        </tbody>
    </table>
     <button onclick="checkOut()">退房</button>
</body>
</html>

client.js代码如下:

  
$.ajax({
	url:"ClientCheckInServlet",
	type:"get",	
	success:function(value){
//		alert(value);
//		alert('成功');
		console.log(value)
		var arr=value.data
		
		for(var i=0;i<arr.length;i++){
			$("tbody").append("<tr>"+
					"<td>"+arr[i].id+"</td>"+
					"<td>"+arr[i].room_number+"</td>"+
					"<td>"+arr[i].status+"</td>"+
					"<td><input type='button' value='入住' class='checkin' index='"+arr[i].id+"' index1='"+arr[i].status+"' > </td>"
					+"</tr>")
			
		}
      
//        window.location.href = 'check_in.html';
    
		//点修改小模块展现  未来元素不能直接帮事件,要邦最近的在html已有的上一层元素
	$("tbody").on("click",".checkin",function(){
		var id= $(this).attr("index")
		var status =$(this).attr("index1")
		$.ajax({
			url: "UpdateServlet",
			type: "post",
			data:{id},
	        success: function (value) {
	        	if (status=="occupied"){alert('房间已满');}
	        	else{console.log(value);
	            alert(value);}
	           
	        },
	        error: function () {
	            alert("出错啦");
	        }
			
		})
		
	})
	},
	error:function(){
		alert('登录失败');
	},
	

})

ClientCheckInServlet代码实现了对房间信息的查询如下:

package com.qcby.servlet;

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 com.qcby.db.MysqlUtil;


/**
 * Servlet implementation class ClientCheckInServlet
 */
@WebServlet("/ClientCheckInServlet")
public class ClientCheckInServlet extends HttpServlet {
	private static final long serialVersionUID = 1L;
       
    /**
     * @see HttpServlet#HttpServlet()
     */
    public ClientCheckInServlet() {
        super();
        // TODO Auto-generated constructor stub
    }

	/**
	 * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response)
	 */
	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		System.out.println("get");
		String sql="select * from rooms";
		String[] columns= {"id","room_number","status"};
		String[] columns = {"id", "room_number", "status", "resident_name"};
		String res=MysqlUtil.getJsonBySql(sql, columns);
		System.out.println(res);
		response.setContentType("text/json;charset=utf-8");
		response.getWriter().write(res);
	}

	/**
	 * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response)
	 */
	protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
	
	}

}

入住按钮的绑定

package com.qcby.servlet;

import java.io.IOException;
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 com.qcby.db.MysqlUtil;

/**
 * Servlet implementation class CheckInServlet
 */
@WebServlet("/CheckInServlet")
public class CheckInServlet extends HttpServlet {
	private static final long serialVersionUID = 1L;
       
    /**
     * @see HttpServlet#HttpServlet()
     */
    public CheckInServlet() {
        super();
        // TODO Auto-generated constructor stub
    }

	/**
	 * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response)
	 */
	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		// TODO Auto-generated method stub
		response.getWriter().append("Served at: ").append(request.getContextPath());
	}

	/**
	 * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response)
	 */
	protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		   Connection conn = null;
	        try {
	            conn = MysqlUtil.getConnection();
	            conn.setAutoCommit(false); // 开启事务
	            
	            // 获取参数
	            String roomId = request.getParameter("room_id");
	            String userId = request.getParameter("user_id");

	            // 检查用户是否已有未退房的记录
	            String checkSql = "SELECT COUNT(*) FROM check_ins WHERE user_id = ? AND check_out_time IS NULL";
	            try (PreparedStatement psCheck = conn.prepareStatement(checkSql)) {
	                psCheck.setInt(1, Integer.parseInt(userId));
	                ResultSet rs = psCheck.executeQuery();
	                if (rs.next() && rs.getInt(1) > 0) {
	                    response.getWriter().write("{\"status\":\"error\",\"message\":\"您已入住其他房间,请先退房\"}");
	                    return;
	                }
	            }

	            // 更新房间状态
	            String updateRoomSql = "UPDATE rooms SET status = 'occupied' WHERE id = ?";
	            try (PreparedStatement psRoom = conn.prepareStatement(updateRoomSql)) {
	                psRoom.setInt(1, Integer.parseInt(roomId));
	                psRoom.executeUpdate();
	            }

	            // 插入入住记录
	            String insertCheckInSql = "INSERT INTO check_ins (user_id, room_id) VALUES (?, ?)";
	            try (PreparedStatement psCheckIn = conn.prepareStatement(insertCheckInSql)) {
	                psCheckIn.setInt(1, Integer.parseInt(userId));
	                psCheckIn.setInt(2, Integer.parseInt(roomId));
	                psCheckIn.executeUpdate();
	            }

	            conn.commit(); // 提交事务
	            response.getWriter().write("{\"status\":\"success\"}");
	        } catch (Exception e) {
	            if (conn != null) {
	                try { conn.rollback(); } catch (SQLException ex) { ex.printStackTrace(); }
	            }
	            response.getWriter().write("{\"status\":\"error\",\"message\":\"" + e.getMessage() + "\"}");
	        } finally {
	            if (conn != null) {
	                try { conn.close(); } catch (SQLException e) { e.printStackTrace(); }
	            }
	        }
	        
	        
	        
	    
	}

}
检查用户是否已有未退房记录
String checkSql = "SELECT COUNT(*) FROM check_ins WHERE user_id = ? AND check_out_time IS NULL";
try (PreparedStatement psCheck = conn.prepareStatement(checkSql)) {
    psCheck.setInt(1, Integer.parseInt(userId));
    ResultSet rs = psCheck.executeQuery();
    if (rs.next() && rs.getInt(1) > 0) {
        response.getWriter().write("{\"status\":\"error\",\"message\":\"您已入住其他房间,请先退房\"}");
        return; // 终止请求处理
    }
}

业务规则:不允许用户同时入住多个房间。

逻辑:

  • 查询 check_ins 表中该用户是否存在 check_out_time 为 NULL 的记录(即未退房)。
  • 若存在,返回错误信息,阻止本次入住。
更新房间状态为 “已占用”
String updateRoomSql = "UPDATE rooms SET status = 'occupied' WHERE id = ?";
try (PreparedStatement psRoom = conn.prepareStatement(updateRoomSql)) {
    psRoom.setInt(1, Integer.parseInt(roomId));
    psRoom.executeUpdate(); // 执行更新
}

操作:将目标房间的状态从 available(可用)改为 occupied(已占用)。

做用:确保其他用户无法同时入住同一房间。

插入入住记录
String insertCheckInSql = "INSERT INTO check_ins (user_id, room_id) VALUES (?, ?)";
try (PreparedStatement psCheckIn = conn.prepareStatement(insertCheckInSql)) {
    psCheckIn.setInt(1, Integer.parseInt(userId));
    psCheckIn.setInt(2, Integer.parseInt(roomId));
    psCheckIn.executeUpdate(); // 插入记录
}

退房操作:

package com.qcby.servlet;

import java.io.IOException;
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 com.qcby.db.MysqlUtil;


@WebServlet("/CheckOutServlet")
public class CheckOutServlet extends HttpServlet {
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    	  Connection conn = null;
          try {
              conn = MysqlUtil.getConnection();
              conn.setAutoCommit(false); // 开启事务

              String userId = request.getParameter("user_id");
              if (userId == null || userId.isEmpty()) {
                  sendError(response, "用户ID不能为空");
                  return;
              }

              // 1. 查询用户当前入住的房间ID
              String getRoomSql = "SELECT room_id FROM check_ins WHERE user_id = ? AND check_out_time IS NULL ORDER BY check_in_time DESC LIMIT 1";
              int roomId = -1;
              try (PreparedStatement ps = conn.prepareStatement(getRoomSql)) {
                  ps.setInt(1, Integer.parseInt(userId));
                  ResultSet rs = ps.executeQuery();
                  if (rs.next()) {
                      roomId = rs.getInt("room_id");
                  } else {
                      sendError(response, "未找到有效入住记录");
                      return;
                  }
              }

              // 2. 更新入住记录的退房时间
              String updateCheckInSql = "UPDATE check_ins SET check_out_time = NOW() WHERE user_id = ? AND check_out_time IS NULL";
              try (PreparedStatement ps = conn.prepareStatement(updateCheckInSql)) {
                  ps.setInt(1, Integer.parseInt(userId));
                  int affectedRows = ps.executeUpdate();
                  if (affectedRows == 0) {
                      sendError(response, "退房失败:未更新入住记录");
                      return;
                  }
              }

              // 3. 更新房间状态为可用
              String updateRoomSql = "UPDATE rooms SET status = 'available' WHERE id = ?";
              try (PreparedStatement ps = conn.prepareStatement(updateRoomSql)) {
                  ps.setInt(1, roomId);
                  ps.executeUpdate();
              }

              conn.commit(); // 提交事务
              sendSuccess(response, "退房成功");
          } catch (Exception e) {
              rollback(conn);
              sendError(response, "系统错误: " + e.getMessage());
          } finally {
              closeConnection(conn);
          }
      }

      // -------------------------------- 工具方法 --------------------------------
      private void sendSuccess(HttpServletResponse response, String message) throws IOException {
          response.setContentType("application/json");
          response.getWriter().write("{\"status\":\"success\",\"message\":\"" + message + "\"}");
      }

      private void sendError(HttpServletResponse response, String message) throws IOException {
          response.setContentType("application/json");
          response.getWriter().write("{\"status\":\"error\",\"message\":\"" + message + "\"}");
      }

      private void rollback(Connection conn) {
          if (conn != null) {
              try {
                  conn.rollback();
              } catch (SQLException e) {
                  e.printStackTrace();
              }
          }
      }

      private void closeConnection(Connection conn) {
          if (conn != null) {
              try {
                  conn.setAutoCommit(true); // 恢复自动提交模式
                  conn.close();
              } catch (SQLException e) {
                  e.printStackTrace();
              }
          }
    }
}

日期:4月5日

任务:管理端的用户管理和房间管理,入住代码的优化

用户管理有数据库数据的回显,以及删除修改功能的实现。

前端代码:

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>用户管理</title>
<script src='js/jquery-3.7.1.min.js'></script>
<script src="js/jquery.cookie.min.js"></script>
<script src='js/users.js' defer></script>

<style>
body {
    font-family: Arial, sans-serif;
    margin: 20px;
    background-color: #f5f5f5;
}

table {
    width: 100%;
    border-collapse: collapse;
    margin-bottom: 20px;
    box-shadow: 0 0 10px rgba(0,0,0,0.1);
}

th, td {
    padding: 12px 15px;
    text-align: left;
    border-bottom: 1px solid #ddd;
}

th {
    background-color: #4CAF50;
    color: white;
}

tr:hover {
    background-color: #f5f5f5;
}

tr:nth-child(even) {
    background-color: #f2f2f2;
}

button, input[type="button"] {
    background-color: #4CAF50;
    color: white;
    padding: 8px 16px;
    border: none;
    border-radius: 4px;
    cursor: pointer;
    margin-right: 10px;
    margin-bottom: 20px;
}

button:hover, input[type="button"]:hover {
    background-color: #45a049;
}

.addModel, .deleteModel, .updateModel {
    width: 300px;
    padding: 20px;
    margin-top: 20px;
    border: 1px solid #ddd;
    border-radius: 5px;
    background-color: white;
    box-shadow: 0 0 10px rgba(0,0,0,0.1);
    display: none;
}

input[type="text"] {
    width: 100%;
    padding: 8px;
    margin: 8px 0;
    box-sizing: border-box;
    border: 1px solid #ddd;
    border-radius: 4px;
}

.back {
    background-color: #f44336;
}

.back:hover {
    background-color: #d32f2f;
}
</style>
</head>
<body>
    <button onclick="window.location.href='room.html'">房间管理</button>
    <table>
        <thead></thead>
        <tbody>
            <tr>
                <th>id</th>
                <th>姓名</th>
                <th>密码</th>
                <th>电话</th>
                <th>身份证</th>
                <th>状态</th>
                <th>操作</th>
            </tr>
        </tbody>
    </table>
    
    <div class="updateModel">
        姓名:<input type='text' class='upname'><br>
        密码:<input type='text' class='uppassword'><br>
        电话:<input type='text' class='upphone'><br>
        身份证:<input type='text' class='upidcard'><br>
        状态:<input type='text' class='upstatus' list="optionList"><br>
        
        <datalist id="optionList">
	<option value="入住">入住</option>
	<option value="未入住">未入住</option>
		</datalist>
        
        <input type='button' value='更新' class='upBtn'>
        <input type='button' value='取消' class='back'>
    </div>
    
    <div class="deleteModel">
        姓名:<input type='text' class='delname'><br>
        密码:<input type='text' class='delpassword'><br>
        电话:<input type='text' class='delphone'><br>
        身份证:<input type='text' class='delidcard'><br>
        状态:<input type='text' class='delstatus'><br>

        <input type='button' value='删除' class='delBtn'>
        <input type='button' value='取消' class='back'>
    </div>
</body>
</html>

 users.js代码如下:

$.ajax({
	url:"users",
	type:"get",	
	success:function(value){
//		alert(value);
//		alert('成功');
		console.log(value)
		var arr=value.data
		
		for(var i=0;i<arr.length;i++){
			$("tbody").append("<tr>"+
					"<td>"+arr[i].id+"</td>"+
					"<td>"+arr[i].name+"</td>"+
					"<td>"+arr[i].password+"</td>"+
					"<td>"+arr[i].phone+"</td>"+
					"<td>"+arr[i].id_card+"</td>"+
					"<td>"+arr[i].status+"</td>"+
					"<td><input type='button' value='修改' class='update' index='"+arr[i].id+"'> <input type='button' value='删除' class='delete' index='"+arr[i].id+"'>  </td>"
					+"</tr>")
			
		}
	},
		error:function(){
			alert('登录失败');
		}
		})
	//修改	
		$("tbody").on("click",".update",function(){
//			设置cookie
//			$.cookie("id", $(this).attr("index"))
//			location.href="update.html"
			$(".updateModel").css("display","block")
			var id= $(this).attr("index")
		    $.ajax({
		        url: "SearchById?id="+id,
		        type: "get", 
		        success: function (value) {
//		        	alert("1111");
		        	console.log(value);
		        	var obj=value.data[0];
		        	$(".upname").val(obj.name)
		        	$(".uppassword").val(obj.password)
		        	$(".upphone").val(obj.phone)
		        	$(".upidcard").val(obj.id_card)
		        	$(".upstatus").val(obj.status)
		        	$(".upBtn").attr("index",obj.id)

		        },
		        error: function () {
		            alert("出错啦");
		        }
		    });		
			
		})
//更新
$(".upBtn").click(function(){
			var id= $(this).attr("index")
			var name = $(".upname").val().trim();
		   	var password = $(".uppassword").val().trim();
		   	var phone = $(".upphone").val().trim();
		   	var id_card = $(".upidcard").val().trim();
		   	var status = $(".upstatus").val().trim();
		    $.ajax({
		        url: "userUpdate",
		        type: "post", 
		        data:{id, name, password, phone,id_card,status},
		        success: function (value) {
		        	alert("修改成功")
//		        	alert("1111");
		        	console.log(value);
		        	location.reload();

		        },
		        error: function () {
		            alert("出错啦");
		        }
		    });		
			
		})
		
//	删除	
//点修改小模块展现  未来元素不能直接帮事件,要邦最近的在html已有的上一层元素
$("tbody").on("click",".delete",function(){
	$(".deleteModel").css("display","block")			
	var id= $(this).attr("index")
    $.ajax({
        url: "SearchById?id="+id,
        type: "get", 
        success: function (value) {
//        	alert("1111");
        	console.log(value);
        	var obj=value.data[0];
        	$(".delname").val(obj.name)
        	$(".delpassword").val(obj.password)
        	$(".delphone").val(obj.phone)
        	$(".delidcard").val(obj.id_card)
        	$(".delstatus").val(obj.status)
        	$(".delBtn").attr("index",obj.id)

        },
        error: function () {
            alert("出错啦");
        }
    });		
	
})


//删除
$(".delBtn").click(function(){
	
	var id= $(this).attr("index")
	console.log(id)
    $.ajax({
        url: "DeleteServlet",
        type: "post", 
        data: {id},
        success: function (value) {
            alert(value);
            location.reload();
        },
        error: function () {
            alert("出错啦");
        }
    });



})


//点取消小模块隐藏	
	$(".back").click(function(){
	$(".addModel").css("display","none")
	$(".updateModel").css("display","none")
	$(".deleteModel").css("display","none")
	})

searchbyid代码如下:

package com.qcby.servlet;

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 com.qcby.db.MysqlUtil;

/**
 * Servlet implementation class SearchById
 */
@WebServlet("/SearchById")
public class SearchById extends HttpServlet {
	private static final long serialVersionUID = 1L;
       
    /**
     * @see HttpServlet#HttpServlet()
     */
    public SearchById() {
        super();
        // TODO Auto-generated constructor stub
    }

	/**
	 * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response)
	 */
	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		String id=request.getParameter("id");
//		String sql="select *from room where id="+id;
		String sql="select *from users where id="+id;
		String[] colums= {"id","name","password","phone","id_card","status"};
//		String[] colums= {"id","room_number","status"};
		String res=MysqlUtil.getJsonBySql(sql, colums);
		System.out.println(res);
		response.setContentType("text/json;charset=utf-8");
		response.getWriter().write(res);
	
	}

	/**
	 * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response)
	 */
	protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		// TODO Auto-generated method stub
		doGet(request, response);
	}

}

DeleteServlet代码如下:

package com.qcby.servlet;

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 com.qcby.db.MysqlUtil;
import com.sun.xml.internal.bind.v2.runtime.Name;

/**
 * Servlet implementation class UpdateServlet
 */
@WebServlet("/DeleteServlet")
public class DeleteServlet extends HttpServlet {
	private static final long serialVersionUID = 1L;
       
    /**
     * @see HttpServlet#HttpServlet()
     */
    public DeleteServlet() {
        super();
        // TODO Auto-generated constructor stub
    }

	/**
	 * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response)
	 */
	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		// TODO Auto-generated method stub
		response.getWriter().append("Served at: ").append(request.getContextPath());
	}

	/**
	 * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response)
	 */
	protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		System.out.println("post成功!!");
		String id = request.getParameter("id");
		String sql="DELETE from users where id="+id+";";
		
	    int num=MysqlUtil.del(sql);
	    String res="worng";
	    if(num>0) {
	    	res="删除成功";
	    }
	    response.setCharacterEncoding("utf-8");
	    response.getWriter().write(res);
	}

}

房间管理实现的功能包括数据的回显,数据的修改、删除以及添加。

前端代码:

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>房间管理</title>
<script src='js/jquery-3.7.1.min.js'></script>
<script src="js/jquery.cookie.min.js"></script>
<script src='js/room.js' defer></script>

<style>
body {
    font-family: Arial, sans-serif;
    margin: 20px;
    background-color: #f5f5f5;
}

table {
    width: 100%;
    border-collapse: collapse;
    margin-bottom: 20px;
    box-shadow: 0 0 10px rgba(0,0,0,0.1);
}

th, td {
    padding: 12px 15px;
    text-align: left;
    border-bottom: 1px solid #ddd;
}

th {
    background-color: #4CAF50;
    color: white;
}

tr:hover {
    background-color: #f5f5f5;
}

tr:nth-child(even) {
    background-color: #f2f2f2;
}

button, input[type="button"] {
    background-color: #4CAF50;
    color: white;
    padding: 8px 16px;
    border: none;
    border-radius: 4px;
    cursor: pointer;
    margin-right: 10px;
    margin-bottom: 20px;
}

button:hover, input[type="button"]:hover {
    background-color: #45a049;
}

.addModel, .deleteModel, .updateModel {
    width: 300px;
    padding: 20px;
    margin-top: 20px;
    border: 1px solid #ddd;
    border-radius: 5px;
    background-color: white;
    box-shadow: 0 0 10px rgba(0,0,0,0.1);
    display: none;
}

input[type="text"] {
    width: 100%;
    padding: 8px;
    margin: 8px 0;
    box-sizing: border-box;
    border: 1px solid #ddd;
    border-radius: 4px;
}

.back {
    background-color: #f44336;
}

.back:hover {
    background-color: #d32f2f;
}
</style>
</head>
<body>
    <button onclick="window.location.href='users.html'">用户管理</button>
    <input type="button" value='添加' class='add'>
    <table>
        <thead></thead>
        <tbody>
            <tr>
                <th>id</th>
                <th>房间号</th>
                <th>状态</th>
               
                <th>操作</th>
                 <th>住户</th>
            </tr>
        </tbody>
    </table>
    
    <div class="updateModel">
        房间号:<input type='text' class='uproomnumber'><br>
        状态:<input type='text' class='upstatus' list="optionList"><br>
        <datalist id="optionList">
	<option value="available">available</option>
	<option value="occupied">occupied</option>
		</datalist>
        <input type='button' value='更新' class='upBtn'>
        <input type='button' value='取消' class='back'>
    </div>
    
    <div class="deleteModel">
        房间号:<input type='text' class='delroomnumber'><br>
        状态:<input type='text' class='delstatus'><br>
        <input type='button' value='删除' class='delBtn'>
        <input type='button' value='取消' class='back'>
    </div>
    
    <div class='addModel'>
        房间号:<input type='text' class='addroomnumber'><br>
        状态:<input type='text' class='addstatus' list="optionList"><br>
        
<datalist id="optionList">
	<option value="available">available</option>
	<option value="occupied">occupied</option>
</datalist>
        
        <input type='button' value='添加' class='addBtn'>
        <input type='button' value='取消' class='back'>
    </div>
</body>
</html>

room.js代码:

$.ajax({
	url:"ClientCheckInServlet",
	type:"get",	
	success:function(value){
//		alert(value);
//		alert('成功');
		console.log(value)
		var arr=value.data
		
		
		for(var i=0;i<arr.length;i++){
//			---------------------------
			 var residentName = arr[i].resident_name || "空"; // 处理空值情况
//			 ---------------------------
			$("tbody").append("<tr>"+
					"<td>"+arr[i].id+"</td>"+
					"<td>"+arr[i].room_number+"</td>"+
					"<td>"+arr[i].status+"</td>"+
					"<td><input type='button' value='修改' class='update' index='"+arr[i].id+"'> <input type='button' value='删除' class='delete' index='"+arr[i].id+"'>  </td>"
//					------------------------------------
					+
					 "<td>"+residentName+"</td>"+ // 新增住户列
//			        -------------------------------------2
					+"</tr>")
			
		}
	},
		error:function(){
			alert('登录失败');
		}
		})
	//修改	
		$("tbody").on("click",".update",function(){
//			设置cookie
//			$.cookie("id", $(this).attr("index"))
//			location.href="update.html"
			$(".updateModel").css("display","block")
			var id= $(this).attr("index")
		    $.ajax({
		        url: "RoomSearchById?id="+id,
		        type: "get", 
		        success: function (value) {
//		        	alert("1111");
		        	console.log(value);
		        	var obj=value.data[0];
		        	$(".uproomnumber").val(obj.room_number)
		        	$(".upstatus").val(obj.status)
		        	$(".upBtn").attr("index",obj.id)

		        },
		        error: function () {
		            alert("出错啦");
		        }
		    });		
			
		})
//更新
$(".upBtn").click(function(){
			var id= $(this).attr("index")
			var room_number = $(".uproomnumber").val().trim();
		   	var status = $(".upstatus").val().trim();
		    $.ajax({
		        url: "roomUpdate",
		        type: "post", 
		        data:{id, room_number,status},
		        success: function (value) {
		        	alert("修改成功")
//		        	alert("1111");
		        	console.log(value);
		        	location.reload();

		        },
		        error: function () {
		            alert("出错啦");
		        }
		    });		
			
		})
		
//	删除	
//点修改小模块展现  未来元素不能直接帮事件,要邦最近的在html已有的上一层元素
$("tbody").on("click",".delete",function(){
	$(".deleteModel").css("display","block")			
	var id= $(this).attr("index")
    $.ajax({
        url: "RoomSearchById?id="+id,
        type: "get", 
        success: function (value) {
//        	alert("1111");
        	console.log(value);
        	var obj=value.data[0];
        	$(".delroomnumber").val(obj.room_number)
        	$(".delstatus").val(obj.status)
        	$(".delBtn").attr("index",obj.id)

        },
        error: function () {
            alert("出错啦");
        }
    });		
	
})


//删除
$(".delBtn").click(function(){
	
	var id= $(this).attr("index")
	console.log(id)
    $.ajax({
        url: "RoomDeleteServlet",
        type: "post", 
        data: {id},
        success: function (value) {
            alert(value);
            location.reload();
        },
        error: function () {
            alert("出错啦");
        }
    });



})
//点添加小模块展现
$(".add").click(function(){
	$(".addModel").css("display","block")
})
//添加
   $(".addBtn").click(function(){
	var room_number = $(".addroomnumber").val().trim();
    var status = $(".addstatus").val().trim();
    if (room_number === "") {
        alert("房间号不能为空");
        return;
    }
    if (status === "") {
        alert("状态不能为空");
        return;
    }
	
    $.ajax({
        url: "AddServlet",
        type: "post", 
        data: { room_number, status },
        success: function (value) {
            alert(value);
          location.href="room.html"
        },
        error: function () {
            alert("出错啦");
        }
    });	
	
   })		


//点取消小模块隐藏	
	$(".back").click(function(){
	$(".addModel").css("display","none")
	$(".updateModel").css("display","none")
	$(".deleteModel").css("display","none")
	})
	
	
	

RoomDeleteServlet代码如下:

package com.qcby.servlet;

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 com.qcby.db.MysqlUtil;

/**
 * Servlet implementation class RoomDeleteServlet
 */
@WebServlet("/RoomDeleteServlet")
public class RoomDeleteServlet extends HttpServlet {
	private static final long serialVersionUID = 1L;
       
    /**
     * @see HttpServlet#HttpServlet()
     */
    public RoomDeleteServlet() {
        super();
        // TODO Auto-generated constructor stub
    }

	/**
	 * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response)
	 */
	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
	}

	/**
	 * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response)
	 */
	protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		System.out.println("post成功!!");
		String id = request.getParameter("id");
		String sql="DELETE from rooms where id="+id+";";
		
	    int num=MysqlUtil.del(sql);
	    String res="worng";
	    if(num>0) {
	    	res="删除成功";
	    }
	    response.setCharacterEncoding("utf-8");
	    response.getWriter().write(res);
	}

}

RoomSearchById代码如下:

package com.qcby.servlet;

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 com.qcby.db.MysqlUtil;

/**
 * Servlet implementation class RoomSearchById
 */
@WebServlet("/RoomSearchById")
public class RoomSearchById extends HttpServlet {
	private static final long serialVersionUID = 1L;
       
    /**
     * @see HttpServlet#HttpServlet()
     */
    public RoomSearchById() {
        super();
        // TODO Auto-generated constructor stub
    }

	/**
	 * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response)
	 */
	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		String id=request.getParameter("id");
		String sql="select *from rooms where id="+id;
//		String sql="select *from users where id="+id;
//		String[] colums= {"id","name","password","phone","id_card","status"};
		String[] colums= {"id","room_number","status"};
		String res=MysqlUtil.getJsonBySql(sql, colums);
		System.out.println(res);
		response.setContentType("text/json;charset=utf-8");
		response.getWriter().write(res);
	}

	/**
	 * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response)
	 */
	protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

	}

}

roomUpdate代码如下:

package com.qcby.servlet;

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 com.qcby.db.MysqlUtil;

/**
 * Servlet implementation class roomUpdate
 */
@WebServlet("/roomUpdate")
public class roomUpdate extends HttpServlet {
	private static final long serialVersionUID = 1L;
       
    /**
     * @see HttpServlet#HttpServlet()
     */
    public roomUpdate() {
        super();
        // TODO Auto-generated constructor stub
    }

	/**
	 * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response)
	 */
	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
	}

	/**
	 * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response)
	 */
	protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//		System.out.println("update post成功");
		 String id = request.getParameter("id");
		 String room_number = request.getParameter("room_number");
		 String status = request.getParameter("status");
		    if (!"available".equals(status) && !"occupied".equals(status)) {
		        status = "available";  // 设置默认值或抛出异常
		    }
		 String sql = "UPDATE rooms set room_number=\""+room_number+"\",status=\""+status+"\" where id="+id+";";
		 int num=MysqlUtil.update(sql);
	        String res="worng";
		    if(num>0) {
		    	res="修改成功";
		    }
		    response.setCharacterEncoding("utf-8");
		    response.getWriter().write(res);
	}

}

check_in代码的优化:

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>入住管理</title>
<script src="js/jquery-3.7.1.min.js"></script>
<script src="js/jquery.cookie.min.js"></script>
<script>
function checkUserOccupied(userId) {
    return new Promise((resolve) => {
        $.ajax({
            url: "CheckUserOccupancyServlet",
            type: "post",
            data: { user_id: userId },
            async: false,
            success: function(response) {
                resolve(response.occupied);
            }
        });
    });
}

function checkOut() {
    var userId = $.cookie("user_id");
    if (!userId) {
        alert("请先登录");
        return;
    }
    $.ajax({
        url: "CheckOutServlet",
        type: "post",
        data: { user_id: userId },
        success: function(response) {
            if (response.status === "success") {
                alert("退房成功");
                location.reload(); // 退房后刷新页面,重新启用按钮
            } else {
                alert("退房失败:" + response.message);
            }
        }
    });
}

$(document).ready(function() {
    var userId = $.cookie("user_id");
    window.userIsOccupied = false; // 新增全局标记
    
    // 页面加载时检查用户状态并禁用按钮
    if (userId) {
        checkUserOccupied(userId).then(occupied => {
            if (occupied) {
                $(".checkin").prop("disabled", true); // 禁用所有入住按钮
                window.userIsOccupied = true; // 设置已入住标记
            }
        });
    }

    // 加载房间列表(唯一的 AJAX 入口)
    $.ajax({
        url: "ClientCheckInServlet",
        type: "get",
        success: function(value) {
            var rooms = value.data || [];
            $("tbody").empty();
            $("thead").html(`
                <tr>
                    <th>房间ID</th>
                    <th>房间号</th>
                    <th>状态</th>
                    <th>操作</th>
                </tr>
            `);

            rooms.forEach(room => {
                $("tbody").append(`
                    <tr>
                        <td>${room.id}</td>
                        <td>${room.room_number}</td>
                        <td>${room.status === "available" ? "可用" : "已占用"}</td>
                        <td><input type='button' value='入住' class='checkin' 
                            index='${room.id}' 
                            index1='${room.status}' 
                        ></td>
                    </tr>
                `);
            });

            // 入住按钮点击事件(唯一的事件绑定)
            $("tbody").on("click", ".checkin", async function() {
                var roomId = $(this).attr("index");
                var userId = $.cookie("user_id");
                var $thisBtn = $(this); // 缓存当前按钮
                
                if (!userId) {
                    alert("请先登录");
                    return;
                }

                // 强校验:用户已入住时直接阻止(优先级高于后端)
                if (window.userIsOccupied) { 
                    alert("您已入住,不可选择其他房间");
                    return;
                }

                // 前端校验:用户是否已入住(防止按钮未禁用时的非法操作)
                if (await checkUserOccupied(userId)) {
                    alert("您已入住,不可选择其他房间");
                    return;
                }

                // 发送入住请求(严格处理后端响应)
                $.ajax({
                    url: "CheckInServlet",
                    type: "post",
                    data: { room_id: roomId, user_id: userId },
                    success: function(response) {
                        var result = JSON.parse(response);
                        if (result.status === "success") {
                            alert("入住成功!");
                            window.userIsOccupied = true; // 标记已入住
                            $(".checkin").prop("disabled", true); // 禁用所有按钮
                            location.reload(); // 刷新页面更新房间状态
                        } else {
                            // 关键:处理后端错误(如房间已占用、用户已入住)
                            alert("入住失败:" + result.message);
                            // 若房间状态变化,可单独更新当前房间按钮(非必须)
                            // if (result.message === "房间已被占用") $thisBtn.prop("disabled", true);
                        }
                    },
                    error: function() {
                        alert("请求失败,请稍后再试");
                    }
                });
            });
        }
    });
});
</script>
<style>
body {
    font-family: Arial, sans-serif;
    margin: 20px;
    background-color: #f5f5f5;
}

table {
    width: 100%;
    border-collapse: collapse;
    margin-bottom: 20px;
    box-shadow: 0 0 10px rgba(0, 0, 0, 0.1);
}

th, td {
    padding: 12px 15px;
    text-align: left;
    border-bottom: 1px solid #ddd;
}

th {
    background-color: #4CAF50;
    color: white;
}

tr:hover {
    background-color: #f5f5f5;
}

tr:nth-child(even) {
    background-color: #f2f2f2;
}

input[type="button"] {
    padding: 6px 12px;
    background-color: #4CAF50;
    color: white;
    border: none;
    border-radius: 4px;
    cursor: pointer;
}

input[type="button"]:disabled {
    background-color: #cccccc;
    cursor: not-allowed;
}

.checkout-btn {
    margin-top: 20px;
    display: block;
    padding: 10px 20px;
    background-color: #f44336;
    color: white;
    border: none;
    border-radius: 4px;
    cursor: pointer;
}
</style>
</head>
<body>
    <h2>房间入住管理</h2>
    <table>
        <thead></thead>
        <tbody>
            <!-- 动态生成的房间列表 -->
        </tbody>
    </table>
    <button class="checkout-btn" onclick="checkOut()">退房</button>
</body>
</html>

CheckUserOccupancyServlet代码如下:

package com.qcby.servlet;

import java.io.IOException;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;

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 com.qcby.db.MysqlUtil;

/**
 * Servlet implementation class CheckUserOccupancyServlet
 */
@WebServlet("/CheckUserOccupancyServlet")
public class CheckUserOccupancyServlet extends HttpServlet {
	private static final long serialVersionUID = 1L;
       
    /**
     * @see HttpServlet#HttpServlet()
     */
    public CheckUserOccupancyServlet() {
        super();
        // TODO Auto-generated constructor stub
    }

	/**
	 * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response)
	 */
	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		// TODO Auto-generated method stub
		response.getWriter().append("Served at: ").append(request.getContextPath());
	}

	/**
	 * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response)
	 */
	protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
		resp.setContentType("application/json;charset=utf-8");
        int userId = Integer.parseInt(req.getParameter("user_id"));
        
        try (Connection conn = MysqlUtil.getConnection();
             PreparedStatement ps = conn.prepareStatement(
                 "SELECT COUNT(*) FROM check_ins WHERE user_id = ? AND check_out_time IS NULL"
             )) {
            ps.setInt(1, userId);
            ResultSet rs = ps.executeQuery();
            boolean occupied = false;
            if (rs.next()) occupied = rs.getInt(1) > 0;
            resp.getWriter().print("{\"occupied\":" + occupied + "}");
        } catch (Exception e) {
            resp.getWriter().print("{\"occupied\":false}");
        }

	}

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值