diff --git a/pom.xml b/pom.xml index 616f2f1..7b7ec21 100644 --- a/pom.xml +++ b/pom.xml @@ -165,6 +165,17 @@ mysql test + + org.apache.poi + poi-ooxml + 5.2.3 + + + javax.servlet + javax.servlet-api + 4.0.1 + provided + diff --git a/src/main/java/org/cmh/backend/Config/SecurityConfig.java b/src/main/java/org/cmh/backend/Config/SecurityConfig.java index c917d0a..c5a4336 100644 --- a/src/main/java/org/cmh/backend/Config/SecurityConfig.java +++ b/src/main/java/org/cmh/backend/Config/SecurityConfig.java @@ -4,6 +4,8 @@ import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.security.config.annotation.web.builders.HttpSecurity; import org.springframework.security.config.annotation.web.configurers.AbstractHttpConfigurer; +import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; +import org.springframework.security.crypto.password.PasswordEncoder; import org.springframework.security.web.SecurityFilterChain; @Configuration @@ -11,13 +13,22 @@ public class SecurityConfig { @Bean public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception { - // Use the new API to disable CSRF + // Disable CSRF http.csrf(AbstractHttpConfigurer::disable) - // Permit all requests + // Permit all requests to all endpoints .authorizeHttpRequests(authorize -> authorize - .anyRequest().permitAll() - ); + .anyRequest().permitAll() // Allow all requests without authentication + ) + // Disable form login + .formLogin(AbstractHttpConfigurer::disable) + // Disable logout + .logout(AbstractHttpConfigurer::disable); return http.build(); } + + @Bean + public PasswordEncoder passwordEncoder() { + return new BCryptPasswordEncoder(); + } } diff --git a/src/main/java/org/cmh/backend/MeetingManagement/controller/MeetingController.java b/src/main/java/org/cmh/backend/MeetingManagement/controller/MeetingController.java new file mode 100644 index 0000000..9da414a --- /dev/null +++ b/src/main/java/org/cmh/backend/MeetingManagement/controller/MeetingController.java @@ -0,0 +1,203 @@ +package org.cmh.backend.MeetingManagement.controller; + +import org.cmh.backend.MeetingManagement.model.Meeting; +import org.cmh.backend.MeetingManagement.service.MeetingService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.*; + +import java.time.LocalDateTime; +import java.time.OffsetDateTime; +import java.time.format.DateTimeFormatter; +import java.util.List; +import java.util.Map; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; +import java.io.IOException; +import org.apache.poi.xssf.usermodel.XSSFWorkbook; +import org.apache.poi.xssf.usermodel.XSSFSheet; +import org.apache.poi.xssf.usermodel.XSSFRow; +import javax.servlet.http.HttpServletResponse; + + +@RestController +@RequestMapping("/meetings") +public class MeetingController { + + @Autowired + private MeetingService meetingService; + + private DateTimeFormatter formatter = DateTimeFormatter.ISO_OFFSET_DATE_TIME; + + @GetMapping("/listAll") + public ResponseEntity> listAll() { + List data = meetingService.getAllMeetings(); + return ResponseEntity.ok(data); + } + + @PostMapping("/addMeeting") + public ResponseEntity add(@RequestBody Map credentials) { + try { + Meeting meeting = new Meeting(); + if (credentials.get("id") != null) { + meeting.setId(Long.parseLong(credentials.get("id"))); + } + meeting.setName(credentials.get("name")); + meeting.setOrganizer(credentials.get("organizer")); + + // Parse startTime and endTime to OffsetDateTime, then convert to LocalDateTime + OffsetDateTime startTime = OffsetDateTime.parse(credentials.get("startTime"), formatter); + OffsetDateTime endTime = OffsetDateTime.parse(credentials.get("endTime"), formatter); + meeting.setStartTime(startTime.toLocalDateTime()); + meeting.setEndTime(endTime.toLocalDateTime()); + + meeting.setContent(credentials.get("content")); + meeting.setStatus(credentials.get("status")); + + Meeting meetingAdd = meetingService.createMeeting(meeting); + return new ResponseEntity<>(meetingAdd, HttpStatus.CREATED); + } catch (Exception e) { + return new ResponseEntity<>(null, HttpStatus.BAD_REQUEST); + } + } + + @PostMapping("/deleteMeeting") + public ResponseEntity delete(@RequestBody Map credentials) { + try { + meetingService.deleteMeeting(Long.valueOf(credentials.get("id"))); + return new ResponseEntity<>("success", HttpStatus.OK); + } catch (Exception e) { + return new ResponseEntity<>("failure", HttpStatus.BAD_REQUEST); + } + } + + + @PostMapping("/updateMeeting") + public ResponseEntity update(@RequestBody Map credentials) { + try { + // Validate and parse id + String idStr = credentials.get("id"); + if (idStr == null || idStr.isEmpty()) { + throw new IllegalArgumentException("ID cannot be null or empty"); + } + Long id = Long.parseLong(idStr); + + // Validate and parse other fields + String name = credentials.get("name"); + if (name == null || name.isEmpty()) { + throw new IllegalArgumentException("Name cannot be null or empty"); + } + + String organizer = credentials.get("organizer"); + if (organizer == null || organizer.isEmpty()) { + throw new IllegalArgumentException("Organizer cannot be null or empty"); + } + + String startTimeStr = credentials.get("startTime"); + if (startTimeStr == null || startTimeStr.isEmpty()) { + throw new IllegalArgumentException("Start time cannot be null or empty"); + } + LocalDateTime startTime = LocalDateTime.parse(startTimeStr, DateTimeFormatter.ISO_LOCAL_DATE_TIME); + + String endTimeStr = credentials.get("endTime"); + if (endTimeStr == null || endTimeStr.isEmpty()) { + throw new IllegalArgumentException("End time cannot be null or empty"); + } + LocalDateTime endTime = LocalDateTime.parse(endTimeStr, DateTimeFormatter.ISO_LOCAL_DATE_TIME); + + String content = credentials.get("content"); + if (content == null || content.isEmpty()) { + throw new IllegalArgumentException("Content cannot be null or empty"); + } + + String status = credentials.get("status"); + if (status == null || status.isEmpty()) { + throw new IllegalArgumentException("Status cannot be null or empty"); + } + + // Create and update meeting + Meeting meeting = new Meeting(); + meeting.setId(id); + meeting.setName(name); + meeting.setOrganizer(organizer); + meeting.setStartTime(startTime); + meeting.setEndTime(endTime); + meeting.setContent(content); + meeting.setStatus(status); + + Meeting updatedMeeting = meetingService.updateMeeting(meeting.getId(), meeting); + return new ResponseEntity<>(updatedMeeting, HttpStatus.OK); + } catch (IllegalArgumentException e) { + return new ResponseEntity<>(null, HttpStatus.BAD_REQUEST); + } catch (Exception e) { + e.printStackTrace(); // 打印异常信息 + return new ResponseEntity<>(null, HttpStatus.INTERNAL_SERVER_ERROR); + } + } + + @PostMapping("/getMeetingById") + public ResponseEntity getById(@RequestBody Map credentials) { + try { + Meeting meeting = meetingService.getMeetingById(Long.valueOf(credentials.get("id"))).orElse(null); + return new ResponseEntity<>(meeting, HttpStatus.OK); + } catch (Exception e) { + return new ResponseEntity<>(null, HttpStatus.BAD_REQUEST); + } + } + + @PostMapping("/searchMeetings") + public ResponseEntity> searchMeetings(@RequestBody Map params) { + String name = params.get("name"); + String organizer = params.get("organizer"); + OffsetDateTime startTimeStr = OffsetDateTime.parse(params.get("startTime"),formatter); + LocalDateTime startTime1 = (startTimeStr.toLocalDateTime()); + //LocalDateTime startTime = startTimeStr != null ? LocalDateTime.parse(startTimeStr) : null; + + List meetings = meetingService.searchMeetings(name, organizer, startTime1); + return new ResponseEntity<>(meetings, HttpStatus.OK); + } + + @PostMapping("/export") + public void exportMeetings(@RequestBody Map params, HttpServletResponse response) { + String name = params.get("name"); + String organizer = params.get("organizer"); + String startTimeStr = params.get("startTime"); + LocalDateTime startTime = startTimeStr != null ? LocalDateTime.parse(startTimeStr) : null; + + List meetings = meetingService.searchMeetings(name, organizer, startTime); + + // 生成Excel文件 + try (XSSFWorkbook workbook = new XSSFWorkbook()) { + XSSFSheet sheet = workbook.createSheet("Meetings"); + XSSFRow header = sheet.createRow(0); + header.createCell(0).setCellValue("会议ID"); + header.createCell(1).setCellValue("会议名称"); + header.createCell(2).setCellValue("组织者"); + header.createCell(3).setCellValue("开始时间"); + header.createCell(4).setCellValue("结束时间"); + header.createCell(5).setCellValue("状态"); + + int rowIdx = 1; + for (Meeting meeting : meetings) { + XSSFRow row = sheet.createRow(rowIdx++); + row.createCell(0).setCellValue(meeting.getId()); + row.createCell(1).setCellValue(meeting.getName()); + row.createCell(2).setCellValue(meeting.getOrganizer()); + row.createCell(3).setCellValue(meeting.getStartTime().toString()); + row.createCell(4).setCellValue(meeting.getEndTime().toString()); + row.createCell(5).setCellValue(meeting.getStatus()); + } + + response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"); + response.setHeader("Content-Disposition", "attachment; filename=meetings.xlsx"); + workbook.write(response.getOutputStream()); + } catch (IOException e) { + e.printStackTrace(); + } + } + + +} \ No newline at end of file diff --git a/src/main/java/org/cmh/backend/MeetingManagement/model/Meeting.java b/src/main/java/org/cmh/backend/MeetingManagement/model/Meeting.java new file mode 100644 index 0000000..ff06aef --- /dev/null +++ b/src/main/java/org/cmh/backend/MeetingManagement/model/Meeting.java @@ -0,0 +1,48 @@ +package org.cmh.backend.MeetingManagement.model; + +import jakarta.persistence.Entity; +import jakarta.persistence.GeneratedValue; +import jakarta.persistence.GenerationType; +import jakarta.persistence.Id; +import lombok.Getter; +import lombok.Setter; +import java.time.LocalDateTime; + +@Setter +@Getter +@Entity +public class Meeting { + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + private Long id; + private String name; + private String organizer; + private LocalDateTime startTime; // Changed to LocalDateTime + private LocalDateTime endTime; // Changed to LocalDateTime + private String content; + private String status; + + public Meeting() {} + + public Meeting(String name, String organizer, LocalDateTime startTime, LocalDateTime endTime, String content, String status) { + this.name = name; + this.organizer = organizer; + this.startTime = startTime; + this.endTime = endTime; + this.content = content; + this.status = status; + } + + @Override + public String toString() { + return "Meeting{" + + "id=" + id + + ", name='" + name + '\'' + + ", organizer='" + organizer + '\'' + + ", startTime=" + startTime + + ", endTime=" + endTime + + ", content='" + content + '\'' + + ", status='" + status + '\'' + + '}'; + } +} \ No newline at end of file diff --git a/src/main/java/org/cmh/backend/MeetingManagement/repository/MeetingRepository.java b/src/main/java/org/cmh/backend/MeetingManagement/repository/MeetingRepository.java new file mode 100644 index 0000000..20a987c --- /dev/null +++ b/src/main/java/org/cmh/backend/MeetingManagement/repository/MeetingRepository.java @@ -0,0 +1,15 @@ +package org.cmh.backend.MeetingManagement.repository; + +import org.cmh.backend.MeetingManagement.model.Meeting; +import org.springframework.data.jpa.repository.JpaRepository; +import java.time.LocalDateTime; +import java.util.List; +import org.springframework.data.jpa.repository.Query; + +public interface MeetingRepository extends JpaRepository { + @Query("SELECT m FROM Meeting m WHERE " + + "(?1 IS NULL OR m.name LIKE %?1%) AND " + + "(?2 IS NULL OR m.organizer LIKE %?2%) AND " + + "(?3 IS NULL OR m.startTime >= ?3)") + List searchMeetings(String name, String organizer, LocalDateTime startTime); +} diff --git a/src/main/java/org/cmh/backend/MeetingManagement/service/MeetingService.java b/src/main/java/org/cmh/backend/MeetingManagement/service/MeetingService.java new file mode 100644 index 0000000..b9de395 --- /dev/null +++ b/src/main/java/org/cmh/backend/MeetingManagement/service/MeetingService.java @@ -0,0 +1,74 @@ +package org.cmh.backend.MeetingManagement.service; + +import org.cmh.backend.MeetingManagement.model.Meeting; +import org.cmh.backend.MeetingManagement.repository.MeetingRepository; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import java.time.LocalDateTime; +import java.util.List; +import java.util.Optional; + +@Service +public class MeetingService { + @Autowired + private MeetingRepository meetingRepository; + + public List getAllMeetings() { + return meetingRepository.findAll(); + } + + public Optional getMeetingById(Long id) { + return meetingRepository.findById(id); + } + + public Meeting createMeeting(Meeting meeting) { + validateMeeting(meeting); + return meetingRepository.save(meeting); + } + + public Meeting updateMeeting(Long id, Meeting meetingDetails) { + validateMeeting(meetingDetails); + Meeting meeting = meetingRepository.findById(id) + .orElseThrow(() -> new RuntimeException("Meeting not found with id " + id)); + meeting.setName(meetingDetails.getName()); + meeting.setOrganizer(meetingDetails.getOrganizer()); + meeting.setStartTime(meetingDetails.getStartTime()); + meeting.setEndTime(meetingDetails.getEndTime()); + meeting.setContent(meetingDetails.getContent()); + meeting.setStatus(meetingDetails.getStatus()); + return meetingRepository.save(meeting); + } + + public void deleteMeeting(Long id) { + Meeting meeting = meetingRepository.findById(id) + .orElseThrow(() -> new RuntimeException("Meeting not found with id " + id)); + meetingRepository.delete(meeting); + } + + private void validateMeeting(Meeting meeting) { + if (meeting.getName() == null || meeting.getName().isEmpty()) { + throw new RuntimeException("会议名称不能为空"); + } + if (meeting.getOrganizer() == null || meeting.getOrganizer().isEmpty()) { + throw new RuntimeException("组织者不能为空"); + } + if (meeting.getStartTime() == null) { + throw new RuntimeException("开始时间不能为空"); + } + if (meeting.getEndTime() == null) { + throw new RuntimeException("结束时间不能为空"); + } + if (meeting.getStatus() == null || meeting.getStatus().isEmpty()) { + throw new RuntimeException("状态不能为空"); + } + } + + + public List searchMeetings(String name, String organizer, LocalDateTime startTime) { + // 根据条件搜索会议 + return meetingRepository.searchMeetings(name, organizer, startTime); + } + } + +