From 3298574159e697b457623316bd96ff9fe01b24d2 Mon Sep 17 00:00:00 2001 From: MaDaLei Date: Thu, 16 Apr 2026 21:20:28 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E6=B4=97=E7=BE=8E=E6=8A=A5=E5=91=8A?= =?UTF-8?q?=E5=9B=BE=E7=89=87=E8=A1=A8=E9=87=8D=E6=9E=84=20-=20ReportImage?= =?UTF-8?q?=E5=AE=9E=E4=BD=93=EF=BC=8C=E6=94=AF=E6=8C=81=E5=A4=9A=E5=9B=BE?= =?UTF-8?q?=E4=B8=8A=E4=BC=A0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../petstore/controller/ReportController.java | 39 +++++++-- src/main/java/com/petstore/entity/Report.java | 13 +-- .../java/com/petstore/entity/ReportImage.java | 47 +++++++++++ .../petstore/mapper/ReportImageMapper.java | 16 ++++ .../com/petstore/mapper/ReportMapper.java | 1 + .../com/petstore/service/ReportService.java | 84 +++++++++++++------ 6 files changed, 162 insertions(+), 38 deletions(-) create mode 100644 src/main/java/com/petstore/entity/ReportImage.java create mode 100644 src/main/java/com/petstore/mapper/ReportImageMapper.java diff --git a/src/main/java/com/petstore/controller/ReportController.java b/src/main/java/com/petstore/controller/ReportController.java index 8e8b1ea..9a721f5 100644 --- a/src/main/java/com/petstore/controller/ReportController.java +++ b/src/main/java/com/petstore/controller/ReportController.java @@ -1,6 +1,7 @@ package com.petstore.controller; import com.petstore.entity.Report; +import com.petstore.entity.ReportImage; import com.petstore.entity.Store; import com.petstore.service.ReportService; import com.petstore.service.StoreService; @@ -9,9 +10,7 @@ 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; -import java.util.Map; +import java.util.*; import java.util.stream.Collectors; @RestController @@ -75,10 +74,23 @@ public class ReportController { item.put("staffName", r.getStaffName()); item.put("reportToken", r.getReportToken()); item.put("createTime", r.getCreateTime()); - item.put("beforePhoto", fullUrl(r.getBeforePhoto())); - item.put("afterPhoto", fullUrl(r.getAfterPhoto())); item.put("storeId", r.getStoreId()); item.put("userId", r.getUserId()); + // 图片列表 + List imgs = r.getImages(); + List beforePhotos = new ArrayList<>(); + List afterPhotos = new ArrayList<>(); + if (imgs != null) { + for (ReportImage img : imgs) { + if ("before".equals(img.getPhotoType())) { + beforePhotos.add(fullUrl(img.getPhotoUrl())); + } else if ("after".equals(img.getPhotoType())) { + afterPhotos.add(fullUrl(img.getPhotoUrl())); + } + } + } + item.put("beforePhotos", beforePhotos); + item.put("afterPhotos", afterPhotos); return item; }).collect(Collectors.toList()); if (usePaging && paged != null) { @@ -115,8 +127,21 @@ public class ReportController { Map data = new HashMap<>(); data.put("id", report.getId()); data.put("appointmentId", report.getAppointmentId()); - data.put("beforePhoto", report.getBeforePhoto()); - data.put("afterPhoto", report.getAfterPhoto()); + // 图片列表 + List imgs = report.getImages(); + List beforePhotos = new ArrayList<>(); + List afterPhotos = new ArrayList<>(); + if (imgs != null) { + for (ReportImage img : imgs) { + if ("before".equals(img.getPhotoType())) { + beforePhotos.add(img.getPhotoUrl()); + } else if ("after".equals(img.getPhotoType())) { + afterPhotos.add(img.getPhotoUrl()); + } + } + } + data.put("beforePhotos", beforePhotos); + data.put("afterPhotos", afterPhotos); data.put("remark", report.getRemark()); data.put("userId", report.getUserId()); data.put("storeId", report.getStoreId()); diff --git a/src/main/java/com/petstore/entity/Report.java b/src/main/java/com/petstore/entity/Report.java index e55334c..5204dbe 100644 --- a/src/main/java/com/petstore/entity/Report.java +++ b/src/main/java/com/petstore/entity/Report.java @@ -2,8 +2,11 @@ package com.petstore.entity; import jakarta.persistence.*; import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.annotation.JsonIgnore; import lombok.Data; import java.time.LocalDateTime; +import java.util.ArrayList; +import java.util.List; @Data @Entity @@ -24,14 +27,12 @@ public class Report { @Column(name = "appointment_id") private Long appointmentId; - @Column(name = "before_photo", columnDefinition = "TEXT") - private String beforePhoto; - - @Column(name = "after_photo", columnDefinition = "TEXT") - private String afterPhoto; - private String remark; + @Transient + @JsonIgnore + private List images = new ArrayList<>(); + @Column(name = "user_id") private Long userId; diff --git a/src/main/java/com/petstore/entity/ReportImage.java b/src/main/java/com/petstore/entity/ReportImage.java new file mode 100644 index 0000000..f337b18 --- /dev/null +++ b/src/main/java/com/petstore/entity/ReportImage.java @@ -0,0 +1,47 @@ +package com.petstore.entity; + +import jakarta.persistence.*; +import com.fasterxml.jackson.annotation.JsonIgnore; +import lombok.Data; +import java.time.LocalDateTime; + +@Data +@Entity +@Table(name = "t_report_image") +public class ReportImage { + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + private Long id; + + @ManyToOne(fetch = FetchType.LAZY) + @JoinColumn(name = "report_id", insertable = false, updatable = false) + @JsonIgnore + private Report report; + + @Column(name = "report_id") + private Long reportId; + + @Column(name = "photo_url", length = 500) + private String photoUrl; + + /** 图片类型:before=服务前,after=服务后 */ + @Column(name = "photo_type", length = 20) + private String photoType; + + /** 排序序号,同类型内按顺序展示 */ + @Column(name = "sort_order") + private Integer sortOrder; + + @Column(name = "create_time") + private LocalDateTime createTime; + + @PrePersist + protected void onCreate() { + if (createTime == null) { + createTime = LocalDateTime.now(); + } + if (sortOrder == null) { + sortOrder = 0; + } + } +} diff --git a/src/main/java/com/petstore/mapper/ReportImageMapper.java b/src/main/java/com/petstore/mapper/ReportImageMapper.java new file mode 100644 index 0000000..f0aca20 --- /dev/null +++ b/src/main/java/com/petstore/mapper/ReportImageMapper.java @@ -0,0 +1,16 @@ +package com.petstore.mapper; + +import com.petstore.entity.ReportImage; +import org.springframework.data.jpa.repository.JpaRepository; + +import java.util.List; + +public interface ReportImageMapper extends JpaRepository { + List findByReportIdOrderBySortOrderAsc(Long reportId); + + List findByReportIdAndPhotoTypeOrderBySortOrderAsc(Long reportId, String photoType); + + void deleteByReportId(Long reportId); + + List findByReportIdIn(List reportIds); +} diff --git a/src/main/java/com/petstore/mapper/ReportMapper.java b/src/main/java/com/petstore/mapper/ReportMapper.java index 30895c0..b34f92c 100644 --- a/src/main/java/com/petstore/mapper/ReportMapper.java +++ b/src/main/java/com/petstore/mapper/ReportMapper.java @@ -26,4 +26,5 @@ public interface ReportMapper extends JpaRepository { Page findByUserId(Long userId, Pageable pageable); Page findByStoreIdAndUserId(Long storeId, Long userId, Pageable pageable); + } diff --git a/src/main/java/com/petstore/service/ReportService.java b/src/main/java/com/petstore/service/ReportService.java index e8c102c..5267052 100644 --- a/src/main/java/com/petstore/service/ReportService.java +++ b/src/main/java/com/petstore/service/ReportService.java @@ -1,11 +1,7 @@ package com.petstore.service; -import com.petstore.entity.Appointment; -import com.petstore.entity.Report; -import com.petstore.entity.User; -import com.petstore.mapper.AppointmentMapper; -import com.petstore.mapper.ReportMapper; -import com.petstore.mapper.UserMapper; +import com.petstore.entity.*; +import com.petstore.mapper.*; import lombok.RequiredArgsConstructor; import org.springframework.data.domain.Page; import org.springframework.data.domain.PageRequest; @@ -21,6 +17,7 @@ import java.util.UUID; @RequiredArgsConstructor public class ReportService { private final ReportMapper reportMapper; + private final ReportImageMapper reportImageMapper; private final AppointmentMapper appointmentMapper; private final UserMapper userMapper; @@ -63,34 +60,68 @@ public class ReportService { report.setCreateTime(LocalDateTime.now()); report.setUpdateTime(LocalDateTime.now()); - return reportMapper.save(report); + + // 先保存 Report 以获取生成的 ID + Report saved = reportMapper.save(report); + + // 处理图片列表:设置 reportId 后通过 reportImageMapper 保存 + if (saved.getImages() != null && !saved.getImages().isEmpty()) { + for (ReportImage img : saved.getImages()) { + img.setReportId(saved.getId()); + reportImageMapper.save(img); + } + } + + return saved; + } + + /** 查询单条报告并填充图片 */ + private Report enrichImages(Report r) { + if (r == null) return null; + List imgs = reportImageMapper.findByReportIdOrderBySortOrderAsc(r.getId()); + r.setImages(imgs); + return r; + } + + /** 批量填充图片(列表用) */ + private List enrichImages(List reports) { + if (reports == null || reports.isEmpty()) return reports; + List ids = reports.stream().map(Report::getId).toList(); + List allImages = reportImageMapper.findByReportIdIn(ids); + java.util.Map> map = allImages.stream() + .collect(java.util.stream.Collectors.groupingBy(ReportImage::getReportId)); + for (Report r : reports) { + r.setImages(map.getOrDefault(r.getId(), java.util.List.of())); + } + return reports; } public Report getByAppointmentId(Long appointmentId) { if (appointmentId == null) { return null; } - return reportMapper.findFirstByAppointmentIdOrderByCreateTimeDesc(appointmentId).orElse(null); + return enrichImages(reportMapper.findFirstByAppointmentIdOrderByCreateTimeDesc(appointmentId).orElse(null)); } public Report getByToken(String token) { if (token == null || token.isBlank()) { return null; } - return reportMapper.findFirstByReportToken(token).orElse(null); + return enrichImages(reportMapper.findFirstByReportToken(token).orElse(null)); } public List list(Long storeId, Long userId) { + List reports; if (storeId != null && userId != null) { - return reportMapper.findByStoreIdAndUserIdOrderByCreateTimeDesc(storeId, userId); + reports = reportMapper.findByStoreIdAndUserIdOrderByCreateTimeDesc(storeId, userId); + } else if (storeId != null) { + reports = reportMapper.findByStoreIdOrderByCreateTimeDesc(storeId); + } else if (userId != null) { + reports = reportMapper.findByUserIdOrderByCreateTimeDesc(userId); + } else { + reports = reportMapper.findAllByOrderByCreateTimeDesc(); } - if (storeId != null) { - return reportMapper.findByStoreIdOrderByCreateTimeDesc(storeId); - } - if (userId != null) { - return reportMapper.findByUserIdOrderByCreateTimeDesc(userId); - } - return reportMapper.findAllByOrderByCreateTimeDesc(); + return enrichImages(reports); } public Page page(Long storeId, Long userId, int pageNo, int pageSize) { @@ -99,15 +130,18 @@ public class ReportService { Math.max(pageSize, 1), Sort.by(Sort.Direction.DESC, "createTime") ); + Page paged; if (storeId != null && userId != null) { - return reportMapper.findByStoreIdAndUserId(storeId, userId, pageable); + paged = reportMapper.findByStoreIdAndUserId(storeId, userId, pageable); + } else if (storeId != null) { + paged = reportMapper.findByStoreId(storeId, pageable); + } else if (userId != null) { + paged = reportMapper.findByUserId(userId, pageable); + } else { + paged = reportMapper.findAll(pageable); } - if (storeId != null) { - return reportMapper.findByStoreId(storeId, pageable); - } - if (userId != null) { - return reportMapper.findByUserId(userId, pageable); - } - return reportMapper.findAll(pageable); + // 填充图片 + enrichImages(paged.getContent()); + return paged; } }