Wechat Mini | Note-8

微信小程序开发 Note-8


搜索功能整合 & 首页联调

通过修改index.js中对于getAllVideoList,加入对应的参数,搜索内容和分页记录;

以达到搜索返回视频列表的目标;(上拉刷新和下拉刷新不进行刷新)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
// 共用方法
getAllVideoList: function (page, isSaveRecord) {
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
});
}
});
}

热搜查询联调 & 视频对象播放与暂停

Q:对视频对象进行mute设置时,跳转到搜索页面和主页时,视频依然播放音乐;

A:在JS中进行相应的修改;

步骤: 在生命周期的onLoad(),获取videoContext,onShow()对视频进行播放,

​ 在跳转时,onHide()进行视频暂停;

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
const app = getApp()
Page({
data: {
cover:"cover"
},
videoCtx:{},
onLoad:function(){
var me = this;
me.videoCtx = wx.createVideoContext("myVideo", me);
},
onShow:function(){
var me = this;
me.videoCtx.play();
},
onHide:function(){
var me = this;
me.videoCtx.pause();
},
// 搜索
showSearch:function(){
wx.navigateTo({
url: '../searchVideo/searchVideo'
})
}
})

上传视频功能复用 & 测试

在pages同级目录下,创建一个utils,videoUtil.js

1
2
3
4
5
6
7
8
9
10
11
12
// videoUtil.js
// 视频上传-跳转至BGM选择页面
function uploadVideo() {
var me = this;
wx.chooseVideo({
...
});
}
// videoUtil.js 导出
module.exports = {
uploadVideo: uploadVideo
}
1
2
3
4
5
6
7
8
9
var videoUtil = require('../../utils/videoUtil.js') // 引用
const app = getApp()
Page({
...
// 上传视频
upload:function(){
videoUtil.uploadVideo();
}
})

首页进入视频展示页

从首页中的对象,获取到JSON数据,然后通过转换的形式,转换成字符串,传到videoinfo,在videoinfo中,再转换回JSON对象,进行数据的获取和赋值;

1
2
3
4
5
6
7
8
9
10
11
// index.js
// 具体的视频信息-跳转
showVideoInfo: function(e) {
var me = this;
var videoList = me.data.videoList;
var arrindex = e.target.dataset.arrindex;
var videoInfo = JSON.stringify(videoList[arrindex]);
wx.redirectTo({
url: '../videoinfo/videoinfo?videoInfo=' + videoInfo
})
}
1
2
3
4
5
6
7
8
9
10
11
12
// videoinfo.js
onLoad: function(params) {
var me = this;
me.videoCtx = wx.createVideoContext("myVideo", me);
// 获取上一页面传入的参数
var videoInfo = JSON.parse(params.videoInfo);
me.setData({
videoId: videoInfo.id,
src: app.serverUrl + videoInfo.videoPath,
videoInfo: videoInfo
});
}

页面重定向

对于没有登录的用户,可以搜索,但是不能进行个人信息页面的跳转和视频的上传;

所以需要对于没有登录的用户,进行页面的拦截和重定向;

1
2
3
4
5
6
7
8
9
10
11
12
showMine: function() {
var user = app.getGlobalUserInfo();
if (user == null || user == undefined || user == "") {
wx.navigateTo({
url: '../userLogin/login',
});
} else {
wx.navigateTo({
url: '../mine/mine',
});
}
}

在从视频详细页面跳转到登录页面之后,我们希望登录后,再次跳转回到之前的视频详细页面;

那么我们需要将原视频详细页面的信息传到登录页面,再进行页面的重定向跳转;

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
// videoInfo.js
Page({
// 上传视频
upload: function() {
var me = this;
var user = app.getGlobalUserInfo();
// 重定向数据定义
var videoInfo = JSON.stringify(me.data.videoInfo);
var realUrl = '../videoinfo/videoinfo#videoInfo@' + videoInfo;
if (user == null || user == undefined || user == "") {
wx.navigateTo({
url: '../userLogin/login?redirectUrl=' + realUrl,
});
} else {
videoUtil.uploadVideo();
}
}
})
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
// login.js
const app = getApp()

