diff --git a/health_care.sql b/health_care.sql index 206a0e40f4866bf4c6c95dd64d6d8cafff2823f5..447016b2c91d59075f9d249633a679ba082d3b5d 100644 --- a/health_care.sql +++ b/health_care.sql @@ -16,8 +16,24 @@ SET NAMES utf8mb4; SET FOREIGN_KEY_CHECKS = 0; - -- ---------------------------- +-- Available beds +-- ---------------------------- +SELECT + id AS hospital_id, + name AS hospital_name, + address AS location, + phone, + maxAmount AS total_beds, + (maxAmount - amountPatient) AS available_beds +FROM + hospital +WHERE + status = 1 + AND (maxAmount - amountPatient) > 0 +ORDER BY + available_beds DESC; + -- ---------------------------- -- Table structure for common_admin -- ---------------------------- DROP TABLE IF EXISTS `common_admin`; diff --git a/src/main/java/com/cardiff/client_project/controller/ViewController.java b/src/main/java/com/cardiff/client_project/controller/ViewController.java index d51626a3e32286b6396cb8b5867a1b7db45bf255..51267180b1f63b4440ded84075269358f7b65e45 100644 --- a/src/main/java/com/cardiff/client_project/controller/ViewController.java +++ b/src/main/java/com/cardiff/client_project/controller/ViewController.java @@ -39,4 +39,8 @@ public class ViewController { // System.out.println("result"+result.getData()); return "mainHospitalView"; } + @GetMapping("/beds") + public String bedsView() { + return "beds"; + } } diff --git a/src/main/java/com/cardiff/client_project/controller/hospital/HospitalController.java b/src/main/java/com/cardiff/client_project/controller/hospital/HospitalController.java index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..9a22547954e9fb9361f1274ec15304a473ee78f5 100644 --- a/src/main/java/com/cardiff/client_project/controller/hospital/HospitalController.java +++ b/src/main/java/com/cardiff/client_project/controller/hospital/HospitalController.java @@ -0,0 +1,44 @@ +package com.cardiff.client_project.controller.hospital; + +import com.cardiff.client_project.pojo.dto.HospitalDTO; +import com.cardiff.client_project.service.HospitalService; +import com.cardiff.client_project.utils.Result; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.*; + +import java.util.List; + +@RestController +@RequestMapping("/api/hospitals") +public class HospitalController { + + @Autowired + private HospitalService hospitalService; + + @GetMapping("/available") + public Result getAvailableBeds( + @RequestParam(required = false, defaultValue = "") String name) { + return hospitalService.getAvailableBeds(name); + } + + @PostMapping + public Result addHospital(@RequestBody HospitalDTO hospitalDTO) { + return hospitalService.insertHospitalInfo(hospitalDTO); + } + + @PutMapping("/{id}") + public Result updateHospital(@PathVariable Integer id, @RequestBody HospitalDTO hospitalDTO) { + hospitalDTO.setId(id); + return hospitalService.updateHospital(hospitalDTO); + } + + @DeleteMapping + public Result deleteHospitals(@RequestBody List<Integer> ids) { + return hospitalService.deleteHospitalById(ids); + } + + @GetMapping + public Result getAllHospitals() { + return hospitalService.getAllHospitals(); + } +} diff --git a/src/main/java/com/cardiff/client_project/mapper/HospitalMapper.java b/src/main/java/com/cardiff/client_project/mapper/HospitalMapper.java new file mode 100644 index 0000000000000000000000000000000000000000..e2aafbebf621537229d446cff7a22b2e5aeb93fa --- /dev/null +++ b/src/main/java/com/cardiff/client_project/mapper/HospitalMapper.java @@ -0,0 +1,121 @@ +package com.cardiff.client_project.mapper; + +import com.cardiff.client_project.pojo.dto.HospitalDTO; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.jdbc.core.JdbcTemplate; +import org.springframework.stereotype.Repository; + +import java.util.List; +import java.util.stream.Collectors; + +@Repository +public class HospitalMapper { + @Autowired + private JdbcTemplate jdbcTemplate; + + public List<HospitalDTO> findAvailableBeds(String name) { + String sql = """ + SELECT + h.id AS hospital_id, + h.name AS hospital_name, + h.address AS location, + h.phone, + h.maxAmount AS total_beds, + (h.maxAmount - h.amountPatient) AS available_beds, + ROUND(((h.amountPatient * 1.0) / h.maxAmount * 100), 1) AS occupancy_rate + FROM + hospital h + WHERE + h.status = 1 + AND (h.maxAmount - h.amountPatient) > 0 + AND h.name LIKE ? + ORDER BY + available_beds DESC, + occupancy_rate ASC + """; + + return jdbcTemplate.query(sql, + new Object[]{"%" + name + "%"}, + (rs, rowNum) -> { + HospitalDTO hospital = new HospitalDTO(); + hospital.setId(rs.getInt("hospital_id")); + hospital.setName(rs.getString("hospital_name")); + hospital.setLocation(rs.getString("location")); + hospital.setPhone(rs.getString("phone")); + hospital.setTotalBeds(rs.getInt("total_beds")); + hospital.setAvailableBeds(rs.getInt("available_beds")); + hospital.setOccupancyRate(rs.getDouble("occupancy_rate")); + return hospital; + }); + } + + public int insertHospital(HospitalDTO hospitalDTO) { + String sql = """ + INSERT INTO hospital (name, address, phone, maxAmount, amountPatient, status) + VALUES (?, ?, ?, ?, 0, 1) + """; + + return jdbcTemplate.update(sql, + hospitalDTO.getName(), + hospitalDTO.getLocation(), + hospitalDTO.getPhone(), + hospitalDTO.getTotalBeds() + ); + } + + public int updateHospital(HospitalDTO hospitalDTO) { + String sql = """ + UPDATE hospital + SET name = ?, + address = ?, + phone = ?, + maxAmount = ? + WHERE id = ? + """; + + return jdbcTemplate.update(sql, + hospitalDTO.getName(), + hospitalDTO.getLocation(), + hospitalDTO.getPhone(), + hospitalDTO.getTotalBeds(), + hospitalDTO.getId() + ); + } + + public int[] deleteHospitalByIds(List<Integer> ids) { + String sql = "DELETE FROM hospital WHERE id = ?"; + List<Object[]> batchArgs = ids.stream() + .map(id -> new Object[]{id}) + .collect(Collectors.toList()); + + return jdbcTemplate.batchUpdate(sql, batchArgs); + } + + public List<HospitalDTO> findAllHospitals() { + String sql = """ + SELECT + h.id AS hospital_id, + h.name AS hospital_name, + h.address AS location, + h.phone, + h.maxAmount AS total_beds, + (h.maxAmount - h.amountPatient) AS available_beds, + ROUND(((h.amountPatient * 1.0) / h.maxAmount * 100), 1) AS occupancy_rate + FROM hospital h + WHERE h.status = 1 + ORDER BY h.name + """; + + return jdbcTemplate.query(sql, (rs, rowNum) -> { + HospitalDTO hospital = new HospitalDTO(); + hospital.setId(rs.getInt("hospital_id")); + hospital.setName(rs.getString("hospital_name")); + hospital.setLocation(rs.getString("location")); + hospital.setPhone(rs.getString("phone")); + hospital.setTotalBeds(rs.getInt("total_beds")); + hospital.setAvailableBeds(rs.getInt("available_beds")); + hospital.setOccupancyRate(rs.getDouble("occupancy_rate")); + return hospital; + }); + } +} \ No newline at end of file diff --git a/src/main/java/com/cardiff/client_project/mapper/SuperAdminMapper.java b/src/main/java/com/cardiff/client_project/mapper/SuperAdminMapper.java index 7a3a35086eb638fd9cb269d2f915a87dc2b6ed30..5b8f193c0fa1c1783e6773215956011cab01e29e 100644 --- a/src/main/java/com/cardiff/client_project/mapper/SuperAdminMapper.java +++ b/src/main/java/com/cardiff/client_project/mapper/SuperAdminMapper.java @@ -30,7 +30,7 @@ import java.util.Map; public class SuperAdminMapper { @Autowired - JdbcTemplate jdbcTemplate;; + JdbcTemplate jdbcTemplate; /** * ser registration diff --git a/src/main/java/com/cardiff/client_project/pojo/dto/HospitalDTO.java b/src/main/java/com/cardiff/client_project/pojo/dto/HospitalDTO.java new file mode 100644 index 0000000000000000000000000000000000000000..15a4f4d57b02ad18433012c53422f898a76c6bb9 --- /dev/null +++ b/src/main/java/com/cardiff/client_project/pojo/dto/HospitalDTO.java @@ -0,0 +1,14 @@ +package com.cardiff.client_project.pojo.dto; + +import lombok.Data; + +@Data +public class HospitalDTO { + private int id; + private String name; + private String location; + private String phone; + private int totalBeds; + private int availableBeds; + private double occupancyRate; +} \ No newline at end of file diff --git a/src/main/java/com/cardiff/client_project/service/HospitalService.java b/src/main/java/com/cardiff/client_project/service/HospitalService.java new file mode 100644 index 0000000000000000000000000000000000000000..77f1a34538d0a1336793664dc38aaf39c589cafd --- /dev/null +++ b/src/main/java/com/cardiff/client_project/service/HospitalService.java @@ -0,0 +1,14 @@ +package com.cardiff.client_project.service.imp; + +import com.cardiff.client_project.pojo.dto.HospitalDTO; +import com.cardiff.client_project.utils.Result; + +import java.util.List; + +public interface HospitalService { + Result getAvailableBeds(String name); + Result insertHospitalInfo(HospitalDTO hospitalDTO); + Result updateHospital(HospitalDTO hospitalDTO); + Result deleteHospitalById(List<Integer> ids); + Result getAllHospitals(); +} \ No newline at end of file diff --git a/src/main/java/com/cardiff/client_project/service/imp/HospitalService.java b/src/main/java/com/cardiff/client_project/service/imp/HospitalService.java deleted file mode 100644 index c91d961556b418fdcbaf66c0debc54f64ccbe123..0000000000000000000000000000000000000000 --- a/src/main/java/com/cardiff/client_project/service/imp/HospitalService.java +++ /dev/null @@ -1,4 +0,0 @@ -package com.cardiff.client_project.service.imp; - -public class HospitalService { -} diff --git a/src/main/java/com/cardiff/client_project/service/imp/HospitalServiceImpl.java b/src/main/java/com/cardiff/client_project/service/imp/HospitalServiceImpl.java new file mode 100644 index 0000000000000000000000000000000000000000..ac7f8bd094a53a25e336ba6d9ce10d17a0f56543 --- /dev/null +++ b/src/main/java/com/cardiff/client_project/service/imp/HospitalServiceImpl.java @@ -0,0 +1,79 @@ +package com.cardiff.client_project.service.impl; + +import com.cardiff.client_project.mapper.HospitalMapper; +import com.cardiff.client_project.pojo.dto.HospitalDTO; +import com.cardiff.client_project.service.HospitalService; +import com.cardiff.client_project.utils.Result; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import java.util.List; + +@Service +public class HospitalServiceImpl implements HospitalService { + + @Autowired + private HospitalMapper hospitalMapper; + + @Override + public Result getAvailableBeds(String name) { + try { + List<HospitalDTO> hospitals = hospitalMapper.findAvailableBeds(name); + if (hospitals.isEmpty()) { + return Result.error("No hospitals with available beds found."); + } + return Result.success(hospitals); + } catch (Exception e) { + return Result.error("Error fetching available beds: " + e.getMessage()); + } + } + + @Override + public Result insertHospitalInfo(HospitalDTO hospitalDTO) { + try { + int result = hospitalMapper.insertHospital(hospitalDTO); + if (result > 0) { + return Result.success("Hospital added successfully."); + } + return Result.error("Failed to add hospital."); + } catch (Exception e) { + return Result.error("Error adding hospital: " + e.getMessage()); + } + } + + @Override + public Result updateHospital(HospitalDTO hospitalDTO) { + try { + int result = hospitalMapper.updateHospital(hospitalDTO); + if (result > 0) { + return Result.success("Hospital updated successfully."); + } + return Result.error("Failed to update hospital."); + } catch (Exception e) { + return Result.error("Error updating hospital: " + e.getMessage()); + } + } + + @Override + public Result deleteHospitalById(List<Integer> ids) { + try { + int[] results = hospitalMapper.deleteHospitalByIds(ids); + if (results.length > 0) { + return Result.success("Hospitals deleted successfully."); + } + return Result.error("No hospitals were deleted."); + } catch (Exception e) { + return Result.error("Error deleting hospitals: " + e.getMessage()); + } + } + + @Override + public Result getAllHospitals() { + try { + List<HospitalDTO> hospitals = hospitalMapper.findAllHospitals(); + return Result.success(hospitals); + } catch (Exception e) { + return Result.error("Error fetching hospitals: " + e.getMessage()); + } + } +} \ No newline at end of file diff --git a/src/main/resources/static/css/beds.css b/src/main/resources/static/css/beds.css new file mode 100644 index 0000000000000000000000000000000000000000..b2ba53f45371d34df99d68fc4670e3064566680c --- /dev/null +++ b/src/main/resources/static/css/beds.css @@ -0,0 +1,302 @@ +body { + + font-family: 'Arial', sans-serif; + + margin: 0; + + padding: 0; + + background-color: #f4f4f9; + + color: #333; + +} + + + +/* Header */ + +header { + + background-color: #003366; + + color: white; + + text-align: center; + + padding: 20px 0; + + box-shadow: 0px 4px 8px rgba(0, 0, 0, 0.1); + +} + + + +header h1 { + + margin: 0; + + font-size: 2.5rem; + +} + + + +header p { + + margin: 10px 0 0; + + font-size: 1.1rem; + +} + + + +/* Toolbar */ + +#toolbar { + + display: flex; + + gap: 15px; + + padding: 20px; + + background-color: #ffffff; + + margin: 20px auto; + + border-radius: 8px; + + max-width: 1200px; + + box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1); + +} + + + +/* Input Fields */ + +.searchBox { + + padding: 10px; + + border: 1px solid #ddd; + + border-radius: 5px; + + font-size: 1rem; + + flex: 1; + +} + + + +/* Buttons */ + +.btn { + + padding: 10px 20px; + + font-size: 1rem; + + border: none; + + border-radius: 5px; + + cursor: pointer; + + transition: background-color 0.3s ease, transform 0.1s ease; + +} + + + +.search-btn { + + background-color: #007bff; + + color: white; + +} + + + +.search-btn:hover { + + background-color: #0056b3; + +} + + + +.add-btn { + + background-color: #28a745; + + color: white; + +} + + + +.add-btn:hover { + + background-color: #218838; + +} + + + +/* Table Styles */ + +.table-container { + + padding: 20px; + + background-color: white; + + border-radius: 8px; + + max-width: 1200px; + + margin: 0 auto; + + box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1); + +} + + + +table { + + width: 100%; + + border-collapse: collapse; + + text-align: left; + +} + + + +table th, table td { + + padding: 10px 15px; + + border: 1px solid #ddd; + +} + + + +table th { + + background-color: #003366; + + color: white; + +} + + + +table tbody tr:nth-child(even) { + + background-color: #f9f9f9; + +} + + + +table tbody tr:hover { + + background-color: #f1f1f1; + +} + + + +/* Modal Styles */ + +#overlay { + + display: none; + + position: fixed; + + top: 0; + + left: 0; + + width: 100%; + + height: 100%; + + background-color: rgba(0, 0, 0, 0.8); + + z-index: 1000; + +} + + + +#formContainer { + + background-color: white; + + padding: 20px; + + border-radius: 10px; + + max-width: 500px; + + margin: 100px auto; + + position: relative; + + text-align: left; + +} + + + +#formContainer h2 { + + margin-top: 0; + + color: #333; + +} + + + +#formContainer form input, + +#formContainer form button { + + width: 100%; + + margin-bottom: 15px; + +} + + + +.cancel-btn { + + background-color: #dc3545; + + color: white; + +} + + + +.cancel-btn:hover { + + background-color: #c82333; + +} + diff --git a/src/main/resources/static/html/beds.html b/src/main/resources/static/html/beds.html new file mode 100644 index 0000000000000000000000000000000000000000..402a1b3390061d08284d7fea6042a321d0fd9b98 --- /dev/null +++ b/src/main/resources/static/html/beds.html @@ -0,0 +1,173 @@ +<!DOCTYPE html> +<html lang="en"> +<head> + <meta charset="UTF-8"> + <meta name="viewport" content="width=device-width, initial-scale=1.0"> + <title>Available Beds Dashboard</title> + <link rel="stylesheet" href="../css/beds.css"> + <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.0.0-beta3/css/all.min.css"> + <script src="https://code.jquery.com/jquery-3.6.0.min.js"></script> +</head> +<body> +<div class="main-container"> + + <!-- Header Section --> + + <header> + + <h1>Hospital Management Dashboard</h1> + + <p>Track and manage hospital bed availability with ease</p> + + </header> + + + + <!-- Toolbar Section --> + + <div id="toolbar"> + + <label for="searchName">Search by Name:</label> + + <input type="text" id="searchName" class="searchBox" placeholder="Enter hospital name..."> + + + + <label for="searchLocation">Location:</label> + + <input type="text" id="searchLocation" class="searchBox" placeholder="Enter location..."> + + + + <label for="searchStatus">Status:</label> + + <select id="searchStatus" class="searchBox"> + + <option value="">All</option> + + <option value="active">Active</option> + + <option value="inactive">Inactive</option> + + </select> + + + + <button id="searchButton" class="btn search-btn">Search</button> + + <button id="addButton" class="btn add-btn">Add Hospital</button> + + </div> + + + + <!-- Table Section --> + + <div class="table-container"> + + <h2>Hospitals with Available Beds</h2> + + <table> + + <thead> + + <tr> + + <th>Hospital ID</th> + + <th>Hospital Name</th> + + <th>Location</th> + + <th>Phone</th> + + <th>Total Beds</th> + + <th>Available Beds</th> + + <th>Actions</th> + + </tr> + + </thead> + + <tbody> + + <!-- Table Rows Populated Dynamically --> + + </tbody> + + </table> + + </div> + +</div> + + + +<!-- Add/Edit Modal --> + +<div id="overlay"> + + <div id="formContainer"> + + <h2 id="modalTitle">Add New Hospital</h2> + + <form id="hospitalForm"> + + <input type="hidden" id="hospitalId"> + + <label for="hospitalName">Hospital Name:</label> + + <input type="text" id="hospitalName" placeholder="Enter hospital name..." required> + + + + <label for="hospitalLocation">Location:</label> + + <input type="text" id="hospitalLocation" placeholder="Enter location..." required> + + + + <label for="hospitalPhone">Phone:</label> + + <input type="text" id="hospitalPhone" placeholder="Enter phone number..." required> + + + + <label for="hospitalTotalBeds">Total Beds:</label> + + <input type="number" id="hospitalTotalBeds" placeholder="Enter total beds..." required> + + + + <label for="hospitalAvailableBeds">Available Beds:</label> + + <input type="number" id="hospitalAvailableBeds" placeholder="Enter available beds..." required> + + + + <button type="submit" class="btn save-btn">Save</button> + + <button type="button" id="cancelButton" class="btn cancel-btn">Cancel</button> + + </form> + + </div> + +</div> + + + +<footer> + + <p>© 2024 Hospital Management System</p> + +</footer> + + + +<script src="../js/beds.js"></script> + +</body> +</html> diff --git a/src/main/resources/static/js/beds.js b/src/main/resources/static/js/beds.js new file mode 100644 index 0000000000000000000000000000000000000000..5d1b183692d3df9f8999ebbb3ec94b21a18fc5e1 --- /dev/null +++ b/src/main/resources/static/js/beds.js @@ -0,0 +1,73 @@ +$(document).ready(function () { + loadHospitals(); + + function loadHospitals() { + $.ajax({ + url: '/api/hospitals/available', + method: 'GET', + success: function(response) { + if(response.code === 200) { + populateTable(response.data); + } else { + alert(response.msg); + } + }, + error: function(xhr) { + alert('Error loading hospitals: ' + xhr.responseText); + } + }); + } + + $("#hospitalForm").submit(function(e) { + e.preventDefault(); + const hospitalData = { + name: $("#hospitalName").val(), + location: $("#hospitalLocation").val(), + phone: $("#hospitalPhone").val(), + totalBeds: parseInt($("#hospitalTotalBeds").val()), + availableBeds: parseInt($("#hospitalAvailableBeds").val()) + }; + + $.ajax({ + url: '/api/hospitals', + method: 'POST', + contentType: 'application/json', + data: JSON.stringify(hospitalData), + success: function(response) { + if(response.code === 200) { + alert('Hospital added successfully'); + $("#overlay").fadeOut(); + loadHospitals(); + } else { + alert(response.msg); + } + }, + error: function(xhr) { + alert('Error adding hospital: ' + xhr.responseText); + } + }); + }); + + // Add delete functionality + $(document).on('click', '.delete-btn', function() { + const hospitalId = $(this).data('id'); + if(confirm('Are you sure you want to delete this hospital?')) { + $.ajax({ + url: '/api/hospitals', + method: 'DELETE', + contentType: 'application/json', + data: JSON.stringify([hospitalId]), + success: function(response) { + if(response.code === 200) { + loadHospitals(); + } else { + alert(response.msg); + } + }, + error: function(xhr) { + alert('Error deleting hospital: ' + xhr.responseText); + } + }); + } + }); +});