专栏首页编程坑太多「小程序JAVA实战」小程序的视频点赞功能开发(62)

「小程序JAVA实战」小程序的视频点赞功能开发(62)

视频点赞关系有3张表,用户表(获得点赞数量),视频表(获得点赞数量),用户喜欢视频的关联表,需要同时操作三张表。源码:https://github.com/limingios/wxProgram.git 中No.15和springboot

后台开发

  • mapper.xml开发

VideosUserMapper.xml

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd" >
<mapper namespace="com.idig8.mapper.VideosUsersMapper" >
  <resultMap id="BaseResultMap" type="com.idig8.pojo.vo.VideosVO" >
    <!--
      WARNING - @mbg.generated
    -->
    <id column="id" property="id" jdbcType="VARCHAR" />
    <result column="user_id" property="userId" jdbcType="VARCHAR" />
    <result column="audio_id" property="audioId" jdbcType="VARCHAR" />
    <result column="video_desc" property="videoDesc" jdbcType="VARCHAR" />
    <result column="video_path" property="videoPath" jdbcType="VARCHAR" />
    <result column="video_seconds" property="videoSeconds" jdbcType="REAL" />
    <result column="video_width" property="videoWidth" jdbcType="INTEGER" />
    <result column="video_height" property="videoHeight" jdbcType="INTEGER" />
    <result column="cover_path" property="coverPath" jdbcType="VARCHAR" />
    <result column="like_counts" property="likeCounts" jdbcType="BIGINT" />
    <result column="status" property="status" jdbcType="INTEGER" />
    <result column="create_time" property="createTime" jdbcType="TIMESTAMP" />
    <result column="username" property="username" jdbcType="VARCHAR" />
    <result column="face_image" property="faceImage" jdbcType="VARCHAR" />
    <result column="nickname" property="nickname" jdbcType="VARCHAR" />
  </resultMap>

  <select id="queryAllVideos" resultMap="BaseResultMap" parameterType="String">
      select v.*,u.face_image,u.username,u.nickname from videos v
      left join users u on v.user_id = u.id
      where 
          1 = 1
          <if test="videoDesc !=null  and videoDesc != '' ">
              and v.video_desc like '%${videoDesc}%'
          </if>
          and v.status = 1
      order by v.create_time

  </select>


  <update id="addVideoLikeCount" parameterType="String">
      update videos set like_counts=like_counts+1 where id=#{videoId}
  </update>

   <update id="reduceVideoLikeCount" parameterType="String">
      update videos set like_counts=like_counts-1 where id=#{videoId}
  </update>
</mapper>

UsersMapper.xml

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd" >
<mapper namespace="com.idig8.mapper.UsersMapper" >
  <resultMap id="BaseResultMap" type="com.idig8.pojo.Users" >
    <!--
      WARNING - @mbg.generated
    -->
    <id column="id" property="id" jdbcType="VARCHAR" />
    <result column="username" property="username" jdbcType="VARCHAR" />
    <result column="password" property="password" jdbcType="VARCHAR" />
    <result column="face_image" property="faceImage" jdbcType="VARCHAR" />
    <result column="nickname" property="nickname" jdbcType="VARCHAR" />
    <result column="fans_counts" property="fansCounts" jdbcType="INTEGER" />
    <result column="follow_counts" property="followCounts" jdbcType="INTEGER" />
    <result column="receive_like_counts" property="receiveLikeCounts" jdbcType="INTEGER" />
  </resultMap>

  <update id="addReceiveLikeCount" parameterType="String">
      update users set receive_like_counts = receive_like_counts+1 where id=#{userId}
  </update>

    <update id="reduceReceiveLikeCount" parameterType="String">
      update users set receive_like_counts = receive_like_counts-1 where id=#{userId}
  </update>

</mapper>
  • service 和 serviceImpl

VideoService.java

package com.idig8.service;

import java.util.List;

import com.idig8.pojo.Videos;
import com.idig8.utils.PagedResult;

public interface VideoService {


    /**
     * 保存视频信息
     * @param Id
     * @return
     */
    public String saveVideo(Videos video);

