视频功能
一、发布视频
数据库表结构
| { |
| "_id": ObjectId("5e82dd6164019531fc471ff0"), |
| "vid": NumberLong("100001"), |
| "userId": NumberLong("3"), |
| "picUrl": "https://tanhua-dev.oss-cn-zhangjiakou.aliyuncs.com/photo/4/1.jpg", |
| "videoUrl": "https://tanhua-dev.oss-cn-zhangjiakou.aliyuncs.com/images/video/1576134125940400.mp4", |
| "created": NumberLong("1585634657964"), |
| "seeType": NumberInt("1"), |
| "locationName": "上海市", |
| "_class": "com.tanhua.dubbo.server.pojo.Video", |
| "likeCount": 0, |
| "commentCount": 0, |
| "loveCount": 0 |
| } |
数据模型实体类
| package com.tanhua.model.mongo; |
| |
| import lombok.AllArgsConstructor; |
| import lombok.Data; |
| import lombok.NoArgsConstructor; |
| import org.bson.types.ObjectId; |
| import org.springframework.data.mongodb.core.mapping.Document; |
| |
| @Data |
| @NoArgsConstructor |
| @AllArgsConstructor |
| @Document(collection = "video") |
| public class Video implements java.io.Serializable { |
| |
| private static final long serialVersionUID = -3136732836884933873L; |
| |
| private ObjectId id; |
| private Long vid; |
| private Long created; |
| |
| |
| private Long userId; |
| private String text; |
| private String picUrl; |
| private String videoUrl; |
| |
| |
| private Integer likeCount=0; |
| private Integer commentCount=0; |
| private Integer loveCount=0; |
| } |
| |
1. VideoController
| package com.tanhua.server.controller; |
| |
| import com.tanhua.model.domain.PageResult; |
| import com.tanhua.server.service.SmallVideoService; |
| import org.springframework.beans.factory.annotation.Autowired; |
| import org.springframework.http.ResponseEntity; |
| import org.springframework.web.bind.annotation.*; |
| import org.springframework.web.multipart.MultipartFile; |
| |
| import java.io.IOException; |
| |
| @RestController |
| @RequestMapping("/smallVideos") |
| public class VideoController { |
| |
| |
| @Autowired |
| private SmallVideoService smallVideoService; |
| |
| |
| |
| |
| |
| |
| |
| |
| @PostMapping |
| public ResponseEntity uploadSmallVideos(MultipartFile videoThumbnail,MultipartFile videoFile) throws IOException { |
| |
| smallVideoService.uploadSmallVideos(videoThumbnail,videoFile); |
| |
| return ResponseEntity.ok(null); |
| } |
| |
| } |
| |
2.SmallVideoService
| package com.tanhua.server.service; |
| |
| import cn.hutool.core.collection.CollUtil; |
| import cn.hutool.core.util.PageUtil; |
| import com.github.tobato.fastdfs.domain.conn.FdfsWebServer; |
| import com.github.tobato.fastdfs.domain.fdfs.StorePath; |
| import com.github.tobato.fastdfs.service.FastFileStorageClient; |
| import com.tanhua.autoconfig.template.OssTemplate; |
| import com.tanhua.commons.utils.Constants; |
| import com.tanhua.dubbo.api.FocusUserApi; |
| import com.tanhua.dubbo.api.UserInfoApi; |
| import com.tanhua.dubbo.api.VideoApi; |
| import com.tanhua.model.domain.PageResult; |
| import com.tanhua.model.domain.UserInfo; |
| import com.tanhua.model.mongo.FocusUser; |
| import com.tanhua.model.mongo.Video; |
| import com.tanhua.model.vo.ErrorResult; |
| import com.tanhua.model.vo.VideoVo; |
| import com.tanhua.server.exception.BusinessException; |
| import com.tanhua.server.interceptor.ThreadLocalUtils; |
| import org.apache.dubbo.config.annotation.DubboReference; |
| import org.springframework.beans.factory.annotation.Autowired; |
| import org.springframework.data.redis.core.RedisTemplate; |
| import org.springframework.stereotype.Service; |
| import org.springframework.util.StringUtils; |
| import org.springframework.web.multipart.MultipartFile; |
| |
| import java.io.IOException; |
| import java.util.ArrayList; |
| import java.util.Arrays; |
| import java.util.List; |
| import java.util.Map; |
| import java.util.stream.Collectors; |
| |
| @Service |
| public class SmallVideoService { |
| |
| |
| |
| @DubboReference |
| private VideoApi videoApi; |
| |
| @DubboReference |
| private FocusUserApi focusUserApi; |
| |
| @Autowired |
| private OssTemplate ossTemplate; |
| |
| @DubboReference |
| private UserInfoApi userInfoApi; |
| |
| @Autowired |
| private RedisTemplate<String,String> redisTemplate; |
| |
| @Autowired |
| private FastFileStorageClient client; |
| |
| @Autowired |
| private FdfsWebServer webServer; |
| |
| |
| |
| |
| |
| |
| |
| |
| public void uploadSmallVideos(MultipartFile videoThumbnail, MultipartFile videoFile) throws IOException { |
| |
| |
| |
| if(videoThumbnail.isEmpty() || videoFile.isEmpty()){ |
| throw new BusinessException(ErrorResult.error()); |
| } |
| |
| |
| |
| |
| |
| String imageUrl = ossTemplate.upload(videoThumbnail.getOriginalFilename(), videoThumbnail.getInputStream()); |
| |
| String filename = videoFile.getOriginalFilename(); |
| |
| filename = filename.substring(filename.lastIndexOf(".") + 1); |
| |
| StorePath path = client.uploadFile(videoFile.getInputStream(), videoFile.getSize(), filename, null); |
| String videoUrl = webServer.getWebServerUrl()+path.getFullPath(); |
| |
| |
| Video video = new Video(); |
| video.setUserId(ThreadLocalUtils.getUserId()); |
| video.setPicUrl(imageUrl); |
| video.setVideoUrl(videoUrl); |
| video.setText("自古忠孝难两全"); |
| |
| |
| String videoId = videoApi.save(video); |
| |
| if(StringUtils.isEmpty(videoId)){ |
| throw new BusinessException(ErrorResult.error()); |
| } |
| } |
| |
| |
3.VideoApiImpl
| package com.tanhua.dubbo.api; |
| |
| import com.tanhua.dubbo.utils.IdWorker; |
| import com.tanhua.model.mongo.FocusUser; |
| import com.tanhua.model.mongo.Video; |
| import org.apache.dubbo.config.annotation.DubboService; |
| import org.springframework.beans.factory.annotation.Autowired; |
| import org.springframework.data.domain.Sort; |
| import org.springframework.data.mongodb.core.MongoTemplate; |
| import org.springframework.data.mongodb.core.query.Criteria; |
| import org.springframework.data.mongodb.core.query.Query; |
| |
| import java.util.List; |
| |
| @DubboService |
| public class VideoApiImpl implements VideoApi { |
| |
| @Autowired |
| private MongoTemplate mongoTemplate; |
| |
| |
| @Autowired |
| private IdWorker idWorker; |
| |
| |
| |
| |
| |
| public String save(Video video) { |
| |
| |
| video.setVid(idWorker.getNextId("video")); |
| video.setCreated(System.currentTimeMillis()); |
| |
| mongoTemplate.save(video); |
| |
| return video.getId().toHexString(); |
| } |
| |
| |
| } |
| |
二、查看视频列表
1.VideoController
| |
| |
| |
| |
| |
| |
| |
| |
| @GetMapping |
| public ResponseEntity lookSmallVideos( |
| @RequestParam(defaultValue = "1") Integer page , @RequestParam(defaultValue = "10") Integer pagesize |
| ){ |
| |
| PageResult pageResult = smallVideoService.lookSmallVideos(page,pagesize); |
| |
| return ResponseEntity.ok(pageResult); |
| } |
| |
2.SmallVideoService
| |
| |
| |
| |
| |
| |
| public PageResult lookSmallVideos(Integer page, Integer pagesize) { |
| |
| |
| Long userId = ThreadLocalUtils.getUserId(); |
| String redisKey = Constants.VIDEOS_RECOMMEND + userId; |
| String redisValues = redisTemplate.opsForValue().get(redisKey); |
| |
| int redisPage = 0; |
| |
| List<Video> videos = new ArrayList<>(); |
| if(!StringUtils.isEmpty(redisValues)){ |
| |
| |
| String[] values = redisValues.split(","); |
| |
| if(( page-1 ) * pagesize < values.length) { |
| List<Long> vids = Arrays.stream(values).skip((page - 1) * pagesize).limit(pagesize) |
| .map(e -> Long.valueOf(e)) |
| .collect(Collectors.toList()); |
| videos = videoApi.lookRcommendVideos(vids); |
| } |
| |
| redisPage = PageUtil.totalPage(values.length, pagesize); |
| } |
| |
| if(CollUtil.isEmpty(videos)){ |
| |
| |
| videos = videoApi.lookVideos(page-redisPage,pagesize); |
| } |
| |
| |
| |
| List<Long> userIds = CollUtil.getFieldValues(videos, "userId", Long.class); |
| Map<Long, UserInfo> userInfoMap = userInfoApi.batchQueryUserInfo(userIds, null); |
| |
| |
| |
| List<VideoVo> vos = new ArrayList<>(); |
| for (Video video : videos) { |
| Long id = video.getUserId(); |
| UserInfo userInfo = userInfoMap.get(id); |
| |
| if(userInfo != null){ |
| VideoVo vo = VideoVo.init(userInfo, video); |
| |
| String key = Constants.FOCUS_USER_KEY + userId; |
| if(redisTemplate.hasKey(key)){ |
| vo.setHasFocus(1); |
| } |
| |
| vos.add(vo); |
| } |
| } |
| |
| return new PageResult(page,pagesize,0,vos); |
| |
| } |
3.VideoApiImpl
| |
| |
| |
| |
| |
| |
| |
| public List<Video> lookRcommendVideos(List<Long> vids) { |
| |
| Criteria criteria = Criteria.where("vid").in(vids); |
| Query query = Query.query(criteria); |
| List<Video> videos = mongoTemplate.find(query, Video.class); |
| return videos; |
| } |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| public List<Video> lookVideos(int page, Integer pagesize) { |
| |
| Query query = new Query(); |
| Query query1 = query.skip((page - 1) * pagesize).limit(pagesize).with(Sort.by(Sort.Order.desc("created"))); |
| List<Video> videos = mongoTemplate.find(query1, Video.class); |
| return videos; |
| } |
三、关注视频发布用户
数据库表结构分析
| { |
| "_id": ObjectId("6364ca6fb25a645456f713f3"), |
| "userId": NumberLong("1"), |
| "followUserId": NumberLong("106"), |
| "created": NumberLong("1667549807183"), |
| "_class": "com.tanhua.model.mongo.FocusUser" |
| } |
封装数据的实体类
| package com.tanhua.model.mongo; |
| |
| import lombok.AllArgsConstructor; |
| import lombok.Data; |
| import lombok.NoArgsConstructor; |
| import org.bson.types.ObjectId; |
| import org.springframework.data.mongodb.core.mapping.Document; |
| |
| |
| @Data |
| @NoArgsConstructor |
| @AllArgsConstructor |
| @Document(collection = "focus_user") |
| public class FocusUser implements java.io.Serializable{ |
| |
| private static final long serialVersionUID = 3148619072405056052L; |
| |
| private ObjectId id; |
| private Long userId; |
| private Long followUserId; |
| private Long created; |
| } |
1.VideoController
| |
| |
| |
| |
| |
| |
| |
| @PostMapping("/{uid}/userFocus") |
| public ResponseEntity focusUser(@PathVariable("uid") Long focusUserId){ |
| |
| smallVideoService.focusVideoUser(focusUserId); |
| return ResponseEntity.ok(null); |
| } |
| |
2.SmallVideoService
| |
| |
| |
| |
| public void focusVideoUser(Long focusUserId) { |
| |
| Long currentUserId = ThreadLocalUtils.getUserId(); |
| FocusUser focusUser = new FocusUser(); |
| focusUser.setUserId(currentUserId); |
| focusUser.setFollowUserId(focusUserId); |
| focusUser.setCreated(System.currentTimeMillis()); |
| |
| |
| String key = Constants.FOCUS_USER_KEY + currentUserId; |
| String hashKey = String.valueOf(focusUserId); |
| redisTemplate.opsForHash().put(key, hashKey, "1"); |
| |
| |
| |
| focusUserApi.save(focusUser); |
| |
| |
| } |
3.FocusUserApiImpl
| package com.tanhua.dubbo.api; |
| |
| import com.tanhua.model.mongo.FocusUser; |
| import org.apache.dubbo.config.annotation.DubboService; |
| import org.bson.types.ObjectId; |
| import org.springframework.beans.factory.annotation.Autowired; |
| import org.springframework.data.mongodb.core.MongoTemplate; |
| import org.springframework.data.mongodb.core.query.Criteria; |
| import org.springframework.data.mongodb.core.query.Query; |
| |
| @DubboService |
| public class FocusUserApiImpl implements FocusUserApi { |
| |
| @Autowired |
| private MongoTemplate mongoTemplate; |
| |
| |
| |
| |
| |
| |
| public void save(FocusUser focusUser) { |
| |
| |
| Criteria criteria = |
| Criteria.where("userId") |
| .is(focusUser.getUserId()) |
| .and("followUserId") |
| .is(focusUser.getFollowUserId()); |
| Query query = Query.query(criteria); |
| |
| FocusUser user = mongoTemplate.findOne(query, FocusUser.class); |
| if( user== null){ |
| focusUser.setId(ObjectId.get()); |
| mongoTemplate.save(focusUser); |
| } |
| } |
| } |
| |
四、取消关注用户
1.VideoController
| |
| |
| |
| |
| |
| |
| |
| @PostMapping("/{uid}/userUnFocus") |
| public ResponseEntity userUnFocus(@PathVariable("uid") Integer unFocusUserId){ |
| smallVideoService.unFoucus(unFocusUserId); |
| return ResponseEntity.ok(null); |
| } |
2.SmallVideoController
| |
| |
| |
| |
| |
| public void unFoucus(Integer unFocusUserId) { |
| Long currentUserId = ThreadLocalUtils.getUserId(); |
| |
| |
| videoApi.delete(currentUserId,unFocusUserId); |
| |
| String key = Constants.FOCUS_USER_KEY + currentUserId; |
| String hashKey = String.valueOf(unFocusUserId); |
| redisTemplate.opsForHash().delete(key, hashKey); |
| |
| } |
3.VideoApiImpl
| |
| |
| |
| |
| public void delete(Long currentUserId, Integer unFocusUserId) { |
| Criteria criteria = Criteria.where("userId").is(currentUserId).and("followUserId").is(unFocusUserId); |
| Query query = Query.query(criteria); |
| |
| mongoTemplate.remove(query, FocusUser.class); |
| } |
| |
五、对视频发布评论
数据库表结构
Comment
| { |
| "_id": ObjectId("6365d7c3154d4f5e9de96a55"), |
| "publishId": ObjectId("6364acefd95af276934d011a"), |
| |
| "commentType": NumberInt("2"), |
| "content": "欧文好好打球好吗", |
| "userId": NumberLong("1"), |
| "publishUserId": NumberLong("106"), |
| "created": NumberLong("1667618754738"), |
| "likeCount": NumberInt("0"), |
| "_class": "com.tanhua.model.mongo.Comment" |
| } |
Video
| { |
| "_id": ObjectId("5e82dd6264019531fc471ff2"), |
| "vid": NumberLong("100002"), |
| "userId": NumberLong("8"), |
| "picUrl": "https://tanhua-dev.oss-cn-zhangjiakou.aliyuncs.com/photo/10/1564567528297.jpg", |
| "videoUrl": "https://tanhua-dev.oss-cn-zhangjiakou.aliyuncs.com/images/video/1576134125940400.mp4", |
| "created": NumberLong("1585634658007"), |
| "seeType": NumberInt("1"), |
| "locationName": "上海市", |
| "_class": "com.tanhua.dubbo.server.pojo.Video", |
| "likeCount": 0, |
| "commentCount": 0, |
| "loveCount": 0 |
| } |
| |
vo对象,这个是返回给页面的对象
| package com.tanhua.model.vo; |
| |
| import com.tanhua.model.domain.UserInfo; |
| import lombok.AllArgsConstructor; |
| import lombok.Data; |
| import lombok.NoArgsConstructor; |
| import org.springframework.beans.BeanUtils; |
| |
| import java.io.Serializable; |
| import java.text.SimpleDateFormat; |
| import java.util.Date; |
| |
| @Data |
| @NoArgsConstructor |
| @AllArgsConstructor |
| public class CommentVo implements Serializable { |
| |
| private String id; |
| private String avatar; |
| private String nickname; |
| |
| |
| private String content; |
| private String createDate; |
| private Integer likeCount; |
| private Integer hasLiked; |
| |
| public static CommentVo init(UserInfo userInfo, com.tanhua.model.mongo.Comment item) { |
| |
| CommentVo vo = new CommentVo(); |
| BeanUtils.copyProperties(userInfo, vo); |
| BeanUtils.copyProperties(item, vo); |
| vo.setHasLiked(0); |
| Date date = new Date(item.getCreated()); |
| vo.setCreateDate(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(date)); |
| vo.setId(item.getId().toHexString()); |
| return vo; |
| } |
| } |
| |
1.Controller接收参数调用Service层
| |
| |
| |
| |
| |
| |
| |
| @PostMapping("/{id}/comments") |
| public ResponseEntity commentVideo(@PathVariable("id") String videoId, |
| @RequestBody Map map ){ |
| |
| |
| String comment = (String) map.get("comment"); |
| |
| smallVideoService.commentVideo(videoId,comment); |
| return ResponseEntity.ok(null); |
| |
| } |
2.Service层创建对象封装数据,调用api层保存数据
| |
| |
| |
| |
| |
| public void commentVideo(String videoId, String comment) { |
| |
| Long currnetUserId = ThreadLocalUtils.getUserId(); |
| |
| |
| |
| Comment videoComment = new Comment(); |
| videoComment.setPublishId(new ObjectId(videoId)); |
| videoComment.setCommentType(CommentType.COMMENT.getType()); |
| videoComment.setContent(comment); |
| videoComment.setUserId(currnetUserId); |
| videoComment.setCreated(System.currentTimeMillis()); |
| |
| |
| Integer count = commentApi.saveVideoMent(videoComment); |
| |
| } |
3.api,操作mongoDb保存数据
| |
| |
| |
| |
| |
| public Integer saveVideoMent(Comment videoComment) { |
| |
| |
| ObjectId videoId = videoComment.getPublishId(); |
| |
| Video video = mongoTemplate.findById(videoId, Video.class); |
| videoComment.setPublishUserId(video.getUserId()); |
| |
| |
| mongoTemplate.save(videoComment); |
| |
| |
| |
| |
| |
| Criteria criteria = Criteria.where("id").is(videoComment.getPublishId()); |
| Query query = Query.query(criteria); |
| |
| Update update = new Update(); |
| |
| if(videoComment.getCommentType() == CommentType.LIKE.getType()){ |
| |
| update.inc("likeCount", 1); |
| }else if(videoComment.getCommentType() == CommentType.COMMENT.getType() ){ |
| update.inc("commentCount", 1); |
| }else { |
| update.inc("loveCount", 1); |
| } |
| |
| FindAndModifyOptions options = new FindAndModifyOptions(); |
| options.returnNew(true); |
| |
| |
| Video andModify = mongoTemplate.findAndModify(query, update, options, Video.class); |
| |
| Integer count = andModify.statisCount(videoComment.getCommentType()); |
| |
| return count; |
| } |
六、查看视频的评论列表
1.Controller
| |
| |
| |
| |
| |
| |
| |
| |
| @GetMapping("/{id}/comments") |
| public ResponseEntity lookVideoComment(@PathVariable("id") String videoId, |
| @RequestParam(defaultValue = "1") Integer page, |
| @RequestParam(defaultValue = "10") Integer pagesize){ |
| |
| PageResult pageResult = smallVideoService.lookVideoComment(videoId,page,pagesize); |
| return ResponseEntity.ok(pageResult); |
| } |
| |
2.Service
| |
| |
| |
| |
| |
| |
| |
| public PageResult lookVideoComment(String videoId, Integer page, Integer pagesize) { |
| |
| |
| |
| List<Comment> comments = commentApi.lookVideoComment(videoId,page,pagesize,CommentType.COMMENT); |
| |
| if(CollUtil.isEmpty(comments)){ |
| return new PageResult(); |
| } |
| |
| List<Long> userIds = CollUtil.getFieldValues(comments, "userId", Long.class); |
| Map<Long, UserInfo> userInfoMap = userInfoApi.batchQueryUserInfo(userIds, null); |
| |
| |
| List<CommentVo> vos = new ArrayList<>(); |
| |
| for (Comment comment : comments) { |
| Long userId = comment.getUserId(); |
| |
| UserInfo userInfo = userInfoMap.get(userId); |
| if(userInfo != null){ |
| CommentVo vo = CommentVo.init(userInfo, comment); |
| |
| String key = Constants.VIDEOCOMMENT_INTERACT_KEY +comment.getId().toHexString(); |
| String hashKey = Constants.VIDEOCOMMENT_LIKE + ThreadLocalUtils.getUserId(); |
| |
| if(redisTemplate.opsForHash().hasKey(key, hashKey)){ |
| vo.setHasLiked(1); |
| } |
| |
| |
| vos.add(vo); |
| } |
| } |
| |
| return new PageResult(page,pagesize,0,vos); |
| |
| |
| } |
3.api层,操作mongo
| |
| |
| |
| |
| |
| |
| |
| |
| public List<Comment> lookVideoComment(String videoId, Integer page, Integer pagesize, CommentType comment) { |
| |
| |
| Criteria criteria = Criteria.where("publishId").is(new ObjectId(videoId)).and("commentType").is(comment.getType()); |
| |
| Query query = Query.query(criteria); |
| query.skip((page - 1) * pagesize).limit(pagesize).with(Sort.by(Sort.Order.desc("created"))); |
| |
| List<Comment> comments = mongoTemplate.find(query, Comment.class); |
| return comments; |
| } |
七、对视频评论点赞
1.Controller层
| |
| |
| |
| |
| |
| |
| |
| @PostMapping("/comments/{id}/like") |
| public ResponseEntity videoCommentLike(@PathVariable("id") String videoCommentId){ |
| smallVideoService.videoCommentLike(videoCommentId); |
| |
| return ResponseEntity.ok(null); |
| |
| } |
2.Service层
| |
| |
| |
| |
| public void videoCommentLike(String videoCommentId) { |
| |
| commentApi.videoCommentLike(videoCommentId); |
| |
| |
| |
| String key = Constants.VIDEOCOMMENT_INTERACT_KEY +videoCommentId; |
| String hashKey = Constants.VIDEOCOMMENT_LIKE + ThreadLocalUtils.getUserId(); |
| redisTemplate.opsForHash().put(key, hashKey, "1"); |
| |
| } |
| |
api层次,操作mongdb
| |
| |
| |
| |
| public void videoCommentLike(String videoCommentId) { |
| Criteria criteria = Criteria.where("id").is(new ObjectId(videoCommentId)); |
| Query query = Query.query(criteria); |
| |
| |
| Update update = new Update(); |
| update.inc("likeCount", 1); |
| |
| |
| mongoTemplate.updateFirst(query, update, Comment.class); |
| |
| } |
| |
八、取消对视频评论的点赞
1.Controller
| |
| |
| |
| |
| |
| |
| |
| |
| @PostMapping("/comments/{id}/dislike") |
| public ResponseEntity disLikeVideoComment(@PathVariable("id") String videoCommentId){ |
| |
| smallVideoService.disLikeVideoComment(videoCommentId); |
| return ResponseEntity.ok(null); |
| } |
2.Service层次
| |
| |
| |
| |
| |
| public void disLikeVideoComment(String videoCommentId) { |
| commentApi.disLikeVideoComment(videoCommentId); |
| |
| |
| String key = Constants.VIDEOCOMMENT_INTERACT_KEY +videoCommentId; |
| |
| String hashKey = Constants.VIDEOCOMMENT_LIKE + ThreadLocalUtils.getUserId(); |
| redisTemplate.opsForHash().delete(key, hashKey); |
| } |
3.api层
| |
| |
| |
| |
| |
| public void disLikeVideoComment(String videoCommentId) { |
| |
| Criteria criteria = Criteria.where("id").is(new ObjectId(videoCommentId)); |
| Query query = Query.query(criteria); |
| |
| Update update = new Update(); |
| update.inc("likeCount", -1); |
| |
| |
| mongoTemplate.findAndModify(query, update,Comment.class ); |
| } |
九、对视频点赞
Controller表现层
| |
| |
| |
| |
| |
| |
| |
| |
| @PostMapping("/{id}/like") |
| public ResponseEntity likeVideo(@PathVariable("id") String videoId){ |
| smallVideoService.likeVideo(videoId); |
| return ResponseEntity.ok(null); |
| } |
Service
| |
| |
| |
| |
| |
| public void likeVideo(String videoId) { |
| |
| |
| Long currentUserId = ThreadLocalUtils.getUserId(); |
| Boolean result = commentApi.isLike(currentUserId, videoId, CommentType.LIKE); |
| |
| if(result){ |
| throw new BusinessException(ErrorResult.error()); |
| } |
| |
| Comment comment = new Comment(); |
| comment.setPublishId(new ObjectId(videoId)); |
| comment.setUserId(currentUserId); |
| comment.setCommentType(CommentType.LIKE.getType()); |
| comment.setCreated(System.currentTimeMillis()); |
| |
| Integer count = commentApi.saveVideoMent(comment); |
| |
| |
| |
| String key = Constants.VIDEO_INTERACT_KEY +videoId; |
| String hashKey = Constants.VIDEO_LIKE_HASHKEY + currentUserId; |
| redisTemplate.opsForHash().put(key, hashKey, "1"); |
| } |
api层
| |
| |
| |
| |
| public Boolean isLike(Long userId, String movementId, CommentType commentType) { |
| Criteria criteria = Criteria.where("userId").is(userId) |
| .and("publishId").is(new ObjectId(movementId)) |
| .and("commentType").is(commentType.getType()); |
| Query query = Query.query(criteria); |
| boolean result = mongoTemplate.exists(query, Comment.class); |
| |
| return result; |
| } |
| |
| |
| |
| |
| |
| |
| |
| |
| public Integer saveVideoMent(Comment videoComment) { |
| |
| |
| ObjectId videoId = videoComment.getPublishId(); |
| |
| Video video = mongoTemplate.findById(videoId, Video.class); |
| videoComment.setPublishUserId(video.getUserId()); |
| |
| |
| mongoTemplate.save(videoComment); |
| |
| |
| |
| |
| |
| Criteria criteria = Criteria.where("id").is(videoComment.getPublishId()); |
| Query query = Query.query(criteria); |
| |
| Update update = new Update(); |
| |
| if(videoComment.getCommentType() == CommentType.LIKE.getType()){ |
| |
| update.inc("likeCount", 1); |
| }else if(videoComment.getCommentType() == CommentType.COMMENT.getType() ){ |
| update.inc("commentCount", 1); |
| }else { |
| update.inc("loveCount", 1); |
| } |
| |
| FindAndModifyOptions options = new FindAndModifyOptions(); |
| options.returnNew(true); |
| |
| |
| Video andModify = mongoTemplate.findAndModify(query, update, options, Video.class); |
| |
| Integer count = andModify.statisCount(videoComment.getCommentType()); |
| |
| return count; |
| } |
| |
| |
| |
十、取消点赞
Controller
| |
| |
| |
| |
| |
| |
| |
| @PostMapping("/{id}/dislike") |
| public ResponseEntity disLike(@PathVariable("id") String videoId){ |
| smallVideoService.disLikeVideo(videoId); |
| return ResponseEntity.ok(null); |
| } |
Service
| |
| |
| |
| |
| |
| public void disLikeVideo(String videoId) { |
| |
| |
| Long currentUserId = ThreadLocalUtils.getUserId(); |
| Boolean result = commentApi.isLike(currentUserId, videoId, CommentType.LIKE); |
| if(!result){ |
| |
| throw new BusinessException(ErrorResult.error()); |
| } |
| |
| |
| Comment comment = new Comment(); |
| comment.setUserId(ThreadLocalUtils.getUserId()); |
| comment.setPublishId(new ObjectId(videoId)); |
| comment.setCommentType(CommentType.LIKE.getType()); |
| comment.setCreated(System.currentTimeMillis()); |
| |
| Integer count = commentApi.disLikeVideo(comment); |
| |
| |
| |
| String key = Constants.VIDEO_INTERACT_KEY +videoId; |
| String hashKey = Constants.VIDEO_LIKE_HASHKEY + currentUserId; |
| redisTemplate.opsForHash().delete(key, hashKey); |
| } |
ApiImpl
| |
| |
| |
| |
| |
| public Integer disLikeVideo(Comment comment) { |
| |
| |
| Criteria criteria = Criteria.where("userId").is(comment.getUserId()) |
| .and("publishId").is(comment.getPublishId()) |
| .and("commentType").is(comment.getCommentType()); |
| Query query = Query.query(criteria); |
| mongoTemplate.remove(query, Comment.class); |
| |
| |
| |
| |
| Criteria criteria1 = Criteria.where("id").is(comment.getPublishId()); |
| Query query1 =Query.query(criteria1); |
| |
| |
| Update update = new Update(); |
| if(comment.getCommentType() == CommentType.LIKE.getType()){ |
| update.inc("likeCount",-1); |
| }else if (comment.getCommentType() == CommentType.COMMENT.getType()){ |
| update.inc("commentCount", -1); |
| }else{ |
| update.inc("loveCount", -1); |
| } |
| |
| FindAndModifyOptions options = new FindAndModifyOptions(); |
| options.returnNew(true); |
| |
| Video modify = mongoTemplate.findAndModify(query1, update, options, Video.class); |
| |
| Integer count = modify.statisCount(comment.getCommentType()); |
| |
| return count; |
| } |
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 25岁的心里话
· 闲置电脑爆改个人服务器(超详细) #公网映射 #Vmware虚拟网络编辑器
· 零经验选手,Compose 一天开发一款小游戏!
· 因为Apifox不支持离线,我果断选择了Apipost!
· 通过 API 将Deepseek响应流式内容输出到前端