You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

559 lines
18 KiB

<template>
<cu-custom bgColor="bg-white" :isBack="true">
<template #backText></template>
<template #content>朋友圈</template>
</cu-custom>
<!-- #ifdef APP-PLUS -->
<scroll-view scroll-y @scrolltolower="scrollbot" :lower-threshold="0" refresher-enabled="true" :refresher-triggered="refreshing"
:refresher-threshold="50" @refresherrefresh="onRefresh" style="height: 88vh;">
<!-- #endif -->
<!-- #ifdef H5 -->
<scroll-view scroll-y @scrolltolower="scrollbot" :lower-threshold="0" refresher-enabled="true" :refresher-triggered="refreshing"
:refresher-threshold="50" @refresherrefresh="onRefresh" style="height: 93vh;">
<!-- #endif -->
<!-- -->
<view @click="onicons" :style="{paddingBottom: paddingB+'px'}">
<view class="im-friend-header">
<view class="im-friend-bg">
<image class="im-friend-image" src="/static/image/user-card-bg.jpg" mode="widthFix"></image>
</view>
<view class="im-user im-flex im-justify-content-start align-center">
<text class="text-white mr-5">{{userInfo.realname}}</text>
<image class="radius-10" style="width:120rpx;height:120rpx" :src="userInfo.avatar" mode="widthFix"></image>
</view>
<view style="position: absolute;top: 15px;right: 18px;" @click="tomoments">
<image class="radius-10" style="width:50rpx;height:50rpx" src="/static/image/moments.png" mode="widthFix"></image>
</view>
</view>
<view class="text-center" style="background-color: #fff;padding: 10px;" @click="tonotice" v-if="notice>0">
<view style="width: 100px;height: 30px;background-color: #f0f0f0;line-height: 30px;margin: auto;border-radius: 5px;color: #6b72ff;">{{notice}}条新信息</view>
</view>
<view v-for="(item,index) in list" :key="index">
<view class="cu-card dynamic no-card">
<view class="cu-item shadow">
<view class="cu-list menu-avatar">
<view class="cu-item" style="padding-top: 20px;">
<view class="cu-avatar round lg" :style="[{backgroundImage:'url('+item.user.avatar+')'}]"></view>
<view class="content flex-sub">
<view>{{item.user.nickname}}</view>
<view class="text-gray text-sm flex justify-between">
{{item.create_time}}
</view>
</view>
</view>
</view>
<view class="text-content" style="word-break: break-word;" v-if="contenthtml(item.content)" @click="handleLink(item.content)" v-html="item.content"></view>
<view class="text-content" style="word-break: break-word;" v-html="item.content" v-else></view>
<view class="grid" style="margin: 0px 24rpx;">
<view class="grid" style="margin: 2rpx 0px;padding: 0px 8rpx;" v-for="(itemss,indexs) in item.files" :key="indexs">
<!-- flex-sub -->
<view class="bg-img" v-if="itemss.type==1">
<image :src="apiUrl+itemss.src" mode="aspectFill" style="width: 200rpx;height: 200rpx;" :data-src="apiUrl+itemss.src" @tap="previewImage"></image>
</view>
<view class='course-video' :style="item.files ? $util.imageCoverStyle(270,480) : ''" v-if="itemss.type==2">
<view class="relative-shadow" @tap="handlePlay(itemss)" style="">
<view class="cuIcon-video icon-center f-28 c-white"></view>
</view>
<im-image style="position: absolute;top: 0px;" :src="apiUrl+itemss.privacy" ></im-image>
<!-- :info="item.files" -->
</view>
</view>
</view>
<view v-if="item.location_address" @tap="openLocation(item.location)" class="im-location-msg im-flex im-rows im-nowrap im-align-items-center radius-8 pd-10">
<view class="f-20 cuIcon-location pr-5"></view>
<view>
<view class="f-10 mb-5">{{item.location_address}}</view>
<!-- <view class="c-999 f-12">{{item.extends && item.extends.address}}</view> -->
</view>
</view>
<view style="display: flex;align-items: center;justify-content: space-between;">
<view class="text-gray text-sm padding" style="color: #383bff;" v-if="item.user_id==userInfo.user_id">{{item.privacy_describe == '公开'?'':item.privacy_describe}}</view>
<view v-else></view>
<view class="text-gray text-sm text-right padding">
<!-- <text class="cuIcon-attentionfill margin-lr-xs"></text> 10 -->
<!-- +item.is_like -->
<text @click="onLike(item.id)" :class="['cuIcon-appreciatefill', item.is_like === 1 ? 'text-red' : 'margin-lr-xs']"></text> {{item.likes.length}}
<text @click="onComment(index)" class="cuIcon-messagefill margin-lr-xs"></text> {{item.comment.length}}
<text v-if="item.user_id==userInfo.user_id" class="cuIcon-delete" style="margin-left: 5px;" @click="Delete(item.id)">删除</text>
</view>
</view>
<view v-show="numindex === index&&boll" style="margin: 5px 15px 5px 15px;position: relative;box-shadow:0px 0px 5px rgba(0, 0, 0, 0.2);">
<view style="padding-bottom: 45px;">
<!-- <uni-easyinput id="input" type="textarea" autoHeight v-model="content" placeholder="评论"></uni-easyinput> -->
<!-- id="editor1" -->
<editor :id="'editor' + index" class=" bg-white c-333" style="min-height: 50px;height: 50px;padding:0px 10px;" :adjust-position="false"
maxlength="200" cursor-spacing="10" @input="changeMsgText" @ready="onEditorReady(index)" :read-only="readOnly"> </editor>
<!-- @focus="InputFocus" @blur="InputBlur" -->
</view>
<view style="position: absolute;bottom: 5px;right: 10px;">
<view style="display: flex;justify-content: space-between;">
<view>
<view class="im-menus cuIcon-emoji f-28 ml-5 mr-10" hover-class="tap" @click.stop="showAppBox"></view>
<scroll-view scroll-y class="icon" v-if="isFocus">
<view class="im-flex im-wrap im-justify-content-start im-align-items-center pd-10">
<view v-for="(item,index) in currentEmojiList" class="im-emoji-item" :key="index">
<image :src="item.src" style="width:44rpx;height:44rpx;" mode="aspectFit" lazy-load @tap="chooseEmoji(item)"></image>
</view>
</view>
</scroll-view>
</view>
<button class="cu-btn bg-green shadow " @touchend.prevent="sendTextMsg(item.id)">发送</button>
</view>
</view>
</view>
<view class="flex Likeview" v-if="item.likes.length!=0">
<view v-for="(itemws,indexws) in item.likes" :key="indexws" class="flex align-center" style="margin-right: 5px;">
<uni-icons type="heart" size="15" color="#576b95"></uni-icons>
<view style="margin-left: 2px;">{{itemws.nickname}}</view>
</view>
</view>
<view style="margin-bottom: 10px;">
<view class="cu-list menu-avatar comment" style="margin-top: 0px;" v-for="(iteme,indexw) in item.comment" :key="indexw">
<view class="comment_view">
<view class="content">
<view class="flex align-center" style="gap: 12rpx;" @click.stop="onComment(index,iteme.id)">
<view>
<view class="flex" v-if="iteme.reply_user_name!==''">
<view>{{iteme.nickname}} <text style="color: #000;margin-right: 5px;">回复</text></view>
<view class="flex-sub"> {{iteme.reply_user_name}}</view>
</view>
<view v-else>{{iteme.nickname}}</view>
</view>
<view class="text-gray text-content text-df" style="flex: 1; min-width: 0; word-break: break-word;">
<view class="text-content content_img" style="color: #000;" v-if="contenthtml(iteme.content)" @click.stop="handleLink(iteme.content,index,iteme.id)" v-html="iteme.content"></view>
<view class="text-content" style="color: #000;" v-html="iteme.content" v-else></view>
<!-- <mp-html container-style="overflow: hidden;display:inline;white-space: pre-wrap;color: #000;" :content="emojiToHtml(iteme.content)"/> -->
</view>
</view>
</view>
</view>
</view>
</view>
</view>
</view>
</view>
<view v-if="list.length==0" style="display: flex;justify-content: center;align-items: center;margin-top: 40px;">
<view>
<image src="@/static/image/empty.png" mode="widthFix" style="width: 560rpx;"></image>
<view style="text-align: center;color: #ccc;font-size: 40rpx;margin-right: 10px;">暂无数据</view>
</view>
</view>
</view>
<uni-load-more :status="status" :content-text="contentText"></uni-load-more>
</scroll-view>
</template>
<script>
import { useloginStore } from '@/store/login'
import config from '@/common/config.js'
import emoji from '@/utils/emoji.js'
import Edit from '@/utils/edit.js'
import { chat } from '@/mixins/chat.js'
import imImage from '@/components/message/im-image.vue';
import pinia from '@/store/index'
import { storeToRefs } from 'pinia';
import { useMsgStore } from '@/store/message';
const msgStore = useMsgStore(pinia)
const {NoticeCount} = storeToRefs(msgStore);
const loginStore = useloginStore()
export default {
components:{
imImage
},
mixins:[chat],
data() {
return {
notice:NoticeCount,
isCard: true,
apiUrl: config.apiUrl,
userInfo:loginStore.userInfo,
paddingB:0,
page:1,
limit:20,
content:'',
numindex:-1,
boll:false,
list:[],
// editorCtx:null,
editorCtx:{},
currentEmojiList:[],
emojiMap:[],
isFocus:false,
edit: null,
readOnly:false,
refreshing: false,
status: 'more',//状态
inputMsg:'',
bool: 0,
//显示的状态
contentText: {
contentdown: '查看更多',
contentrefresh: '加载中....',
contentnomore: '没有更多咯'
},
};
},
created(){
// #ifdef H5
this.paddingB=this.inlineTools;
// #endif
// #ifndef H5
this.paddingB=this.navBarHeight+this.inlineTools;
// #endif
this.currentEmojiList=emoji[0]['children'];
let emojiMap=[];
// 解析所有表情
emoji.forEach(function (item) {
let child=item.children;
if(child.length>0){
child.forEach(function (val) {
let name=val.name;
let src=val.src;
emojiMap[name]=src;
})
}
});
this.emojiMap=emojiMap;
this.page = 1;
this.wechatMomentsList();
},
onShow() {
if(this.bool==1){
this.page = 1;
this.wechatMomentsList();
}
},
methods: {
onRefresh() {
this.page = 1
this.wechatMomentsList()
if (this.refreshing) return;
this.refreshing = true;
setTimeout(() => {
this.refreshing = false;
}, 1000)
},
contenthtml(val){
return val && (val.includes('http://') || val.includes('https://'));
},
handleLink(url,index,id){
const textOnly = url.replace(/<[^>]+>/g, '');
const urlRegex = /https?:\/\/[^\s"']+/g;
const urls = textOnly.match(urlRegex) || [];
// console.log(urls);
if(urls.length > 0){
urls.forEach((res,index)=>{
// #ifdef H5
window.open(urls[index], '_blank');
// #endif
// #ifdef APP-PLUS
plus.runtime.openURL(urls[index]);
// #endif
})
}else{
this.onComment(index,id)
return
}
},
IsCard(e) {
this.isCard = e.detail.value
},
wechatMomentsList(){
let params = {page:this.page,limit:this.limit}
this.status = 'loading'; // 加载中
this.$api.compaApi.wechatMomentsList(params).then(res => {
res.data.forEach((res)=>{
const [latitudeStr, longitudeStr] = res.location.split('+');
const location = {
latitude: +latitudeStr,
longitude: +longitudeStr
};
res.location = location
res.content = res.content.replace(/\n/g, '<br>')
})
this.bool = 0
if (this.page === 1) {
this.list = res.data
} else {
this.list = this.list.concat(res.data);
}
// 判断是否还有更多数据
if (this.list.length < res.count) {
this.status = 'more'; // 还有更多数据
} else {
this.status = 'noMore'; // 没有更多数据
}
// console.log(res);
})
},
scrollbot(){
if (this.status == 'noMore') {
return;
}
this.page++
this.wechatMomentsList()
// console.log('已触发底部事件');
},
tomoments(){
this.bool = 1;
uni.navigateTo({
url:'/pages/compass/sendtoMoments'
})
},
tonotice(){
this.bool = 1;
uni.navigateTo({
url:'/pages/compass/Informationdetails'
})
},
onLike(id){
this.$api.compaApi.onlikes({posts_id:id}).then(res => {
this.wechatMomentsList()
// this.list = res.data
// console.log(res);
})
},
onComment(index,id){
// 如果点击的是同一个项,关闭编辑
if (this.numindex === index) {
this.boll = false
uni.removeStorageSync('pid')
this.numindex = -1
return
}
this.numindex = index
this.boll = !this.boll
if(id&&this.boll == true){
uni.setStorageSync('pid',id)
}
},
showAppBox(){
this.isFocus = !this.isFocus;
},
onicons(){
this.isFocus = false;
},
// 选择表情
chooseEmoji(item){
// #ifdef H5
this.editorCtx[this.numindex].insertImage({
src: item.src,
alt: item.title,
width: 18,
height: 18,
nowrap:true,
extClass:'emoji-image',
success: ()=>{
},
complete: ()=> {
this.editorCtx[this.numindex].blur();
},
});
// console.log(this.editorCtx[this.numindex]);
// #endif
// #ifndef H5
this.readOnly= true
setTimeout(()=>{
this.editorCtx[this.numindex].insertImage({
src: item.src,
alt: item.title,
width: 18,
height: 18,
nowrap:true,
extClass:'emoji-image',
success: function() {
},
complete: ()=> {
this.readOnly= false
},
});
},10);
// #endif
},
onEditorReady(index) {
const editorId = 'editor' + index;
// #ifdef MP-BAIDU
// this.editorCtx = requireDynamicLib('editorLib').createEditorContext('editor1');
this.editorCtx[index] = requireDynamicLib('editorLib').createEditorContext(editorId);
// #endif
// #ifdef APP-PLUS || MP-WEIXIN || H5
const query = uni.createSelectorQuery().in(this);
// query.select('#editor1').context((res) => {
query.select('#editor' + index).context((res) => {
this.edit = new Edit({context: res.context,maxCount: 300});
this.editorCtx[index] = res.context
}).exec()
// #endif
},
changeMsgText(e){
const txt=e.detail.text.replace(/\n/g, '');
if(txt=='' && e.detail.html=='<p><br></p>'){
this.inputMsg='';
}else{
this.inputMsg=e.detail.html;
}
},
// 自动解析消息中的表情
emojiToHtml(str){
if(!str){
return;
}
let emojiMap=this.emojiMap;
return str.replace(/\[!(\w+)\]/gi, function (str, match) {
var file = match;
return emojiMap[file] ? "<img class='mr-5' style=\"width:18px;height:18px\" emoji-name=\"".concat(match, "\" src=\"").concat(emojiMap[file], "\" />") : "[!".concat(match, "]");
});
},
previewImage(e) {
//预览图片
var current = e.target.dataset.src
uni.previewImage({
current: current,
urls: [current]
})
},
Delete(id){
const _this = this
uni.showModal({
title: "提示",
content: "是否要删除该内容",
success: (res) => {
if (res.confirm) {
_this.$api.compaApi.Deleteapost({posts_id:id}).then(res => {
_this.wechatMomentsList()
})
}else if (res.cancel) {
console.log('用户点击取消');
}
}
})
},
sendTextMsg(id1){
const _this = this
const pid = uni.getStorageSync('pid')
const currentIndex = this.numindex
this.editorCtx[currentIndex].getContents({
success:(e)=>{
let msg=e.html;
// console.log('消息发送',e);
let params = {posts_id:id1,content:msg,pid:pid?pid:""}
const text = /^\s*$/.test(params.content.replace(/<[^>]+>/g, ""));
const hasImg = /<img\b/i.test(params.content);
if(params.content==''|| (text && !hasImg)){
uni.showToast({title: '内容不能为空!',icon:'error'});
return
}
_this.$api.compaApi.oncomments(params).then(res => {
uni.removeStorageSync('pid')
_this.wechatMomentsList()
_this.inputMsg = ""
_this.boll = false;
_this.editorCtx[currentIndex].clear();
// _this.list = res.data
// console.log(_this.editorCtx.clear());
})
}
})
},
}
}
</script>
<style scoped lang="scss">
.im-friend-header{
width:100%;height:400rpx;position: relative;
.im-friend-bg{
width:100%;height:400rpx;overflow: hidden;
.im-friend-image{
width:100%;height:400rpx;
}
}
}
.im-user{
position: absolute;
right:60rpx;
top:210rpx;
overflow: hidden;
}
.icon{
top: -440rpx;
left: -170rpx;
width: 400rpx;
height: 400rpx;
position: absolute;
border-radius: 10rpx;
background-color: #fff;
box-shadow:0px 0px 5px rgba(0, 0, 0, 0.2);
.im-emoji-item{
padding:22rpx;
}
}
.im-input{
height:100%;
font-size: 28rpx;
min-height:150rpx;
max-height: 300rpx;
padding:14rpx 14rpx;
border-radius:10rpx;
word-break: break-all;
margin:0 8rpx !important;
}
.im-location-msg{
color:#2B2E3D;
margin: 5px 10px;
text-align: left !important;
}
.relative-shadow{
z-index:1;
width:100%;
height:100%;
height: 240px;
display: flex;
position: absolute;
align-items: center;
justify-content: center;
}
.Likeview{
padding: 5px;
display: flex;
color: #576b95;
align-items: center;
background-color: #f7f7f7;
margin: 0rem 0.9375rem 0rem 2rem;
}
.course-video{
overflow: hidden;
position: relative;
}
.comment_view{
height: auto;
color: #576b95;
padding: 20rpx 30rpx;
background-color: #f7f7f7;
margin: 0rem 0.9375rem 0rem 2rem;
}
::v-deep .ql-editor{
padding-top: 10px;
}
::v-deep .content_img img{
width: 18px;
margin-right: 5px;
}
</style>