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 9a22547954e9fb9361f1274ec15304a473ee78f5..3c0febe66a112052fd516375c2b628950f6103d9 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 @@ -10,6 +10,7 @@ import java.util.List; @RestController @RequestMapping("/api/hospitals") +@PreAuthorize("hasAnyRole('ADMIN', 'HOSPITAL', 'SUPER')") public class HospitalController { @Autowired diff --git a/src/main/java/com/cardiff/client_project/mapper/HospitalMapper.java b/src/main/java/com/cardiff/client_project/mapper/HospitalMapper.java index e2aafbebf621537229d446cff7a22b2e5aeb93fa..eed7b73da213b9ac2b0ef70055c00c893880b81c 100644 --- a/src/main/java/com/cardiff/client_project/mapper/HospitalMapper.java +++ b/src/main/java/com/cardiff/client_project/mapper/HospitalMapper.java @@ -10,10 +10,11 @@ import java.util.stream.Collectors; @Repository public class HospitalMapper { + @Autowired private JdbcTemplate jdbcTemplate; - public List<HospitalDTO> findAvailableBeds(String name) { + public List<HospitalDTO> findAvailableBeds(String name, String location, Integer minBeds) { String sql = """ SELECT h.id AS hospital_id, @@ -27,15 +28,23 @@ public class HospitalMapper { hospital h WHERE h.status = 1 - AND (h.maxAmount - h.amountPatient) > 0 - AND h.name LIKE ? + AND (h.maxAmount - h.amountPatient) > ? + AND (? IS NULL OR h.name LIKE ?) + AND (? IS NULL OR h.address LIKE ?) ORDER BY available_beds DESC, occupancy_rate ASC """; return jdbcTemplate.query(sql, - new Object[]{"%" + name + "%"}, + ps -> { + int paramIndex = 1; + ps.setInt(paramIndex++, minBeds != null ? minBeds : 0); + ps.setString(paramIndex++, name); + ps.setString(paramIndex++, name != null ? "%" + name + "%" : "%"); + ps.setString(paramIndex++, location); + ps.setString(paramIndex++, location != null ? "%" + location + "%" : "%"); + }, (rs, rowNum) -> { HospitalDTO hospital = new HospitalDTO(); hospital.setId(rs.getInt("hospital_id")); @@ -118,4 +127,18 @@ public class HospitalMapper { return hospital; }); } + + public int updateBedCount(int hospitalId, int currentPatients) { + String sql = """ + UPDATE hospital + SET amountPatient = ? + WHERE id = ? + AND maxAmount >= ? + """; + + return jdbcTemplate.update(sql, + currentPatients, + hospitalId, + currentPatients); + } } \ 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 5b8f193c0fa1c1783e6773215956011cab01e29e..5c21a0023b6fd47a94ff1cbbd5aac4341c073a62 100644 --- a/src/main/java/com/cardiff/client_project/mapper/SuperAdminMapper.java +++ b/src/main/java/com/cardiff/client_project/mapper/SuperAdminMapper.java @@ -223,6 +223,271 @@ public class SuperAdminMapper { + /** + * fuzzy query + * @param selectDTO + * @return + */ + public List<SelectVO> selectByItem(SelectDTO selectDTO) { + System.out.println("test:"+selectDTO); + // Get query type + String type = selectDTO.getType(); + // Build the basic SQL and parameter list + StringBuilder sql = new StringBuilder("SELECT * FROM"); + if(type.contains("commonAdmin")){ + sql.append(" common_admin "); + } + if(type.contains("hospital")){ + sql.append(" hospital "); + } + + //Dynamic table name stitching + sql.append(" WHERE 1=1 "); + List<Object> params = new ArrayList<>(); + + //Dynamic concatenation of query conditions + if (selectDTO.getName() != null && selectDTO.getName()!="") { + sql.append(" AND name LIKE ?"); + params.add("%" + selectDTO.getName() + "%"); + } + if (selectDTO.getPhone() != null && selectDTO.getPhone()!="") { + sql.append(" AND phone LIKE ?"); + params.add("%" + selectDTO.getPhone() + "%"); + } + if (selectDTO.getAddress() != null && selectDTO.getAddress()!="") { + sql.append(" AND address LIKE ?"); + params.add("%" + selectDTO.getAddress() + "%"); + } + if (Integer.valueOf(selectDTO.getStatus())!=null) { + sql.append(" AND status = ?, "); + params.add(selectDTO.getStatus()); + } + sql.setLength(sql.length() - 2); + + System.out.println("sql: "+sql.toString()); + List<SelectVO> query = jdbcTemplate.query(sql.toString(), params.toArray(), new BeanPropertyRowMapper<>(SelectVO.class)); + System.out.println("quert"+query); + return query; + + //String type=selectVo.getType(); +// String first="select * from "; +// String second = " where "; +// if(selectVo.getName()!=null){ +// second+="name like '%"+selectVo.getName()+"%'"; +// } +// if(selectVo.getPhone()!=null){ +// second+="phone like '%"+selectVo.getPhone()+"%'"; +// } +// if(selectVo.getAddress()!=null){ +// second+="address like '%"+selectVo.getAddress()+"'"; +// } +// +// +// List<SelectDTO> query=new ArrayList<>(); +// if("commonAdmin".equals(type)){ +// String sql=first+"common_admin"+second; +// System.out.println(sql); +// query = jdbcTemplate.query(sql, new BeanPropertyRowMapper<>(SelectDTO.class)); +// } +// if("hospital".equals(type)){ +// String sql=first+"hospital"+second; +// System.out.println(sql); +// query = jdbcTemplate.query(sql, new BeanPropertyRowMapper<>(SelectDTO.class)); +// } +// System.out.println(query); + } + + /** + * ser registration + * @param commonAdmin + */ + public Result insertUserInform(CommonAdmin commonAdmin) { + + //Check whether the account exists(If the user name and email address are the same, the account is confirmed to exist) + String sql = "SELECT count(id) FROM common_admin where name = ? and email = ?"; + Integer count= jdbcTemplate.queryForObject(sql, new Object[]{commonAdmin.getName(), commonAdmin.getEmail()}, Integer.class); + System.out.println(count); + if(count>0){ + return Result.error(ResponseCode.ACCOUNT_EXISTS_ERROR); + } + + //insert data + SimpleJdbcInsert insert = new SimpleJdbcInsert(jdbcTemplate) + .withTableName("common_admin") + .usingGeneratedKeyColumns("id"); + + Map<String, Object> parameters = new HashMap<>(); + parameters.put("name",commonAdmin.getName()); + parameters.put("password",commonAdmin.getPassword()); + parameters.put("email",commonAdmin.getEmail()); + parameters.put("phone",commonAdmin.getPhone()); + parameters.put("type",commonAdmin.getType()); + parameters.put("status",commonAdmin.getStatus()); + parameters.put("roleId",commonAdmin.getRoleId()); + + Number number = insert.executeAndReturnKey(parameters); + if(number.longValue() > 0){ + return Result.success(ResponseCode.SUCCESS); + }else { + return Result.error(ResponseCode.ERROR); + } + } + + /** + * Batch deletion based on id + * @param ids + * @return + */ + public int[] deleteByIdAndType(List<Integer> ids,String type) { + String sql = ""; + String sql_1=""; + String sql_2=""; + if(type.equals("hospital")){ + sql = "DELETE FROM hospital WHERE id=?"; + sql_1="ALTER TABLE hospital DROP COLUMN id;"; + sql_2="ALTER TABLE hospital ADD COLUMN id INT NOT NULL PRIMARY KEY AUTO_INCREMENT FIRST;"; + } + if(type.equals("commonAdmin")){ + sql = "DELETE FROM common_admin WHERE id=?"; + sql_1="ALTER TABLE common_admin DROP COLUMN id;"; + sql_2="ALTER TABLE common_admin ADD COLUMN id INT NOT NULL PRIMARY KEY AUTO_INCREMENT FIRST;"; + } + List<Object[]> idList = new ArrayList<>(); + // Build parameter list + for (Integer id : ids) { + idList.add(new Object[]{id}); + } + // Batch delete + int[] item = jdbcTemplate.batchUpdate(sql, idList); + jdbcTemplate.update(sql_1); + jdbcTemplate.update(sql_2); + return item; + } + + /** + * select admin + * @return + */ + public List<AdminVO> selectAllAdmin() { + + // Parameterized queries avoid SQL injection + String sql = "SELECT * FROM common_admin ORDER BY status DESC"; + List<AdminVO> query = jdbcTemplate.query(sql,new BeanPropertyRowMapper<>(AdminVO.class)); + return query; + } + + /** + * select hospital + * @return + */ + public List<Hospital> selectAllHospital(){ + + // Parameterized queries avoid SQL injection + String sql = "SELECT * FROM hospital ORDER BY status DESC"; + List<Hospital> query = jdbcTemplate.query(sql, new BeanPropertyRowMapper<>(Hospital.class)); + System.out.println(query); + return query; + } + + + /** + * update data + * @param o + */ + public List update(Object o) { + if(o instanceof CommonAdmin){ + CommonAdmin commonAdmin=(CommonAdmin)o; + StringBuilder sql = new StringBuilder("UPDATE common_admin SET "); + List<Object> params = new ArrayList<>(); + + if (commonAdmin.getName() != null && !commonAdmin.getName().isEmpty()) { + sql.append("name = ?, "); + params.add(commonAdmin.getName()); + } + + if (commonAdmin.getEmail() != null && !commonAdmin.getEmail().isEmpty()) { + sql.append("email = ?, "); + params.add(commonAdmin.getEmail()); + } + + if (commonAdmin.getPhone() != null && !commonAdmin.getPhone().isEmpty()) { + sql.append("phone = ?, "); + params.add(commonAdmin.getPhone()); + } + if (Integer.valueOf(commonAdmin.getStatus())!=null) { + sql.append("status = ?, "); + params.add(commonAdmin.getStatus()); + } + // Remove the last comma and space + sql.setLength(sql.length() - 2); + + // Add the WHERE clause + sql.append(" WHERE id = ?"); + params.add(commonAdmin.getId()); + + jdbcTemplate.update(sql.toString(), params.toArray()); + + List<AdminVO> adminVOS = selectAllAdmin(); + return adminVOS; + + } + if(o instanceof Hospital){ + + Hospital hospital = (Hospital) o; + System.out.println("hospital"+hospital); + StringBuilder sql = new StringBuilder("UPDATE hospital SET "); + List<Object> params = new ArrayList<>(); + + if (hospital.getEmail() != null && !hospital.getEmail().isEmpty()) { + sql.append("email = ?, "); + params.add(hospital.getEmail()); + } + + if (hospital.getName() != null && !hospital.getName().isEmpty()) { + sql.append("name = ?, "); + params.add(hospital.getName()); + } + + if (hospital.getPhone() != null && !hospital.getPhone().isEmpty()) { + sql.append("phone = ?, "); + params.add(hospital.getPhone()); + } + + if (Integer.valueOf(hospital.getStatus()) != null) { + sql.append("status = ?, "); + params.add(hospital.getStatus()); + } + + if (hospital.getAddress() != null && !hospital.getAddress().isEmpty()) { + sql.append("address = ?, "); + params.add(hospital.getAddress()); + } + + if ((Integer.valueOf(hospital.getMaxAmount()) != null)){ + sql.append("maxAmount = ?, "); + params.add(hospital.getMaxAmount()); + } + + if (Integer.valueOf(hospital.getAmountPatient()) != null) { + sql.append("amountPatient = ?, "); + params.add(hospital.getAmountPatient()); + } + + + sql.setLength(sql.length() - 2); + sql.append(" WHERE id = ?"); + params.add(hospital.getId()); + + jdbcTemplate.update(sql.toString(), params.toArray()); + + List<Hospital> hospitals = selectAllHospital(); + return hospitals; + } + return null; + } + + + /** * fuzzy query * @param selectDTO 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 index ac7f8bd094a53a25e336ba6d9ce10d17a0f56543..23b4540816937c3538dd758918c2b1ca8505130a 100644 --- a/src/main/java/com/cardiff/client_project/service/imp/HospitalServiceImpl.java +++ b/src/main/java/com/cardiff/client_project/service/imp/HospitalServiceImpl.java @@ -76,4 +76,17 @@ public class HospitalServiceImpl implements HospitalService { return Result.error("Error fetching hospitals: " + e.getMessage()); } } + + @Override + public Result updateBedCount(int hospitalId, int currentPatients) { + try { + int result = hospitalMapper.updateBedCount(hospitalId, currentPatients); + if (result > 0) { + return Result.success("Bed count updated successfully"); + } + return Result.error("Failed to update bed count - check capacity limits"); + } catch (Exception e) { + return Result.error("Error updating bed count: " + 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 index b2ba53f45371d34df99d68fc4670e3064566680c..a4e0cdfaad170e03267217d21b6f5fc07609866f 100644 --- a/src/main/resources/static/css/beds.css +++ b/src/main/resources/static/css/beds.css @@ -1,302 +1,247 @@ +/* Base Styles */ body { - - font-family: 'Arial', sans-serif; - + font-family: 'Poppins', sans-serif; margin: 0; - padding: 0; - - background-color: #f4f4f9; - - color: #333; - + background: linear-gradient(135deg, #f6f8fd 0%, #f1f4f9 100%); + color: #2c3e50; } - - -/* Header */ - +/* Header Styling */ header { - - background-color: #003366; - + background: linear-gradient(135deg, #1f2937 0%, #374151 100%); color: white; - text-align: center; - - padding: 20px 0; - - box-shadow: 0px 4px 8px rgba(0, 0, 0, 0.1); - + padding: 2rem 0; + box-shadow: 0 4px 15px rgba(0, 0, 0, 0.1); + margin-bottom: 2rem; } - - header h1 { - - margin: 0; - font-size: 2.5rem; - + margin: 0; + font-weight: 600; + letter-spacing: 0.5px; } - - header p { - - margin: 10px 0 0; - font-size: 1.1rem; - + margin-top: 0.5rem; + opacity: 0.9; } +/* Main Container */ +.main-container { + max-width: 1400px; + margin: 0 auto; + padding: 0 2rem; +} - -/* Toolbar */ - +/* Toolbar Section */ #toolbar { - + background: white; + padding: 1.5rem; + border-radius: 12px; + box-shadow: 0 4px 6px rgba(0, 0, 0, 0.05); + margin-bottom: 2rem; 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); - + align-items: center; + gap: 1rem; + flex-wrap: wrap; } - - -/* 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; - + padding: 0.75rem 1rem; + border: 2px solid #e5e7eb; + border-radius: 8px; + font-size: 0.95rem; + transition: all 0.3s ease; + min-width: 200px; } - - -.add-btn { - - background-color: #28a745; - - color: white; - +.searchBox:focus { + border-color: #3b82f6; + box-shadow: 0 0 0 3px rgba(59, 130, 246, 0.1); + outline: none; } - - -.add-btn:hover { - - background-color: #218838; - -} - - - -/* Table Styles */ - +/* Table Styling */ .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); - + background: white; + border-radius: 12px; + box-shadow: 0 4px 6px rgba(0, 0, 0, 0.05); + overflow: hidden; + margin-bottom: 2rem; } - - table { - width: 100%; + border-collapse: separate; + border-spacing: 0; +} - border-collapse: collapse; - +th { + background: #f8fafc; + color: #1f2937; + font-weight: 600; + padding: 1.25rem 1rem; text-align: left; - + border-bottom: 2px solid #e5e7eb; } - - -table th, table td { - - padding: 10px 15px; - - border: 1px solid #ddd; - +td { + padding: 1.25rem 1rem; + border-bottom: 1px solid #e5e7eb; + color: #4b5563; } +tr:hover td { + background-color: #f8fafc; +} +/* Button Styling */ +.btn { + padding: 0.75rem 1.5rem; + border-radius: 8px; + font-weight: 500; + cursor: pointer; + transition: all 0.3s ease; + border: none; + font-size: 0.95rem; +} -table th { - - background-color: #003366; - +.primary-btn { + background: #3b82f6; color: white; - } - - -table tbody tr:nth-child(even) { - - background-color: #f9f9f9; - +.primary-btn:hover { + background: #2563eb; + transform: translateY(-1px); } - - -table tbody tr:hover { - - background-color: #f1f1f1; - +.secondary-btn { + background: #e5e7eb; + color: #4b5563; } +.secondary-btn:hover { + background: #d1d5db; +} - -/* Modal Styles */ - -#overlay { - - display: none; - +/* Modal Styling */ +.modal-overlay { position: fixed; - top: 0; - left: 0; - - width: 100%; - - height: 100%; - - background-color: rgba(0, 0, 0, 0.8); - + right: 0; + bottom: 0; + background: rgba(0, 0, 0, 0.5); + display: flex; + align-items: center; + justify-content: center; z-index: 1000; - + backdrop-filter: blur(4px); } - - -#formContainer { - - background-color: white; - - padding: 20px; - - border-radius: 10px; - - max-width: 500px; - - margin: 100px auto; - - position: relative; - - text-align: left; - +.modal { + background: white; + border-radius: 12px; + padding: 2rem; + width: 90%; + max-width: 600px; + box-shadow: 0 20px 25px -5px rgba(0, 0, 0, 0.1); } - - -#formContainer h2 { - - margin-top: 0; - - color: #333; - +.modal-header { + margin-bottom: 1.5rem; } +.modal-header h2 { + font-size: 1.5rem; + color: #1f2937; + margin: 0; +} +.form-group { + margin-bottom: 1.5rem; +} -#formContainer form input, - -#formContainer form button { +.form-group label { + display: block; + margin-bottom: 0.5rem; + color: #4b5563; + font-weight: 500; +} +.form-group input { width: 100%; - - margin-bottom: 15px; - + padding: 0.75rem; + border: 2px solid #e5e7eb; + border-radius: 8px; + transition: all 0.3s ease; } - - -.cancel-btn { - - background-color: #dc3545; - - color: white; - +.form-group input:focus { + border-color: #3b82f6; + box-shadow: 0 0 0 3px rgba(59, 130, 246, 0.1); + outline: none; } +/* Status Indicators */ +.status-badge { + padding: 0.5rem 1rem; + border-radius: 9999px; + font-size: 0.875rem; + font-weight: 500; + display: inline-block; +} +.status-available { + background: #dcfce7; + color: #166534; +} -.cancel-btn:hover { +.status-limited { + background: #fff7ed; + color: #9a3412; +} - background-color: #c82333; +.status-full { + background: #fef2f2; + color: #991b1b; +} +/* Footer */ +footer { + text-align: center; + padding: 2rem 0; + color: #6b7280; + font-size: 0.875rem; +} + +/* Responsive Design */ +@media (max-width: 768px) { + .main-container { + padding: 0 1rem; + } + + #toolbar { + flex-direction: column; + align-items: stretch; + } + + .searchBox { + width: 100%; + } + + th, td { + padding: 1rem 0.75rem; + } + + .btn { + width: 100%; + margin-bottom: 0.5rem; + } } diff --git a/src/main/resources/static/html/beds.html b/src/main/resources/static/html/beds.html index 402a1b3390061d08284d7fea6042a321d0fd9b98..471d94c364065baa41fc56f2edf10dc147787c67 100644 --- a/src/main/resources/static/html/beds.html +++ b/src/main/resources/static/html/beds.html @@ -7,6 +7,7 @@ <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> + <link href="https://fonts.googleapis.com/css2?family=Poppins:wght@400;500;600&display=swap" rel="stylesheet"> </head> <body> <div class="main-container"> diff --git a/src/main/resources/static/js/mainHospitalView.js b/src/main/resources/static/js/mainHospitalView.js index 1e6a9e183c6874cc0af7b47a9784c149e4a06117..9f0ff36d31489d66ad022a1899fc0c5a94d29a8c 100644 --- a/src/main/resources/static/js/mainHospitalView.js +++ b/src/main/resources/static/js/mainHospitalView.js @@ -217,8 +217,14 @@ $(document).on("dblclick","#searchButton",function (){ //use jQuery's load() to load content dynamically,Events cannot be bound in dom mode $(document).on("click", "#searchButton", function () { - let status=document.getElementById("searchStatus").value; - + let status = document.getElementById("searchStatus").value; + + if (status === "active") { + status = 1; + } else if (status === "inactive") { + status = 0; + } else { + status = ""; // Allow all statuses if none selected if(status==="active"){ status=1; } @@ -228,6 +234,16 @@ $(document).on("click", "#searchButton", function () { status=1; } + var data = { + 'name': document.getElementById("searchName").value, + 'phone': document.getElementById("searchPhone").value, + 'address': document.getElementById("searchAddress").value, + 'type': "hospital", + 'status': status + }; + + console.log("Search data:", data); // Debugging line + var data={ 'name':document.getElementById("searchName").value, 'phone':document.getElementById("searchPhone").value, @@ -240,6 +256,12 @@ $(document).on("click", "#searchButton", function () { url: "/superAdmin/select", type: "POST", data: JSON.stringify(data), + dataType: "json", + success: function (response) { + if (response.code !== 0) { + updateTable(response.data); + } else { + alert(response.msg); dataType: "Json", success: function (data) { @@ -250,14 +272,17 @@ $(document).on("click", "#searchButton", function () { alert(data.msg) } }, + error: function (xhr) { + alert('Error during search: ' + xhr.responseText); + } }); }); function updateTable(data) { - let tbody = $("table tbody"); // choose table's tbody - tbody.empty(); // clean old data - console.log(data) - // create new table + let tbody = $("table tbody"); + tbody.empty(); + console.log("Table data:", data); // Debugging line + data.forEach(row => { const tr = ` <tr