原创文章,欢迎转载。转载请注明:转载自IT人故事会,谢谢!
原文链接地址:「小程序JAVA实战」小程序的视频点赞功能开发(62)
视频点赞关系有3张表,用户表(获得点赞数量),视频表(获得点赞数量),用户喜欢视频的关联表,需要同时操作三张表。源码:https://github.com/limingios/wxProgram.git 中No.15和springboot
后台开发
mapper.xml开发
VideosUserMapper.xml
update videos set like_counts=like_counts+1 where id=#{videoId}
update videos set like_counts=like_counts-1 where id=#{videoId}
UsersMapper.xml
update users set receive_like_counts = receive_like_counts+1 where id=#{userId}
update users set receive_like_counts = receive_like_counts-1 where id=#{userId}
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 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;@Servicepublic 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);
Listlist = videosUsersMapper.queryAllVideos(desc);
PageInfopageList = 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 ListgethostList() { 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{ 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{
public ListqueryAllVideos(@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:许多的功能如果分解,逻辑清晰的话,剩下的都是搬砖活。