feat:增加菜谱收藏接口

This commit is contained in:
2025-07-02 19:55:45 +08:00
parent b569a26f5d
commit 7c033e2cbe
12 changed files with 270 additions and 17 deletions

View File

@@ -45,6 +45,12 @@ public class FoodController {
return foodService.queryRecipeByUser(id); return foodService.queryRecipeByUser(id);
} }
@Operation(summary = "查询用户收藏菜谱")
@GetMapping("/recipe/user/favourite")
public List<SummaryDto> queryRecipeUserFavourite() {
return foodService.queryRecipeUserFavourite();
}
@Operation(summary = "查询美食菜谱") @Operation(summary = "查询美食菜谱")
@GetMapping("/recipe") @GetMapping("/recipe")
public List<SummaryDto> queryRecipeSummary(FoodQueryVo foodQueryVo) { public List<SummaryDto> queryRecipeSummary(FoodQueryVo foodQueryVo) {
@@ -116,6 +122,18 @@ public class FoodController {
return foodService.deleteLike(id); return foodService.deleteLike(id);
} }
@Operation(summary = "增加收藏")
@PostMapping("/recipe/{id}/favourite")
public Boolean addFavourite(@PathVariable("id") long id) {
return foodService.addFavourite(id);
}
@Operation(summary = "取消收藏")
@DeleteMapping("/recipe/{id}/favourite")
public Boolean deleteFavourite(@PathVariable("id") long id) {
return foodService.deleteFavourite(id);
}
@Operation(summary = "查询美食类别") @Operation(summary = "查询美食类别")
@GetMapping("/category") @GetMapping("/category")
public List<String> queryCategory() { public List<String> queryCategory() {

View File

@@ -14,6 +14,8 @@ public interface FoodDao {
List<SummaryDto> queryRecipeByUser(@Param("id") Long id); List<SummaryDto> queryRecipeByUser(@Param("id") Long id);
List<SummaryDto> queryRecipeUserFavourite(@Param("user") String user);
IPage<SummaryDto> querySummaryByPage(IPage<SummaryDto> page, IPage<SummaryDto> querySummaryByPage(IPage<SummaryDto> page,
@Param("query") FoodQueryVo foodQueryVo); @Param("query") FoodQueryVo foodQueryVo);

View File

@@ -28,6 +28,9 @@ public class RecipeDto {
@Range(min = 0, max = 5, message = "推荐指数在0-5之间") @Range(min = 0, max = 5, message = "推荐指数在0-5之间")
private Integer recommendRate; private Integer recommendRate;
@Schema(description = "是否分享")
private Boolean isShare;
@Schema(description = "美食食材") @Schema(description = "美食食材")
private List<MaterialDto> materialList; private List<MaterialDto> materialList;
@@ -41,10 +44,26 @@ public class RecipeDto {
@Schema(description = "备注") @Schema(description = "备注")
private String remark; private String remark;
@Schema(description = "用户id")
@JsonView(ReadView.class)
private Long userId;
@Schema(description = "姓名")
@JsonView(ReadView.class)
private String username;
@Schema(description = "头像")
@JsonView(ReadView.class)
private String avatar;
@Schema(description = "点赞用户") @Schema(description = "点赞用户")
@JsonView(ReadView.class) @JsonView(ReadView.class)
private List<Long> likeList; private List<Long> likeList;
@Schema(description = "收藏用户")
@JsonView(ReadView.class)
private List<Long> favouriteList;
@Schema(description = "评论内容") @Schema(description = "评论内容")
@JsonView(ReadView.class) @JsonView(ReadView.class)
private List<CommentDto> commentList; private List<CommentDto> commentList;

View File

@@ -21,12 +21,27 @@ public class SummaryDto {
@Schema(description = "推荐指数") @Schema(description = "推荐指数")
private Integer recommendRate; private Integer recommendRate;
@Schema(description = "是否共享")
private Boolean isShare;
@Schema(description = "美食记录") @Schema(description = "美食记录")
private List<RecordDto> recordList; private List<RecordDto> recordList;
@Schema(description = "点赞总数") @Schema(description = "点赞总数")
private Integer likeCount; private Integer likeCount;
@Schema(description = "收藏总数")
private Integer favouriteCount;
@Schema(description = "评论总数") @Schema(description = "评论总数")
private Integer commentCount; private Integer commentCount;
@Schema(description = "用户id")
private Long userId;
@Schema(description = "姓名")
private String username;
@Schema(description = "头像")
private String avatar;
} }

View File

@@ -0,0 +1,18 @@
package com.cxx.food.entity;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableName;
import com.cxx.framework.data.AbstractEntity;
import lombok.Data;
import lombok.EqualsAndHashCode;
@Data
@EqualsAndHashCode(callSuper = true)
@TableName("favourite_record")
public class FavouriteRecord extends AbstractEntity {
@TableField("type")
private String type;
@TableField("subject_id")
private Long subjectId;
}

View File

@@ -19,6 +19,9 @@ public class Recipe extends AbstractEntity {
@TableField("recommend_rate") @TableField("recommend_rate")
private Integer recommendRate; private Integer recommendRate;
@TableField("is_share")
private Integer isShare;
@TableField("remark") @TableField("remark")
private String remark; private String remark;
} }

View File

@@ -0,0 +1,9 @@
package com.cxx.food.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.cxx.food.entity.FavouriteRecord;
import org.apache.ibatis.annotations.Mapper;
@Mapper
public interface FavouriteRecordMapper extends BaseMapper<FavouriteRecord> {
}

View File

@@ -0,0 +1,10 @@
package com.cxx.food.service;
import com.cxx.food.constant.BizType;
public interface FavouriteService {
Boolean addFavourite(BizType type, Long subjectId);
Boolean deleteFavourite(Long subjectId);
}

View File

@@ -26,10 +26,16 @@ public interface FoodService {
Boolean deleteLike(Long recipeId); Boolean deleteLike(Long recipeId);
Boolean addFavourite(Long recipeId);
Boolean deleteFavourite(Long recipeId);
RecipeDto queryRecipeById(Long id); RecipeDto queryRecipeById(Long id);
List<SummaryDto> queryRecipeByUser(Long id); List<SummaryDto> queryRecipeByUser(Long id);
List<SummaryDto> queryRecipeUserFavourite();
List<SummaryDto> queryRecipeSummary(FoodQueryVo foodQueryVo); List<SummaryDto> queryRecipeSummary(FoodQueryVo foodQueryVo);
IPage<SummaryDto> querySummaryByPage(Integer currentPage, Integer pageSize, FoodQueryVo foodQueryVo); IPage<SummaryDto> querySummaryByPage(Integer currentPage, Integer pageSize, FoodQueryVo foodQueryVo);

View File

@@ -0,0 +1,49 @@
package com.cxx.food.service.impl;
import cn.dev33.satoken.stp.StpUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.cxx.food.constant.BizType;
import com.cxx.food.entity.FavouriteRecord;
import com.cxx.food.mapper.FavouriteRecordMapper;
import com.cxx.food.service.FavouriteService;
import com.cxx.framework.web.CustomException;
import jakarta.annotation.Resource;
import org.springframework.stereotype.Service;
@Service
public class FavouriteServiceImpl implements FavouriteService {
@Resource
private FavouriteRecordMapper favouriteRecordMapper;
@Override
public Boolean addFavourite(BizType type, Long subjectId) {
LambdaQueryWrapper<FavouriteRecord> queryWrapper = new LambdaQueryWrapper<>();
queryWrapper.eq(FavouriteRecord::getSubjectId, subjectId).eq(FavouriteRecord::getCreateBy, StpUtil.getLoginIdAsString());
FavouriteRecord favourite = favouriteRecordMapper.selectOne(queryWrapper);
if (favourite != null) {
throw new CustomException("已经收藏了");
}
FavouriteRecord newFavourite = new FavouriteRecord();
newFavourite.setType(type.getCode());
newFavourite.setSubjectId(subjectId);
return favouriteRecordMapper.insert(newFavourite) == 1;
}
@Override
public Boolean deleteFavourite(Long subjectId) {
LambdaQueryWrapper<FavouriteRecord> queryWrapper = new LambdaQueryWrapper<>();
queryWrapper.eq(FavouriteRecord::getSubjectId, subjectId).eq(FavouriteRecord::getCreateBy, StpUtil.getLoginIdAsString());
FavouriteRecord favourite = favouriteRecordMapper.selectOne(queryWrapper);
if (favourite == null) {
throw new CustomException("该记录不存在");
}
return favouriteRecordMapper.deleteById(favourite) == 1;
}
}

View File

@@ -12,6 +12,7 @@ import com.cxx.food.entity.*;
import com.cxx.food.entity.Record; import com.cxx.food.entity.Record;
import com.cxx.food.mapper.*; import com.cxx.food.mapper.*;
import com.cxx.food.service.CommentService; import com.cxx.food.service.CommentService;
import com.cxx.food.service.FavouriteService;
import com.cxx.food.service.FoodService; import com.cxx.food.service.FoodService;
import com.cxx.food.service.LikeService; import com.cxx.food.service.LikeService;
import com.cxx.food.vo.FoodQueryVo; import com.cxx.food.vo.FoodQueryVo;
@@ -42,15 +43,15 @@ public class FoodServiceImpl implements FoodService {
@Resource @Resource
private RecordMapper recordMapper; private RecordMapper recordMapper;
@Resource
private CommentRecordMapper commentRecordMapper;
@Resource @Resource
private LikeService likeService; private LikeService likeService;
@Resource @Resource
private CommentService commentService; private CommentService commentService;
@Resource
private FavouriteService favouriteService;
@Override @Override
@Transactional @Transactional
public Boolean addRecipe(RecipeDto recipeDto) { public Boolean addRecipe(RecipeDto recipeDto) {
@@ -60,6 +61,7 @@ public class FoodServiceImpl implements FoodService {
} }
Recipe recipe = new Recipe(); Recipe recipe = new Recipe();
recipe.setIsShare(recipeDto.getIsShare() ? 1 : 0);
BeanUtils.copyProperties(recipeDto, recipe); BeanUtils.copyProperties(recipeDto, recipe);
recipeMapper.insert(recipe); recipeMapper.insert(recipe);
resetFoodRecipe(recipe.getId(), recipeDto); resetFoodRecipe(recipe.getId(), recipeDto);
@@ -75,6 +77,7 @@ public class FoodServiceImpl implements FoodService {
} }
Recipe recipe = new Recipe(); Recipe recipe = new Recipe();
recipe.setIsShare(recipeDto.getIsShare() ? 1 : 0);
BeanUtils.copyProperties(recipeDto, recipe); BeanUtils.copyProperties(recipeDto, recipe);
recipe.setId(id); recipe.setId(id);
recipeMapper.updateById(recipe); recipeMapper.updateById(recipe);
@@ -104,6 +107,7 @@ public class FoodServiceImpl implements FoodService {
newRecipe.setName(recordDto.getName()); newRecipe.setName(recordDto.getName());
newRecipe.setCategory("其他"); newRecipe.setCategory("其他");
newRecipe.setRecommendRate(0); newRecipe.setRecommendRate(0);
newRecipe.setIsShare(0);
newRecipe.setRemark(""); newRecipe.setRemark("");
recipeMapper.insert(newRecipe); recipeMapper.insert(newRecipe);
recipeId = newRecipe.getId(); recipeId = newRecipe.getId();
@@ -113,7 +117,7 @@ public class FoodServiceImpl implements FoodService {
Record record = new Record(); Record record = new Record();
record.setFoodId(recipeId); record.setFoodId(recipeId);
record.setPerson((String) StpUtil.getLoginId()); record.setPerson(StpUtil.getLoginIdAsString());
BeanUtils.copyProperties(recordDto, record); BeanUtils.copyProperties(recordDto, record);
recordMapper.insert(record); recordMapper.insert(record);
@@ -123,7 +127,7 @@ public class FoodServiceImpl implements FoodService {
@Override @Override
public Boolean updateRecord(Long id, RecordDto recordDto) { public Boolean updateRecord(Long id, RecordDto recordDto) {
if (recordMapper.selectById(id) == null) { if (recordMapper.selectById(id) == null) {
throw new CustomException("成果不存在"); throw new CustomException("记录不存在");
} }
Record record = new Record(); Record record = new Record();
@@ -164,6 +168,20 @@ public class FoodServiceImpl implements FoodService {
return likeService.deleteLike(recipeId); return likeService.deleteLike(recipeId);
} }
@Override
public Boolean addFavourite(Long recipeId) {
if (recipeMapper.selectById(recipeId) == null) {
throw new CustomException("该菜谱不存在");
}
return favouriteService.addFavourite(BizType.RECIPE, recipeId);
}
@Override
public Boolean deleteFavourite(Long recipeId) {
return favouriteService.deleteFavourite(recipeId);
}
private void resetFoodRecipe(Long id, RecipeDto recipeDto) { private void resetFoodRecipe(Long id, RecipeDto recipeDto) {
materialMapper.delete(Wrappers.lambdaQuery(Material.class).eq(Material::getFoodId, id)); materialMapper.delete(Wrappers.lambdaQuery(Material.class).eq(Material::getFoodId, id));
stepMapper.delete(Wrappers.lambdaQuery(Step.class).eq(Step::getFoodId, id)); stepMapper.delete(Wrappers.lambdaQuery(Step.class).eq(Step::getFoodId, id));
@@ -208,6 +226,11 @@ public class FoodServiceImpl implements FoodService {
return foodDao.queryRecipeByUser(id); return foodDao.queryRecipeByUser(id);
} }
@Override
public List<SummaryDto> queryRecipeUserFavourite() {
return foodDao.queryRecipeUserFavourite(StpUtil.getLoginIdAsString());
}
@Override @Override
public List<SummaryDto> queryRecipeSummary(FoodQueryVo foodQueryVo) { public List<SummaryDto> queryRecipeSummary(FoodQueryVo foodQueryVo) {
return foodDao.queryRecipeSummary(foodQueryVo, StpUtil.getLoginIdAsString()); return foodDao.queryRecipeSummary(foodQueryVo, StpUtil.getLoginIdAsString());

View File

@@ -6,7 +6,11 @@
<result property="name" column="name"/> <result property="name" column="name"/>
<result property="category" column="category"/> <result property="category" column="category"/>
<result property="recommendRate" column="recommendRate"/> <result property="recommendRate" column="recommendRate"/>
<result property="isShare" column="isShare"/>
<result property="remark" column="remark"/> <result property="remark" column="remark"/>
<result property="userId" column="userId"/>
<result property="username" column="username"/>
<result property="avatar" column="avatar"/>
<collection property="materialList" ofType="com.cxx.food.dto.MaterialDto" <collection property="materialList" ofType="com.cxx.food.dto.MaterialDto"
column="id" select="queryMaterial"> column="id" select="queryMaterial">
</collection> </collection>
@@ -19,6 +23,9 @@
<collection property="likeList" ofType="long" <collection property="likeList" ofType="long"
column="id" select="queryRecipeLike"> column="id" select="queryRecipeLike">
</collection> </collection>
<collection property="favouriteList" ofType="long"
column="id" select="queryRecipeFavourite">
</collection>
<collection property="commentList" ofType="com.cxx.food.dto.CommentDto" <collection property="commentList" ofType="com.cxx.food.dto.CommentDto"
column="id" select="queryRecipeComment"> column="id" select="queryRecipeComment">
</collection> </collection>
@@ -52,7 +59,12 @@
<result property="name" column="name"/> <result property="name" column="name"/>
<result property="category" column="category"/> <result property="category" column="category"/>
<result property="recommendRate" column="recommendRate"/> <result property="recommendRate" column="recommendRate"/>
<result property="isShare" column="isShare"/>
<result property="userId" column="userId"/>
<result property="username" column="username"/>
<result property="avatar" column="avatar"/>
<result property="likeCount" column="likeCount"/> <result property="likeCount" column="likeCount"/>
<result property="favouriteCount" column="favouriteCount"/>
<result property="commentCount" column="commentCount"/> <result property="commentCount" column="commentCount"/>
<collection property="recordList" ofType="com.cxx.food.dto.RecordDto"> <collection property="recordList" ofType="com.cxx.food.dto.RecordDto">
<id property="id" column="workId"/> <id property="id" column="workId"/>
@@ -77,6 +89,13 @@
AND type = 'recipe' AND type = 'recipe'
</select> </select>
<select id="queryRecipeFavourite" resultType="long">
SELECT a.create_by AS id
FROM favourite_record AS a
WHERE subject_id = #{id}
AND type = 'recipe'
</select>
<select id="queryRecipeComment" resultMap="commentResultMap"> <select id="queryRecipeComment" resultMap="commentResultMap">
SELECT a.id AS id, SELECT a.id AS id,
b.username AS username, b.username AS username,
@@ -138,23 +157,33 @@
a.name AS name, a.name AS name,
a.category AS category, a.category AS category,
a.recommend_rate AS recommendRate, a.recommend_rate AS recommendRate,
a.remark AS remake a.remark AS remake,
a.is_share AS isShare,
b.id AS userId,
b.username AS username,
b.avatar AS avatar
FROM recipe a FROM recipe a
LEFT JOIN user b on a.create_by = b.id
WHERE a.id = #{id} WHERE a.id = #{id}
</select> </select>
<select id="queryRecipeByUser" resultMap="foodSummaryResultMap"> <select id="queryRecipeByUser" resultMap="foodSummaryResultMap">
SELECT a.id AS id, SELECT a.id AS id,
a.name AS name, a.name AS name,
a.category AS category, a.category AS category,
a.recommend_rate AS recommendRate, a.recommend_rate AS recommendRate,
b.person AS person, u.id AS userId,
b.date AS date, u.username AS username,
b.image_url AS imageUrl, u.avatar AS avatar,
COALESCE(c.like_count, 0) AS likeCount, b.person AS person,
COALESCE(d.comment_count, 0) AS commentCount b.date AS date,
b.image_url AS imageUrl,
COALESCE(c.like_count, 0) AS likeCount,
COALESCE(d.comment_count, 0) AS commentCount,
COALESCE(e.favourite_count, 0) AS favouriteCount
FROM recipe a FROM recipe a
LEFT JOIN record b ON a.id = b.food_id LEFT JOIN record b ON a.id = b.food_id
LEFT JOIN user u on a.create_by = u.id
LEFT JOIN (SELECT subject_id, COUNT(id) AS like_count LEFT JOIN (SELECT subject_id, COUNT(id) AS like_count
FROM like_record FROM like_record
WHERE type = 'recipe' WHERE type = 'recipe'
@@ -163,7 +192,47 @@
FROM comment_record FROM comment_record
WHERE type = 'recipe' WHERE type = 'recipe'
GROUP BY subject_id) d ON a.id = d.subject_id GROUP BY subject_id) d ON a.id = d.subject_id
LEFT JOIN (SELECT subject_id, COUNT(id) AS favourite_count
FROM favourite_record
WHERE type = 'recipe'
GROUP BY subject_id) e ON a.id = e.subject_id
WHERE a.create_by = #{id} WHERE a.create_by = #{id}
AND a.is_share = 1
ORDER BY a.update_time DESC
</select>
<select id="queryRecipeUserFavourite" resultMap="foodSummaryResultMap">
SELECT a.id AS id,
a.name AS name,
a.category AS category,
a.recommend_rate AS recommendRate,
u.id AS userId,
u.username AS username,
u.avatar AS avatar,
b.person AS person,
b.date AS date,
b.image_url AS imageUrl,
COALESCE(c.like_count, 0) AS likeCount,
COALESCE(d.comment_count, 0) AS commentCount,
COALESCE(e.favourite_count, 0) AS favouriteCount
FROM recipe a
LEFT JOIN record b ON a.id = b.food_id
LEFT JOIN user u on a.create_by = u.id
LEFT JOIN favourite_record f on a.id = f.subject_id
LEFT JOIN (SELECT subject_id, COUNT(id) AS like_count
FROM like_record
WHERE type = 'recipe'
GROUP BY subject_id) c ON a.id = c.subject_id
LEFT JOIN (SELECT subject_id, COUNT(id) AS comment_count
FROM comment_record
WHERE type = 'recipe'
GROUP BY subject_id) d ON a.id = d.subject_id
LEFT JOIN (SELECT subject_id, COUNT(id) AS favourite_count
FROM favourite_record
WHERE type = 'recipe'
GROUP BY subject_id) e ON a.id = e.subject_id
WHERE f.create_by = #{user}
AND a.is_share = 1
ORDER BY a.update_time DESC ORDER BY a.update_time DESC
</select> </select>
@@ -171,7 +240,8 @@
SELECT a.id AS id, SELECT a.id AS id,
a.name AS name, a.name AS name,
a.category AS category, a.category AS category,
a.recommend_rate AS recommendRate a.recommend_rate AS recommendRate,
a.is_share AS isShare
FROM recipe a FROM recipe a
<where> <where>
<if test="query.category != null and query.category != ''"> <if test="query.category != null and query.category != ''">
@@ -185,13 +255,19 @@
a.name AS name, a.name AS name,
a.category AS category, a.category AS category,
a.recommend_rate AS recommendRate, a.recommend_rate AS recommendRate,
a.is_share AS isShare,
u.id AS userId,
u.username AS username,
u.avatar AS avatar,
b.person AS person, b.person AS person,
b.date AS date, b.date AS date,
b.image_url AS imageUrl, b.image_url AS imageUrl,
COALESCE(c.like_count, 0) AS likeCount, COALESCE(c.like_count, 0) AS likeCount,
COALESCE(d.comment_count, 0) AS commentCount COALESCE(d.comment_count, 0) AS commentCount,
COALESCE(e.favourite_count, 0) AS favouriteCount
FROM recipe a FROM recipe a
LEFT JOIN record b ON a.id = b.food_id LEFT JOIN record b ON a.id = b.food_id
LEFT JOIN user u ON a.create_by = u.id
LEFT JOIN ( LEFT JOIN (
SELECT subject_id, COUNT(id) AS like_count SELECT subject_id, COUNT(id) AS like_count
FROM like_record FROM like_record
@@ -204,6 +280,11 @@
WHERE type = 'recipe' WHERE type = 'recipe'
GROUP BY subject_id GROUP BY subject_id
) d ON a.id = d.subject_id ) d ON a.id = d.subject_id
LEFT JOIN (SELECT subject_id, COUNT(id) AS favourite_count
FROM favourite_record
WHERE type = 'recipe'
GROUP BY subject_id
) e ON a.id = e.subject_id
<where> <where>
<if test="query.category != null and query.category != ''"> <if test="query.category != null and query.category != ''">
a.category = #{query.category} a.category = #{query.category}