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/config/AuthenticationFailHandler.java b/src/main/java/com/cardiff/client_project/config/AuthenticationFailHandler.java index 0964c4dcac89acbfb08cc6dd9d71e834a0ff73e1..c249d1ffcd59d85db45d6988b8e269ef44c6e956 100644 --- a/src/main/java/com/cardiff/client_project/config/AuthenticationFailHandler.java +++ b/src/main/java/com/cardiff/client_project/config/AuthenticationFailHandler.java @@ -4,7 +4,6 @@ import com.cardiff.client_project.utils.Result; import com.fasterxml.jackson.databind.ObjectMapper; import jakarta.servlet.http.HttpServletRequest; import jakarta.servlet.http.HttpServletResponse; -import org.springframework.context.annotation.Configuration; import org.springframework.security.core.AuthenticationException; import org.springframework.security.web.authentication.AuthenticationFailureHandler; import org.springframework.stereotype.Component; diff --git a/src/main/java/com/cardiff/client_project/config/AuthenticationSuccessHandler.java b/src/main/java/com/cardiff/client_project/config/AuthenticationSuccessHandler.java index a52fa0a18b58a8de7eac16726cb01c25756c2c76..bbb78fd0635be7f4bf19d71a7f0f31804fc2db24 100644 --- a/src/main/java/com/cardiff/client_project/config/AuthenticationSuccessHandler.java +++ b/src/main/java/com/cardiff/client_project/config/AuthenticationSuccessHandler.java @@ -4,8 +4,6 @@ import com.cardiff.client_project.utils.Result; import com.fasterxml.jackson.databind.ObjectMapper; import jakarta.servlet.http.HttpServletRequest; import jakarta.servlet.http.HttpServletResponse; - -import org.springframework.context.annotation.Configuration; import org.springframework.security.core.Authentication; import org.springframework.stereotype.Component; diff --git a/src/main/java/com/cardiff/client_project/config/CustomAuthenticationEntryPoint.java b/src/main/java/com/cardiff/client_project/config/CustomAuthenticationEntryPoint.java index eceecba360311841d3106a720833effa1a73bf80..384904ab09945cdb25b5de3c292b9d055af59126 100644 --- a/src/main/java/com/cardiff/client_project/config/CustomAuthenticationEntryPoint.java +++ b/src/main/java/com/cardiff/client_project/config/CustomAuthenticationEntryPoint.java @@ -1,8 +1,5 @@ package com.cardiff.client_project.config; -import com.cardiff.client_project.constant.ResponseCode; -import com.cardiff.client_project.utils.Result; -import com.fasterxml.jackson.databind.ObjectMapper; import jakarta.servlet.ServletException; import jakarta.servlet.http.HttpServletRequest; import jakarta.servlet.http.HttpServletResponse; diff --git a/src/main/java/com/cardiff/client_project/config/WebMvcConfiguration.java b/src/main/java/com/cardiff/client_project/config/WebMvcConfiguration.java index 3f294c4e54727736c489dfe8a98673653389fee8..1c9e2d0ac6923fed4f6546afd3b547973c0170fb 100644 --- a/src/main/java/com/cardiff/client_project/config/WebMvcConfiguration.java +++ b/src/main/java/com/cardiff/client_project/config/WebMvcConfiguration.java @@ -1,6 +1,5 @@ package com.cardiff.client_project.config; -import org.springframework.context.annotation.Configuration; import org.springframework.stereotype.Component; import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry; import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; diff --git a/src/main/java/com/cardiff/client_project/config/WebSecurityConfig.java b/src/main/java/com/cardiff/client_project/config/WebSecurityConfig.java index e52ca434ba9a6085a7f80a3f3491d6c473293296..52debc2ccae9a26bd0a2f4f41166cfeff9d19532 100644 --- a/src/main/java/com/cardiff/client_project/config/WebSecurityConfig.java +++ b/src/main/java/com/cardiff/client_project/config/WebSecurityConfig.java @@ -2,7 +2,6 @@ package com.cardiff.client_project.config; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.Bean; - import org.springframework.security.config.annotation.web.builders.HttpSecurity; import org.springframework.security.config.core.GrantedAuthorityDefaults; import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; 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..10f4ab017f7afce672ac4fd7af16c9fdf65c754d 100644 --- a/src/main/java/com/cardiff/client_project/controller/ViewController.java +++ b/src/main/java/com/cardiff/client_project/controller/ViewController.java @@ -23,7 +23,7 @@ public class ViewController { @GetMapping("/defaultLoadMain") public String loadMainView_1(Model model) { - Result result = superAdminService.selectAllAdmin(); + Result result = superAdminService.selectAllAdmin(); // Add data to the model model.addAttribute("tableData", result.getData()); return "mainSupAdminView"; @@ -36,7 +36,11 @@ public class ViewController { // Add data to the model System.out.println("result"+result.getData()); model.addAttribute("tableData", result.getData()); - // System.out.println("result"+result.getData()); + // 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 b4a15ea296f4bf12b843f1348a3f743e4e5d1fde..780437bff1c39c9a1d9d3fdcb464793e50d5e075 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 @@ -1 +1,46 @@ -package com.cardiff.client_project.controller.hospital; \ No newline at end of file +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.security.access.prepost.PreAuthorize; +import org.springframework.web.bind.annotation.*; + +import java.util.List; + +@RestController +@RequestMapping("/api/hospitals") +@PreAuthorize("hasAnyRole('ADMIN', 'HOSPITAL', 'SUPER')") +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..eed7b73da213b9ac2b0ef70055c00c893880b81c --- /dev/null +++ b/src/main/java/com/cardiff/client_project/mapper/HospitalMapper.java @@ -0,0 +1,144 @@ +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 location, Integer minBeds) { + 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) > ? + 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, + 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")); + 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; + }); + } + + 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 7a3a35086eb638fd9cb269d2f915a87dc2b6ed30..875327dfaf774e26572f62dc4d1301566e608def 100644 --- a/src/main/java/com/cardiff/client_project/mapper/SuperAdminMapper.java +++ b/src/main/java/com/cardiff/client_project/mapper/SuperAdminMapper.java @@ -304,31 +304,26 @@ public class SuperAdminMapper { */ public Object getInforByName(String username){ + try { + String sql = "select * from super_admin where name=?"; + return jdbcTemplate.queryForObject(sql, new Object[]{username}, new BeanPropertyRowMapper<>(SuperUser.class)); + } catch (Exception s) { try { - // 1. 查询 super_admin 表 - String sql = "select * from super_admin where name=?"; - return jdbcTemplate.queryForObject(sql, new Object[]{username}, new BeanPropertyRowMapper<>(SuperUser.class)); - } catch (Exception s) { + String sql = "select * from hospital where email=?"; + return jdbcTemplate.queryForObject(sql, new Object[]{username}, new BeanPropertyRowMapper<>(Hospital.class)); + } catch (Exception h) { try { - // 2. 查询 hospital 表 - String sql = "select * from hospital where email=?"; - return jdbcTemplate.queryForObject(sql, new Object[]{username}, new BeanPropertyRowMapper<>(Hospital.class)); - } catch (Exception h) { + String sql = "select * from common_admin where email=?"; + return jdbcTemplate.queryForObject(sql, new Object[]{username}, new BeanPropertyRowMapper<>(CommonAdmin.class)); + } catch (Exception c) { try { - // 3. 查询 common_admin 表 - String sql = "select * from common_admin where email=?"; - return jdbcTemplate.queryForObject(sql, new Object[]{username}, new BeanPropertyRowMapper<>(CommonAdmin.class)); - } catch (Exception c) { - try { - // 4. 查询 patient 表 - String sql = "select * from patient where email=?"; - return jdbcTemplate.queryForObject(sql, new Object[]{username}, new BeanPropertyRowMapper<>(Patient.class)); - } catch (Exception p) {} - } + String sql = "select * from patient where email=?"; + return jdbcTemplate.queryForObject(sql, new Object[]{username}, new BeanPropertyRowMapper<>(Patient.class)); + } catch (Exception p) {} } } - // 如果所有查询都为空,返回 null - return null; + } + return null; } /** @@ -381,4 +376,16 @@ public class SuperAdminMapper { return Result.error(ResponseCode.ERROR); } } + + /** + * page select + * @param pageSize + */ + public List<CommonAdmin> selectPageCommonAdmin(Integer pageSize,Integer pageNumber) { + String sql="select * from common_admin LIMIT ? OFFSET ?"; + int offset = (pageNumber - 1) * pageSize; + List<CommonAdmin> query = jdbcTemplate.query(sql, new Object[]{pageSize,offset}, new BeanPropertyRowMapper<>(CommonAdmin.class)); + System.out.println(query); + return query; + } } 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 index 03e782f07ec7e49834727032f01f05700efb0e0d..5a7e1a0b04d0167a18646ed57597bb0c54932a37 100644 --- a/src/main/java/com/cardiff/client_project/service/HospitalService.java +++ b/src/main/java/com/cardiff/client_project/service/HospitalService.java @@ -1,4 +1,15 @@ package com.cardiff.client_project.service; +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(); + Result updateBedCount(int hospitalId, int currentPatients); +} \ 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..79fdb9d580c3f58e0e96ec2b4f0858a331c2bc74 --- /dev/null +++ b/src/main/java/com/cardiff/client_project/service/imp/HospitalServiceImpl.java @@ -0,0 +1,92 @@ +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,"",0); + 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()); + } + } + + @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 new file mode 100644 index 0000000000000000000000000000000000000000..a4e0cdfaad170e03267217d21b6f5fc07609866f --- /dev/null +++ b/src/main/resources/static/css/beds.css @@ -0,0 +1,247 @@ +/* Base Styles */ +body { + font-family: 'Poppins', sans-serif; + margin: 0; + padding: 0; + background: linear-gradient(135deg, #f6f8fd 0%, #f1f4f9 100%); + color: #2c3e50; +} + +/* Header Styling */ +header { + background: linear-gradient(135deg, #1f2937 0%, #374151 100%); + color: white; + text-align: center; + padding: 2rem 0; + box-shadow: 0 4px 15px rgba(0, 0, 0, 0.1); + margin-bottom: 2rem; +} + +header h1 { + font-size: 2.5rem; + margin: 0; + font-weight: 600; + letter-spacing: 0.5px; +} + +header p { + 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 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; + align-items: center; + gap: 1rem; + flex-wrap: wrap; +} + +.searchBox { + padding: 0.75rem 1rem; + border: 2px solid #e5e7eb; + border-radius: 8px; + font-size: 0.95rem; + transition: all 0.3s ease; + min-width: 200px; +} + +.searchBox:focus { + border-color: #3b82f6; + box-shadow: 0 0 0 3px rgba(59, 130, 246, 0.1); + outline: none; +} + +/* Table Styling */ +.table-container { + 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; +} + +th { + background: #f8fafc; + color: #1f2937; + font-weight: 600; + padding: 1.25rem 1rem; + text-align: left; + border-bottom: 2px solid #e5e7eb; +} + +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; +} + +.primary-btn { + background: #3b82f6; + color: white; +} + +.primary-btn:hover { + background: #2563eb; + transform: translateY(-1px); +} + +.secondary-btn { + background: #e5e7eb; + color: #4b5563; +} + +.secondary-btn:hover { + background: #d1d5db; +} + +/* Modal Styling */ +.modal-overlay { + position: fixed; + top: 0; + left: 0; + 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); +} + +.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); +} + +.modal-header { + margin-bottom: 1.5rem; +} + +.modal-header h2 { + font-size: 1.5rem; + color: #1f2937; + margin: 0; +} + +.form-group { + margin-bottom: 1.5rem; +} + +.form-group label { + display: block; + margin-bottom: 0.5rem; + color: #4b5563; + font-weight: 500; +} + +.form-group input { + width: 100%; + padding: 0.75rem; + border: 2px solid #e5e7eb; + border-radius: 8px; + transition: all 0.3s ease; +} + +.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; +} + +.status-limited { + background: #fff7ed; + color: #9a3412; +} + +.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 new file mode 100644 index 0000000000000000000000000000000000000000..471d94c364065baa41fc56f2edf10dc147787c67 --- /dev/null +++ b/src/main/resources/static/html/beds.html @@ -0,0 +1,174 @@ +<!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> + <link href="https://fonts.googleapis.com/css2?family=Poppins:wght@400;500;600&display=swap" rel="stylesheet"> +</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); + } + }); + } + }); +}); diff --git a/src/main/resources/static/js/mainSupAdminView.js b/src/main/resources/static/js/mainSupAdminView.js index ad3e90a1665d6559797168ade084783dcbce797c..8d4328f4f27bf1ae04881fd531bca973f0f1062f 100644 --- a/src/main/resources/static/js/mainSupAdminView.js +++ b/src/main/resources/static/js/mainSupAdminView.js @@ -253,4 +253,23 @@ function updateTable(data) { `; tbody.append(tr); }); -} \ No newline at end of file +} +$(document).on("change","#page-size",function (){ + let pageSize=document.getElementById("page-size").value + $.ajax({ + contentType: "application/json", + url: `/superAdmin/pageSelect?type=commonAdmin&pageSize=${pageSize}`, + type: "GET", + dataType: "Json", + success: function (data) { + console.log(data) + if (data.code != 0) { + updateTable(data.data) + //location.reload() + } else { + alert(data.msg) + } + }, + }) + +}) \ No newline at end of file diff --git a/src/main/resources/templates/mainSupAdminView.html b/src/main/resources/templates/mainSupAdminView.html index ac416b15d3f5a0fb095cc4ebecaa2b9299e38350..c0d52d8c8936318bcfcdc2a215e498caa8fafdb3 100644 --- a/src/main/resources/templates/mainSupAdminView.html +++ b/src/main/resources/templates/mainSupAdminView.html @@ -91,7 +91,14 @@ <button type="button" id="addAdmin" style="margin-right: 170px;margin-left: 20px">Submit</button> <button type="button" onclick="location.reload()">Cancel</button> </div> - +<div> + <select id="page-size"> + <option value="">items per page</option> + <option value="1">1</option> + <option value="2">2</option> + <option value="15">15</option> + </select> +</div> <script src="/js/mainSupAdminView.js"></script> </body> </html> diff --git a/src/test/java/com/cardiff/client_project/SuperAdminControllerTest.java b/src/test/java/com/cardiff/client_project/SuperAdminControllerTest.java deleted file mode 100644 index c173f9d8e76571d6e34666518a1e1cc7089191a3..0000000000000000000000000000000000000000 --- a/src/test/java/com/cardiff/client_project/SuperAdminControllerTest.java +++ /dev/null @@ -1,106 +0,0 @@ -package com.cardiff.client_project; - -import com.cardiff.client_project.pojo.dto.SelectDTO; -import com.cardiff.client_project.pojo.dto.SignUserDTO; -import com.cardiff.client_project.service.SuperAdminService; -import com.cardiff.client_project.utils.Result; -import com.fasterxml.jackson.databind.ObjectMapper; -import org.junit.jupiter.api.Test; -import org.mockito.ArgumentMatchers; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc; -import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.boot.test.mock.mockito.MockBean; -import org.springframework.http.MediaType; -import org.springframework.test.web.servlet.MockMvc; - -import java.util.Arrays; -import java.util.List; - -import static org.mockito.Mockito.*; -import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.*; -import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath; -import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; - -@SpringBootTest -@AutoConfigureMockMvc -public class SuperAdminControllerTest { - - @Autowired - private MockMvc mockMvc; - - @MockBean - private SuperAdminService superAdminService; - - @Test - void testSignIn() throws Exception { - // Construct test data - SignUserDTO signDTO = new SignUserDTO(); - signDTO.setName("testUser"); - signDTO.setPassword("password123"); - - Result expectedResult = Result.success("User registered successfully"); - when(superAdminService.insertUserInform(any(SignUserDTO.class))).thenReturn(expectedResult); - - // post - mockMvc.perform(post("/superAdmin/sign") - .contentType(MediaType.APPLICATION_JSON) - .content(new ObjectMapper().writeValueAsString(signDTO))) - .andExpect(status().isOk()) - .andExpect(jsonPath("$.msg").value("User registered successfully")); - - // Verify that the service layer is invoked - verify(superAdminService, times(1)).insertUserInform(any(SignUserDTO.class)); - } - - @Test - void testDeleteHospitalById() throws Exception { - List<Integer> ids = Arrays.asList(1, 2, 3); - Result mockResult = Result.success("successfully"); - when(superAdminService.deleteById(eq(ids), eq("hospital"))).thenReturn(mockResult); - - mockMvc.perform(delete("/superAdmin/deleteHospitalById") - .contentType(MediaType.APPLICATION_JSON) - .content(new ObjectMapper().writeValueAsString(ids))) - .andExpect(status().isOk()) - .andExpect(jsonPath("$.code").value(1)) - .andExpect(jsonPath("$.msg").value("successfully")); - - verify(superAdminService, times(1)).deleteById(eq(ids), eq("hospital")); - } - - @Test - void testSelectByItem() throws Exception { - SelectDTO selectDTO = new SelectDTO(); - selectDTO.setName("testQuery"); - Result mockResult = Result.success("Query successful"); - when(superAdminService.selectByItem(any(SelectDTO.class))).thenReturn(mockResult); - - mockMvc.perform(post("/superAdmin/select") - .contentType(MediaType.APPLICATION_JSON) - .content(new ObjectMapper().writeValueAsString(selectDTO))) - .andExpect(status().isOk()) - .andExpect(jsonPath("$.code").value(1)) - .andExpect(jsonPath("$.msg").value("Query successful")); - - verify(superAdminService, times(1)).selectByItem(any(SelectDTO.class)); - } - - @Test - void testUpdateById() throws Exception { - SelectDTO selectDTO = new SelectDTO(); - selectDTO.setId(1); - selectDTO.setName("newData"); - Result mockResult = Result.success("Update successful"); - when(superAdminService.update(any(SelectDTO.class))).thenReturn(mockResult); - - mockMvc.perform(put("/superAdmin/update") - .contentType(MediaType.APPLICATION_JSON) - .content(new ObjectMapper().writeValueAsString(selectDTO))) - .andExpect(status().isOk()) - .andExpect(jsonPath("$.code").value(1)) - .andExpect(jsonPath("$.msg").value("Update successful")); - - verify(superAdminService, times(1)).update(any(SelectDTO.class)); - } -}