From c149d53f7e2245a5699cef00f9d88b12f90c49a4 Mon Sep 17 00:00:00 2001 From: guqing <38999863+guqing@users.noreply.github.com> Date: Thu, 18 Nov 2021 20:28:32 +0800 Subject: [PATCH] feat: support photo likes (#1537) * feat: support photo likes * feat: add CacheLock annotation to likes api --- .../controller/admin/api/PhotoController.java | 9 ++++++++ .../java/run/halo/app/model/dto/PhotoDTO.java | 5 +++++ .../java/run/halo/app/model/entity/Photo.java | 12 +++++++++++ .../halo/app/repository/PhotoRepository.java | 13 ++++++++++++ .../run/halo/app/service/PhotoService.java | 7 +++++++ .../app/service/impl/PhotoServiceImpl.java | 21 ++++++++++++++++++- 6 files changed, 66 insertions(+), 1 deletion(-) diff --git a/src/main/java/run/halo/app/controller/admin/api/PhotoController.java b/src/main/java/run/halo/app/controller/admin/api/PhotoController.java index cb8edb81b..20f49d00b 100644 --- a/src/main/java/run/halo/app/controller/admin/api/PhotoController.java +++ b/src/main/java/run/halo/app/controller/admin/api/PhotoController.java @@ -18,6 +18,8 @@ import org.springframework.web.bind.annotation.PutMapping; import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; +import run.halo.app.cache.lock.CacheLock; +import run.halo.app.cache.lock.CacheParam; import run.halo.app.model.dto.PhotoDTO; import run.halo.app.model.entity.Photo; import run.halo.app.model.params.PhotoParam; @@ -87,6 +89,13 @@ public class PhotoController { return new PhotoDTO().convertFrom(photoService.update(photo)); } + @PutMapping("{photoId:\\d+}/likes") + @ApiOperation("Likes a photo") + @CacheLock(autoDelete = false, traceRequest = true) + public void likes(@PathVariable @CacheParam Integer photoId) { + photoService.increaseLike(photoId); + } + @GetMapping("teams") @ApiOperation("Lists all of photo teams") public List listTeams() { diff --git a/src/main/java/run/halo/app/model/dto/PhotoDTO.java b/src/main/java/run/halo/app/model/dto/PhotoDTO.java index 09b239746..37020aef8 100644 --- a/src/main/java/run/halo/app/model/dto/PhotoDTO.java +++ b/src/main/java/run/halo/app/model/dto/PhotoDTO.java @@ -6,7 +6,10 @@ import run.halo.app.model.dto.base.OutputConverter; import run.halo.app.model.entity.Photo; /** + * Photo dto. + * * @author ryanwang + * @author guqing * @date 2019-03-21 */ @Data @@ -27,4 +30,6 @@ public class PhotoDTO implements OutputConverter { private String location; private String description; + + private Long likes; } diff --git a/src/main/java/run/halo/app/model/entity/Photo.java b/src/main/java/run/halo/app/model/entity/Photo.java index d127ba143..d574f4275 100644 --- a/src/main/java/run/halo/app/model/entity/Photo.java +++ b/src/main/java/run/halo/app/model/entity/Photo.java @@ -13,6 +13,7 @@ import javax.persistence.TemporalType; import lombok.Data; import lombok.EqualsAndHashCode; import lombok.ToString; +import org.hibernate.annotations.ColumnDefault; import org.hibernate.annotations.GenericGenerator; /** @@ -79,6 +80,13 @@ public class Photo extends BaseEntity { @Column(name = "team") private String team; + /** + * Likes. + */ + @Column(name = "likes", nullable = false) + @ColumnDefault("0") + private Long likes; + @Override public void prePersist() { super.prePersist(); @@ -102,5 +110,9 @@ public class Photo extends BaseEntity { if (team == null) { team = ""; } + + if (likes == null || likes < 0) { + likes = 0L; + } } } diff --git a/src/main/java/run/halo/app/repository/PhotoRepository.java b/src/main/java/run/halo/app/repository/PhotoRepository.java index cd4a5fe59..b73c9d54f 100644 --- a/src/main/java/run/halo/app/repository/PhotoRepository.java +++ b/src/main/java/run/halo/app/repository/PhotoRepository.java @@ -3,6 +3,7 @@ package run.halo.app.repository; import java.util.List; import org.springframework.data.domain.Sort; import org.springframework.data.jpa.repository.JpaSpecificationExecutor; +import org.springframework.data.jpa.repository.Modifying; import org.springframework.data.jpa.repository.Query; import run.halo.app.model.entity.Photo; import run.halo.app.repository.base.BaseRepository; @@ -12,6 +13,7 @@ import run.halo.app.repository.base.BaseRepository; * * @author johnniang * @author ryanwang + * @author guqing * @date 2019-04-03 */ public interface PhotoRepository @@ -33,4 +35,15 @@ public interface PhotoRepository */ @Query(value = "select distinct p.team from Photo p") List findAllTeams(); + + /** + * Updates photo likes. + * + * @param likes likes delta + * @param photoId photo id must not be null + * @return updated rows + */ + @Modifying + @Query("update Photo p set p.likes = p.likes + :likes where p.id = :photoId") + int updateLikes(long likes, Integer photoId); } diff --git a/src/main/java/run/halo/app/service/PhotoService.java b/src/main/java/run/halo/app/service/PhotoService.java index 7c1adc081..31bf34e70 100644 --- a/src/main/java/run/halo/app/service/PhotoService.java +++ b/src/main/java/run/halo/app/service/PhotoService.java @@ -79,4 +79,11 @@ public interface PhotoService extends CrudService { * @return list of teams */ List listAllTeams(); + + /** + * Increases photo likes(1). + * + * @param photoId photo id must not be null + */ + void increaseLike(Integer photoId); } diff --git a/src/main/java/run/halo/app/service/impl/PhotoServiceImpl.java b/src/main/java/run/halo/app/service/impl/PhotoServiceImpl.java index f73932882..27875a4b5 100644 --- a/src/main/java/run/halo/app/service/impl/PhotoServiceImpl.java +++ b/src/main/java/run/halo/app/service/impl/PhotoServiceImpl.java @@ -6,6 +6,7 @@ import java.util.Map; import java.util.Set; import java.util.stream.Collectors; import javax.persistence.criteria.Predicate; +import lombok.extern.slf4j.Slf4j; import org.apache.commons.lang3.StringUtils; import org.springframework.data.domain.Page; import org.springframework.data.domain.Pageable; @@ -13,7 +14,9 @@ import org.springframework.data.domain.Sort; import org.springframework.data.jpa.domain.Specification; import org.springframework.lang.NonNull; import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; import org.springframework.util.Assert; +import run.halo.app.exception.BadRequestException; import run.halo.app.model.dto.PhotoDTO; import run.halo.app.model.entity.Photo; import run.halo.app.model.params.PhotoParam; @@ -25,11 +28,13 @@ import run.halo.app.service.base.AbstractCrudService; import run.halo.app.utils.ServiceUtils; /** - * PhotoService implementation class + * PhotoService implementation class. * * @author ryanwang + * @author guqing * @date 2019-03-14 */ +@Slf4j @Service public class PhotoServiceImpl extends AbstractCrudService implements PhotoService { @@ -116,6 +121,20 @@ public class PhotoServiceImpl extends AbstractCrudService implem return photoRepository.findAllTeams(); } + @Override + @Transactional + public void increaseLike(Integer photoId) { + Assert.notNull(photoId, "Photo id must not be null"); + + int affectedRows = photoRepository.updateLikes(1L, photoId); + + if (affectedRows != 1) { + log.error("Photo with id: [{}] may not be found", photoId); + throw new BadRequestException( + "Failed to increase likes 1 for photo with id " + photoId); + } + } + @NonNull private Specification buildSpecByQuery(@NonNull PhotoQuery photoQuery) { Assert.notNull(photoQuery, "Photo query must not be null");