    /**
     * 分析查询视频列表
     * @param video
     * @param isSaveRecord
     * @param page
     * @param pageSize
     * @return
     */
    public PagedResult getAllVideos(Videos video,Integer isSaveRecord,Integer page,Integer pageSize);

    /**
     * 获取热搜词列表
     * @return
     */
    public List<String> gethostList();

    public void userLikeVideo(String userId,String videoId,String videoCreaterId);

    public void userUnLikeVideo(String userId,String videoId,String videoCreaterId);

}

VideoServiceImpl.java

package com.idig8.service.Impl;

import java.util.List;

import org.n3r.idworker.Sid;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.idig8.mapper.SearchRecordsMapper;
import com.idig8.mapper.UsersLikeVideosMapper;
import com.idig8.mapper.UsersMapper;
import com.idig8.mapper.VideosMapper;
import com.idig8.mapper.VideosUsersMapper;
import com.idig8.pojo.SearchRecords;
import com.idig8.pojo.UsersLikeVideos;
import com.idig8.pojo.Videos;
import com.idig8.pojo.vo.VideosVO;
import com.idig8.service.VideoService;
import com.idig8.utils.PagedResult;

import tk.mybatis.mapper.entity.Example;
import tk.mybatis.mapper.entity.Example.Criteria;

@Service
public class VideoServiceImpl implements VideoService {

    @Autowired
    private VideosMapper videosMapper;

    @Autowired
    private UsersMapper usersMapper;

    @Autowired
    private VideosUsersMapper videosUsersMapper;

    @Autowired
    private SearchRecordsMapper searchRecordsMapper;

    @Autowired
    private UsersLikeVideosMapper usersLikeVideosMapper;

    @Autowired
    private Sid sid;

    @Transactional(propagation = Propagation.REQUIRED)
    public String saveVideo(Videos video) {
        String id = sid.nextShort();
        video.setId(id);

        videosMapper.insertSelective(video);
        return id;

    }

    @Override
    @Transactional(propagation = Propagation.REQUIRED)
    public PagedResult getAllVideos(Videos video, Integer isSaveRecord, Integer page, Integer pageSize) {

        String desc = video.getVideoDesc();
        if (isSaveRecord != null && isSaveRecord == 1) {
            SearchRecords record = new SearchRecords();
            String recordId = sid.nextShort();
            record.setId(recordId);
            record.setContent(desc);
            searchRecordsMapper.insert(record);
        }

        PageHelper.startPage(page, pageSize);
        List<VideosVO> list = videosUsersMapper.queryAllVideos(desc);
        PageInfo<VideosVO> pageList = new PageInfo<>(list);

        PagedResult result = new PagedResult();
        result.setPage(page);
        result.setTotal(pageList.getPages());
        result.setRows(list);
        result.setRecords(pageList.getTotal());

        return result;
    }

    @Transactional(propagation = Propagation.SUPPORTS)
    @Override
    public List<String> gethostList() {

        return searchRecordsMapper.gethotList();
    }

    @Override
    public void userLikeVideo(String userId, String videoId, String videoCreaterId) {

        // 1.保存用戶和视频的关联关系
        String likeId = sid.nextShort();
        UsersLikeVideos usersLikeVideos = new UsersLikeVideos();
        usersLikeVideos.setId(likeId);
        usersLikeVideos.setUserId(userId);
        usersLikeVideos.setVideoId(videoId);
        usersLikeVideosMapper.insert(usersLikeVideos);

        // 2.视频喜欢的累加
        videosUsersMapper.addVideoLikeCount(videoId);

        // 3. 用户喜欢的累加
        usersMapper.addReceiveLikeCount(userId);

    }

    @Override
    public void userUnLikeVideo(String userId, String videoId, String videoCreaterId) {
        Example example = new Example(UsersLikeVideos.class);
        Criteria criteria = example.createCriteria();
        criteria.andEqualTo("userId", userId);
        criteria.andEqualTo("videoId", videoId);
        usersLikeVideosMapper.deleteByExample(example);
        // 2.视频喜欢的累减
        videosUsersMapper.reduceVideoLikeCount(videoId);

        // 3. 用户喜欢的累减
        usersMapper.reduceReceiveLikeCount(userId);
    }
}
  • mapper.java文件

