一、注册和登录功能这两个功能比较简单,就不详细记录了,需要注意的是【密码】出于安全考虑用了@JsonIgnore,这样返回的VO的json数据给前端的时候就忽略掉。public class UsersVO { private String id; private String username; private String userToken; @JsonIgnore private String password; }二、上传个人头像并展示1. 微信小程序前端只需要把图片的临时路径传给后端接口,后台再保存到本地和数据库前端:后台接口:@PostMapping("/uploadFace") public IMoocJSONResult uploadFace(String userId, @RequestParam(“file”) MultipartFile[] files) throws Exception { if(StringUtils.isBlank(userId)){ return IMoocJSONResult.errorMsg(“用户Id不能为空”); } //文件保存的命名空间 String fileSpace = FILE_SPACE; //保存到数据库的相对路径 String uploadPathDB = “/” + userId +"/face"; FileOutputStream fileOutputStream = null; InputStream inputStream = null; try { if(files !=null && files.length>0){ String fileName = files[0].getOriginalFilename(); if(StringUtils.isNoneBlank(fileName)){ //文件上传的最终保存路径 String finalFacePath = fileSpace + uploadPathDB + “/” +fileName; //设置数据库保存的路径 uploadPathDB += ("/" + fileName); File outFile = new File(finalFacePath); if(outFile.getParentFile() !=null || !outFile.getParentFile().isDirectory()){ //创建父文件夹 outFile.getParentFile().mkdirs(); } fileOutputStream = new FileOutputStream(outFile); inputStream = files[0].getInputStream(); IOUtils.copy(inputStream,fileOutputStream); } }else{ IMoocJSONResult.errorMsg(“上传出错”); } } catch (IOException e) { e.printStackTrace(); IMoocJSONResult.errorMsg(“上传出错”); }finally { if(fileOutputStream!=null){ fileOutputStream.flush(); fileOutputStream.close(); } } Users user = new Users(); user.setId(userId); user.setFaceImage(uploadPathDB); userService.updateUserInfo(user); return IMoocJSONResult.ok(uploadPathDB); }2. 静态资源配置,显示图片三、上传视频、选择BGM(可选)上传视频和上传头像的实现是差不多的,多了截图、与BGM合并的操作 //将视频和BGM合并 MergeVideoMp3 tool = new MergeVideoMp3(FFMPEG_EXE); String videoInputPath = finalVideoPath; String videoOutputName = UUID.randomUUID().toString() + “.mp4”; uploadPathDB = “/” + userId + “/video/” + videoOutputName; finalVideoPath = FILE_SPACE + uploadPathDB; tool.convertor(videoInputPath,mp3InputPath,videoSeconds,finalVideoPath); 。。。。。 //对视频进行截图 FetchVideoCover videoCover = new FetchVideoCover(FFMPEG_EXE); videoCover.getCover(finalVideoPath, FILE_SPACE + coverPathDB);三、首页展示视频列表,分页========================前端=============================== 后端分页查询 PageHelper.startPage(page, pageSize); List<VideosVO> list = videosMapper.queryAllVideos(desc, userId); PageInfo<VideosVO> pageList = new PageInfo<>(list); PagedResult pagedResult = new PagedResult(); pagedResult.setPage(page); pagedResult.setTotal(pageList.getPages()); pagedResult.setRows(list); pagedResult.setRecords(pageList.getTotal()); return pagedResult; 前端成功回调函数,对视频列表进行拼接 var videoList = res.data.data.rows; var newVideoList = me.data.videoList; me.setData({ videoList: newVideoList.concat(videoList), page: page, totalPage: res.data.data.total, serverUrl: serverUrl }); 上拉刷新,即下一页 onReachBottom: function(){ var me = this; var currentPage = me.data.page; var totalPage = me.data.totalPage; //判断当前页数和总页数是否相等,如果相等则无需查询 if(currentPage == totalPage){ wx.showToast({ title: ‘已经没有视频啦!!’, icon: “none” }); return; } var page = currentPage + 1; me.getAllVideoList(page,0); } 下拉刷新回到第一页 onPullDownRefresh: function(){ wx.showNavigationBarLoading(); this.getAllVideoList(1,0); },四、点击播放视频点击视频触发事件,跳转页面 showVideoInfo: function(e){ console.log(e); var me = this; var videoList = me.data.videoList; var arrIndex = e.target.dataset.arrindex; console.log(arrIndex); var videoInfo = JSON.stringify(videoList[arrIndex]); wx.redirectTo({ url: ‘../videoinfo/videoinfo?videoInfo=’ + videoInfo }) }五、点赞和关注视频点赞和取消 @Override @Transactional(propagation = Propagation.REQUIRED) public void userLikeVideo(String userId, String videoId, String videoCreaterId) { //1. 保存用户和视频的喜欢点赞关联关系表 String likeId = sid.nextShort(); UsersLikeVideos ulv = new UsersLikeVideos(); ulv.setId(likeId); ulv.setUserId(userId); ulv.setVideoId(videoId); usersLikeVideosMapper.insert(ulv); //2. 视频喜欢数量累加 videosMapper.addVideoLikeCount(videoId); //3. 用户受喜欢数量的累加 usersMapper.addReceiveLikeCount(userId); } @Override @Transactional(propagation = Propagation.REQUIRED) public void userUnLikeVideo(String userId, String videoId, String videoCreaterId) { //1. 删除用户和视频的喜欢点赞关联关系表 UsersLikeVideosExample example = new UsersLikeVideosExample(); example.createCriteria().andUserIdEqualTo(userId).andVideoIdEqualTo(videoId); usersLikeVideosMapper.deleteByExample(example); //2. 视频喜欢数量累减 videosMapper.reduceVideoLikeCount(videoId); //3. 用户受喜欢数量的累减 usersMapper.reduceReceiveLikeCount(userId); }关注用户和取消关注 @Override @Transactional(propagation = Propagation.REQUIRED) public void saveUserFanRelation(String userId, String fanId) { UsersFans userFan = new UsersFans(); String relId = sid.nextShort(); userFan.setId(relId); userFan.setUserId(userId); userFan.setFanId(fanId); usersFansMapper.insert(userFan); usersMapper.addFansCount(userId); usersMapper.addFollersCount(fanId); } @Override @Transactional(propagation = Propagation.REQUIRED) public void deleteUserFanRelation(String userId, String fanId) { UsersFansExample example = new UsersFansExample(); example.createCriteria().andFanIdEqualTo(fanId).andUserIdEqualTo(userId); usersFansMapper.deleteByExample(example); usersMapper.reduceFansCount(userId); usersMapper.reduceFollersCount(fanId); }六、视频热搜关键词使用了一个微信小程序搜索框组件:https://github.com/mindawei/w…前端页面加载事件:热搜词的查询语句: <select id=“getHotWords” resultType=“string”> SELECT content FROM search_records GROUP BY content ORDER BY COUNT(content) DESC </select>六、显示我点过赞的视频(即收藏)<!– 查询我喜欢的视频 –> <select id=“queryMyLikeVideos” resultMap=“BaseResultMap” parameterType=“String”> select v.,u.face_image as face_image,u.nickname as nickname from videos v left join vuser u on v.user_id = u.id where v.id in (select ulv.video_id from users_like_videos ulv where ulv.user_id = #{userId}) and v.status = 1 order by v.create_time desc </select>七、查询我关注的人发的视频 <!– 查询我关注的人发的视频 –> <select id=“queryMyFollowVideos” resultMap=“BaseResultMap” parameterType=“String”> select v.,u.face_image as face_image,u.nickname as nickname from videos v left join vuser u on v.user_id = u.id where v.user_id in (select uf.user_id from users_fans uf where uf.fan_id = #{userId}) and v.status = 1 order by v.create_time desc </select>八、举报 获取举报的内容然后发送请求:九、评论留言和回复 POJO设计:public class Comments { private String id; private String fatherCommentId; private String toUserId; private String videoId; private String fromUserId; //留言者,评论的用户id private Date createTime; private String comment; //评论内容}点击某条评论,回复: replyFocus:function(e){ var me = this; var fatherCommentId = e.currentTarget.dataset.fathercommentid; var toUserId = e.currentTarget.dataset.touserid; var toNickname = e.currentTarget.dataset.tonickname; me.setData({ placeholder: “回复 " + toNickname, replyToUserId: toUserId, replyFatherCommentId: fatherCommentId, commentFocus: true }); },前端确认留言,保存: