Files
im/pages/find/friend-circle/friend-circle.vue
T
2026-02-15 19:40:36 +08:00

750 lines
18 KiB
Vue
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 class="content" id="content">
<u-navbar
@leftClick="leftClick"
:bgColor="scrollTop>bannarHeight?'#f4f4f4':'transparent'"
title="朋友圈"
title-size="36"
:leftIconColor="scrollTop>bannarHeight?'#333':'#fff'"
:titleStyle ="{color:scrollTop>bannarHeight?'#333':'#fff'}"
:title-bold="true"
:border-bottom="false">
<view slot="right" class="u-margin-right-20" @click="showTypeSheet"
@longpress="linkToRelease({releaseType:0})">
<u-icon name="camera" :color="scrollTop>bannarHeight?'#333':'#fff'" size="32"></u-icon>
</view>
</u-navbar>
<!-- 我的朋友圈基本信息 -->
<view class="content-imgbox" :class="{top:scrollTop>bannarHeight}">
<image class="bgimg" v-if="storeCircleSettings.bg" :src="cdn(storeCircleSettings.bg)" mode="scaleToFill" @tap="showSheet"></image>
<view class="bgimg" v-else @tap="showSheet"></view>
<MyAvatar class="headimg" :src="storeSelfInfo.faceURL" :desc="storeSelfInfo.nickname || storeSelfInfo.remark"
:isGroup="Boolean(storeSelfInfo.groupID)" size="66" @tap="linkToBusinessCard(storeSelfInfo.userID)" />
<text class="nickname">{{ storeSelfInfo.nickname || storeSelfInfo.remark }}</text>
</view>
<!-- 个性签名 -->
<view class="signature">
<u--text :text="storeSelfInfo.bio" :lines="4" size="13" color="#999"></u--text>
</view>
<view v-if="storeCircleUnreadCount>0" style="display: flex;justify-content: center;">
<view @click="clearUnReadCount()"
style="width: 300rpx;height:70rpx;line-height:70rpx;background-color: #333333;color: #ffffff;border-radius:10rpx;display: flex;align-items: center;">
<view style="width:80rpx;padding:0 10rpx;">
<MyAvatar :src="storeSelfInfo.faceURL" class="headimg" desc=" " size="24"/>
</view>
<view style="flex:1;">
{{storeCircleUnreadCount}}条新信息
</view>
</view>
</view>
<!-- 朋友圈列表 -->
<view class="content-circle">
<!-- storeCircleData是vuex变量不在本页面定义 -->
<template v-if="storeCircleData!=null&&storeCircleData.length>0">
<template v-for="(item, index) in storeCircleData" >
<CircleItem :key="index" :index="index" :item="item" @userEvent="onUserEvent"></CircleItem>
</template>
</template>
<template v-else>
<view style="margin-top: 30%;">
<u-empty text="暂无动态,发一条试试吧~"></u-empty>
</view>
</template>
</view>
<u-overlay :show="showInput" @click="showInput = false">
<view class="input-box" :style="{
height: '100rpx',
bottom:keyboardHeight+'px'
}" @tap.stop>
<view class="input-box-flex">
<view class="input-box-flex-grow">
<input :adjust-position="false" type="text" class="content" id="input" v-model="content"
:confirm-type="'send'" :confirm-hold="true" placeholder-style="color:#DDD;" :cursor-spacing="6"
:placeholder="placeholder" :focus="true" @confirm="commitComment" />
</view>
<u-button class="btn" type="primary" size="mini" @tap.prevent.stop="commitComment">发送</u-button>
</view>
</view>
</u-overlay>
<!-- 视频预览 -->
<view v-if="previewVideoFlag==true">
<videoPlayer :previewVideoFlag="previewVideoFlag" :previewVideoSrc="previewVideoSrc" @quitPlay="previewVideoFlag=false"></videoPlayer>
</view>
<!-- 删除朋友圈确认框 -->
<u-modal :show="delCircleObj.delCircleModelFlag"
:showConfirmButton="true" confirmText="删除" confirmColor="#fa3534"
:showCancelButton="true" cancelText="取消" cancelColor="#000000"
content="删除该朋友圈?"
@confirm="confirmDelCircle()" @cancel="cancelDelCircle()">
</u-modal>
</view>
</template>
<script>
import videoPlayer from '@/components/videoPlayer.vue';
import {getFriendCircle} from "@/api/login.js"
import UserBase from "@/components/User.vue"
import MyAvatar from "@/components/MyAvatar/index.vue";
import CircleItem from "./components/circleItem.vue"
import { mapGetters } from "vuex";
import util from "@/util";
export default {
name: 'firendCircle',
mixins:[UserBase],
components:{videoPlayer ,MyAvatar,CircleItem},
computed:{
...mapGetters(["storeSelfInfo",'storeCircleData','storeCircleUnreadCount','storeCircleTopUnreadItems','storeCircleSettings']),
},
data() {
return {
loadMoreFlag:true,//可以分页加载吗
bannarHeight:202,
scrollTop: 0,
content: '',
placeholder: '',
showInput: false,
keyboardHeight:0,
focus: false,
id: '', //某一条朋友圈id
commentInfo: {},
currentItem: {},
previewVideoFlag:false,
previewVideoSrc:'',
page:1,
limit:5,
//删除对象参数
delCircleObj:{
delCircleModelFlag:false,
tempDelCircleId:'',
tempDelIndex:"",
}
};
},
//vuex变量
watch:{
storeCircleData:function(val){
//console.log("监听到朋友圈内容有变动",val.length);
}
},
onReady() {
let that = this;
uni.onKeyboardHeightChange(res => {
that.keyboardHeight = res.height;
if (res.height == 0) {
that.showInput = false;
return;
}
});
},
onShow: function(option) {
//let windowHeight = this.$u.sys().windowHeight;
//this.scrollViewHeight = windowHeight - 90;
//console.log("onshow",this.page);
},
onLoad:function(){
let that=this;
let param={
page:1,
limit:this.limit,
moreFlag:false
};
this.$store.dispatch('circle/getFriendCircleInfo');
this.getCircleDataList(param);
uni.$on("handleFriendCircle", function(friendCircleMessage) {
console.log("监听到朋友圈动态有更新",friendCircleMessage);
//let id= friendCircleMessage.content.id;
//let newPraise= friendCircleMessage.content.likes;
//const index = that.storeCircleData.findIndex(i => i.id ==id);
//that.storeCircleData[index].likes=JSON.parse(newPraise);
if(friendCircleMessage.content.is_liked&&friendCircleMessage.userId!=that.storeSelfInfo.userID){
that.$store.dispatch('circle/updateUnreadCount',1);
}
})
},
//下拉刷新
async onPullDownRefresh() {
let that=this;
that.page=1;
that.limit=5;
that.loadMoreFlag=true;//可以分页加载
let param={
page:1,
limit:this.limit,
moreFlag:false
};
await this.getCircleDataList(param);
uni.stopPullDownRefresh();
},
methods: {
goto:util.goto,
cdn:util.cdn,
clearUnReadCount(){
this.$store.dispatch('circle/updateUnreadCount',0-this.unreadCount);
},
//初始化朋友圈
getCircleDataList:function(param){
let that=this;
this.$store.dispatch('circle/getFriendCircleList',param);
},
//滚动事件
scrolling: function(scrollTop) {
//console.log("event",event);
let that = this;
if (that.showInput == true) {
return;
}
//let scrollTop = event.detail.scrollTop;
// setTimeout(function() {
// that.currentScroll = scrollTop;
// }, 300);
},
//加载更多
loadMore:function(){
let that=this;
if(that.loadMoreFlag==false){
if(that.page>1){
//that.page;
console.log("暂无更多",that.page);
}
return;
}
that.page++;
let param={
page:that.page,
limit:that.limit,
moreFlag:true
}
console.log("page",param.page);
that.getCircleDataList(param);
},
//打开底部更换相册封面弹窗
showSheet() {
const _this = this;
uni.showActionSheet({
itemList:['更换相册封面'],
success: function (res) {
if(res.tapIndex == 0){
_this.goto('/pages/find/friend-circle/chooseCircleBgImg');
}
},
fail: function (res) {
console.log(res.errMsg);
}
})
},
showTypeSheet() {
const _this = this;
uni.showActionSheet({
itemList:['文字','照片','视频'],
success: function (res) {
//toChooseRelease
if([1,2].includes(res.tapIndex)){
_this.toChooseRelease(res.tapIndex);
}else{
_this.linkToRelease({releaseType:0})
}
},
fail: function (res) {
console.log(res.errMsg);
}
})
},
//点赞
clickThumb(item,index) {
let that=this;
let flag=true;
if (item.is_liked) {
flag=false;
}
console.log("当前动态下标",index);
console.log("点赞列表",item);
let param={
id:item.id,
user_id: this.storeSelfInfo.userID,
nickname: this.storeSelfInfo.nickname,
avatar: this.storeSelfInfo.avatar,
is_liked:flag
};
this.$store.dispatch('circle/like',param).then(res=>{
console.log("点赞更新成功",res.data);
}).catch(e=>{
item.is_liked = !item.is_liked;
console.log("评论失败",e);
});
},
//跳转到名片
linkToBusinessCard(userId) {
if(userId==this.storeSelfInfo.userID){
return;
}
this.goto('/pages/common/userCard?sourceID='+userId);
},
//删除朋友圈
deleteCircle:function(item,index){
let that=this;
that.delCircleObj.tempDelCircleId=item.id;
that.delCircleObj.tempDelIndex=index;
that.delCircleObj.delCircleModelFlag=true;
},
confirmDelCircle:function(){
let that=this;
let delCircleId=that.delCircleObj.tempDelCircleId;
let delIndex=that.delCircleObj.tempDelIndex;
let param={
id:delCircleId
};
that.delCircleObj.delCircleModelFlag=false;
this.$store.dispatch('circle/deleteFriendCircleList',param);
},
cancelDelCircle:function(){
let that=this;
that.delCircleObj.delCircleModelFlag=false;
that.delCircleObj.tempDelCircleId="";
that.delCircleObj.tempDelIndex="";
},
//点击评论 唤出输入框和键盘
handleComment(comment, index) {
let that = this;
this.content = '';
that.currentItem = that.storeCircleData[index];
this.id = that.currentItem.id;
this.commentInfo = comment || {};
this.placeholder = '评论:';
if (comment) {
//console.log("评论内容",comment);
if (comment.comment.user_id == this.storeSelfInfo.userID) {
//如果是回复自己
this.placeholder = `评论:`;
} else {
// xxx评论...
this.placeholder = `回复${comment.user.nickname}:`;
}
}
this.showInput = true;
},
//提交评论消息
commitComment() {
let that=this;
if (!that.$u.trim(that.content)) {
return;
}
let param={
reply_user_id:that.commentInfo?.user_id || '',
body:that.content,
id:that.currentItem.id
};
this.$store.dispatch('circle/comment',param).then(res=>{
console.log("评论失败1",res);
that.closeInputModel();
}).catch(e=>{
console.log("评论失败",e);
});
},
//查看大图或者预览视频
previewImg(current, data) {
let that=this;
let releaseType= data.releaseType;
let fileList=data.fileList;
if(releaseType==2){
that.previewVideoSrc=fileList[0];
that.previewVideoFlag=true;
}else{
uni.previewImage({
current:current,
urls: fileList,
});
return;
}
},
//关闭键盘 关闭输入框
closeInputModel() {
this.showInput = false;
this.content = '';
this.id = '';
this.commentInfo = {};
uni.hideKeyboard();
},
//选择发表朋友圈的方式
toChooseRelease: function(index) {
let that = this;
let tempFilePaths = [];
//拍照
if (index == 1) {
uni.chooseImage({
count: 9, //默认9
sizeType: ['original', 'compressed'], //可以指定是原图还是压缩图,默认二者都有
sourceType: ['camera','album'], //从相册选择
success: function(res) {
tempFilePaths = res.tempFilePaths;
let param = {
releaseType: 1,
tempFilePaths: tempFilePaths
}
that.linkToRelease(param);
return;
}
});
return ;
}
//选择视频
if (index == 2) {
uni.chooseVideo({
sourceType: ['camera', 'album'],
maxDuration: 60,
success: function(res) {
//console.log("视频",res);
let filePath = res.tempFilePath;
tempFilePaths.push(filePath);
let param = {
releaseType: 2,
tempFilePaths: tempFilePaths
}
that.linkToRelease(param);
return;
}
});
return ;
}
},
//点击自定义组件相机按钮
linkToRelease(params) {
console.log(params);
let url = "/pages/find/friend-circle/releaseFriendCircle?";
for(let key in params){
if(key!="tempFilePaths"){
url+=key+"="+params[key]+"&";
}
}
uni.navigateTo({
url:url,
success(res) {
res.eventChannel.emit('successEvent',params);
}
})
},
getVideoPoster(videoSrc){
console.log("video",videoSrc);
return "http://192.168.31.125:9090/we-chat/images/friendCircle/1715421601709.mp4";
//return videoSrc;
},
leftClick(e){
this.goto('/pages/find/index/index',"2");
},
onUserEvent(e){
switch(e.type){
case 'clickThumb':
this.clickThumb(e.item,e.index);
break;
case 'handleComment':
this.handleComment(e.comment,e.index);
break;
case 'deleteCircle':
this.deleteCircle(e.item,e.index);
break;
case 'linkToBusinessCard':
this.linkToBusinessCard(e.userID);
break;
}
},
cdn:util.cdn
},
onReachBottom() {
this.loadMore();
},
onPageScroll({scrollTop}) {
this.scrollTop = scrollTop;
//console.log(scrollTop)
//this.scrolling(scrollTop);
}
};
</script>
<style lang="scss" scoped>
page {
background-color: #ffffff;
}
.comment-hover-class {
background-color: #FFFFFF;
}
image {
will-change: transform;
}
.content {
.scrollView{
::-webkit-scrollbar{
display: none;
width: 0;
height: 0;
}
}
&-imgbox {
position: relative;
&.top{
background: #f4f4f4;
}
.bgimg {
width: 100%;
height: 560rpx;
background-color: #474747;
}
.headimg {
//width: 110rpx;
//height: 110rpx;
border-radius: 6rpx;
position: absolute;
right: 30rpx;
bottom: -20rpx;
}
.nickname {
color: #ffffff;
position: absolute;
right: 170rpx;
bottom: 20rpx;
font-size: 30rpx;
font-weight: bold;
}
}
&-circle {
&-box {
padding: 18rpx 30rpx;
border-bottom: 1rpx solid #f2eeee;
display: flex;
flex-direction: row;
justify-content: flex-start;
align-items: flex-start;
.headimg {
width: 80rpx;
height: 80rpx;
.img {
width: 100%;
height: 100%;
border-radius: 10rpx;
}
}
.content {
flex: 1;
padding-left: 18rpx;
font-size: 32rpx;
&-name {
color: #36648b;
font-weight: bold;
font-size: 32rpx;
}
&-desc {
color: #000000;
padding-top: 4rpx;
//line-height: 36rpx;
font-size: 32rpx;
}
&-img {
margin-top: 10rpx;
.img-1 {
will-change: transform;
width: 280rpx;
height: auto;
max-height: 400rpx;
}
&-more {
display: flex;
flex-wrap: wrap;
.img-more {
display: block;
width: 160rpx;
height: 160rpx;
margin: 4rpx;
}
.img-3 {
margin: 4rpx 4rpx 4rpx 0;
}
}
}
.msg-box {
width: 100%;
background-color: #FFF;
margin-top: 15rpx;
border-radius: 4rpx;
.thumbinfo {
// border-bottom: 1rpx solid gray;
padding: 6rpx;
display: flex;
align-items: center;
flex-wrap: wrap;
&-icon {
width: 28rpx;
height: 28rpx;
line-height: 28rpx;
margin-right: 15rpx;
text-align: center;
vertical-align: middle;
padding-left: 10rpx;
}
&-name {
font-size: 28rpx;
color: #36648b;
}
}
.comment {
padding: 6rpx 8rpx;
color: $uni-text-color;
font-size: 28rpx;
&-box {
padding: 4rpx 0;
&-name {
color: #36648b;
.callback {
color: $uni-text-color;
}
}
&-content {
word-break: break-all;
}
}
}
}
}
.relavivetime {
display: flex;
justify-content: space-between;
align-items: center;
font-size: 26rpx;
.time {
color: $uni-text-color-grey;
}
.icon-box {
display: flex;
align-items: center;
&-item {
//background-color: #F8F8F8;
padding: 4rpx 12rpx;
border-radius: 6rpx;
&.thumb {
margin-right: 10rpx;
}
}
.img {
width: 34rpx;
height: 34rpx;
}
}
}
}
}
.input-box {
position: fixed;
bottom: 0;
left: 0;
width: 100%;
box-sizing: content-box;
z-index: 999;
background-color: #eaeaea;
// margin-bottom: 0rpx;
// margin-bottom: constant(safe-area-inset-bottom);
// margin-bottom: env(safe-area-inset-bottom);
&-flex {
display: flex;
justify-content: flex-start;
align-items: center;
flex-wrap: nowrap;
flex-direction: row;
padding: 0 20rpx;
height: 100rpx;
&-grow {
flex-grow: 1;
.content {
background-color: #fff;
height: 60rpx;
padding: 0 20rpx;
border-radius: 12rpx;
font-size: 28rpx;
caret-color: $uni-color-success;
}
}
.btn {
margin-left: 20rpx;
background-color: $uni-color-success;
border: none;
width: 60px;
}
}
}
.signature {
display: flex;
justify-content: flex-end;
font-size: 24rpx;
color: gray;
padding: 35rpx 30rpx 35rpx 100rpx;
text-align: right;
}
.slot-wrap {
display: flex;
align-items: center;
padding: 0 30rpx;
}
.slot-btn {
width: 200rpx;
height: 200rpx;
display: flex;
justify-content: center;
align-items: center;
background: rgb(244, 245, 246);
border-radius: 10rpx;
border:1rpx solid $u-border-color
}
}
</style>