UsersMapper.java

package com.idig8.mapper;

import com.idig8.pojo.Users;
import com.idig8.utils.MyMapper;

public interface UsersMapper extends MyMapper<Users> {

    public void addReceiveLikeCount(String userId);

    public void reduceReceiveLikeCount(String userId);

}

VideosUsersMapper.java

package com.idig8.mapper;

import java.util.List;

import org.apache.ibatis.annotations.Param;

import com.idig8.pojo.Videos;
import com.idig8.pojo.vo.VideosVO;
import com.idig8.utils.MyMapper;

public interface VideosUsersMapper extends MyMapper<VideosVO> {

    public List<VideosVO> queryAllVideos(@Param("videoDesc") String videoDesc);

    public void addVideoLikeCount(String videoId);

    public void reduceVideoLikeCount(String videoId);

}
  • controller.java

VideoController.java

package com.idig8.controller;

import java.io.File;
import java.util.Date;
import java.util.UUID;

import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;

import com.idig8.pojo.Bgm;
import com.idig8.pojo.Videos;
import com.idig8.service.BgmService;
import com.idig8.service.VideoService;
import com.idig8.utils.FetchVideoCover;
import com.idig8.utils.JSONResult;
import com.idig8.utils.MergeVideoMp3;
import com.idig8.utils.PagedResult;
import com.idig8.utils.enums.VideoStatusEnum;
import com.idig8.utils.file.FileUtil;

import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;


@RestController
@Api(value="视频相关业务的接口", tags= {"视频相关业务的controller"})
@RequestMapping("/video")
public class VideoController extends BasicController {

    @Autowired
    private BgmService bgmService;

    @Autowired
    private VideoService videosService;

    @Value("${server.file.path}")
    private String fileSpace;

    @Value("${server.ffmpeg.path}")
    private String ffmpegexe;


    @ApiOperation(value="上传视频", notes="上传视频的接口")
    @ApiImplicitParams({
        @ApiImplicitParam(name="userId", value="用户id", required=true, 
                dataType="String", paramType="form"),
        @ApiImplicitParam(name="bgmId", value="背景音乐id", required=false, 
                dataType="String", paramType="form"),
        @ApiImplicitParam(name="videoSeconds", value="背景音乐播放长度", required=true, 
                dataType="String", paramType="form"),
        @ApiImplicitParam(name="videoWidth", value="视频宽度", required=true, 
                dataType="String", paramType="form"),
        @ApiImplicitParam(name="videoHeight", value="视频高度", required=true, 
                dataType="String", paramType="form"),
        @ApiImplicitParam(name="desc", value="视频描述", required=false, 
                dataType="String", paramType="form")
    })
    @PostMapping(value="/upload", headers="content-type=multipart/form-data")
    public JSONResult upload(String userId, 
                String bgmId, double videoSeconds, 
                int videoWidth, int videoHeight,
                String desc,
                @ApiParam(value="短视频", required=true)
                MultipartFile file) throws Exception {

        if (StringUtils.isBlank(userId)) {
            return JSONResult.errorMsg("用户id不能为空...");
        }
        // 文件保存的命名空间
        String fileName = file.getOriginalFilename();
        // 保存到数据库中的相对路径
        String path = "";
        String videOutPath = "";
        String ImagePath = "";
        try {
             path = FileUtil.uploadFile(file.getBytes(), fileSpace, fileName);
            } catch (Exception e) {
                e.getStackTrace();
                   return JSONResult.errorMsg(e.getMessage());
            }                


        if(StringUtils.isNotBlank(bgmId)){
            Bgm bgm = bgmService.queryBgmById(bgmId);
            String mp3BgmPath = fileSpace + bgm.getPath();
            MergeVideoMp3 mergeVideoMp3 = new MergeVideoMp3(ffmpegexe);
            String videOutPathName = UUID.randomUUID().toString()+".mp4";
            File targetFile = new File(fileSpace + userId);
            if (!targetFile.exists()) {
                targetFile.mkdirs();
            }
            videOutPath = "/"+userId+"/"+videOutPathName;
            String videoInput = fileSpace +path;
            mergeVideoMp3.convertor(videoInput, mp3BgmPath, videoSeconds, fileSpace +videOutPath);

        }else{
            videOutPath = path;

        }

        ImagePath =  "/"+userId+"/"+UUID.randomUUID().toString()+".jpg";;
        FetchVideoCover fetchVideoCover = new FetchVideoCover(ffmpegexe);
        fetchVideoCover.getCover(fileSpace +videOutPath, fileSpace +ImagePath);


        Videos videos = new Videos();
        videos.setAudioId(bgmId);
        videos.setCreateTime(new Date());
        videos.setVideoDesc(desc);
        videos.setId(UUID.randomUUID().toString());
        videos.setUserId(userId);
        videos.setVideoHeight(videoHeight);
        videos.setVideoWidth(videoWidth);
        videos.setVideoPath(videOutPath);
        videos.setCoverPath(ImagePath);
        videos.setStatus(VideoStatusEnum.SUCCESS.value);
        videosService.saveVideo(videos);

        return JSONResult.ok(path);

    }

