視頻顯示的內容是視頻的截圖,用戶的頭像,用戶的暱稱,都須要一個結合。因此涉及到關聯查詢.源碼:https://github.com/limingios/wxProgram.git 中wx-springboot 和 No.15html
官網介紹
java
https://developers.weixin.qq.com/miniprogram/dev/dev/api/system/system-info/wx.getSystemInfo.htmlios
獲取系統信息
git
由於如今手機的屏幕大小不一致,顯示適配是個很大的問題,如何適配首選要拿到對應手機的像素值,經過像素值獲取響應的信息,動態的控制適配。github
自定義關聯查詢,經過分頁組件查詢出來對應的組合數據,controller提供分頁接口。web
java分頁工具spring
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; } }
java組件原理
sql
經過攔截的方式,當在執行某條sql語句的時候在根據不一樣數據庫的方言,在sql語句查詢的時候添加查詢limit。PageHelper是一款好用的開源免費的Mybatis第三方物理分頁插件,其實我並不想加上好用兩個字,可是爲了表揚插件做者開源免費的崇高精神,我堅決果斷的加上了好用一詞做爲讚美。本來覺得分頁插件,應該是很簡單的,然而PageHelper比我想象的要複雜許多,它作的很強大,也很完全,強大到使用者可能並不須要這麼多功能,完全到一參能夠兩用。可是,我認爲,做爲分頁插件,完成物理分頁任務是根本,其它的不少智能並非必要的,保持它夠傻夠憨,專業術語叫stupid,簡單就是美。數據庫
增長Vo返回參數實體apache
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; } }
數據庫查詢java的mapper
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(); }
數據庫Mybatis的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"> 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>
service的接口和實現
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; } }
controller的開發
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方法迭代循環展現數據。下次說下上拉和下拉刷新。