diff --git a/src/main/java/com/petstore/controller/ReportController.java b/src/main/java/com/petstore/controller/ReportController.java index 8899275..fb6244d 100644 --- a/src/main/java/com/petstore/controller/ReportController.java +++ b/src/main/java/com/petstore/controller/ReportController.java @@ -5,6 +5,7 @@ import com.petstore.entity.ReportImage; import com.petstore.entity.Store; import com.petstore.service.ReportHighlightVideoService; import com.petstore.service.ReportService; +import com.petstore.service.ReportTestimonialService; import com.petstore.service.StoreService; import lombok.RequiredArgsConstructor; import org.springframework.http.MediaType; @@ -23,6 +24,7 @@ public class ReportController { private final ReportService reportService; private final StoreService storeService; private final ReportHighlightVideoService reportHighlightVideoService; + private final ReportTestimonialService reportTestimonialService; @Value("${app.base-url:http://localhost:8080}") private String baseUrl; @@ -235,4 +237,30 @@ public class ReportController { } return Map.of("code", 200, "message", "删除成功"); } + + /** + * 宠主寄语(生成分享海报前提交,同一报告覆盖更新;供后续口碑墙) + */ + @PostMapping("/{token}/testimonial") + public Map submitTestimonial(@PathVariable("token") String token, + @RequestBody Map body) { + String content = body.get("content") == null ? "" : body.get("content").toString(); + boolean isPublic = true; + if (body.get("isPublic") != null) { + isPublic = Boolean.parseBoolean(body.get("isPublic").toString()); + } + try { + var row = reportTestimonialService.submit(token, content, isPublic); + return Map.of( + "code", 200, + "data", Map.of( + "id", row.getId(), + "content", row.getContent(), + "isPublic", row.getIsPublic() + ) + ); + } catch (IllegalArgumentException e) { + return Map.of("code", 400, "message", e.getMessage()); + } + } } diff --git a/src/main/java/com/petstore/entity/ReportTestimonial.java b/src/main/java/com/petstore/entity/ReportTestimonial.java new file mode 100644 index 0000000..72ef21b --- /dev/null +++ b/src/main/java/com/petstore/entity/ReportTestimonial.java @@ -0,0 +1,43 @@ +package com.petstore.entity; + +import jakarta.persistence.*; +import lombok.Data; + +import java.time.LocalDateTime; + +/** + * 宠主在生成分享海报时填写的一句话(口碑素材)。 + * 同一报告保留一条:重复提交则更新内容与时间。 + */ +@Data +@Entity +@Table( + name = "t_report_testimonial", + indexes = { + @Index(name = "idx_rt_store_time", columnList = "store_id,create_time") + } +) +public class ReportTestimonial { + + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + private Long id; + + @Column(name = "report_id", nullable = false, unique = true) + private Long reportId; + + @Column(name = "store_id") + private Long storeId; + + @Column(length = 200, nullable = false) + private String content; + + @Column(name = "is_public", nullable = false, columnDefinition = "TINYINT(1) DEFAULT 1") + private Boolean isPublic = true; + + @Column(name = "create_time") + private LocalDateTime createTime; + + @Column(name = "update_time") + private LocalDateTime updateTime; +} diff --git a/src/main/java/com/petstore/mapper/ReportTestimonialMapper.java b/src/main/java/com/petstore/mapper/ReportTestimonialMapper.java new file mode 100644 index 0000000..75fc601 --- /dev/null +++ b/src/main/java/com/petstore/mapper/ReportTestimonialMapper.java @@ -0,0 +1,11 @@ +package com.petstore.mapper; + +import com.petstore.entity.ReportTestimonial; +import org.springframework.data.jpa.repository.JpaRepository; + +import java.util.Optional; + +public interface ReportTestimonialMapper extends JpaRepository { + + Optional findByReportId(Long reportId); +} diff --git a/src/main/java/com/petstore/service/ReportTestimonialService.java b/src/main/java/com/petstore/service/ReportTestimonialService.java new file mode 100644 index 0000000..6e69598 --- /dev/null +++ b/src/main/java/com/petstore/service/ReportTestimonialService.java @@ -0,0 +1,48 @@ +package com.petstore.service; + +import com.petstore.entity.Report; +import com.petstore.entity.ReportTestimonial; +import com.petstore.mapper.ReportMapper; +import com.petstore.mapper.ReportTestimonialMapper; +import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Service; + +import java.time.LocalDateTime; + +@Service +@RequiredArgsConstructor +public class ReportTestimonialService { + + private final ReportMapper reportMapper; + private final ReportTestimonialMapper testimonialMapper; + + /** + * 保存或更新该报告下的宠主寄语(幂等:按 report_id 唯一)。 + */ + public ReportTestimonial submit(String reportToken, String content, boolean isPublic) { + Report report = reportMapper.findFirstByReportTokenAndDeletedFalse(reportToken).orElse(null); + if (report == null) { + throw new IllegalArgumentException("报告不存在或已失效"); + } + if (content == null || content.isBlank()) { + throw new IllegalArgumentException("寄语不能为空"); + } + String trimmed = content.trim(); + if (trimmed.length() > 200) { + throw new IllegalArgumentException("寄语最多 200 字"); + } + + LocalDateTime now = LocalDateTime.now(); + ReportTestimonial row = testimonialMapper.findByReportId(report.getId()).orElse(null); + if (row == null) { + row = new ReportTestimonial(); + row.setReportId(report.getId()); + row.setStoreId(report.getStoreId()); + row.setCreateTime(now); + } + row.setContent(trimmed); + row.setIsPublic(isPublic); + row.setUpdateTime(now); + return testimonialMapper.save(row); + } +}