    @PostMapping(value="/showAll")
    @ApiOperation(value="视频列表", notes="分页的视频列表")
    public JSONResult upload(@RequestBody Videos video,Integer isSaveRecord,
            Integer page) throws Exception {
        if(page == null){
            page = 1;
        }
        PagedResult result = videosService.getAllVideos(video,isSaveRecord,page, PAGE_SIZE);     
        return JSONResult.ok(result);

    }

    @PostMapping(value="/userLike")
    @ApiOperation(value="热搜词列表", notes="热搜词列表")
    public JSONResult userLike(String userId,String videoId,String videoCreaterId) throws Exception {

        videosService.userLikeVideo(userId, videoId, videoCreaterId);
        return JSONResult.ok();

    }

    @PostMapping(value="/userUnLike")
    public JSONResult userUnLike(String userId,String videoId,String videoCreaterId) throws Exception {
        videosService.userUnLikeVideo(userId, videoId, videoCreaterId);
        return JSONResult.ok();

    }

    @PostMapping(value="/hot")
    public JSONResult upload() throws Exception {

        return JSONResult.ok(videosService.gethostList());

    }
}

小程序前端修改

var videoUtils = require('../../utils/videoUtils.js')
const app = getApp()
Page({

  data: {
    cover:'cover',
    videoContext:"",
    videoInfo:{},
    videId:'',
    src:'',
    userLikeVideo:false
  },


  showSearch:function(){
    wx.navigateTo({
      url: '../videoSearch/videoSearch',
    })
  },
  onLoad:function(params){
    var me = this;
    me.videoContext = wx.createVideoContext('myVideo', me);
    var videoInfo = JSON.parse(params.videoInfo);
    var videoWidth = videoInfo.videoWidth;
    var videoHeight = videoInfo.videoHeight;
    var cover = 'cover';
    if (videoWidth > videoHeight){
      cover = '';
    }
    me.setData({
      videId: videoInfo.id,
      src: app.serverUrl + videoInfo.videoPath,
      videoInfo: videoInfo,
      cover: cover
    })


  },
  showIndex:function(){
    wx.redirectTo({
      url: '../index/index',
    })
  },

  onShow:function(){
    var me = this;
    me.videoContext.play();
  },
  onHide:function(){
    var me = this;
    me.videoContext.pause();
  },
  upload:function(){

    var me = this;
    var userInfo = app.getGlobalUserInfo();

    var videoInfo = JSON.stringify(me.data.videoInfo);
    var realUrl = '../videoInfo/videoInfo#videoInfo@' + videoInfo;

    if (userInfo.id == '' || userInfo.id == undefined) {
      wx.navigateTo({
        url: '../userLogin/userLogin?realUrl=' + realUrl,
      })
    } else {
      videoUtils.uploadVideo();
    }


  },
  showMine: function () {
    var me = this;
    var userInfo = app.getGlobalUserInfo();

    var videoInfo = JSON.parse

    if (userInfo.id == '' || userInfo.id == undefined){
      wx.navigateTo({
        url: '../userLogin/userLogin',
      })
    }else{
      wx.navigateTo({
        url: '../mine/mine',
      })
    }


  },

  likeVideoOrNot: function () {
    var me = this;
    var userInfo = app.getGlobalUserInfo();


    var videoInfoStr = JSON.stringify(me.data.videoInfo);
    var realUrl = '../videoInfo/videoInfo#videoInfo@' + videoInfoStr;
    if (userInfo.id == '' || userInfo.id == undefined) {
      wx.navigateTo({
        url: '../userLogin/userLogin?realUrl=' + realUrl,
      })
    } else {
      var videoInfo = me.data.videoInfo;
      var userLikeVideo = me.data.userLikeVideo;
      var url = "/video/userLike?userId=" + userInfo.id + "&videoId=" + videoInfo.id + "&videoCreaterId=" + userLikeVideo.userId;

      if (userLikeVideo){
        var url = "/video/userUnLike?userId=" + userInfo.id + "&videoId=" + videoInfo.id + "&videoCreaterId=" + userLikeVideo.userId;
      }
      wx.showLoading({
        title: '....',
      })
      wx.request({
        url: app.serverUrl + url,
        method: "POST",
        header: {
          'content-type': 'application/json', // 默认值
          'headerUserId': userInfo.id,
          'headerUserToken': userInfo.userToken
        },
        success: function (res) {
          wx.hideLoading();
          me.setData({
            userLikeVideo: !userLikeVideo,
          })
        }
      })

    }


  }
})

