diff --git a/src/main/java/com/petstore/controller/AppointmentController.java b/src/main/java/com/petstore/controller/AppointmentController.java index 1c650e8..8f738e2 100644 --- a/src/main/java/com/petstore/controller/AppointmentController.java +++ b/src/main/java/com/petstore/controller/AppointmentController.java @@ -3,6 +3,7 @@ package com.petstore.controller; import com.petstore.entity.Appointment; import com.petstore.service.AppointmentService; import lombok.RequiredArgsConstructor; +import org.springframework.data.domain.Page; import org.springframework.web.bind.annotation.*; import java.util.HashMap; @@ -21,19 +22,41 @@ public class AppointmentController { public Map list( @RequestParam(required = false) Long userId, @RequestParam(required = false) Long storeId, - @RequestParam(required = false) String status) { + @RequestParam(required = false) String status, + @RequestParam(required = false) Integer page, + @RequestParam(required = false) Integer pageSize) { + if (storeId == null && userId == null) { + return Map.of("code", 400, "message", "userId或storeId必填"); + } + List appointments; + boolean usePaging = page != null || pageSize != null; + if (usePaging) { + int pageNo = page == null ? 1 : page; + int size = pageSize == null ? 20 : pageSize; + pageNo = Math.max(pageNo, 1); + size = Math.min(Math.max(size, 1), 200); + Page paged = appointmentService.pageByScope(userId, storeId, status, pageNo - 1, size); + return Map.of( + "code", 200, + "data", paged.getContent(), + "page", pageNo, + "pageSize", size, + "total", paged.getTotalElements(), + "totalPages", paged.getTotalPages(), + "hasNext", paged.hasNext() + ); + } + if (storeId != null) { appointments = (status != null && !status.isEmpty()) ? appointmentService.getByStoreIdAndStatus(storeId, status) : appointmentService.getByStoreId(storeId); - } else if (userId != null) { + } else { appointments = (status != null && !status.isEmpty()) ? appointmentService.getByUserIdAndStatus(userId, status) : appointmentService.getByUserId(userId); - } else { - return Map.of("code", 400, "message", "userId或storeId必填"); } return Map.of("code", 200, "data", appointments); diff --git a/src/main/java/com/petstore/controller/ReportController.java b/src/main/java/com/petstore/controller/ReportController.java index a48e5be..8e8b1ea 100644 --- a/src/main/java/com/petstore/controller/ReportController.java +++ b/src/main/java/com/petstore/controller/ReportController.java @@ -7,6 +7,7 @@ import com.petstore.service.StoreService; import lombok.RequiredArgsConstructor; import org.springframework.web.bind.annotation.*; import org.springframework.beans.factory.annotation.Value; +import org.springframework.data.domain.Page; import java.util.HashMap; import java.util.List; @@ -47,8 +48,22 @@ public class ReportController { @GetMapping("/list") public Map list(@RequestParam(required = false) Long storeId, - @RequestParam(required = false) Long userId) { - List reports = reportService.list(storeId, userId); + @RequestParam(required = false) Long userId, + @RequestParam(required = false) Integer page, + @RequestParam(required = false) Integer pageSize) { + boolean usePaging = page != null || pageSize != null; + List reports; + Page paged = null; + Integer pageNo = null; + Integer size = null; + if (usePaging) { + pageNo = Math.max(page == null ? 1 : page, 1); + size = Math.min(Math.max(pageSize == null ? 20 : pageSize, 1), 200); + paged = reportService.page(storeId, userId, pageNo - 1, size); + reports = paged.getContent(); + } else { + reports = reportService.list(storeId, userId); + } // 附加技师名称,并补全图片URL List> data = reports.stream().map(r -> { Map item = new HashMap<>(); @@ -66,6 +81,17 @@ public class ReportController { item.put("userId", r.getUserId()); return item; }).collect(Collectors.toList()); + if (usePaging && paged != null) { + return Map.of( + "code", 200, + "data", data, + "page", pageNo, + "pageSize", size, + "total", paged.getTotalElements(), + "totalPages", paged.getTotalPages(), + "hasNext", paged.hasNext() + ); + } return Map.of("code", 200, "data", data); } diff --git a/src/main/java/com/petstore/entity/Appointment.java b/src/main/java/com/petstore/entity/Appointment.java index 630bc60..8d10e44 100644 --- a/src/main/java/com/petstore/entity/Appointment.java +++ b/src/main/java/com/petstore/entity/Appointment.java @@ -6,7 +6,13 @@ import java.time.LocalDateTime; @Data @Entity -@Table(name = "t_appointment") +@Table( + name = "t_appointment", + indexes = { + @Index(name = "idx_appt_store_status_time", columnList = "store_id,status,appointment_time"), + @Index(name = "idx_appt_user_status_time", columnList = "user_id,status,appointment_time") + } +) public class Appointment { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) diff --git a/src/main/java/com/petstore/entity/Report.java b/src/main/java/com/petstore/entity/Report.java index 37b5363..e55334c 100644 --- a/src/main/java/com/petstore/entity/Report.java +++ b/src/main/java/com/petstore/entity/Report.java @@ -7,7 +7,14 @@ import java.time.LocalDateTime; @Data @Entity -@Table(name = "t_report") +@Table( + name = "t_report", + indexes = { + @Index(name = "idx_report_appointment_id", columnList = "appointment_id"), + @Index(name = "idx_report_token", columnList = "report_token"), + @Index(name = "idx_report_store_user_time", columnList = "store_id,user_id,create_time") + } +) public class Report { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) diff --git a/src/main/java/com/petstore/entity/ServiceType.java b/src/main/java/com/petstore/entity/ServiceType.java index 81042fa..97e3c18 100644 --- a/src/main/java/com/petstore/entity/ServiceType.java +++ b/src/main/java/com/petstore/entity/ServiceType.java @@ -6,7 +6,12 @@ import java.time.LocalDateTime; @Data @Entity -@Table(name = "t_service_type") +@Table( + name = "t_service_type", + indexes = { + @Index(name = "idx_service_type_store_id", columnList = "store_id") + } +) public class ServiceType { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) diff --git a/src/main/java/com/petstore/entity/Store.java b/src/main/java/com/petstore/entity/Store.java index bbfabd6..64656be 100644 --- a/src/main/java/com/petstore/entity/Store.java +++ b/src/main/java/com/petstore/entity/Store.java @@ -6,7 +6,13 @@ import java.time.LocalDateTime; @Data @Entity -@Table(name = "t_store") +@Table( + name = "t_store", + indexes = { + @Index(name = "idx_store_invite_code", columnList = "invite_code"), + @Index(name = "idx_store_owner_id", columnList = "owner_id") + } +) public class Store { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) diff --git a/src/main/java/com/petstore/entity/User.java b/src/main/java/com/petstore/entity/User.java index e9d4883..6d795c0 100644 --- a/src/main/java/com/petstore/entity/User.java +++ b/src/main/java/com/petstore/entity/User.java @@ -6,7 +6,13 @@ import java.time.LocalDateTime; @Data @Entity -@Table(name = "t_user") +@Table( + name = "t_user", + indexes = { + @Index(name = "idx_user_phone", columnList = "phone"), + @Index(name = "idx_user_store_id", columnList = "store_id") + } +) public class User { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) diff --git a/src/main/java/com/petstore/mapper/AppointmentMapper.java b/src/main/java/com/petstore/mapper/AppointmentMapper.java index ce524a7..5dba41f 100644 --- a/src/main/java/com/petstore/mapper/AppointmentMapper.java +++ b/src/main/java/com/petstore/mapper/AppointmentMapper.java @@ -1,6 +1,8 @@ package com.petstore.mapper; import com.petstore.entity.Appointment; +import org.springframework.data.domain.Page; +import org.springframework.data.domain.Pageable; import org.springframework.data.jpa.repository.JpaRepository; import java.util.List; @@ -10,4 +12,9 @@ public interface AppointmentMapper extends JpaRepository { List findByUserIdAndStatus(Long userId, String status); List findByStoreId(Long storeId); List findByStoreIdAndStatus(Long storeId, String status); + + Page findByUserId(Long userId, Pageable pageable); + Page findByUserIdAndStatus(Long userId, String status, Pageable pageable); + Page findByStoreId(Long storeId, Pageable pageable); + Page findByStoreIdAndStatus(Long storeId, String status, Pageable pageable); } diff --git a/src/main/java/com/petstore/mapper/ReportMapper.java b/src/main/java/com/petstore/mapper/ReportMapper.java index 5a217d9..30895c0 100644 --- a/src/main/java/com/petstore/mapper/ReportMapper.java +++ b/src/main/java/com/petstore/mapper/ReportMapper.java @@ -1,7 +1,29 @@ package com.petstore.mapper; import com.petstore.entity.Report; +import org.springframework.data.domain.Page; +import org.springframework.data.domain.Pageable; import org.springframework.data.jpa.repository.JpaRepository; +import java.util.List; +import java.util.Optional; + public interface ReportMapper extends JpaRepository { + Optional findFirstByAppointmentIdOrderByCreateTimeDesc(Long appointmentId); + + Optional findFirstByReportToken(String reportToken); + + List findByStoreIdOrderByCreateTimeDesc(Long storeId); + + List findByUserIdOrderByCreateTimeDesc(Long userId); + + List findByStoreIdAndUserIdOrderByCreateTimeDesc(Long storeId, Long userId); + + List findAllByOrderByCreateTimeDesc(); + + Page findByStoreId(Long storeId, Pageable pageable); + + Page findByUserId(Long userId, Pageable pageable); + + Page findByStoreIdAndUserId(Long storeId, Long userId, Pageable pageable); } diff --git a/src/main/java/com/petstore/service/AppointmentService.java b/src/main/java/com/petstore/service/AppointmentService.java index 4c6dc61..a9d58a8 100644 --- a/src/main/java/com/petstore/service/AppointmentService.java +++ b/src/main/java/com/petstore/service/AppointmentService.java @@ -3,6 +3,10 @@ package com.petstore.service; import com.petstore.entity.Appointment; import com.petstore.mapper.AppointmentMapper; import lombok.RequiredArgsConstructor; +import org.springframework.data.domain.Page; +import org.springframework.data.domain.PageRequest; +import org.springframework.data.domain.Pageable; +import org.springframework.data.domain.Sort; import org.springframework.stereotype.Service; import java.time.LocalDateTime; @@ -33,6 +37,26 @@ public class AppointmentService { return appointmentMapper.findByStoreIdAndStatus(storeId, status); } + public Page pageByScope(Long userId, Long storeId, String status, int pageNo, int pageSize) { + Pageable pageable = PageRequest.of( + Math.max(pageNo, 0), + Math.max(pageSize, 1), + Sort.by(Sort.Direction.DESC, "appointmentTime") + ); + boolean hasStatus = status != null && !status.isBlank(); + if (storeId != null) { + return hasStatus + ? appointmentMapper.findByStoreIdAndStatus(storeId, status, pageable) + : appointmentMapper.findByStoreId(storeId, pageable); + } + if (userId != null) { + return hasStatus + ? appointmentMapper.findByUserIdAndStatus(userId, status, pageable) + : appointmentMapper.findByUserId(userId, pageable); + } + return Page.empty(pageable); + } + public Appointment getById(Long id) { return appointmentMapper.findById(id).orElse(null); } diff --git a/src/main/java/com/petstore/service/ReportService.java b/src/main/java/com/petstore/service/ReportService.java index b020714..e8c102c 100644 --- a/src/main/java/com/petstore/service/ReportService.java +++ b/src/main/java/com/petstore/service/ReportService.java @@ -7,12 +7,15 @@ import com.petstore.mapper.AppointmentMapper; import com.petstore.mapper.ReportMapper; import com.petstore.mapper.UserMapper; import lombok.RequiredArgsConstructor; +import org.springframework.data.domain.Page; +import org.springframework.data.domain.PageRequest; +import org.springframework.data.domain.Pageable; +import org.springframework.data.domain.Sort; import org.springframework.stereotype.Service; import java.time.LocalDateTime; import java.util.List; import java.util.UUID; -import java.util.stream.Collectors; @Service @RequiredArgsConstructor @@ -64,23 +67,47 @@ public class ReportService { } public Report getByAppointmentId(Long appointmentId) { - return reportMapper.findAll().stream() - .filter(r -> r.getAppointmentId().equals(appointmentId)) - .findFirst() - .orElse(null); + if (appointmentId == null) { + return null; + } + return reportMapper.findFirstByAppointmentIdOrderByCreateTimeDesc(appointmentId).orElse(null); } public Report getByToken(String token) { - return reportMapper.findAll().stream() - .filter(r -> token.equals(r.getReportToken())) - .findFirst() - .orElse(null); + if (token == null || token.isBlank()) { + return null; + } + return reportMapper.findFirstByReportToken(token).orElse(null); } public List list(Long storeId, Long userId) { - return reportMapper.findAll().stream() - .filter(r -> storeId == null || storeId.equals(r.getStoreId())) - .filter(r -> userId == null || userId.equals(r.getUserId())) - .collect(Collectors.toList()); + if (storeId != null && userId != null) { + return reportMapper.findByStoreIdAndUserIdOrderByCreateTimeDesc(storeId, userId); + } + if (storeId != null) { + return reportMapper.findByStoreIdOrderByCreateTimeDesc(storeId); + } + if (userId != null) { + return reportMapper.findByUserIdOrderByCreateTimeDesc(userId); + } + return reportMapper.findAllByOrderByCreateTimeDesc(); + } + + public Page page(Long storeId, Long userId, int pageNo, int pageSize) { + Pageable pageable = PageRequest.of( + Math.max(pageNo, 0), + Math.max(pageSize, 1), + Sort.by(Sort.Direction.DESC, "createTime") + ); + if (storeId != null && userId != null) { + return reportMapper.findByStoreIdAndUserId(storeId, userId, pageable); + } + if (storeId != null) { + return reportMapper.findByStoreId(storeId, pageable); + } + if (userId != null) { + return reportMapper.findByUserId(userId, pageable); + } + return reportMapper.findAll(pageable); } }