Page({
data: {

},
// 视频页面重定向跳转到登录页面,做参数的处理(接收与反传)
onLoad: function(params) {
var me = this;
var redirectUrl = params.redirectUrl;
redirectUrl = redirectUrl.replace(/#/g, "?");
redirectUrl = redirectUrl.replace(/@/g, "=");
me.redirectUrl = redirectUrl;
},
// 登录
doLogin: function(e) {
...
if (username.length == 0 || password.length == 0) {
...
} else {
...
// BackEnd
wx.request({
...
success: function(res) {
...
// app.userInfo = res.data.data;
// fixme 修改原有全局对象为本地缓存
app.setGlobalUserInfo(res.data.data);

// 页面跳转
var redirectUrl = me.redirectUrl;
if (redirectUrl != null && redirectUrl != undefined && redirectUrl != "") {
wx.redirectTo({
url: redirectUrl,
});
} else {
wx.redirectTo({
url: '../mine/mine',
});
}
} else if (status == 500) {
...
});
}
}
})
}
}
})

拦截器配置与注册

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
// 模拟拦截器配置(对所有请求进行拦截)
public class MiniInterceptor implements HandlerInterceptor {
/**
* 拦截请求判断,预处理(Controller之前)
*/
@Override
public boolean preHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o) throws Exception {
if (true) {
System.out.println("请求拦截");
return false;
}
// 返回false:请求被拦截,返回
// 返回true:请求允许,继续执行
return true;
}

/**
* 请求Controller之后,渲染视图之前
*/
@Override
public void postHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, ModelAndView modelAndView) throws Exception {
}

/**
* 请求和视图渲染之后
*/
@Override
public void afterCompletion(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, Exception e) throws Exception {
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
// 拦截器注册
@Configuration
public class WebMvcConfig extends WebMvcConfigurerAdapter {
@Bean
public MiniInterceptor miniInterceptor(){
return new MiniInterceptor();
}
/**
* 注册中心
*/
@Override
public void addInterceptors(InterceptorRegistry registry) {
// 对UserController进行拦截注册
registry.addInterceptor(miniInterceptor()).addPathPatterns("/user/**");
super.addInterceptors(registry);
}
}

完善登录拦截 & 限制单台手机登录

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
public class MiniInterceptor implements HandlerInterceptor {
@Autowired
private RedisOperator redis;
public static final String USER_REDIS_SESSION = "user-redis-session";

/**
* 拦截请求判断,预处理(Controller之前)
*/
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object o) throws Exception {
String userId = request.getHeader("userId");
String userToken = request.getHeader("userToken");

if (StringUtils.isNotBlank(userId) && StringUtils.isNotBlank(userToken)) {
String uniqueToken = redis.get(USER_REDIS_SESSION + ":" + userId);
// Token超时限制的判断 重新登录
if (StringUtils.isEmpty(uniqueToken) && StringUtils.isBlank(uniqueToken)) {
System.out.println("请登录");
returnErrorResponse(response, IMoocJSONResult.errorTokenMsg("请登录"));
return false;
} else {
// 限制一台手机登录
if (!uniqueToken.equals(userToken)) {
System.out.println("帐号异点登录");
returnErrorResponse(response, IMoocJSONResult.errorTokenMsg("帐号异点登录"));
return false;
}
}
} else {
returnErrorResponse(response, IMoocJSONResult.errorTokenMsg("请登录"));
return false;
}
return true;
}

/**
* 公用返回JSON格式
*/
public void returnErrorResponse(HttpServletResponse response, IMoocJSONResult result) throws IOException, UnsupportedEncodingException {
OutputStream out = null;
try {
response.setCharacterEncoding("utf-8");
response.setContentType("text/json");
out = response.getOutputStream();
out.write(JsonUtils.objectToJson(result).getBytes("utf-8"));
out.flush();
} finally {
if (out != null) {
out.close();
}
}
}
}

拦截器联调

