2025-02-20 17:38:47 +08:00

1016 lines
30 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="main">
<!-- :style="{
overflow: isShow ? 'hidden' : 'auto',
height: isShow ? '100vh' : '100%',
}" -->
<view class="contentBox">
<view class="contentTitle">{{ detailObj.POST_TITLE || "" }}</view>
<view class="itemTop">
<view class="topLeft">
<view class="profileBox">
<image
class="profile"
src="/static/images/home/defaultProfit.svg"
/>
</view>
<view class="otherBox">
<view class="userName">{{ detailObj.AUTHOR_NAME || "-" }}</view>
<view class="timeBox">{{ detailObj.PUBLISH_TIME || "-" }}</view>
</view>
</view>
</view>
<view class="detailContent">
{{ detailObj.POST_CONTENT || "" }}
</view>
<view
class="imageList"
v-if="detailObj.ImageList && detailObj.ImageList.length > 0"
>
<view
class="imageItem"
v-for="(item, index) in detailObj.ImageList"
:key="index"
@click="handlePreviewImage(index)"
>
<image class="imageBox" :src="item.ImageUrl" />
</view>
</view>
</view>
<!-- 评论 -->
<view
class="commentBox"
:style="{ paddingBottom: `${68 + safeArea + 8}px` }"
>
<view class="commentTitle"
>评论{{
commentList && commentList.length > 0 ? `(${commentList.length})` : ""
}}</view
>
<scroll-view class="commentScroll" scroll-y>
<view class="commentList" v-if="commentList && commentList.length > 0">
<view
class="commentDetail"
v-for="(item, index) in commentList"
:key="index"
>
<view class="detailLeft">
<image
class="profile"
src="/static/images/home/defaultProfit.svg"
/>
</view>
<view class="detailRight">
<view class="titleBox">{{ item.NICK_NAME || "" }}</view>
<view class="contentText" @click="handleReplyComment(item)">
{{
item.isShowSmall === 1
? item.smallText
: item.POSTDETAIL_CONTENT || ""
}}
<!-- {{ item.POSTDETAIL_CONTENT || "-" }} -->
<span
v-if="item.isShowSmall > 0"
class="expend"
@click.stop="handleChangeIsShowSmall(item)"
>{{
item.isShowSmall === 1
? "展开"
: item.isShowSmall === 2
? "收起"
: ""
}}</span
>
</view>
<view class="bottom">
<view class="bottomLeft">
<text class="timeText">{{ item.OPERATE_DATE || "-" }}</text>
<text class="reply" @click="handleReplyComment(item)"
>回复</text
>
</view>
<view class="bottomRight" @click.stop="handleThumbsUp(item)">
<image
class="commentIcon"
:src="
item.isthumbsUp
? '/static/images/home/thumbsUp.svg'
: '/static/images/home/nothumbsUp.svg'
"
/>
<span
class="thumbsUp"
:style="{ color: item.isthumbsUp ? '#BA922F' : '#716F69' }"
>{{ item.POST_LIKECOUNT || 0 }}</span
>
</view>
</view>
<view
class="childrenList"
v-if="item.children && item.children.length > 0"
>
<view
class="childrenItem"
v-for="(subItem, subIndex) in item.children"
:key="subIndex"
>
<view class="childrenLeft">
<image
class="profile"
src="/static/images/home/defaultProfit.svg"
/>
</view>
<view class="childrenRight">
<view class="childrenTitle">{{
subItem.POSTDETAIL_DESC
? `${subItem.NICK_NAME || ""} 回复 ${
subItem.POSTDETAIL_DESC || ""
}`
: `${subItem.NICK_NAME || ""}`
}}</view>
<view
class="childrenContentText"
@click="handleReplyComment(subItem)"
>
{{
subItem.isShowSmall === 1
? subItem.smallText
: subItem.POSTDETAIL_CONTENT || ""
}}
<!-- {{ item.POSTDETAIL_CONTENT || "-" }} -->
<span
v-if="subItem.isShowSmall > 0"
class="expend"
@click.stop="handleChangeIsShowSmall(subItem)"
>{{
subItem.isShowSmall === 1
? "展开"
: subItem.isShowSmall === 2
? "收起"
: ""
}}</span
>
</view>
<view class="childrenBottom">
<view class="childrenBottomLeft">
<text class="timeText">{{
subItem.OPERATE_DATE || "-"
}}</text>
<text class="reply" @click="handleReplyComment(subItem)"
>回复</text
>
</view>
<view
class="childrenBottomRight"
@click.stop="handleThumbsUp(subItem)"
>
<image
class="commentIcon"
:src="
subItem.isthumbsUp
? '/static/images/home/thumbsUp.svg'
: '/static/images/home/nothumbsUp.svg'
"
/>
<span
class="thumbsUp"
:style="{
color: subItem.isthumbsUp ? '#BA922F' : '#716F69',
}"
>{{ subItem.POST_LIKECOUNT || 0 }}</span
>
</view>
</view>
</view>
</view>
</view>
</view>
</view>
</view>
<view class="noComment" v-else>
<image
class="noCommentIcon"
src="/static/images/home/noComment.svg"
/>
<text class="noDataText">还没有评论发表第一个评论吧</text>
</view>
</scroll-view>
</view>
<view
class="postCommentBox"
:style="{
paddingBottom: `${10 + safeArea}px`,
height: `${68 + safeArea}px`,
}"
>
<view class="userProfile">
<image class="profile" src="/static/images/home/defaultProfit.svg" />
</view>
<view class="userInput" @click="handleShowInputPopup">
写下你的评论...
<!-- <input
style="width: 100%"
placeholder="写下你的评论..."
confirm-type="send"
v-model="commentText"
:maxlength="999"
/> -->
</view>
<!-- <view class="userSubmit" @click="handlePushComment">发送</view> -->
</view>
<uni-popup
ref="popup"
:show="isShow"
:safe-area="false"
@close="handleClosePopup"
@maskClick="handleClosePopup"
>
<view class="inputPopup">
<view class="inputBox">
<textarea
class="titleBox"
:placeholder="placeholder"
placeholder-style="font-size: 24rpx;line-height: 36rpx"
:value="commentText"
@input="handleGetTitle"
:maxlength="999"
:fixed="true"
/>
</view>
<view class="submitBox">
<view class="submitBtn" @click="handlePushComment">发送</view>
</view>
</view>
</uni-popup>
</view>
</template>
<script>
import { mapGetters } from "vuex";
export default {
data() {
return {
currentID: "", // 当前的id
detailObj: {},
commentList: [], // 评论数组
commentText: "", // 评论的内容
safeArea: 0,
isShow: false, // 显示悬浮框
placeholder: "写下你的评论...",
isReply: false, // 判断是否是回复
currentReplayObj: {}, // 当前回复的对象
thumbedUpList: [], // 当前的点赞列表
thumbedUpDetailList: [], // 当前点赞的详情列表
};
},
computed: {
...mapGetters({
user: "user",
}),
},
onLoad(query) {
let systemInfo = uni.getSystemInfoSync();
console.log("systemInfo", systemInfo);
this.safeArea = systemInfo.safeAreaInsets.bottom;
console.log("query", query);
this.handleGetPostDetail(query.id);
},
methods: {
// 预览图片
handlePreviewImage(index) {
let imgList = [];
if (this.detailObj.ImageList && this.detailObj.ImageList.length > 0) {
this.detailObj.ImageList.forEach((item) => {
imgList.push(item.ImageUrl);
});
}
uni.previewImage({
current: imgList[index], // 当前显示图片的http链接
urls: imgList, // 需要预览的图片http链接列表
});
},
// 当前帖子的点赞列表
async handleGetThumbedUp() {
const req = {
SearchParameter: {
POST_ID: this.detailObj.POST_ID,
// POSTDETAIL_IDS: this.detailObj.POST_ID,
MEMBERSHIP_ID: this.user.MEMBERSHIP_ID,
POSTDETAIL_TYPE: 2000, // 用户行为
POSTDETAIL_STATE: 1,
},
PageIndex: 1,
PageSize: 99999,
};
const data = await this.$api.$post("/Member/GetPOSTDETAILList", req);
let list = data.Result_Data.List;
console.log("handleGetThumbedUp", list);
let POSTDETAIL_IDList = [];
if (list && list.length > 0) {
list.forEach((item) => {
POSTDETAIL_IDList.push(item.POSTDETAIL_PID);
});
}
this.thumbedUpList = POSTDETAIL_IDList;
console.log("this.thumbedUpList", this.thumbedUpList);
this.thumbedUpDetailList = list;
},
// 给评论点赞
async handleThumbsUp(obj) {
console.log("obj", obj);
console.log("user", this.user);
console.log("this.thumbedUpList", this.thumbedUpList);
if (
this.thumbedUpList.indexOf(obj.POSTDETAIL_ID) === -1 ||
!(this.thumbedUpList && this.thumbedUpList.length > 0)
) {
const req = {
POST_ID: this.detailObj.POST_ID, // 帖子id
// POSTDETAIL_ID: obj.POSTDETAIL_ID,
POSTDETAIL_PID: obj.POSTDETAIL_ID, // 点赞的时候为-1
MEMBERSHIP_ID: this.user.MEMBERSHIP_ID, // 会员内码
POSTDETAIL_TYPE: 2000, // 用户行为
NICK_NAME: this.user.MEMBERSHIP_NAME, // 用户昵称
POSTDETAIL_STATE: 1, // 状态
};
const data = await this.$api.$post("/Member/SynchroPOSTDETAIL", req);
console.log("data", data);
if (data.Result_Code === 100) {
await this.handleGetThumbedUp();
this.handleGetCommentList();
} else {
uni.showToast({
title: data.Result_Desc,
icon: "none",
});
}
} else {
// 点过赞 取消赞
let currentObj =
this.thumbedUpDetailList[
this.thumbedUpList.indexOf(obj.POSTDETAIL_ID)
];
console.log("currentObj", currentObj);
const req = {
...currentObj,
POSTDETAIL_STATE: 0, // 状态
};
const data = await this.$api.$post("/Member/SynchroPOSTDETAIL", req);
console.log("datadasdasd", data);
if (data.Result_Code === 100) {
await this.handleGetThumbedUp();
this.handleGetCommentList();
} else {
uni.showToast({
title: data.Result_Desc,
icon: "none",
});
}
}
},
// 回复评论
handleReplyComment(obj) {
this.isReply = true;
this.currentReplayObj = obj;
this.handleShowInputPopup();
console.log("obj", obj);
this.placeholder = `回复@${obj.NICK_NAME}`;
},
// 拿到评论的值
handleGetTitle(e) {
this.commentText = e.detail.value;
},
// 关闭悬浮框
handleClosePopup() {
this.isReply = false;
this.isShow = false;
this.placeholder = "";
this.currentReplayObj = {};
this.$refs.popup.close();
console.log("this.isShow", this.isShow);
},
// 显示输入框的底部悬浮框
handleShowInputPopup() {
if (!this.user.MEMBERSHIP_ID) {
let _this = this;
uni.showModal({
title: "温馨提示",
content: "请您授权登录后再操作。",
success(res) {
if (res.confirm) {
if (_this.loginType === "min") {
uni.navigateTo({ url: "/pages/register/index" });
} else {
uni.navigateTo({ url: "/pages/login/index" });
}
}
},
});
return;
}
this.isShow = true;
this.$refs.popup.open("bottom");
},
// 展开
handleChangeIsShowSmall(obj) {
this.commentList.forEach((item) => {
if (obj.POSTDETAIL_ID === item.POSTDETAIL_ID && obj.isShowSmall > 0) {
if (obj.isShowSmall === 1) {
item.isShowSmall = 2;
} else {
item.isShowSmall = 1;
}
}
if (item.children && item.children.length > 0) {
item.children.forEach((subItem) => {
if (
obj.POSTDETAIL_ID === subItem.POSTDETAIL_ID &&
obj.isShowSmall > 0
) {
if (obj.isShowSmall === 1) {
subItem.isShowSmall = 2;
} else {
subItem.isShowSmall = 1;
}
}
});
}
});
},
// 评论列表
async handleGetCommentList(id, pid) {
const req = {
// SearchParameter: {
POST_ID: id || this.detailObj.POST_ID,
POSTDETAIL_PID: pid || -1, // 用户行为
// POSTDETAIL_STATE: 1,
// },
// PageIndex: 1,
// PageSize: 99999,
};
const data = await this.$api.$get(
"/Member/GetNestingPOSTDETAILList",
req
);
let list = this.$utils.wrapTreeNode(data.Result_Data.List);
console.log("handleGetCommentList", list);
if (list && list.length > 0) {
list.reverse();
list.forEach((item) => {
if (item.POSTDETAIL_CONTENT.length > 100) {
item.isShowSmall = 1;
item.smallText = item.POSTDETAIL_CONTENT.slice(0, 100);
} else {
item.isShowSmall = 0;
}
if (this.thumbedUpList.indexOf(item.POSTDETAIL_ID) >= 0) {
item.isthumbsUp = true;
} else {
item.isthumbsUp = false;
}
if (item.children && item.children.length > 0) {
item.children = this.handleGetAllChildren(item.children);
item.children.forEach((subItem) => {
if (subItem.POSTDETAIL_CONTENT.length > 100) {
subItem.isShowSmall = 1;
subItem.smallText = subItem.POSTDETAIL_CONTENT.slice(0, 100);
} else {
subItem.isShowSmall = 0;
}
if (this.thumbedUpList.indexOf(subItem.POSTDETAIL_ID) >= 0) {
subItem.isthumbsUp = true;
} else {
subItem.isthumbsUp = false;
}
});
}
});
}
console.log("list", list);
this.commentList = list;
},
// 循环递归 把全部子级都拿出来
handleGetAllChildren(list) {
let res = [];
if (list && list.length > 0) {
list.forEach((item) => {
res.push(item); // 将当前项加入到结果数组
if (item.children && item.children.length > 0) {
let childrenList = this.handleGetAllChildren(item.children);
res.push(...childrenList); // 使用展开运算符将子节点展开并加入到结果数组
}
});
}
return res;
},
// 发布评论
async handlePushComment() {
console.log("this.commentText", this.commentText);
if (!this.commentText) {
return;
}
let str = JSON.parse(JSON.stringify(this.commentText));
console.log("handlePushComment", str);
this.commentText = "";
let req = {};
if (this.isReply) {
// 回复
req = {
POST_ID: this.detailObj.POST_ID, // 帖子id
POSTDETAIL_PID: this.currentReplayObj.POSTDETAIL_ID,
MEMBERSHIP_ID: this.user.MEMBERSHIP_ID, // 会员内码
POSTDETAIL_TYPE: 3000, // 用户行为
NICK_NAME: this.user.MEMBERSHIP_NAME, // 用户昵称
POSTDETAIL_STATE: 1, // 状态
POSTDETAIL_CONTENT: str,
OPERATE_DATE: new this.$moment().format("YYYY-MM-DD HH:mm:ss"),
POSTDETAIL_DESC:
this.currentReplayObj.POSTDETAIL_PID !== -1
? this.currentReplayObj.NICK_NAME
: "",
};
} else {
// 发布
req = {
POST_ID: this.detailObj.POST_ID, // 帖子id
POSTDETAIL_PID: -1,
MEMBERSHIP_ID: this.user.MEMBERSHIP_ID, // 会员内码
POSTDETAIL_TYPE: 3000, // 用户行为
NICK_NAME: this.user.MEMBERSHIP_NAME, // 用户昵称
POSTDETAIL_STATE: 1, // 状态
POSTDETAIL_CONTENT: str,
OPERATE_DATE: new this.$moment().format("YYYY-MM-DD HH:mm:ss"),
};
}
const data = await this.$api.$post("/Member/SynchroPOSTDETAIL", req);
console.log("handlePushComment", data);
if (data.Result_Code === 100) {
this.handleClosePopup();
this.handleGetCommentList();
} else {
uni.showToast({
title: data.Result_Desc,
icon: "none",
});
}
},
// 把全部的/" 变为 " 全部的''变为'
handleGetShowNewStr(str) {
return str.replace(/\/"/g, '"').replace(/''/g, "'");
},
async handleGetPostDetail(id) {
uni.showLoading({
title: "加载中...",
});
const req = {
POSTId: id,
};
const data = await this.$api.$get("/Member/GetPOSTDetail", req);
data.Result_Data.POST_TITLE = this.handleGetShowNewStr(
data.Result_Data.POST_TITLE
);
data.Result_Data.POST_CONTENT = this.handleGetShowNewStr(
data.Result_Data.POST_CONTENT
);
this.detailObj = data.Result_Data;
console.log("handleGetPostDetail", this.detailObj);
await this.handleGetThumbedUp();
this.handleGetCommentList(id);
uni.hideLoading();
},
},
};
</script>
<style scoped lang="less">
.main {
width: 100vw;
background: #f5f6f7;
.contentBox {
width: 100%;
background: #fff;
box-sizing: border-box;
padding: 8rpx 32rpx 56rpx;
.contentTitle {
font-family: PingFangSC, PingFang SC;
font-weight: 400;
font-size: 40rpx;
color: #130f05;
line-height: 56rpx;
text-align: left;
font-style: normal;
}
.itemTop {
display: flex;
align-items: center;
justify-content: space-between;
margin-top: 16rpx;
.topLeft {
width: calc(100% - 190rpx);
display: flex;
align-items: center;
.profileBox {
width: 72rpx;
height: 72rpx;
margin-right: 16rpx;
.profile {
width: 100%;
height: 100%;
}
}
.otherBox {
width: calc(100% - 88rpx);
.userName {
font-family: PingFangSC, PingFang SC;
font-weight: 400;
font-size: 28rpx;
color: #130f05;
line-height: 40rpx;
text-align: left;
font-style: normal;
text-overflow: ellipsis;
overflow: hidden;
white-space: nowrap;
}
.timeBox {
font-family: PingFangSC, PingFang SC;
font-weight: 400;
font-size: 24rpx;
color: #716f69;
line-height: 36rpx;
text-align: left;
font-style: normal;
text-overflow: ellipsis;
overflow: hidden;
white-space: nowrap;
}
}
}
}
.detailContent {
margin-top: 40rpx;
}
.imageList {
width: 100%;
margin-top: 24rpx;
display: flex;
align-items: center;
flex-wrap: wrap;
.imageItem {
width: 218rpx;
height: 218rpx;
border-radius: 8rpx;
margin-right: 8rpx;
overflow: hidden;
.imageBox {
width: 100%;
height: 100%;
}
}
}
}
.commentBox {
margin-top: 16rpx;
width: 100%;
box-sizing: border-box;
padding: 32rpx;
background: #fff;
.commentTitle {
font-family: PingFangSC, PingFang SC;
font-weight: 400;
font-size: 32rpx;
color: #130f05;
line-height: 44rpx;
text-align: left;
font-style: normal;
}
.commentScroll {
width: 100%;
height: 500px;
.commentList {
width: 100%;
margin-top: 24rpx;
.commentDetail {
display: flex;
align-items: flex-start;
border-bottom: 1px solid #f5f6f7;
padding: 32rpx 0;
.detailLeft {
width: 64rpx;
height: 64rpx;
margin-right: 16rpx;
.profile {
width: 100%;
height: 100%;
}
}
.detailRight {
width: calc(100% - 80rpx);
.titleBox {
font-family: PingFangSC, PingFang SC;
font-weight: 400;
font-size: 28rpx;
color: #716f69;
line-height: 40rpx;
text-align: left;
font-style: normal;
}
.contentText {
margin-top: 4rpx;
font-family: PingFangSC, PingFang SC;
font-weight: 400;
font-size: 28rpx;
color: #130f05;
line-height: 40rpx;
text-align: justify;
font-style: normal;
.expend {
margin-left: 8rpx;
color: #ba922f;
}
}
.bottom {
display: flex;
align-items: center;
justify-content: space-between;
.bottomLeft {
.timeText {
font-family: PingFangSC, PingFang SC;
font-weight: 400;
font-size: 24rpx;
color: #716f69;
line-height: 36rpx;
text-align: left;
font-style: normal;
}
.reply {
font-family: PingFangSC, PingFang SC;
font-weight: 400;
font-size: 24rpx;
color: #ba922f;
line-height: 36rpx;
text-align: left;
font-style: normal;
margin-left: 16rpx;
}
}
.bottomRight {
width: 100rpx;
display: flex;
align-items: center;
justify-content: flex-end;
.commentIcon {
width: 32rpx;
height: 32rpx;
margin-right: 8rpx;
}
.thumbsUp {
font-family: PingFangSC, PingFang SC;
font-weight: 400;
font-size: 24rpx;
color: #716f69;
line-height: 36rpx;
text-align: left;
font-style: normal;
}
}
}
.childrenList {
width: 100%;
.childrenItem {
width: 100%;
box-sizing: border-box;
margin-top: 32rpx;
display: flex;
align-items: flex-start;
.childrenLeft {
width: 56rpx;
height: 56rpx;
margin-right: 16rpx;
.profile {
width: 100%;
height: 100%;
}
}
.childrenRight {
width: calc(100% - 72rpx);
.childrenTitle {
font-family: PingFangSC, PingFang SC;
font-weight: 400;
font-size: 28rpx;
color: #716f69;
line-height: 40rpx;
text-align: left;
font-style: normal;
}
.childrenContentText {
margin-top: 4rpx;
font-family: PingFangSC, PingFang SC;
font-weight: 400;
font-size: 28rpx;
color: #130f05;
line-height: 40rpx;
text-align: justify;
font-style: normal;
.expend {
margin-left: 8rpx;
color: #ba922f;
}
}
.childrenBottom {
display: flex;
align-items: center;
justify-content: space-between;
.childrenBottomLeft {
.timeText {
font-family: PingFangSC, PingFang SC;
font-weight: 400;
font-size: 24rpx;
color: #716f69;
line-height: 36rpx;
text-align: left;
font-style: normal;
}
.reply {
font-family: PingFangSC, PingFang SC;
font-weight: 400;
font-size: 24rpx;
color: #ba922f;
line-height: 36rpx;
text-align: left;
font-style: normal;
margin-left: 16rpx;
}
}
.childrenBottomRight {
width: 100rpx;
display: flex;
align-items: center;
justify-content: flex-end;
.commentIcon {
width: 32rpx;
height: 32rpx;
margin-right: 8rpx;
}
.thumbsUp {
font-family: PingFangSC, PingFang SC;
font-weight: 400;
font-size: 24rpx;
color: #716f69;
line-height: 36rpx;
text-align: left;
font-style: normal;
}
}
}
}
}
}
}
}
}
.noComment {
width: 100%;
height: 300rpx;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
.noCommentIcon {
width: 220rpx;
height: 220rpx;
margin-bottom: 24rpx;
}
.noDataText {
font-family: PingFangSC, PingFang SC;
font-weight: 400;
font-size: 28rpx;
color: #716f69;
line-height: 40rpx;
text-align: justify;
font-style: normal;
}
}
}
.commentScroll ::-webkit-scrollbar {
width: 0;
}
}
.postCommentBox {
width: 100%;
box-sizing: border-box;
padding: 10px 16px;
background: #fff;
border-top: 1px solid #f3f3f3;
display: flex;
align-items: center;
position: fixed;
left: 0;
bottom: 0;
.userProfile {
width: 32px;
height: 32px;
margin-right: 18px;
.profile {
width: 100%;
height: 100%;
}
}
.userInput {
width: calc(100% - 52px);
height: 36px;
display: flex;
align-items: center;
background: #f8f8f9;
color: #b8b7b4;
box-sizing: border-box;
padding-left: 24rpx;
border-radius: 8rpx;
}
.userSubmit {
width: 60px;
height: 30px;
box-sizing: border-box;
color: #fff;
background: #ba922f;
margin-left: 24rpx;
border-radius: 16rpx;
display: flex;
align-items: center;
justify-content: center;
}
}
.inputPopup {
width: 100%;
min-height: 100px;
background: #fff;
border-top-right-radius: 16rpx;
border-top-left-radius: 16rpx;
box-sizing: border-box;
padding: 32rpx;
z-index: 999;
.inputBox {
width: 100%;
.titleBox {
width: 100%;
max-height: 180rpx;
font-size: 24rpx;
line-height: 36rpx;
overflow-y: scroll;
}
}
.submitBox {
width: 100%;
display: flex;
justify-content: flex-end;
.submitBtn {
width: 60px;
height: 30px;
box-sizing: border-box;
color: #fff;
background: #ba922f;
margin-left: 24rpx;
border-radius: 16rpx;
display: flex;
align-items: center;
justify-content: center;
}
}
}
}
</style>