java-mall-app/community/nvueSwiper/nvueSwiper.nvue
2024-11-01 16:35:40 +08:00

797 lines
24 KiB
Plaintext
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<template>
<view>
<!--
注意:这是 H5、微信小程序界面请勿和 new_index.nvue、index.nvue 混用
1. new_index.nvue、index.nvue这两个是App页面
2. 另外data.js 是上一版本留下的假数据,这一版改成了 URL 请求了(如不需要可以删除,也可作为后端请求参考)
3. 请各位大神多多留手,我已经把请求内存开到最大了
4. 视频 id 切记是字符串类型
-->
<image v-if="isShowAixin" src="../static/img/index/aixining.png" :style="'position: fixed; margin-left: '+ aixinLeft +'px; margin-top: '+ aixinTop +'px; width: 70px; height: 65px; transform: rotate('+ Rotate +'deg);'"></image>
<swiper :style="'width: '+ windowWidth +'px; height: '+ windowHeight +'px; background-color: #000000;'" :vertical="true" @animationfinish="animationfinish" @change="change" :current="current" :indicator-dots="false">
<swiper-item v-for="(list,index) in dataList" :key="index">
<view>
<!--
1.v-if用于控制视频在节点的渲染数
2.muted的默认值是 false代表默认是禁音视频的
3.http-cache默认开启视频缓存
4.poster封面方案一这里的封面默认处理存储在阿里云的视频
5.show-loading这里默认去掉播放转圈的标志
v-if="Math.abs(k-index)<=1"
-->
<video v-if="Math.abs(k-index)<=1" :id="list.story_id+''+index" :loop="true" :muted="list.isplay" :controls="false" :http-cache="true" object-fit="cover" :page-gesture="false" :show-fullscreen-btn="false" :show-loading="false" :show-center-play-btn="false" :enable-progress-gesture="false" :src="list.story_video" @ended="ended" @click="tapVideoHover(list.state,$event)"
:style="'width: '+ windowWidth +'px; height: '+ windowHeight +'px; background-color: #000000; z-index: -1;'"></video>
<!--
1.这里是封面(方案二):这里的封面可以自定义。
2.也在代码中做了批注,两种方案可以共存,不会相互影响。
-->
<image v-if="!list.playIng" :src="list.story_file[0]" :style="'width: '+ windowWidth +'px; height: '+ windowHeight +'px; position: absolute;'" mode="aspectFit"></image>
</view>
<!-- 播放状态pause 的时候就会暂停 -->
<view class="videoHover" @click="tapVideoHover(list.state,$event)" @touchstart="touchstartHover" :style="'width: '+ windowWidth +'px; height: '+ windowHeight +'px;'">
<image v-if="list.state=='pause'" class="playState" src="../static/img/index/play.png"></image>
</view>
<view class="userInfo">
<!-- 1.头像 -->
<image @click="tozuozhe(list.user_id)" class="userAvatar" :src="list.user_avatar" mode="aspectFill"></image>
<text class="right-text-avater" @click="onFollow(list.user_id,index)" v-if="(list.user_id != userInfo.user_id && !list.IsFollow)">+</text>
<!-- 2.点赞 -->
<view @click="cLike(list.IsFabulous);" style="opacity: 0.9; margin-top: 17px;">
<image v-if="list.IsFabulous" src="../static/img/index/xin.png" style="width: 40px; height: 40px; position: absolute; right: 6px;" @click.stop="onUnLike" :data-story_id="list.story_id" :data-index="index"></image>
<image v-if="!list.IsFabulous" src="../static/img/index/xin-2.png" style="width: 40px; height: 40px; position: absolute; right: 6px;" @click.stop="onLike" :data-story_id="list.story_id" :data-index="index"></image>
<text style="color: #FFFFFF; margin-top: 5px; font-size: 14px; text-align: center; margin-top: 40px; font-weight: bold;" :class="{'likeNumActive':list.IsFabulous}">{{list.story_like_count}}</text>
</view>
<!-- 3.评论 -->
<view class="comment" @click="toComment(index)" style="opacity: 0.9; margin-top: 17px;">
<image src="../static/img/index/liaotian-2.png" style="width: 35px; height: 35px; position: absolute; right: 7px;"></image>
<text style="color: #FFFFFF; margin-top: 5px; font-size: 14px; font-weight: bold; text-align: center; margin-top: 40px;">{{list.story_comment_count}}</text>
</view>
<!-- 4.收藏 -->
<view class="fav" style="opacity: 0.9; margin-top: 17px;">
<image v-if="(list.IsCollection)" src="../static/img/index/sc-2.png" style="width: 35px; height: 35px; position: absolute; right: 7px;" @click.stop="onUnCollection" :data-story_id="list.story_id" :data-index="index"></image>
<image v-else src="../static/img/index/sc.png" style="width: 35px; height: 35px; position: absolute; right: 7px;" @click.stop="onCollection" :data-story_id="list.story_id" :data-index="index"></image>
<text style="color: #FFFFFF; margin-top: 5px; font-size: 14px; font-weight: bold; text-align: center; margin-top: 40px;">{{list.story_collection_count}}</text>
</view>
<!-- 5.举报 -->
<view @click="report" style="opacity: 0.9; margin-top: 17px;">
<image src="../static/img/index/jubao.png" style="width: 40px; height: 40px; position: absolute; right: 5px;"></image>
<text style="color: #FFFFFF; margin-top: 5px; font-size: 14px; text-align: center; font-weight: bold; margin-top: 40px;">{{__('举报')}}</text>
</view>
</view>
<!-- 最底下的文字部分 -->
<view class="view-product" v-if="list.item_id.length > 0 && list.product_item_name" @click.stop="onProduct(list.item_id)">
<view class="left-view" style="width: 100rpx;height: 100rpx;">
<image :src="list.product_image" class="product_img" style="width: 100rpx;height: 100rpx;"></image>
</view>
<view class="left-view" style="width: 400rpx;height: 100rpx;">
<view class="left-text uni-ellipsis" style="padding-left: 10rpx;">{{list.product_item_name}}</view>
<view class="left-text uni-ellipsis" style="padding-left: 10rpx;font-size: 24rpx;padding-top:4rpx;">{{sprintf(__('价格:%s'), list.item_unit_price)}}</view>
</view>
</view>
<view class="content" style="display: flex;">
<!-- <image :src="list.user_avatar" @click="tozuozhe(list.user_id)" class="userAvatar" style="width: 400rpxpx; height: 100rpx; left: 7px;position: absolute;"></image> -->
<text class="userName" style="width: 250rpx;">@{{list.user_nickname}}</text><!-- i={{i}} -->
<view class="words">
{{list.story_content}}
</view>
</view>
</swiper-item>
</swiper>
<uni-popup type="bottom" ref="pinglun" @touchmove.stop.prevent="moveHandle">
<view v-if="isDouyin" :style="'width: '+ windowWidth +'px; height: '+ (boxStyle.height/heightNum) +'px; background-color: #fff; border-top-left-radius: 10px; border-top-right-radius: 10px;'">
<douyin-scrollview :Width="windowWidth" :story_id="story_id" :videouserID="user_id" :pinlunNum="pinlunNum" :Height="(boxStyle.height/1.23)" :deleteIOSHeight="36" :deleteAndroidHeight="15" @closeScrollview="closeScrollview"></douyin-scrollview>
</view>
</uni-popup>
</view>
</template>
<script>
import {
mapState,
mapMutations
} from 'vuex'
/*
引入评论组件
*/
import douyinScrollview from '@/community/components/douyin-scrollview/douyin-H-scrollview.vue'
import uniPopup from '@/components/uni-popup/uni-popup.vue'
export default {
data() {
return {
windowWidth: 0,
windowHeight: 0,
platform: "",
deleteHeight: 0,
dataList: [],
k: 0,
oldVideo: "",
voice: "",
timeout: "",
current: 0,
story_id: 0,
user_id: 0,
boxStyle: { //视频,图片封面样式🌟💗
'height': 0,
'width': 0,
},
page: 1,
index: 0,
isDouyin: false,
pinlunNum: 0,
deleteHeight: 0, //测试高度🌟💗
// 引入评论 - 参数
heightNum: 1.18,
// 双击点赞参数
touchNum: 0,
aixinLeft: 0,
aixinTop: 0,
isShowAixin: false,
Rotate: 0,
uid: 0,
}
},
components: {
douyinScrollview,
uniPopup
},
computed: mapState(['Config', 'StateCode', 'notice', 'plantformInfo', 'shopInfo', 'userInfo', 'hasLogin', '__', '$',
'sprintf'
]),
watch: {
k(k, old_k) {
console.log(k)
this.dataList[old_k].playIng = false //如果视频暂停,就加载封面
this.dataList[old_k].isplay = true
this.dataList[old_k].state = 'pause'
this.user_id = this.dataList[old_k].user_id;
this.story_id = this.dataList[k].story_id
this.pinlunNum = this.dataList[old_k].story_comment_count;
// uni.createVideoContext(this.dataList[old_k]._id+''+old_k,this).seek(0)
// uni.createVideoContext(this.dataList[old_k]._id+''+old_k,this).pause()
console.log('预留第' + (old_k + 1) + '个视频:' + this.dataList[old_k].story_id + '' + old_k)
// 2.0版本已经去掉了下面这一句,视频不用暂停,只需要把声音禁止就行
uni.createVideoContext(this.dataList[old_k].story_id + '' + old_k, this).stop() //如果视频暂停那么旧视频停止这里的this.dataList[old_k]._id + '' + old_k后面加 old_k 是为了每一个视频的 id 值不同,这样就可以大程度的避免串音问题
console.log('已经暂停 --> 第' + (old_k + 1) + '个视频~') //提示
//增加视频、图文观看量统计
this.dataList[k].state = 'play'
setTimeout(() => {
uni.createVideoContext(this.dataList[k].story_id + '' + k, this).play()
setTimeout(() => {
this.dataList[k].isplay = false
this.dataList[k].playIng = true
}, 50)
}, 250)
var p = k + 1;
console.log('预加载第' + (p + 1) + '个视频:' + this.dataList[p].story_id + '' + p)
}
},
onLoad(options) {
if (options.uid) {
this.uid = options.uid
}
this.platform = uni.getSystemInfoSync().platform
var model = uni.getSystemInfoSync().model
if (this.platform == 'ios' && (model !== 'iPhone6' || model !== 'iPhone6s' || model !== 'iPhone7' || model !== 'iPhone8')) {
this.deleteHeight = 0 //有 tabbar的 修改这里可以改变视频高度
/*
引入评论参数
*/
this.heightNum = 1.27
} else {
this.deleteHeight = 0
/*
引入评论参数
*/
this.heightNum = 1.25
}
this.story_id = options.id ? options.id : 0;
this.windowWidth = uni.getSystemInfoSync().windowWidth
this.windowHeight = uni.getSystemInfoSync().windowHeight
this.boxStyle.width = this.windowWidth + 'px' //给宽度加px
this.boxStyle.height = this.windowHeight - this.deleteHeight; //有 tabbar的 修改这里可以改变视频高度
this.get() //刚进入页面加载数据
},
onShow() {
console.log('回到前台');
if (this.dataList.length !== 0) {
this.dataList[this.k].state = 'play';
uni.createVideoContext(this.dataList[this.k].story_id + '' + this.k, this).play()
}
},
onHide() {
this.dataList[this.k].state = 'pause'; //界面隐藏也要停止播放视频
uni.createVideoContext(this.dataList[this.k].story_id + '' + this.k, this).pause(); //暂停以后继续播放
console.log('到后台');
},
onShareAppMessage() {
// #ifdef MP-WEIXIN
wx.showShareMenu({
withShareTicket: true,
menus: ['shareAppMessage', 'shareTimeline']
});
// #endif
return {
imageUrl: this.dataList[0]['story_file'][0],
title: this.pname,
path: "/community/nvueSwiper/nvueSwiper?id=" + this.story_id + "&uid=" + this.userInfo.user_id
}
},
/**
* 用户点击右上角分享朋友圈
*/
onShareTimeline: function() {
return {
title: this.dataList[0].story_title,
query: {
uid: this.userInfo.user_id,
pid: this.story_id
},
imageUrl: this.dataList[0]['story_file'][0],
}
},
methods: {
...mapMutations(['logout', 'getPlantformInfo', 'forceUserInfo', 'getStoreInfo']),
ended() {
// 1.播放当前视频结束时触发,自动切换下一个视频
// this.current = this.k+1
},
onProduct(item_id) {
this.$.gopage('/pages/product/detail?pid=' + item_id)
},
//取消收藏
onUnCollection: function(a) {
var that = this,
params = {
story_id: a.currentTarget.dataset.story_id
};
that.forceUserInfo(function(user) {
that.index = a.currentTarget.dataset.index;
that.$.request({
url: that.Config.URL.sns.story_collection_remove,
data: params,
success: function(data, status, msg, code) {
if (200 == status) {
that.dataList[that.index].IsCollection = false;
that.dataList[that.index].story_collection_count--;
that.$forceUpdate();
} else {
that.$.confirm(msg)
}
}
});
})
},
//收藏
onCollection: function(a) {
var that = this,
params = {
story_id: a.currentTarget.dataset.story_id
};
that.forceUserInfo(function(user) {
that.index = a.currentTarget.dataset.index;
that.$.request({
url: that.Config.URL.sns.story_collection_add,
data: params,
success: function(data, status, msg, code) {
if (200 == status) {
that.dataList[that.index].IsCollection = true;
that.dataList[that.index].story_collection_count++;
that.$forceUpdate();
} else {
that.$.confirm(msg)
}
}
});
})
},
//举报
report: function() {
this.$.gotopage('/member/member/feedback')
},
closeScrollview() {
// 点击评论里面的叉叉,就会关闭评论
this.$refs.pinglun.close();
},
onUnLike: function(a) {
let that = this;
that.forceUserInfo(function(user) {
that.canceldianzan(a.currentTarget.dataset.story_id)
that.index = a.currentTarget.dataset.index;
});
},
canceldianzan: function(story_id) {
var that = this,
params = {
story_id: story_id
};
that.$.request({
url: this.Config.URL.sns.story_like_remove,
data: params,
success: function(data, status, msg, code) {
if (200 == status) {
//修正当前记录数据
that.dataList[that.index].IsFabulous = false;
that.dataList[that.index].story_like_count--
} else {}
}
});
},
onLike: function(a) {
let that = this;
that.forceUserInfo(function(user) {
that.doLike(a.currentTarget.dataset.story_id);
that.index = a.currentTarget.dataset.index;
});
},
doLike: function(story_id) {
var that = this,
params = {
story_id: story_id
};
that.$.request({
url: this.Config.URL.sns.story_like_add,
data: params,
success: function(data, status, msg, code) {
if (200 == status) {
that.dataList[that.index].IsFabulous = true;
that.dataList[that.index].story_like_count++
} else {}
}
});
},
// 双击点赞效果
touchstartHover(event) {
if (this.touchNum >= 1) {
// console.log('双击 -- X坐标'+ event.touches[0].screenX);
// console.log('双击 -- Y坐标'+ event.touches[0].screenY);
this.aixinLeft = event.touches[0].screenX - 50;
this.aixinTop = event.touches[0].screenY - 50;
this.isShowAixin = true;
let max = 40;
let min = -40;
this.Rotate = Math.floor(Math.random() * (max - min + 1)) + min;
setTimeout(() => {
this.isShowAixin = false;
}, 700)
}
},
//点击播放&&暂停
tapVideoHover(state, event) {
this.dataList[this.k].isShowimage = false
this.dataList[this.k].isShowProgressBarTime = false
this.ProgressBarOpacity = 0.5
this.dotWidth = 0
console.log('state--', state);
// 1.启用双击点赞 --- start
this.touchNum++;
setTimeout(() => {
if (this.touchNum == 1) {
if (state == 'play' || state == 'continue') {
this.dataList[this.k].state = 'pause';
} else {
this.dataList[this.k].state = 'continue';
}
if (this.dataList[this.k].state == 'continue') {
uni.createVideoContext(this.dataList[this.k].story_id + '' + this.k, this).play(); //暂停以后继续播放
}
if (this.dataList[this.k].state == 'pause') {
uni.createVideoContext(this.dataList[this.k].story_id + '' + this.k, this).pause(); //暂停以后继续播放
}
}
if (this.touchNum >= 2) {
this.doubleLike();
}
this.touchNum = 0;
this.$set(this.dataList, this.k, this.dataList[this.k])
}, 200)
// --------------- ending
// 2. 不启用双击点赞 start
// if(state=='play'||state=='continue'){
// this.dataList[this.k].state = 'pause';
// }else{
// this.dataList[this.k].state = 'continue';
// }
// if(this.dataList[this.k].state == 'continue'){
// uni.createVideoContext(this.dataList[this.k]._id+''+this.k,this).play();//暂停以后继续播放
// }
// if(this.dataList[this.k].state == 'pause'){
// uni.createVideoContext(this.dataList[this.k]._id+''+this.k,this).pause();//暂停以后继续播放
// }
// --------------- ending
},
doubleLike() {
if (this.dataList[this.k].like == false) {
this.dataList[this.k].like_n += 1;
this.dataList[this.k].like = true;
}
/*
点赞
*/
},
change(event) {
this.k = event.detail.current
},
tozuozhe(uid) {
uni.navigateTo({
url: '/community/community/userspace?uid=' + uid
});
},
animationfinish(event) {
// 1.这里进行判断,如果是最后一个视频就进入 get() 方法加载视频进入列表
if (this.k == this.dataList.length - 1) {
this.page = parseInt(this.page) + 1;
this.GET()
}
},
//每一组结束时新的请求
GET() {
let that = this;
var params = {
page: this.page,
story_type: 4,
uid: this.uid
};
console.log(params)
this.$.request({
url: this.Config.URL.sns.story_lists,
data: params,
success: (data, status, msg, code) => {
var msg = data.items
// 2.这里把视频添加到视频列表
for (let i = 0; i < msg.length; i++) {
msg[i].story_id = msg[i].story_id + 'k';
msg[i].state = 'pause';
msg[i].playIng = false;
msg[i].isplay = true;
msg[i].isShowimage = false;
msg[i].isShowProgressBarTime = false;
that.dataList.push(msg[i])
}
}
})
},
get() {
// 1.这里引入后端请求数据
// this.dataList = userList;
let that = this;
var params = {
page: this.page,
story_type: 4,
};
console.log(params)
params['story_id'] = that.story_id;
this.$.request({
url: this.Config.URL.sns.story_lists,
data: params,
success: (data, status, msg, code) => {
var msg = data.items
this.user_id = msg[0].user_id;
this.story_id = msg[0].story_id;
this.pinlunNum = msg[0].story_comment_count;
// 2.这里把视频添加到视频列表
for (let i = 0; i < msg.length; i++) {
msg[i].story_id = msg[i].story_id + 'k';
msg[i].state = 'pause';
msg[i].playIng = false;
msg[i].isplay = true;
msg[i].isShowimage = false;
msg[i].isShowProgressBarTime = false;
this.dataList.push(msg[i])
}
// 3.播放当前视频
setTimeout(() => {
this.dataList[this.k].isplay = false
this.dataList[this.k].state = 'play'
uni.createVideoContext(this.dataList[this.k].story_id + '' + this.k, this).play()
this.dataList[this.k].playIng = true
this.$set(this.dataList, this.k, this.dataList[this.k])
}, 200)
// start - 预加载开始
var p = this.k
++p
if (typeof this.dataList[p] != "undefined") {
setTimeout(() => {
uni.createVideoContext(this.dataList[p].story_id + '' + this.k, this).play()
}, 20)
clearTimeout(this.timeout)
this.timeout = setTimeout(() => {
uni.createVideoContext(this.dataList[p].story_id + '' + this.k, this).seek(0)
uni.createVideoContext(this.dataList[p].story_id + '' + this.k, this).pause()
console.log('预加载第' + (p + 1) + '个视频:' + this.dataList[p].story_id + '' + p)
}, 1500)
}
// end - 预加载结束
}
})
},
share() {
uni.showToast({
title: '分享',
icon: 'none'
})
},
onFollow: function(user_id, index) {
let that = this;
that.forceUserInfo(function(user) {
that.AddFollow(user_id, index)
});
},
AddFollow: function(friend_id, index) {
var that = this,
params = {
user_id: friend_id,
OperateId: friend_id,
friend_id: friend_id
};
var list = that.dataList;
that.$.request({
url: this.Config.URL.user.friend_agree,
data: params,
success: function(data, status, msg, code) {
if (200 == status) {
list[index].IsFollow = 1
that.$set(that.dataList, index, list[index]);
that.$forceUpdate();
that.$.alert('关注成功')
} else {}
}
});
},
toComment(index) {
// 注意点击评论之后会执行这里
/*
1先加载缓冲
2获取当前视频 ID 信息
3🌟🌟🌟🌟重要🌟🌟🌟🌟
- 一定要记得看 index.vue 里面
uni.setStorageSync("user",this.peopleList[i]);
这个东西,用于存储当前用户信息。在 插件里面会使用到这个东西,
记得写一下。
4打开评论
*/
uni.showToast({
title: '加载中...',
icon: 'none',
position: 'bottom',
duration: 300
})
uni.setStorageSync("videoID", this.dataList[index].story_id);
this.isDouyin = true;
console.log(8888)
this.$refs.pinglun.open('bottom')
uni.hideLoading();
},
cLike(sss) {
this.dataList[this.k].like = !this.dataList[this.k].like
const video = this.dataList[this.k];
sss ? video.like_n -= 1 : video.like_n += 1;
}
}
}
</script>
<style>
.container {
background-color: #000000;
}
.item {
/* width : 750rpx; */
background-color: #000000;
position: relative;
}
.videoHover {
position: absolute;
top: 0;
left: 0;
flex: 1;
background-color: rgba(0, 0, 0, 0.1);
justify-content: center;
align-items: center;
/* border-style: dashed;
border-color: #DD524D;
border-width: 1px; */
}
.playState {
width: 160rpx;
height: 160rpx;
opacity: 0.2;
}
.userInfo {
position: absolute;
bottom: 30rpx;
right: 20rpx;
flex-direction: column;
width: 100rpx;
}
.userAvatar {
border-radius: 500%;
margin-bottom: 15px;
border-style: solid;
border-width: 2px;
border-color: #ffffff;
}
.userAvatar {
width: 100rpx;
height: 100rpx;
}
.likeIco,
.shareIco,
.commentIco {
width: 60rpx;
height: 60rpx;
margin-top: 15px;
}
.likeNum,
.commentNum,
.shareTex {
color: #ffffff;
font-size: 30rpx;
text-align: center;
margin: 5px;
}
.likeNumActive {
color: red;
}
.content {
width: 620rpx;
z-index: 99;
position: absolute;
bottom: 20rpx;
/* justify-content: center; */
padding: 15rpx;
flex-direction: column;
justify-content: flex-start;
color: #ffffff;
}
.userName {
font-size: 16px;
font-weight: bold;
color: #ffffff;
margin-top: 24rpx;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
.words {
/* margin-top: 40rpx; */
font-size: 14px;
color: #ffffff;
overflow: hidden;
/*文本超出隐藏*/
display: -webkit-box;
/*盒子模型微弹性伸缩模型*/
-webkit-box-orient: vertical;
/*伸缩盒子的子元素垂直排列*/
-webkit-line-clamp: 3;
/*文本显示3行*/
}
.root {
background-color: #000000;
}
.right-text-avater {
position: absolute;
font-size: 14px;
top: 80rpx;
left: 30rpx;
height: 40rpx;
width: 40rpx;
background-color: #DD524D;
color: #FFFFFF;
border-radius: 50%;
text-align: center;
line-height: 40rpx;
z-index: 999;
}
.box_title_guanzhu_text {
width: 140rpx;
position: absolute;
left: 400rpx;
top: -8px;
padding: 15rpx 0rpx;
/* line-height: 56rpx; */
border-radius: 35rpx;
margin-top: 49rpx;
background-color: #DB384C;
color: #fff;
font-size: 25rpx;
align-content: center;
align-items: center;
text-align: center;
line-height: 18px;
}
.view-product {
position: absolute;
margin-left: 16rpx;
width: 500rpx;
bottom: 250rpx;
z-index: 9999;
font-size: 32rpx;
color: #FFFFFF;
//#ifndef APP-PLUS-NVUE
white-space: pre-wrap;
text-overflow: ellipsis;
overflow: hidden;
//#endif
display: flex;
background-color: rgba(0, 0, 0, 0.2);
justify-content: space-between;
flex-direction: row
}
</style>