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.
 
 
 
 
 
 

419 lines
13 KiB

<template>
<cu-custom bgColor="bg-white" :isBack="true">
<template #backText></template>
<template #content>详情</template>
</cu-custom>
<scroll-view scroll-y style="height: 92vh;background-color: #fff;">
<view class="cu-card dynamic no-card">
<view class="cu-item shadow">
<view class="cu-list menu-avatar">
<view class="cu-item" style="margin-top: 20px;height: 160rpx;" v-if="list.user">
<view class="cu-avatar round lg" :style="[{backgroundImage:'url('+list.user.avatar+')'}]"></view>
<view class="content flex-sub" style="word-break: break-word;white-space: pre-wrap;line-break: anywhere;">
<view>{{list.user.nickname}}</view>
<view class="text-gray text-sm flex justify-between">
{{list.create_time}}
</view>
</view>
</view>
</view>
<view class="text-content" v-if="list.content">
<!-- <mp-html container-style="overflow: hidden;display:inline;white-space: pre-wrap" :content="emojiToHtml(list.content)"/> -->
<view class="text-content" style="word-break: break-word;white-space: pre-wrap;line-break: anywhere;" v-if="contenthtml(list.content)" @click="handleLink(list.content)" v-html="list.content"></view>
<view class="text-content" style="word-break: break-word;white-space: pre-wrap;line-break: anywhere;" v-html="list.content.replace(/\n/g, '<br>')" v-else></view>
</view>
<view class="grid" style="margin: 0px 24rpx;">
<view class="grid" style="margin: 2rpx 0px;padding: 0px 8rpx;" v-for="(itemss,indexs) in list.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="list.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: 0%;" :src="apiUrl+itemss.privacy" ></im-image>
</view>
</view>
</view>
<view v-if="list.address" @tap="openLocation(list.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">{{list.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="list.user_id==userInfo.user_id">{{list.privacy == 2?'部分可见':list.privacy == 3?'私密':list.privacy == 4?'不给谁看':''}}</view>
<view v-else></view>
<view class="text-gray text-sm text-right padding">
<text @click="onLike(list.id)" :class="['cuIcon-appreciatefill', list.is_like === 1 ? 'text-red' : 'margin-lr-xs']"></text> {{list.likes?list.likes.length:0}}
<text @click="onComment(null)" class="cuIcon-messagefill margin-lr-xs"></text> {{list.comment?list.comment.length:0}}
<text v-if="list.user_id==userInfo.user_id" class="cuIcon-delete" style="margin-left: 5px;" @click="Delete(list.id)">删除</text>
</view>
</view>
<view v-show="boll" style="margin: 5px 15px;position: relative;box-shadow:0px 0px 5px rgba(0, 0, 0, 0.2);">
<view style="padding-bottom: 45px;">
<editor id="editor" class="bg-white c-333" style="min-height: 50px;height: 50px;padding:0px 10px ;" :adjust-position="false" maxlength="300" cursor-spacing="10"
@input="changeMsgText" @ready="onEditorReady" :read-only="readOnly"> </editor>
</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 " @click="sendTextMsg(list.id)">发送</button>
</view>
</view>
</view>
<view class="flex Likeview" style="flex-wrap: wrap;" v-if="list.likes?.length!==0">
<uni-icons type="heart" size="15" color="#576b95"></uni-icons>
<view v-for="(itemws,indexws) in list.likes" :key="indexws" class="flex align-center" style="margin: 5px;">
<!-- <view style="margin-left: 2px;">{{itemws.nickname}}</view> -->
<image :src="itemws.avatar" mode="widthFix" style="width: 60rpx;margin-left: 2px;"></image>
</view>
</view>
<view style="margin-bottom: 10px;" v-if="list.comment?.length!==0">
<view class="cu-list menu-avatar comment" style="margin-top: 0px;" v-for="(iteme,indexw) in list.comment" :key="indexw">
<view class="comment_view">
<view class="content">
<view class="flex align-center" style="gap: 12rpx;" @click.stop="onComment(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;">
<!-- <mp-html container-style="overflow: hidden;display:inline;white-space: pre-wrap;color: #000;" :content="emojiToHtml(iteme.content)"/> -->
<view class="text-content content_img" style="color: #000;" v-if="contenthtml(iteme.content)" @click="handleLink(iteme.content)" v-html="iteme.content"></view>
<view class="text-content" style="color: #000;" v-html="iteme.content" v-else></view>
</view>
</view>
</view>
</view>
</view>
</view>
</view>
</view>
</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';
const loginStore = useloginStore()
export default {
components:{
imImage
},
mixins:[chat],
data() {
return {
list: {},
boll:false,
edit: null,
userid:'',
inputMsg:'',
posts_id:0,
emojiMap:[],
isFocus:false,
readOnly:false,
currentEmojiList:[],
apiUrl: config.apiUrl,
userInfo:loginStore.userInfo,
}
},
created(){
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;
},
onLoad(option) {
this.posts_id = option.posts_id
if(this.userInfo.user_id==option.userid){
this.userid = ""
}else{
this.userid = option.userid
}
},
onShow() {
if(this.userid){
this.init(this.userid)
}else{
this.init()
}
},
methods: {
showAppBox(){
this.isFocus = !this.isFocus;
},
// 选择表情
chooseEmoji(item){
// #ifdef H5
this.editorCtx.insertImage({
src: item.src,
alt: item.title,
width: 18,
height: 18,
nowrap:true,
extClass:'emoji-image',
success: ()=>{
},
complete: ()=> {
this.editorCtx.blur();
},
});
// #endif
// #ifndef H5
this.readOnly= true
setTimeout(()=>{
this.editorCtx.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() {
// #ifdef MP-BAIDU
this.editorCtx = requireDynamicLib('editorLib').createEditorContext('editor');
// #endif
// #ifdef APP-PLUS || MP-WEIXIN || H5
const query = uni.createSelectorQuery().in(this);
query.select('#editor').context((res) => {
this.edit = new Edit({context: res.context,maxCount: 300});
this.editorCtx = res.context
}).exec()
// #endif
},
previewImage(e) {
//预览图片
var current = e.target.dataset.src
uni.previewImage({
current: current,
urls: [current]
})
},
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;
}
},
onLike(id){
this.$api.compaApi.onlikes({posts_id:id}).then(res => {
if(this.userid){
this.init(this.userid)
}else{
this.init()
}
// this.list = res.data
// console.log(res);
})
},
onComment(id){
this.boll = !this.boll
if(id){
uni.setStorageSync('pid',id)
}else{
uni.removeStorageSync('pid')
}
},
Delete(id){
const _this = this
uni.showModal({
title: "提示",
content: "是否要删除该内容",
success: (res) => {
if (res.confirm) {
_this.$api.compaApi.Deleteapost({posts_id:id}).then(res => {
// if(_this.userid){
// _this.init(_this.userid)
// }else{
// _this.init()
// }
uni.navigateBack({
delta:1
})
})
}else if (res.cancel) {
console.log('用户点击取消');
}
}
})
},
contenthtml(val){
return val && (val.includes('http://') || val.includes('https://'));
},
handleLink(url){
const textOnly = url.replace(/<[^>]+>/g, '');
const urlRegex = /https?:\/\/[^\s"']+/g;
const urls = textOnly.match(urlRegex) || [];
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{
return
}
},
init(id){
this.$api.compaApi.detailsList({posts_id:+this.posts_id,friend_user_id:id?+id:''}).then(res => {
const [latitudeStr, longitudeStr] = res.data.location?.split('+');
const location = {
latitude: +latitudeStr?+latitudeStr:0,
longitude: +longitudeStr?+longitudeStr:0
};
res.data.location = location
this.list = res.data
})
},
sendTextMsg(id1){
const _this = this
const pid = uni.getStorageSync('pid')
this.editorCtx.getContents({
success:(e)=>{
let msg=e.html;
const text = /^\s*$/.test(msg.replace(/<[^>]+>/g, ""));
const hasImg = /<img\b/i.test(msg);
if(msg==''||(text && !hasImg)){
uni.showToast({ title: "内容不能为空", icon: "none" });
msg=''
_this.editorCtx.clear();
return
}
let params = {posts_id:id1,content:msg,pid:pid?pid:""}
// console.log(params);
_this.$api.compaApi.oncomments(params).then(res => {
uni.removeStorageSync('pid')
if(_this.userid){
_this.init(_this.userid)
}else{
_this.init()
}
_this.editorCtx.clear();
this.boll = false;
// _this.list = res.data
// console.log(res);
})
}
})
},
}
}
</script>
<style scoped lang="scss">
.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;
}
.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;
}
}
::v-deep .ql-editor{
padding-top: 10px;
}
::v-deep .content_img img{
width: 18px;
margin-right: 5px;
}
</style>