首页 > 其他分享 >27、视频功能(全)

27、视频功能(全)

时间:2022-11-05 21:55:45浏览次数:50  
标签:comment 视频 功能 27 String public import com id

视频功能

一、发布视频

数据库表结构

{
    "_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; //主键id
    private Long vid; //自动增长
    private Long created; //创建时间


    private Long userId;//当前用户id
    private String text; //文字
    private String picUrl; //视频封面文件,URL
    private String videoUrl; //视频文件,URL


    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;

    /**
     * 发布视频:
     * 请求路径:/smallVideos
     * 请求方式:post
     * 请求参数:videoThumbnail(视频封面文件),videoFile(视频文件)
     */

    @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;



    /**
     * 发布视频
     * @param videoThumbnail  视频封面,图片;
     * @param videoFile  视频
     */
    public void uploadSmallVideos(MultipartFile videoThumbnail, MultipartFile videoFile) throws IOException {

        //1.判断文件或视频是否为空

        if(videoThumbnail.isEmpty() || videoFile.isEmpty()){
            throw new BusinessException(ErrorResult.error());
        }



        //2.图片上传阿里云oss,并得到访问路径

        String imageUrl = ossTemplate.upload(videoThumbnail.getOriginalFilename(), videoThumbnail.getInputStream());
        //3.视频上传fastDFS
        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();

         //4.构造Video对象封装数据
        Video video = new Video();
        video.setUserId(ThreadLocalUtils.getUserId());
        video.setPicUrl(imageUrl);
        video.setVideoUrl(videoUrl);
        video.setText("自古忠孝难两全");
        //5.调用api保存数据

       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) {

        //1.补充缺失的属性
        video.setVid(idWorker.getNextId("video"));
        video.setCreated(System.currentTimeMillis());
        //2.调用方法保存
        mongoTemplate.save(video);
        //3.返回用户id
        return video.getId().toHexString();
    }


}

二、查看视频列表

1.VideoController


    /**
     * 刷视频
     * 请求路径:/smallVideos
     * 请求方式:get
     * 请求参数:page(当前页码),pagesize(每页展示数)
     * 响应数据:VideoVo
     */
    @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

 /**
     * 查看小视频列表
     * @param page
     * @param pagesize
     * @return
     */
    public PageResult lookSmallVideos(Integer page, Integer pagesize) {

        //1.查看redis中是否缓存有大数据推荐系统的推荐id
        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)){

            //2.redis缓存的数据不为空,根据redis缓存的vid分页查询小视频
            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)){
            //3.redis缓存中没有数据

            videos = videoApi.lookVideos(page-redisPage,pagesize);
        }

        //4.提取小视频的用户id,再根据用户id查询用户详情

        List<Long> userIds = CollUtil.getFieldValues(videos, "userId", Long.class);
        Map<Long, UserInfo> userInfoMap = userInfoApi.batchQueryUserInfo(userIds, null);


        //5.遍历videos集合,构造vo对象
        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



    /**
     * 根据vid查
     * @param vids
     * @return
     */
    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;
    }






    /**
     * 根据发布时间倒序查
     * @param page
     * @param pagesize
     * @return
     */
    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; //主键id
    private Long userId; //用户id    106
    private Long followUserId; //关注的用户id   1
    private Long created; //关注时间
}

1.VideoController

 /**
     * 关注视频发布用户:
     * 请求路径:/smallVideos/:uid/userFocus
     * 请求方式:post
     * 请求参数:路径参数uid,要关注得用户id
     *
     */
    @PostMapping("/{uid}/userFocus")
    public ResponseEntity focusUser(@PathVariable("uid") Long focusUserId){

        smallVideoService.focusVideoUser(focusUserId);
        return ResponseEntity.ok(null);
    }

2.SmallVideoService

 /**
     * 关注视频发布作者
     * @param focusUserId
     */
    public void focusVideoUser(Long focusUserId) {
        //1.创建对象封装数据
        Long currentUserId = ThreadLocalUtils.getUserId();
        FocusUser focusUser = new FocusUser();
        focusUser.setUserId(currentUserId);
        focusUser.setFollowUserId(focusUserId);
        focusUser.setCreated(System.currentTimeMillis());

        //2.把关注的数据缓存进redis
        String key = Constants.FOCUS_USER_KEY + currentUserId;
        String hashKey = String.valueOf(focusUserId);
        redisTemplate.opsForHash().put(key, hashKey, "1");

        //3.调用api保存数据

        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


    /**
     * 取消关注
     * 请求路径:/smallVideos/:uid/userUnFocus
     * 请求方式:post
     * 请求参数:uid(要取消关注的用户id)
     */
    @PostMapping("/{uid}/userUnFocus")
    public ResponseEntity userUnFocus(@PathVariable("uid") Integer unFocusUserId){
        smallVideoService.unFoucus(unFocusUserId);
        return ResponseEntity.ok(null);
    }

2.SmallVideoController


    /**
     * 取消关注
     * @param unFocusUserId
     */
    public void unFoucus(Integer unFocusUserId) {
        Long currentUserId = ThreadLocalUtils.getUserId();

        //1.先删除数据库记录
        videoApi.delete(currentUserId,unFocusUserId);
        //2.再删除redis中的缓存
        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"),
    //这里的publishId就是video表的Id
    "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; //评论id
    private String avatar; //头像
    private String nickname; //昵称


    private String content; //评论
    private String createDate; //评论时间
    private Integer likeCount; //点赞数
    private Integer hasLiked; //是否点赞(1是,0否)

    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层

/**
 * 对视频发布评论:
 * 请求路径:/smallVideos/:id/comments
 * 请求方式:post
 * 请求参数:id(路径参数是被评论的视频id);comment(评论的正文)
 * 响应数据:null
 */
@PostMapping("/{id}/comments")
public ResponseEntity commentVideo(@PathVariable("id") String videoId,
                                   @RequestBody Map map ){


    String comment = (String) map.get("comment");
    //1.接收参数调用业务层
    smallVideoService.commentVideo(videoId,comment);
    return ResponseEntity.ok(null);

}

2.Service层创建对象封装数据,调用api层保存数据

 /**
     * 对视频发布评论
     * @param videoId
     * @param comment
     */
    public void commentVideo(String videoId, String comment) {

        Long currnetUserId = ThreadLocalUtils.getUserId();

        //1.创建Comment对象封装数据

        Comment videoComment = new Comment();
        videoComment.setPublishId(new ObjectId(videoId));//被评论的视频Id
        videoComment.setCommentType(CommentType.COMMENT.getType());//是评论?喜欢?还是点赞
        videoComment.setContent(comment);//评论的正文
        videoComment.setUserId(currnetUserId);//评论人的id
        videoComment.setCreated(System.currentTimeMillis());//评论时间

        //2.调用api保存数据
       Integer count = commentApi.saveVideoMent(videoComment);

    }

3.api,操作mongoDb保存数据

 /**
     * 对视频发布评论
     * @param videoComment
     * @return
     */
    public Integer saveVideoMent(Comment videoComment) {

        //1.根据视频的id查询video表,获取里面的用户id数据,封装到videoComment
        ObjectId videoId = videoComment.getPublishId();

        Video video = mongoTemplate.findById(videoId, Video.class);
        videoComment.setPublishUserId(video.getUserId());

        //2.保存到数据库
        mongoTemplate.save(videoComment);

        //3.更新video表里的likeCount或commentCount或loveCount字段
        //并获取更新后的数据

        //设置查询id
        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


    /**
     * 视频评论列表:
     * 请求路径:/smallVideos/:id/comments
     * 请求方式:get
     * 请求参数:String id(视频id),Integer page(当前页码), Integer pagesize(每页显示数)
     * 响应数据:CommentVo
     */
    @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

/**
     * 查看视频评论列表
     * @param videoId
     * @param page
     * @param pagesize
     * @return
     */
    public PageResult lookVideoComment(String videoId, Integer page, Integer pagesize) {

        //1.此处视频的id就是Comment表中的publishId字段
        //根据publishId字段查询和CommentType字段分页查询Comment列表
        List<Comment> comments = commentApi.lookVideoComment(videoId,page,pagesize,CommentType.COMMENT);
        //2.如果comments为空,n证明此视频没有评论,new PageResult返回
        if(CollUtil.isEmpty(comments)){
            return new PageResult();
        }
        //3.提取这些评论的用户id,再根据用户id查询用户详情
        List<Long> userIds = CollUtil.getFieldValues(comments, "userId", Long.class);
        Map<Long, UserInfo> userInfoMap = userInfoApi.batchQueryUserInfo(userIds, null);

        //4.构造vo返回
        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

  /**
     * 查看视频评论列表
     * @param videoId
     * @param page
     * @param pagesize
     * @param comment
     * @return
     */
    public List<Comment> lookVideoComment(String videoId, Integer page, Integer pagesize, CommentType comment) {

        //1.
        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层


    /**
     * 视频评论点赞:
     * 请求路径:/smallVideos/comments/:id/like
     * 请求方式:post
     * 请求参数:路径参数,id(评论的id)
     */
    @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);

        //4.把点赞状态,缓存到Redis
        //存的value是hash值
        String key = Constants.VIDEOCOMMENT_INTERACT_KEY +videoCommentId;//comment的id
        String hashKey = Constants.VIDEOCOMMENT_LIKE + ThreadLocalUtils.getUserId();
        redisTemplate.opsForHash().put(key, hashKey, "1");

    }

api层次,操作mongdb

/**
     * 视频的评论点赞
     * @param videoCommentId
     */
    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


    /**
     * 视频评论取消喜欢:
     * 请求路径:/smallVideos/comments/:id/dislike
     * 请求方式:post
     * 请求参数:id(路径参数),评论id
     */

    @PostMapping("/comments/{id}/dislike")
    public ResponseEntity disLikeVideoComment(@PathVariable("id") String videoCommentId){

        smallVideoService.disLikeVideoComment(videoCommentId);
        return ResponseEntity.ok(null);
    }

2.Service层次


    /**
     * 视频评论取消喜欢
     * @param videoCommentId
     */
    public void disLikeVideoComment(String videoCommentId) {
        commentApi.disLikeVideoComment(videoCommentId);

        //删除redis中缓存的数据
        String key = Constants.VIDEOCOMMENT_INTERACT_KEY +videoCommentId;//comment的id
        
        String hashKey = Constants.VIDEOCOMMENT_LIKE + ThreadLocalUtils.getUserId();
        redisTemplate.opsForHash().delete(key, hashKey);
    }

3.api层


    /**
     * 取消视频评论的喜欢
     * @param videoCommentId
     */
    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表现层


    /**
     * 对视频点赞:
     * 请求路径:/smallVideos/:id/like
     * 请求方式:post
     * 请求参数:id(路径参数),要点赞的那个视频的id
     * 响应结果:null
     */
    @PostMapping("/{id}/like")
    public ResponseEntity likeVideo(@PathVariable("id") String videoId){
        smallVideoService.likeVideo(videoId);
        return ResponseEntity.ok(null);
    }

Service


    /**
     * 对视频点赞
     * @param videoId 视频的id
     */
    public void likeVideo(String videoId) {
        //1.先判断是否已经点赞过,点赞过抛出一个异常,判断的依据是publishId和commentType以及userId字段
        //这里comment表里的publishId字段就是video
        Long currentUserId = ThreadLocalUtils.getUserId();
        Boolean result = commentApi.isLike(currentUserId, videoId, CommentType.LIKE);

        if(result){
            throw new BusinessException(ErrorResult.error());
        }
        //2.创建对象封装数据
        Comment comment = new Comment();
        comment.setPublishId(new ObjectId(videoId));
        comment.setUserId(currentUserId);
        comment.setCommentType(CommentType.LIKE.getType());
        comment.setCreated(System.currentTimeMillis());
        //被评论人的id留到api层次封装
        Integer count = commentApi.saveVideoMent(comment);


        //3.把对视频的点赞记录缓存进redis
        String key = Constants.VIDEO_INTERACT_KEY +videoId;
        String hashKey = Constants.VIDEO_LIKE_HASHKEY + currentUserId;
        redisTemplate.opsForHash().put(key, hashKey, "1");
    }

api层

 /**
     *查看comment表是否有数据,操作的是Comment表;
     * 依据是userId、publishId、commentType这三个字段
     */
    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;
    }



/**
     * 对视频发布评论、点赞、喜欢
     * @param videoComment
     * @return
     */
    public Integer saveVideoMent(Comment videoComment) {

        //1.根据视频的id查询video表,获取里面的用户id数据,封装到videoComment
        ObjectId videoId = videoComment.getPublishId();

        Video video = mongoTemplate.findById(videoId, Video.class);
        videoComment.setPublishUserId(video.getUserId());

        //2.保存到数据库
        mongoTemplate.save(videoComment);

        //3.更新video表里的likeCount或commentCount或loveCount字段
        //并获取更新后的数据

        //根据video的id查询要修改的video
        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

 /**
     * 取消对视频的点赞
     * 请求路径:/smallVideos/:id/dislike
     * 请求方式:post
     * 请求参数:id(路径参数),要取消点赞视频id
     * 响应数据:null
     */
    @PostMapping("/{id}/dislike")
    public ResponseEntity disLike(@PathVariable("id") String videoId){
        smallVideoService.disLikeVideo(videoId);
        return ResponseEntity.ok(null);
    }

Service


    /**
     * 对视频取消点赞
     * @param videoId
     */
    public void disLikeVideo(String videoId) {

        //1.判断是否点赞过,没点赞怎么会有取消点赞
        Long currentUserId = ThreadLocalUtils.getUserId();
        Boolean result = commentApi.isLike(currentUserId, videoId, CommentType.LIKE);//true代表数据库表中有记录,点赞过
        if(!result){
            //没点赞,不可以取消,抛出异常
            throw new BusinessException(ErrorResult.error());
        }

        //2.封装数据,调用api操作MongoDB,删除数据
        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);

        //3.删除redis中的缓存

        String key = Constants.VIDEO_INTERACT_KEY +videoId;
        String hashKey = Constants.VIDEO_LIKE_HASHKEY + currentUserId;
        redisTemplate.opsForHash().delete(key, hashKey);
    }

ApiImpl

/**
 * 取消对视频的点赞
 * @param comment
 * @return
 */
public Integer disLikeVideo(Comment comment) {

    //1.删除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);


    //2.修改video表中的点赞、评论、喜欢等数据,并获取更新后的数据

    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;
}

标签:comment,视频,功能,27,String,public,import,com,id
From: https://www.cnblogs.com/zhangdashuaige/p/16861439.html

相关文章

  • CorelDRAW2023最新版下载及功能讲解
    CorelDRAW2023最新版,支持WIN10系统(64位)转载于:​​https://www.sohu.com/a/602955432_120864439​​coreldraw是一款深受设计师们喜爱的制图软件,它能够帮助设计师绘制出许......
  • OpenCV图像处理与视频分析详解
    1、OpenCV4环境搭建VS2017新建一个控制台项目配置包含目录配置库目录配置链接器配置环境变量重新启动VS20172、第一个图像显示程序main.cpp#i......
  • 教你实现传奇引擎里的物品重叠叠加功能
    HERO引擎:物品叠加功能,目前只支持物品数据库中StdMod=40,41类型的物品,还有有英雄时17。18分类的金针物品和幸运符物品可实现叠加对应类型物品下的“Reserved”字段的值等于......
  • 手把手教你搭建消防安全答题小程序-实现页面间跳转功能
    手把手教你搭建知识答题小程序,系列文章前面的三章,分别描写了如何去搭建答题小程序的首页、答题页以及答题结果页。然而,界面设计篇将告一段落了,接下来将过渡到交互功能篇。......
  • 基于国产芯片RK1126的智能视频分析网关
    产品简介智能边缘计算网关力求打造一个开放式、可扩展、二次开发升级的智能型AI终端,硬件基于arm的CPU,2T算力的NPU,具备更低的功耗,更高的性能,同时扩展多路外围接口,如RS232、4......
  • springboot整合项目-商城个人头像上传功能
    上传头像的功能持久层1.sql语句的规划avatarvarchar(50)str-字节流将对象文件保存在操作系统上,然后在把这个文件的路径个记录下来,保存在avatar中,因为相比于字符......
  • P8627
    题目描述题目描述很简单,一共\(n\)瓶饮料,每\(3\)瓶饮料的瓶盖可以再换\(1\)瓶新的饮料,问最后一共喝了几瓶饮料?题意分析此题一共有\(3\)种做法,接下来我们一个一个......
  • 将Vscode添加右键打开文件夹功能
    1.wan+r输入regedit打开注册表 注册表编辑  2.找到 HKEY_CLASSES_ROOT\*\shell分支  3.在shell下新建“VisualCode”项,在右侧窗口的“默认”双击,在......
  • 房产管理系统之新增房产经纪人信息功能
    新增房产经纪人信息功能(MyBatis实现)这项功能的核心,就在于“新增”两个字,也就是说,我们需要实现的就是在系统管理员的功能页面实现新增房产经纪人信息的功能而这项功能的实......
  • 使用volatile简单实现happen-before功能
    首先解释appen-before,其作用就是保证两个操作的顺序性,特别是多线程中,确保数据的准确性,对于执行顺序会有一定的要求这里引入volatile手动设置 类似的synchronized也可......