PC-mj/pages/details/[id].vue
2023-12-29 18:37:38 +08:00

1591 lines
58 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>
<Head>
<Title>{{ `${seo["title"] || "面经"} - 寄托天下出国留学网` }}</Title>
<Meta name="keyword" :content="seo['keyword']" />
<Meta name="description" :content="seo['description']" />
</Head>
<Header></Header>
<div class="content flexflex">
<div class="left">
<div class="school-box flexcenter">
<a class="school-box-icon" :href="info['school']?.['url']" target="_blank"><img class="school-icon" v-if="info['school']?.['image']" :src="info['school']?.['image']" /></a>
<a class="school-name" :href="info['school']?.['url']" target="_blank">{{ info["school"]?.["name"] }}</a>
<a class="school-en-name" :href="info['school']?.['url']" target="_blank">{{ info["school"]?.["enname"] }}</a>
</div>
<div class="mj-total flexacenter">
该校共有
<div class="value">{{ relatedcount }}</div>
个面经
</div>
<div class="mj-list">
<a class="mj-item flexflex" :class="{ pitch: pitchIndex == index }" v-for="(item, index) in relatedlist" :key="index" @click.prevent="handleItem(item['uniqid'])" :href="`./details/${item['uniqid']}`">
<img class="item-bj" src="@/assets/img/item-bj.svg" />
<div class="mj-header flexacenter">
<img class="mj-avatar" :src="item['avatar']" />
<div class="user-name">{{ item["username"] || "匿名用户" }}</div>
<div class="time">{{ handleDate(item["releasetime"]) }}发布</div>
</div>
<div class="info-list flexflex">
<div class="info-item flexacenter" v-if="item['profession']">
<div class="info-name">专业</div>
<div class="info-value flex1 ellipsis">{{ item["profession"] }}</div>
</div>
<div class="info-item flexacenter" v-if="item['project']">
<div class="info-name">项目</div>
<div class="info-value flex1 ellipsis">{{ item["project"] }}</div>
</div>
<div class="info-item flexacenter" v-if="item['interviewtime']">
<div class="info-name">时间</div>
<div class="info-value flex1 ellipsis">{{ item["interviewtime"] }}</div>
</div>
</div>
</a>
</div>
</div>
<div class="right flex1" @scroll="handleCommentsScroll" v-loading="detailsLoading">
<!-- <div class="right-loading"></div> -->
<div class="header">
<div class="title">{{ info["subject"] }}</div>
<div class="mj-header flexacenter">
<div class="mj-header-left flexacenter">
<el-popover placement="bottom-start" :width="140" trigger="click" popper-class="avatar-box-popper" :show-arrow="false">
<template #reference>
<img class="mj-avatar" :src="info['avatar']" />
</template>
<div class="avatar-box flexflex" v-if="info['uin']">
<!-- <div class="avatar-box flexflex"> -->
<a class="avatar-item flexcenter" target="_blank" @click.prevent="sendMessage(info['uin'])">
<img class="avatar-icon" src="@/assets/img/send-messages-icon.png" />
发送信息
</a>
<a class="avatar-item flexcenter" target="_blank" @click.prevent="TAHomePage(info['uin'])">
<img class="avatar-icon" src="@/assets/img/homepage-icon.png" />
TA的主页
</a>
</div>
</el-popover>
<div class="user-name">{{ info["nickname"] || "匿名用户" }}</div>
<div class="time">{{ handleDate(info["releasetime"]) }}发布</div>
</div>
<div class="mj-header-right flexacenter" v-if="isBrowser">
<img class="eye-icon" src="@/assets/img/eye-icon.svg" />
{{ info["views"] }}
</div>
</div>
</div>
<div class="details-box">
<div class="details-item">
<div class="details-top">申请信息</div>
<div class="details-list">
<div class="details-list-item flexacenter" v-if="info['school']">
<div class="details-name">学校</div>
<a class="details-value" target="_blank" :href="info['school']?.['url']">{{ info["school"]?.name }}</a>
</div>
<div class="details-list-item flexacenter" v-if="info['profession']">
<div class="details-name">专业</div>
<div class="details-value">{{ info["profession"] }}</div>
</div>
<div class="details-list-item flexacenter" v-if="info['project']">
<div class="details-name">项目</div>
<div class="details-value">{{ info["project"] }}</div>
</div>
</div>
</div>
<div class="details-item">
<div class="details-top">面试时间</div>
<div class="details-list">
<div class="details-list-item flexacenter">
<div class="details-name">日期</div>
<div class="details-value date" v-if="info['interviewtime']">{{ timestampToDate(info["interviewtime"]) }}</div>
</div>
</div>
</div>
<div class="details-item">
<div class="details-top">面试过程及内容</div>
<div class="details-list">
<div class="details-list-item flexacenter">
<div class="details-value describe" :class="{ 'unlock-unlock': !isdisplay }" v-if="info['message']">
<!-- {{ info["message"] }} -->
<div v-html="info['message']"></div>
<div class="unlock-mask flexflex" style="width: 693px;">
<div class="">作者设置了浏览限制</div>
<div class="flexacenter">
<div class="emphasis">“回复/点赞”</div>
后即可查看完整内容
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<!-- 讨论 -->
<div class="comment-box">
<div class="comment-title flexacenter">
讨论
<div class="value">{{ commentComments || "" }}</div>
</div>
<div class="post-comment flexacenter">
<textarea class="post-input flex1" placeholder="说说你的想法或疑问…" v-model="commentInputTop"></textarea>
<div class="post-ok flexcenter" @click="submitAnswerComments()">发送</div>
</div>
<template v-if="isEmptyState">
<div class="empty-box">
<Empty hint="说说你的观点吧"></Empty>
</div>
</template>
<template v-else>
<div class="comment-list">
<div class="comment-item flexflex" v-for="(item, index) in commentList" :key="item.id">
<el-popover placement="bottom-start" :width="140" trigger="click" popper-class="avatar-box-popper" :show-arrow="false">
<template #reference>
<img class="comment-avatar" :src="item['avatar']" />
</template>
<div class="avatar-box flexflex" v-if="item['uin']">
<a class="avatar-item flexcenter" target="_blank" @click.prevent="sendMessage(item['uin'])">
<img class="avatar-icon" src="@/assets/img/send-messages-icon.png" />
发送信息
</a>
<a class="avatar-item flexcenter" target="_blank" @click.prevent="TAHomePage(item['uin'])">
<img class="avatar-icon" src="@/assets/img/homepage-icon.png" />
TA的主页
</a>
</div>
</el-popover>
<div class="comment-content flex1">
<div class="comment-header flexacenter">
<div class="comment-header-left flexacenter">
<div class="comments-username">{{ item["nickname"] }}</div>
<div class="comments-time">{{ handleDate(item["timestamp"]) }}</div>
<div class="comments-identity" v-if="item['isauthor']">作者</div>
</div>
<div class="comment-header-right flexacenter">
<div class="menu-box flexacenter">
<img class="menu-icon" src="@/assets/img/menu-icon-gray.svg" />
<div class="report-box flexcenter" @click="report(item['token'])">举报</div>
</div>
<img class="comment-icon" @click="openAnswerCommentsChild(index)" src="@/assets/img/comment-icon-gray.svg" />
<div class="flexacenter like-box" @click="commentLike(index)">
<img class="like-icon" v-if="item['islike'] == 1" src="@/assets/img/like-icon-colours.png" />
<img class="like-icon" v-else src="@/assets/img/like-icon-gray.png" />
<div class="like-quantity">{{ item["likenum"] || 0 }}</div>
</div>
</div>
</div>
<div class="comment-text">{{ item["content"] }}</div>
<!-- <div class="comments-input-box flexacenter" v-if="item['childState']"> -->
<div class="comments-input-box flexacenter" v-if="item['childState']">
<div class="comments-input flexflex">
<textarea class="flex1" placeholder="回复" v-model="commentInput"></textarea>
<div class="comments-btn flexcenter" @click="submitAnswerComments(index)">发送</div>
</div>
<img class="forkfork" @click="closeAnswerCommentsChild(index)" src="@/assets/img/cross-icon.png" />
</div>
<!-- 子评论 -->
<div class="child-comments" v-if="item['child'].length > 0">
<div class="comment-item flexflex" v-for="(ite, i) in item['child']" :key="ite.id">
<!-- <img class="comment-avatar" :src="ite['avatar']" /> -->
<el-popover placement="bottom-start" :width="140" trigger="click" popper-class="avatar-box-popper" :show-arrow="false">
<template #reference>
<img class="comment-avatar" :src="ite['avatar']" />
</template>
<div class="avatar-box flexflex" v-if="item['uin']">
<a class="av atar-item flexcenter" target="_blank" @click.prevent="sendMessage(ite['uin'])">
<img class="avatar-icon" src="@/assets/img/send-messages-icon.png" />
发送信息
</a>
<a class="avatar-item flexcenter" target="_blank" @click.prevent="TAHomePage(ite['uin'])">
<img class="avatar-icon" src="@/assets/img/homepage-icon.png" />
TA的主页
</a>
</div>
</el-popover>
<div class="comment-content flex1">
<div class="comment-header flexacenter">
<div class="comment-header-left flexacenter">
<div class="comments-username">{{ ite["nickname"] }}</div>
<div class="comments-time">{{ handleDate(ite["timestamp"]) }}</div>
<div class="comments-identity" v-if="ite['isauthor']">作者</div>
</div>
<div class="comment-header-right flexacenter">
<div class="menu-box flexacenter">
<img class="menu-icon" src="@/assets/img/menu-icon-gray.svg" />
<div class="report-box flexcenter" @click="report(ite['token'])">举报</div>
</div>
<img class="comment-icon" @click="openAnswerCommentsChild(index, i)" src="@/assets/img/comment-icon-gray.svg" />
<div class="flexacenter like-box" @click="commentLike(index, i)">
<img class="like-icon" v-if="ite['islike'] == 1" src="@/assets/img/like-icon-colours.png" />
<img class="like-icon" v-else src="@/assets/img/like-icon-gray.png" />
<div class="like-quantity">{{ ite["likenum"] || 0 }}</div>
</div>
</div>
</div>
<div class="comment-text">
<div class="comments-reply" v-if="ite?.reply?.nickname">@{{ ite?.reply?.nickname }}</div>
{{ ite["content"] }}
</div>
<div class="comments-input-box flexacenter" v-if="ite['childState']">
<div class="comments-input flexflex">
<textarea class="flex1" placeholder="回复" v-model="commentInput"></textarea>
<div class="comments-btn flexcenter" @click="submitAnswerComments(index, i)">发送</div>
</div>
<img class="forkfork" @click="closeAnswerCommentsChild(index, i)" src="@/assets/img/cross-icon.png" />
</div>
</div>
</div>
</div>
<!-- 还有几个 -->
<div class="comments-also flexacenter" v-if="item['childnum'] >= 3 && item['childnum'] > item['child'].length" @click="alsoCommentsData(index)">
<div class="">还有{{ item["childnum"] - item["child"].length }}条回复</div>
<img class="also-icon" src="@/assets/img/arrow-circular-gray.png" />
</div>
</div>
</div>
</div>
<div class="comment-end" v-if="commentPage == 0 && commentList.length != 0">· End ·</div>
</template>
</div>
</div>
<div class="floor-area flexacenter">
<div class="floor-content flexacenter">
<div class="floor-left flexacenter">
<div class="item flexacenter" @click="handleLike">
<img class="icon" v-if="islike == 1" src="@/assets/img/like-icon-colours.png" />
<img class="icon" v-else src="@/assets/img/like-icon.png" />
{{ info["likenum"] || "" }}
</div>
<div class="item flexacenter"><img class="icon" src="@/assets/img/comment-icon.png" />{{ commentComments }}</div>
<div class="item flexacenter" @click="handleCollect()">
<img class="icon" v-if="iscollection == 1" src="@/assets/img/collect-icon-colours.svg" />
<img class="icon" v-else src="@/assets/img/collect-icon.png" />
{{ info["favnum"] || "收藏" }}
</div>
<el-popover placement="bottom" width="628px" trigger="click" popper-style="padding: 0;border-radius: 10px;" v-model:visible="transmitBoxState">
<template #reference>
<div class="item flexacenter"><img class="icon" src="@/assets/img/transmit-icon.png" />转发</div>
</template>
<div class="transmit-box flexflex">
<img class="cross-icon" @click="transmitBoxState = false" src="@/assets/img/cross-icon.png" />
<div class="transmit-left transmit-web">
<div class="transmit-title">转发网页版</div>
<div class="transmit-content">
<div class="transmit-headline">{{ info["subject"] }}</div>
<div class="transmit-url">{{ getFullUrl() }}</div>
</div>
<div class="transmit-web-btn flexcenter" @click="copyText(`${info['subject']} + ${getFullUrl()}`)">复制链接</div>
</div>
<div class="transmit-right transmit-mini">
<div class="transmit-title">转发小程序版</div>
<div class="transmit-content flexcenter">
<img class="transmit-mini-img" :src="qrcode" />
<div class="flexcenter">
<img class="give-sweep" src="@/assets/img/give-sweep.png" />
扫码转发该问答
</div>
</div>
</div>
</div>
</el-popover>
</div>
<div class="floor-right flexacenter" @mouseenter="handleFloorRight(true)" @mouseleave="handleFloorRight(false)">
手机查看该投票
<img class="arrows-icon" src="@/assets/img/arrows-icon.png" />
<el-popover placement="bottom" width="160px" trigger="hover" v-model:visible="floorRightState" popper-style="padding: 24px;border-radius: 18px;">
<template #reference>
<div class="QR-code-ball flexcenter">
<img class="" src="@/assets/img/QR-code-icon.svg" />
</div>
</template>
<img class="examine-code" :src="qrcode" />
</el-popover>
</div>
</div>
</div>
</div>
<Report v-if="reportAlertShow" :reportToken="reportToken"></Report>
</template>
<script setup>
import { ElMessage } from "element-plus"
const route = useRoute()
let uniqid = route.params.id
onMounted(() => {
// window.addEventListener("scroll", handleScroll)
getDetails()
})
watch(route, () => {
clearAllData()
nextTick(() => getDetails())
})
// 清空全部数据
const clearAllData = () => {
info.value = {}
qrcode.value = ""
iscollection.value = 0
isdisplay.value = true
islike.value = 0
ismyself.value = 0
relatedlist.value = []
relatedcount.value = 0
pitchIndex.value = null
seo.value = {}
commentCount.value = 0
commentPage.value = 1
commentList.value = []
commentLoading = false
token = ""
}
let floorRightState = ref(false) // 右下角 的二维码显示状态
const handleFloorRight = value => {
floorRightState.value = value
}
// 转发弹窗 的 显示状态
let transmitBoxState = ref(false)
let info = ref({})
let qrcode = ref("") // 分享二维码
let iscollection = ref(0) // 是否收藏
let isdisplay = ref(true) // 是否隐藏
let islike = ref(0) // 是否点赞
let ismyself = ref(0) // 是否是作者
let detailsLoading = ref(false) // 详情加载中
const getDetails = () => {
if (detailsLoading.value) return
detailsLoading.value = true
detailsHttp({ uniqid }).then(res => {
if (res.code != 200) {
ElMessage.error(res.message)
return
}
let data = res.data
token = data["token"]
info.value = data["info"]
seo.value = data.seo
iscollection.value = data.iscollection
isdisplay.value = data.isdisplay
islike.value = data.islike
ismyself.value = data.ismyself
qrcode.value = data["share"]["qrcode"]
if (relatedlist.value.length == 0) getRelatedlistHttp()
else CalculateSelectedList()
detailsLoading.value = false
getCommentListHttp()
})
}
// 计算选中的列表
const CalculateSelectedList = () => {
let targetRelatedlist = [...relatedlist.value]
targetRelatedlist.forEach((element, index) => {
if (element["uniqid"] == uniqid) pitchIndex.value = index
})
if (pitchIndex.value == null) {
targetRelatedlist.unshift({
avatar: info.value["avatar"],
interviewtime: timestampToDate(info.value["interviewtime"]),
profession: info.value["profession"],
project: info.value["project"],
releasetime: info.value["releasetime"],
subject: info.value["subject"],
uniqid: uniqid,
username: info.value["nickname"],
})
relatedlist.value = targetRelatedlist
pitchIndex.value = 0
}
}
// 左侧列表数据
let relatedlist = ref([])
let relatedcount = ref(0)
let pitchIndex = ref(null) // 列表选中 index
const getRelatedlistHttp = () => {
relatedlistHttp({ token, page: 1 }).then(res => {
if (res.code != 200) return
let data = res.data
relatedlist.value = data.data
relatedcount.value = data.count
CalculateSelectedList()
})
}
let seo = ref({})
let commentCount = ref(0)
let commentComments = ref(0) // 所有的评论数
let commentPage = ref(1)
let commentList = ref([])
let commentLoading = false
let token = ""
let isEmptyState = ref(false) // 评论是否为空
// 获取详情评论数据
const getCommentListHttp = () => {
if (commentPage.value == 0 || commentLoading || detailsLoading.value) return
commentLoading = true
detailsCommentListHttp({
page: commentPage.value,
childlimit: 1,
limit: 10,
token,
})
.then(res => {
// console.log("res", res)
if (res.code != 200) return
let data = res.data
commentCount.value = data["count"]
if (data["count"] == 0) isEmptyState.value = true
else isEmptyState.value = false
commentList.value = commentList.value.concat(data["data"])
commentComments.value = data["comments"]
if (commentList.value.length == data["count"]) commentPage.value = 0
else commentPage.value++
})
.finally(() => (commentLoading = false))
}
// 获取剩下的子评论
const alsoCommentsData = (index, ind) => {
let targetCommentItem = { ...commentList.value[index] }
const token = targetCommentItem["token"]
const parentid = targetCommentItem["id"]
let page = targetCommentItem["childPage"] ?? 1
detailsChildCommentListHttp({
childlimit: 1,
limit: 10,
page,
parentid,
token,
}).then(res => {
if (res.code != 200) return
let data = res.data
targetCommentItem.child = targetCommentItem.child.concat(data.data)
targetCommentItem["childnum"] = data.count
if (targetCommentItem.child.length == data["count"]) page = 0
else page++
targetCommentItem["childPage"] = page
commentList.value[index] = targetCommentItem
})
}
// 全部的启动到底部
const handleCommentsScroll = e => {
const el = e.target
if (el.scrollHeight - el.scrollTop >= el.clientHeight + 40) return
getCommentListHttp()
}
// 评论点赞
const commentLike = (index, i) => {
const targetCommentList = [...commentList.value]
let token = ""
if (i != null) token = targetCommentList[index]["child"][i].token
else token = targetCommentList[index].token
detailsLikeCommentHttp({ token }).then(res => {
if (res.code != 200) return
let data = res.data
if (i != null) {
targetCommentList[index]["child"][i].islike = data["status"]
targetCommentList[index]["child"][i].likenum = data["likenum"]
} else {
targetCommentList[index].islike = data["status"]
targetCommentList[index].likenum = data["likenum"]
}
ElMessage({
message: res.message,
type: "success",
})
})
}
// 监听滚动到底部
const handleScroll = () => {
return
const scrollTop = document.documentElement.scrollTop || document.body.scrollTop
const scrollHeight = document.documentElement.scrollHeight
const clientHeight = document.documentElement.clientHeight
// console.log(scrollTop + clientHeight >= scrollHeight - 40)
// 列表下 滑动到底部 获取新数据
// if (scrollTop + clientHeight >= scrollHeight - 40) getCommentListHttp()
}
// 打开 回答-评论 的子评论
const openAnswerCommentsChild = (index, i) => {
closeAnswerCommentsChild()
if (i == null) commentList.value[index]["childState"] = true
else commentList.value[index]["child"][i]["childState"] = true
commentInput.value = ""
}
// 关闭 回答-评论 的子评论
const closeAnswerCommentsChild = () => {
commentInput.value = ""
commentList.value.forEach(ele => {
ele["childState"] = false
if (ele["child"] && ele["child"].length != 0) ele["child"].forEach(el => (el["childState"] = false))
})
}
// 讨论的输入框
let commentInputTop = ref("")
let commentInput = ref("")
// 提交回答-评论
const submitAnswerComments = (index, i) => {
const targetCommentList = [...commentList.value]
let content = ""
let parentid = null
if (index == null) content = commentInputTop.value
else content = commentInput.value
if (i != null) parentid = targetCommentList[index]["child"][i]["id"]
else if (index != null) parentid = targetCommentList[index]["id"]
detailsSubmitommentListHttp({
content,
token,
parentid,
}).then(res => {
if (res.code != 200) return
let data = res.data
isdisplay.value = true
if (i != null) {
console.log("111", targetCommentList[index]["child"][i])
let targetData = {
id: data["commentid"],
content,
isauthor: 1,
islike: 0,
likenum: 0,
reply: {
nickname: targetCommentList[index]["child"][i]["nickname"],
},
...data,
}
console.log("targetData", targetData)
targetCommentList[index]["child"].unshift(targetData)
targetCommentList[index]["childnum"]++
} else {
let targetData = {
id: data["commentid"],
content,
isauthor: 1,
islike: 0,
likenum: 0,
...data,
child: [],
}
if (index != null) {
targetCommentList[index]["child"].unshift(targetData)
targetCommentList[index]["childnum"]++
} else {
targetCommentList.unshift(targetData)
commentCount.value++
}
}
commentComments.value++
commentList.value = targetCommentList
// 请求 输入框的数据
commentInputTop.value = ""
commentInput.value = ""
isEmptyState.value = false // 取消有可能的 没有评论
closeAnswerCommentsChild()
ElMessage({
message: res.message,
type: "success",
})
})
}
// 处理时间戳数据
const timestampToDate = timestamp => {
const date = new Date(timestamp * 1000) // 如果你的时间戳是秒级的需要乘以1000
const year = date.getFullYear()
const month = (date.getMonth() + 1).toString().padStart(2, "0") // getMonth() 返回的月份是从0开始计数的
const day = date.getDate().toString().padStart(2, "0")
return `${year}-${month}-${day}`
}
onUnmounted(() => window.removeEventListener("scroll", handleScroll))
// 获取完整 url
const getFullUrl = () => {
if (typeof window === "undefined") return
return window.location.href
}
// 复制
let copyText = text => {
if (navigator.clipboard) {
copyText = () => {
navigator.clipboard.writeText(text)
ElMessage({
message: "复制成功",
type: "success",
})
}
} else {
copyText = () => {
var tempInput = document.createElement("input")
tempInput.value = text
document.body.appendChild(tempInput)
tempInput.select()
document.execCommand("copy")
document.body.removeChild(tempInput)
ElMessage({
message: "复制成功",
type: "success",
})
}
}
copyText()
}
// 点击点赞
const handleLike = () => {
if (islike.value) {
ElMessage.error("不可取消点赞")
return
}
operateLikeHttp({ token }).then(res => {
if (res.code != 200) return
let data = res.data
info.value["likenum"] = data["count"]
islike.value = data["status"]
isdisplay.value = true
ElMessage({
message: res.message,
type: "success",
})
})
}
// 点击 收藏
const handleCollect = () => {
operateCollectHttp({ token }).then(res => {
if (res.code != 200) return
let data = res.data
info.value["favnum"] = data["count"]
iscollection.value = data["status"]
ElMessage({
message: res["message"],
type: "success",
})
})
}
const router = useRouter()
// 处理点击列表
const handleItem = uni => {
// router.push(`/details/${uni}`)
uniqid = uni
// info.value = {}
info.value["message"] = ""
info.value["subject"] = ""
info.value["profession"] = ""
qrcode.value = ""
iscollection.value = 0
isdisplay.value = true
islike.value = 0
ismyself.value = 0
commentCount.value = 0
commentPage.value = 1
commentList.value = []
commentLoading = false
token = ""
// clearAllData()
nextTick(() => getDetails())
replaceState(uni)
}
// 修改 url
const replaceState = uni => {
if (typeof window === "undefined") return
// 替换当前URL但不刷新页面
window.history.pushState({}, "", `${window.location.origin}/details/${uni}`)
}
let reportAlertShow = ref(false)
let reportToken = ref("")
// 点击打开举报
const report = token => {
reportToken.value = token
reportAlertShow.value = true
}
provide("reportAlertShow", reportAlertShow)
// seo的
if (process.server) {
try {
await detailsHttp({ uniqid }).then(res => {
if (res.code != 200) {
ElMessage.error(res.message)
return
}
let data = res.data
token = data["token"]
info.value = data["info"]
seo.value = data.seo
iscollection.value = data.iscollection
isdisplay.value = data.isdisplay
islike.value = data.islike
ismyself.value = data.ismyself
qrcode.value = data["share"]["qrcode"]
if (relatedlist.value.length == 0) getRelatedlistHttp()
else CalculateSelectedList()
detailsLoading.value = false
getCommentListHttp()
})
await relatedlistHttp({ token, page: 1 }).then(res => {
if (res.code != 200) return
let data = res.data
relatedlist.value = data.data
relatedcount.value = data.count
CalculateSelectedList()
})
} catch (error) {}
}
const isBrowser = computed(() => {
return process.client // 使用 process.client 判断是否在浏览器环境下
})
// 点击发送信息
const sendMessage = uin => {
console.log("uin", uin)
redirectToExternalWebsite(`https://bbs.gter.net/home.php?mod=space&showmsg=1&uid=${uin}`)
}
// 点击ta的主页
const TAHomePage = uin => {
redirectToExternalWebsite(`https://bbs.gter.net/home.php?mod=space&uid=${uin}`)
}
// 跳转 url
const redirectToExternalWebsite = url => {
const link = document.createElement("a")
link.href = url
link.target = "_blank"
link.click()
}
</script>
<style lang="less" scoped>
.content {
width: 1200px;
margin: 0 auto 100px;
background: #fff;
border-radius: 15px;
.left {
width: 376px;
border-right: 16px solid #f6f6f6;
padding-top: 30px;
height: calc(100vh - 70px);
overflow: auto;
.school-box {
flex-direction: column;
margin-bottom: 40px;
text-align: center;
.school-box-icon {
height: 52px;
.school-icon {
width: 40px;
height: 40px;
margin-bottom: 12px;
}
}
.school-name {
font-weight: 650;
font-size: 15px;
color: #000000;
margin-bottom: 7px;
height: 28px;
}
.school-en-name {
color: #555555;
font-size: 13px;
height: 18px;
}
}
.mj-total {
color: #7f7f7f;
line-height: 22px;
font-size: 13px;
margin-bottom: 20px;
padding: 0 30px;
.value {
font-weight: 650;
color: #000000;
margin: 0 5px;
}
}
.mj-list {
padding: 0 25px 15px 30px;
.mj-item {
flex-direction: column;
margin-bottom: 15px;
padding: 14px 12px;
position: relative;
z-index: 1;
cursor: pointer;
&.pitch {
.item-bj {
display: block;
}
.mj-header {
.user-name {
color: #fff;
}
.time {
color: #fff;
}
}
.info-list {
.info-item {
.info-name {
color: #fff;
}
.info-value {
color: #fff;
}
}
}
}
.item-bj {
width: 100%;
height: 100%;
z-index: -1;
position: absolute;
top: 0;
left: 0;
display: none;
}
.mj-header {
font-size: 12px;
margin-bottom: 12px;
// justify-content: space-between;
.mj-avatar {
width: 20px;
height: 20px;
margin-right: 10px;
border-radius: 50%;
}
.user-name {
color: #555;
margin-right: 10px;
}
.time {
color: #aaa;
}
}
.info-list {
flex-direction: column;
.info-item {
line-height: 20px;
&:not(:last-of-type) {
margin-bottom: 8px;
}
.info-name {
color: #7f7f7f;
font-size: 13px;
margin-right: 10px;
}
.info-value {
color: #333333;
font-size: 13px;
}
}
}
}
}
}
.right {
height: calc(100vh - 70px);
overflow: auto;
&::-webkit-scrollbar {
width: 0 !important;
}
scrollbar-width: none;
-ms-overflow-style: none;
position: relative;
.header {
padding: 30px 45px 25px;
border-bottom: 1px solid #ebebeb;
.title {
font-size: 24px;
font-weight: 650;
color: #000000;
margin-bottom: 15px;
}
.mj-header-left {
position: relative;
}
.mj-header {
line-height: 22px;
font-size: 13px;
justify-content: space-between;
.mj-avatar {
width: 24px;
height: 24px;
margin-right: 10px;
border-radius: 50%;
}
.user-name {
color: #333333;
margin-right: 10px;
}
.time {
color: #aaaaaa;
}
.mj-header-right {
.eye-icon {
width: 13px;
height: 8px;
margin-right: 5px;
}
font-size: 12px;
color: #aaaaaa;
}
}
}
.details-box {
border-bottom: 1px solid #ebebeb;
padding-top: 41px;
.details-item {
margin-bottom: 40px;
.details-top {
font-weight: 650;
font-size: 14px;
color: #000000;
padding-left: 60px;
position: relative;
margin-bottom: 21px;
&::after {
content: "";
width: 6px;
height: 10px;
position: absolute;
top: 5px;
left: 44px;
background-color: rgba(98, 177, 255, 1);
border-radius: 3px;
}
}
.details-list {
width: 733px;
margin-left: 60px;
padding: 20px;
background: inherit;
background-color: rgba(246, 246, 246, 1);
border-radius: 10px;
font-size: 14px;
.details-list-item {
&:not(:last-of-type) {
margin-bottom: 20px;
}
.details-name {
color: #555;
margin-right: 30px;
}
.details-value {
color: #000000;
white-space: break-spaces;
// width: 693px;
&.date {
font-weight: 900;
font-style: normal;
font-size: 16px;
color: #000000;
font-family: "Arial-Black", "Arial Black", sans-serif;
}
&.describe {
font-size: 15px;
line-height: 30px;
position: relative;
width: 693px;
.unlock-mask {
display: none;
}
&.unlock-unlock {
overflow: hidden;
height: 244px;
cursor: pointer;
.unlock-mask {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
background: linear-gradient(to top, rgba(246, 246, 246, 1) 82%, transparent);
font-size: 14px;
color: #000000;
flex-direction: column;
align-items: center;
justify-content: flex-end;
padding-bottom: 38px;
line-height: normal;
display: flex;
> div {
margin-top: 7px;
}
.emphasis {
font-weight: 650;
color: #fa6b11;
}
}
}
}
}
}
}
}
}
.comment-box {
padding-top: 40px;
padding-left: 45px;
.comment-title {
font-size: 16px;
line-height: 20px;
font-weight: 650;
color: #000000;
margin-bottom: 16px;
.value {
color: #555;
font-weight: 400;
margin-left: 5px;
}
}
.post-comment {
width: 749px;
height: 60px;
background-color: rgba(255, 255, 255, 1);
border: 1px solid rgba(215, 215, 215, 1);
border-radius: 6px;
margin-bottom: 30px;
.post-input {
height: 100%;
border: none;
outline: none;
background-color: transparent;
outline-color: rgba(98, 177, 255, 1);
padding: 10px;
font-size: 14px;
resize: none;
&::placeholder {
color: #aaaaaa;
}
}
.post-ok {
width: 60px;
height: 60px;
background-color: rgba(98, 177, 255, 1);
color: #fff;
font-size: 14px;
cursor: pointer;
border-radius: 6px;
}
}
.empty-box {
padding: 80px 0 110px;
}
.comment-list {
margin-bottom: 78px;
.comment-item {
&:not(:first-of-type) {
.comment-avatar {
margin-top: 10px;
}
.comment-header {
padding-top: 10px;
border-top: 1px dotted #d7d7d7;
}
}
padding-right: 30px;
.comment-avatar {
width: 20px;
height: 20px;
border-radius: 50%;
margin-right: 10px;
}
.comment-content {
.comment-header {
display: flex;
justify-content: space-between;
padding-right: 30px;
margin-bottom: 10px;
.comment-header-left {
font-size: 13px;
.comments-avatar {
width: 20px;
height: 20px;
margin-right: 10px;
border-radius: 50%;
}
.comments-username {
color: #555;
margin-right: 10px;
}
.comments-time {
color: #aaaaaa;
// margin-right: 8px;
margin-right: 10px;
}
.comments-identity {
font-size: 12px;
color: #7f7f7f;
padding: 0 3px;
height: 20px;
background-color: rgba(240, 242, 245, 1);
border: 1px solid rgba(215, 215, 215, 1);
border-radius: 5px;
}
}
.comment-header-right {
.menu-box {
position: relative;
&:hover .report-box {
display: flex;
}
.menu-icon {
width: 14px;
height: 14px;
cursor: pointer;
}
.report-box {
display: none;
position: absolute;
top: 24px;
right: 0;
width: 60px;
height: 24px;
background-color: rgba(246, 246, 246, 1);
border: 1px solid rgba(215, 215, 215, 1);
border-radius: 5px;
font-size: 12px;
color: #7f7f7f;
cursor: pointer;
&::after {
content: "";
width: 58px;
height: 36px;
position: absolute;
top: -14px;
right: 0;
}
}
}
.comment-icon {
width: 14px;
height: 13px;
margin-left: 30px;
cursor: pointer;
}
.like-box {
font-size: 12px;
color: #aaa;
margin-left: 30px;
cursor: pointer;
.like-icon {
width: 14px;
height: 14px;
}
.like-quantity {
margin-left: 6px;
}
}
}
}
.comment-text {
font-size: 14px;
line-height: 22px;
color: #333;
margin-bottom: 10px;
word-break: break-all;
.comments-reply {
color: #92a1bf;
display: inline;
}
}
.comments-input-box {
margin-top: 13px;
margin-bottom: 10px;
.comments-input {
// width: 519px;
flex: 1;
height: 60px;
border: 1px solid rgba(215, 215, 215, 1);
border-radius: 8px;
margin-right: 16px;
position: relative;
z-index: 1;
&::after {
content: "";
width: 20px;
height: 20px;
display: block;
background-color: rgba(215, 215, 215, 1);
position: absolute;
top: -2px;
left: 21px;
transform: rotate(45deg);
z-index: -1;
}
textarea {
border: none;
outline: none;
resize: none;
padding: 11px 16px;
border-radius: 7px 0 0 7px;
}
.comments-btn {
width: 58px;
height: 58px;
background-color: rgba(98, 177, 255, 1);
border-radius: 0 7px 7px 0;
font-size: 14px;
color: #ffffff;
cursor: pointer;
}
}
.forkfork {
width: 12px;
height: 12px;
cursor: pointer;
}
}
}
.child-comments {
.comment-avatar {
margin-top: 10px;
}
.comment-header {
padding-top: 10px;
border-top: 1px dotted #d7d7d7;
}
.comment-item {
padding-right: 0;
}
}
.comments-also {
color: #62b1ff;
line-height: 22px;
font-size: 13px;
height: 46px;
margin-left: 30px;
cursor: pointer;
border-top: 1px dotted #d7d7d7;
.also-icon {
width: 10px;
height: 10px;
margin-left: 8px;
}
}
}
}
.comment-end {
font-size: 12px;
color: #d7d7d7;
text-align: center;
margin-bottom: 158px;
}
}
}
.floor-area {
position: fixed;
left: 0;
bottom: 0;
width: 100vw;
min-width: 1200px;
height: 70px;
z-index: 1;
background-color: rgba(255, 255, 255, 1);
-moz-box-shadow: 0px -1px 2px rgba(0, 0, 0, 0.192156862745098);
-webkit-box-shadow: 0px -1px 2px rgba(0, 0, 0, 0.192156862745098);
box-shadow: 0px -1px 2px rgba(0, 0, 0, 0.192156862745098);
.floor-content {
width: 1200px;
height: 100%;
margin: 0 auto;
padding: 0 30px;
display: flex;
justify-content: space-between;
// background: #000000;
.floor-left {
.item {
cursor: pointer;
color: #aaaaaa;
font-size: 13px;
margin-right: 50px;
.icon {
width: 16px;
margin-right: 5px;
}
&.operate-item {
position: relative;
display: flex;
justify-content: center;
}
}
}
.floor-right {
color: #7f7f7f;
font-size: 13px;
cursor: pointer;
.arrows-icon {
width: 12px;
height: 12px;
margin: 0 10px;
}
.QR-code-ball {
width: 40px;
height: 40px;
background-color: rgba(246, 246, 246, 1);
border-radius: 20px;
cursor: pointer;
}
}
}
}
}
.transmit-box {
width: 628px;
border-radius: 10px;
justify-content: space-between;
padding: 40px 35px 42px;
// z-index: 3;
cursor: auto;
.cross-icon {
width: 22px;
height: 22px;
position: absolute;
top: 6px;
right: 6px;
cursor: pointer;
padding: 6px;
}
.transmit-title {
font-weight: 650;
font-size: 16px;
color: #000000;
line-height: 24px;
margin-bottom: 24px;
}
.transmit-content {
border: 1px solid rgba(242, 242, 242, 1);
border-radius: 16px;
}
.transmit-web {
.transmit-content {
width: 300px;
font-size: 14px;
line-height: 24px;
padding: 14px 16px;
margin-bottom: 32px;
.transmit-headline {
color: #333333;
}
.transmit-url {
color: #aaaaaa;
word-wrap: break-word;
}
}
.transmit-web-btn {
width: 120px;
height: 38px;
background-color: rgba(114, 219, 134, 1);
border-radius: 8px;
font-size: 14px;
color: #fff;
cursor: pointer;
}
}
.transmit-mini {
.transmit-content {
flex-direction: column;
padding: 22px 44px;
.transmit-mini-img {
width: 90px;
height: 90px;
margin-bottom: 21px;
}
color: #555555;
// line-height: 22px;
font-size: 13px;
.give-sweep {
width: 12px;
height: 12px;
margin-right: 8px;
}
}
}
}
.examine-code {
width: 113px;
height: 113px;
}
</style>