視頻顯示的內容是視頻的截圖,用戶的頭像,用戶的暱稱,都須要一個結合。因此涉及到關聯查詢.源碼:https://github.com/limingios/wxProgram.git 中wx-springboot 和 No.15html
https://developers.weixin.qq.com/miniprogram/dev/dev/api/system/system-info/wx.getSystemInfo.htmljava
由於如今手機的屏幕大小不一致,顯示適配是個很大的問題,如何適配首選要拿到對應手機的像素值,經過像素值獲取響應的信息,動態的控制適配。ios
自定義關聯查詢,經過分頁組件查詢出來對應的組合數據,controller提供分頁接口。git
package com.idig8.utils;
import java.util.List;
/**
* @Description: 封裝分頁後的數據格式
*/
public class PagedResult {
private int page; // 當前頁數
private int total; // 總頁數
private long records; // 總記錄數
private List<?> rows; // 每行顯示的內容
public int getPage() {
return page;
}
public void setPage(int page) {
this.page = page;
}
public int getTotal() {
return total;
}
public void setTotal(int total) {
this.total = total;
}
public long getRecords() {
return records;
}
public void setRecords(long records) {
this.records = records;
}
public List<?> getRows() {
return rows;
}
public void setRows(List<?> rows) {
this.rows = rows;
}
}
複製代碼
經過攔截的方式,當在執行某條sql語句的時候在根據不一樣數據庫的方言,在sql語句查詢的時候添加查詢limit。PageHelper是一款好用的開源免費的Mybatis第三方物理分頁插件,其實我並不想加上好用兩個字,可是爲了表揚插件做者開源免費的崇高精神,我堅決果斷的加上了好用一詞做爲讚美。本來覺得分頁插件,應該是很簡單的,然而PageHelper比我想象的要複雜許多,它作的很強大,也很完全,強大到使用者可能並不須要這麼多功能,完全到一參能夠兩用。可是,我認爲,做爲分頁插件,完成物理分頁任務是根本,其它的不少智能並非必要的,保持它夠傻夠憨,專業術語叫stupid,簡單就是美。github
package com.idig8.pojo.vo;
import java.util.Date;
import javax.persistence.*;
public class VideosVO {
private String id;
private String userId;
private String audioId;
private String videoDesc;
private String videoPath;
private Float videoSeconds;
private Integer videoWidth;
private Integer videoHeight;
private String coverPath;
private Long likeCounts;
private Integer status;
private Date createTime;
private String username;
private String faceImage;
private String nickname;
public String getId() {
return id;
}
/**
* @param id
*/
public void setId(String id) {
this.id = id;
}
/**
* 獲取發佈者id
*
* @return user_id - 發佈者id
*/
public String getUserId() {
return userId;
}
/**
* 設置發佈者id
*
* @param userId 發佈者id
*/
public void setUserId(String userId) {
this.userId = userId;
}
/**
* 獲取用戶使用音頻的信息
*
* @return audio_id - 用戶使用音頻的信息
*/
public String getAudioId() {
return audioId;
}
/**
* 設置用戶使用音頻的信息
*
* @param audioId 用戶使用音頻的信息
*/
public void setAudioId(String audioId) {
this.audioId = audioId;
}
/**
* 獲取視頻描述
*
* @return video_desc - 視頻描述
*/
public String getVideoDesc() {
return videoDesc;
}
/**
* 設置視頻描述
*
* @param videoDesc 視頻描述
*/
public void setVideoDesc(String videoDesc) {
this.videoDesc = videoDesc;
}
/**
* 獲取視頻存放的路徑
*
* @return video_path - 視頻存放的路徑
*/
public String getVideoPath() {
return videoPath;
}
/**
* 設置視頻存放的路徑
*
* @param videoPath 視頻存放的路徑
*/
public void setVideoPath(String videoPath) {
this.videoPath = videoPath;
}
/**
* 獲取視頻秒數
*
* @return video_seconds - 視頻秒數
*/
public Float getVideoSeconds() {
return videoSeconds;
}
/**
* 設置視頻秒數
*
* @param videoSeconds 視頻秒數
*/
public void setVideoSeconds(Float videoSeconds) {
this.videoSeconds = videoSeconds;
}
/**
* 獲取視頻寬度
*
* @return video_width - 視頻寬度
*/
public Integer getVideoWidth() {
return videoWidth;
}
/**
* 設置視頻寬度
*
* @param videoWidth 視頻寬度
*/
public void setVideoWidth(Integer videoWidth) {
this.videoWidth = videoWidth;
}
/**
* 獲取視頻高度
*
* @return video_height - 視頻高度
*/
public Integer getVideoHeight() {
return videoHeight;
}
/**
* 設置視頻高度
*
* @param videoHeight 視頻高度
*/
public void setVideoHeight(Integer videoHeight) {
this.videoHeight = videoHeight;
}
/**
* 獲取視頻封面圖
*
* @return cover_path - 視頻封面圖
*/
public String getCoverPath() {
return coverPath;
}
/**
* 設置視頻封面圖
*
* @param coverPath 視頻封面圖
*/
public void setCoverPath(String coverPath) {
this.coverPath = coverPath;
}
/**
* 獲取喜歡/讚美的數量
*
* @return like_counts - 喜歡/讚美的數量
*/
public Long getLikeCounts() {
return likeCounts;
}
/**
* 設置喜歡/讚美的數量
*
* @param likeCounts 喜歡/讚美的數量
*/
public void setLikeCounts(Long likeCounts) {
this.likeCounts = likeCounts;
}
/**
* 獲取視頻狀態:
一、發佈成功
二、禁止播放,管理員操做
*
* @return status - 視頻狀態:
一、發佈成功
二、禁止播放,管理員操做
*/
public Integer getStatus() {
return status;
}
/**
* 設置視頻狀態:
一、發佈成功
二、禁止播放,管理員操做
*
* @param status 視頻狀態:
一、發佈成功
二、禁止播放,管理員操做
*/
public void setStatus(Integer status) {
this.status = status;
}
/**
* 獲取建立時間
*
* @return create_time - 建立時間
*/
public Date getCreateTime() {
return createTime;
}
/**
* 設置建立時間
*
* @param createTime 建立時間
*/
public void setCreateTime(Date createTime) {
this.createTime = createTime;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getFaceImage() {
return faceImage;
}
public void setFaceImage(String faceImage) {
this.faceImage = faceImage;
}
public String getNickname() {
return nickname;
}
public void setNickname(String nickname) {
this.nickname = nickname;
}
}
複製代碼
package com.idig8.mapper;
import java.util.List;
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();
}
複製代碼
<?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">
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
and v.status = 1
order by v.create_time
</select>
</mapper>
複製代碼
package com.idig8.service;
import com.idig8.pojo.Videos;
import com.idig8.utils.PagedResult;
public interface VideoService {
/**
* 保存視頻信息
* @param Id
* @return
*/
public String saveVideo(Videos video);
/**
* 分析查詢視頻列表
* @param page
* @param pageSize
* @return
*/
public PagedResult getAllVideos(Integer page,Integer pageSize);
}
複製代碼
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.github.pagehelper.autoconfigure.PageHelperAutoConfiguration;
import com.idig8.mapper.VideosMapper;
import com.idig8.mapper.VideosUsersMapper;
import com.idig8.pojo.Videos;
import com.idig8.pojo.vo.VideosVO;
import com.idig8.service.VideoService;
import com.idig8.utils.PagedResult;
@Service
public class VideoServiceImpl implements VideoService {
@Autowired
private VideosMapper videosMapper;
@Autowired
private VideosUsersMapper videosUsersMapper;
@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.SUPPORTS)
public PagedResult getAllVideos(Integer page, Integer pageSize) {
PageHelper.startPage(page,pageSize);
List<VideosVO> list = videosUsersMapper.queryAllVideos();
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;
}
}
複製代碼
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.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="分頁的視頻列表")
@ApiImplicitParam(name="page", value="頁碼",
dataType="String", paramType="query")
public JSONResult upload(
Integer page) throws Exception {
if(page == null){
page = 1;
}
PagedResult result = videosService.getAllVideos(page, PAGE_SIZE);
return JSONResult.ok(result);
}
}
複製代碼
<view wx:for="{{videoList}}" class="item-container">
<view style='width:{{screenWidth}}px;height:210px;' class='back-img'>
<image src="{{serverUrl}}{{item.coverPath}}" style='width:{{screenWidth}}px;height:210px;' mode="aspectFit" bindtap='showVideoInfo' data-arrindex='{{index}}'></image>
</view>
<view class="desc">
<view class="faceName">
<image class='myface' src="{{serverUrl}}{{item.faceImage}}"></image>
<view class="nickname">{{item.nickname}}</view>
</view>
</view>
</view>
複製代碼
.item-container {
position: relative;
}
.cover {
width: 100%;
height: 400rpx;
display: block;
}
.back-img{
display: block;
background-color: black;
}
.desc {
margin-top: -40rpx;
margin-bottom: 10rpx;
display: flex;
align-items: center;
}
.desc .right {
display: flex;
flex-direction: column;
align-items: center;
}
.desc .faceName {
display: flex;
flex-direction: column;
align-items: center;
margin-left: 10px;
}
.title {
font-size: 30rpx;
margin-top: 10rpx;
margin-left: 20rpx;
width: 600rpx;
}
.myface {
display: block;
width: 60rpx;
height: 60rpx;
border-radius: 30rpx;
margin-top: 10rpx;
margin-right: 20rpx;
}
.nickname {
font-size: 20rpx;
margin-top: 6rpx;
margin-right: 20rpx;
color: darkgray;
}
複製代碼
const app = getApp()
Page({
data: {
// 用於分頁的屬性
totalPage: 1,
page: 1,
videoList: [],
screenWidth: 350,
serverUrl: "",
searchContent: ""
},
onLoad: function (params) {
var me = this;
var screenWidth = wx.getSystemInfoSync().screenWidth;
me.setData({
screenWidth: screenWidth,
});
var searchContent = params.search;
var isSaveRecord = params.isSaveRecord;
if (isSaveRecord == null || isSaveRecord == '' || isSaveRecord == undefined) {
isSaveRecord = 0;
}
me.setData({
searchContent: searchContent
});
// 獲取當前的分頁數
var page = me.data.page;
var me = this;
var serverUrl = app.serverUrl;
wx.showLoading({
title: '請等待,加載中...',
});
var searchContent = me.data.searchContent;
wx.request({
url: serverUrl + '/video/showAll?page=' + page + "&isSaveRecord=" + isSaveRecord,
method: "POST",
data: {
videoDesc: searchContent
},
success: function (res) {
wx.hideLoading();
wx.hideNavigationBarLoading();
wx.stopPullDownRefresh();
console.log(res.data);
// 判斷當前頁page是不是第一頁,若是是第一頁,那麼設置videoList爲空
if (page === 1) {
me.setData({
videoList: []
});
}
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
});
}
})
}
})
複製代碼
PS:主要說了關聯查詢的步驟,首選創建一個VO類,而後mapper關聯VO類,增長對應xml文件返回VO類,service內添加分頁插件,查詢VO類,經過分頁插件設置。
頁面經過微信組件獲取手機的寬度,經過寬度動態的進行適配,調用接口返回內容經過block方法迭代循環展現數據。下次說下上拉和下拉刷新。web