PS:许多的功能如果分解,逻辑清晰的话,剩下的都是搬砖活。

本文分享自微信公众号 - 编程坑太多(idig88)

原文出处及转载信息见文内详细说明,如有侵权,请联系 yunjia_community@tencent.com 删除。

原始发表时间:2019-01-19

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • proxy in nodejs code

    I train myslef with NodeJS and tried a simple GET call. Here is my code:

    Jerry Wang
  • 如何写出无法维护的代码

    单字母的变量名。比如:a,b,c, x,y,z(如果不够用,可以考虑a1,a2,a3,a4,….)

    冯杰宁
  • Mybatis分页插件-PageHepler的使用

    版权声明:本文为博主原创文章,未经博主允许不得转载。 ...

    用户1212940
  • 一文搞懂springboot启动原理

    SpringBoot为我们做的自动配置,确实方便快捷,但一直搞不明白它的内部启动原理,这次就来一步步解开SpringBoot的神秘面纱,让它不再神秘。

    乱敲代码
  • 面试题: 了解OO的SOLID原则吗

    一个类只应承担一种责任。换句话说,让一个类只做一件事。如果需要承担更多的工作,那么分解这个类。

    用户1263954
  • OPA error

    本地eclipse复现错误的步骤如下: 修改cus.crm.lead项目的pom.xml的参数如下:

    Jerry Wang
  • Android 丢帧原理以及解决方案

    开发中的卡顿我想没跟人都遇到过,之前也是搜博客看看怎么个解决办法,没有认真研究过,今天我打算跟大家聊一聊。

    Android架构
  • 面试题: Mybatis的执行流程是怎样的?

    Configuration.xml:该配置文件是MyBatis的全局配置文件,在这个文件中可以配置诸多项目,但是一般项目中,并不会配置太多内容,常用的内容是别名...

    用户1263954
  • 深度 | 高频量化因子的批量生产与集中管理

    量化因子计算可以定义为一种基于初等计算函数与一阶谓词逻辑的递归过程。量 化因子的本质是股票的某种数量化特征,一般需要通过对股票某些数量信息进行 计算得到。与计算...

    量化投资与机器学习微信公众号
  • Spring 的 Bean 管理(注解方式)

    除了 @Component 外,Spring 提供了 3 个功能基本和 @Component 等效的注解

    希希里之海

扫码关注云+社区

领取腾讯云代金券