对于拦截器方法中,需要获取用户的USERID以及USERTOKEN,所以在用户请求时,在header中加入相应数据,以实现拦截器的功能;

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
Page({
// 加载
onLoad: function() {
...
// BackEnd
wx.request({
...
header: {
'content-type': 'application/json',
'userId': user.id,
'userToken': user.userToken
},
success: function(res) {
...
} else if (res.data.status == 502) {
wx.showToast({
title: res.data.msg,
icon: 'none',
duration: 2000,
success: function() {
wx.redirectTo({
url: '../userLogin/login',
});
}
});
}
}
});
}
})

点赞接口

非常简单的接口,不加以展示;

首先对Mapper进行方法的编写,然后修改对于的XML的语句;

在VideoServiceImpl进行对于方法的实现即可userLikeVideo & userUnLikeVideo

以及Controller的修改;

点赞联调

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
var videoUtil = require('../../utils/videoUtil.js')
const app = getApp()
Page({
data: {
cover: "cover",
videoId: "",
src: "",
videoInfo: {},
userLikeVideo: false
},
// 点赞与取消点赞
likeVideoOrNot: function(e) {
var me = this;
var videoInfo = me.data.videoInfo;
var user = app.getGlobalUserInfo();
// 判断登录

if (user == null || user == undefined || user == "") {
wx.navigateTo({
url: '../userLogin/login',
});
} else {
// 点赞与取消点赞的request
var userLikeVideo = me.data.userLikeVideo;
var url = '/video/userLike?userId=' + user.id + "&videoId=" + videoInfo.id + "&videoCreaterId=" + videoInfo.userId;
if (userLikeVideo) {
// 取消点赞
url = '/video/userUnLike?userId=' + user.id + "&videoId=" + videoInfo.id + "&videoCreaterId=" + videoInfo.userId;
}
// request
var serverUrl = app.serverUrl;
wx.showLoading({
title: '提交中',
})
wx.request({
url: serverUrl + url,
method: 'POST',
header: {
'content-type': 'application/json',
'userId': user.id,
'userToken': user.userToken
},
success:function(res){
wx.hideLoading();
me.setData({
userLikeVideo: !userLikeVideo
});
}
})
}
}
})

视频展示页

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
var videoUtil = require('../../utils/videoUtil.js')
const app = getApp()
Page({
data: {
cover: "cover",
videoId: "",
src: "",
videoInfo: {},
userLikeVideo: false
},
onLoad: function(params) {
// 获取视频发布者信息,点赞关系
var serverUrl = app.serverUrl;
var user = app.getGlobalUserInfo();
var loginUserId = "";
if (user != null && user != undefined && user != "") {
loginUserId = user.id;
}
wx.request({
url: serverUrl + '/user/queryPublisher?loginUserId=' + loginUserId + "&videoId=" + videoInfo.id + "&publishUserId=" + videoInfo.userId,
method:'POST',
success:function(res){
console.log(res.data);
var publisher = res.data.data.publisher;
var userLikeVideo = res.data.data.userLikeVideo;
me.setData({
serverUrl: serverUrl,
publisher: publisher,
userLikeVideo: userLikeVideo
});
}
});
}
})
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
// UserController
@ApiOperation(value = "QUERY VIDEO PUBLISHER INFORMATION", notes = "QUERY VIDEO PUBLISHER INFORMATION API")
@PostMapping("/queryPublisher")
public IMoocJSONResult queryPublisher(String loginUserId,String videoId,String publishUserId) {
if (StringUtils.isBlank(publishUserId)) {
return IMoocJSONResult.errorMsg("信息不存在(无ID)");
}
// 查询发布者用户个人信息
Users userInfo = userService.queryUserInfo(publishUserId);
UsersVO publisher = new UsersVO();
BeanUtils.copyProperties(userInfo, publisher);

// 查询登录用户与点赞关系
boolean userLikeVideo = userService.isUserLikeVideo(loginUserId,videoId);
PublisherVideo bean = new PublisherVideo();
bean.setPublisher(publisher);
bean.setUserLikeVideo(userLikeVideo);

return IMoocJSONResult.ok(bean);
}