PC-mj/pages/details/[id].vue
2024-01-11 17:23:17 +08:00

2452 lines
90 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>
<!-- <div @click="router.push(`/index.html`)">1111</div> -->
<!-- <PageHeade></PageHeade> -->
<div>
<TopHead ref="topHeadRef"></TopHead>
<div class="content flexflex">
<div class="left" :style="{ height: contentRightHeight + 'px' }">
<div class="school-box flexcenter" :style="{ 'pointer-events': info['school']?.['url'] ? 'auto' : 'none' }">
<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" @scroll="handleListScroll">
<template v-for="(item, index) in relatedlist" :key="index">
<a v-if="item['type']" class="mj-item flexflex recommend" :href="item?.url" target="_blank">
<div class="mj-header flexacenter">
<div class="label flexacenter">
<div class="label-text flexcenter">荐</div>
<div class="label-title">{{ labelObj[item["type"] || "offer"] }}</div>
</div>
<h1>{{ item["title"] }}</h1>
</div>
<div class="info-list flexflex" v-if="item['type'] == 'offer'">
<div class="info-item flexacenter">
<div class="info-name">专业</div>
<div class="info-value flex1 ellipsis">{{ item["professional"] }}</div>
</div>
<div class="info-item flexacenter">
<div class="info-name">学位</div>
<div class="info-value flex1 ellipsis">{{ item["degree"] }}</div>
</div>
<div class="info-item flexacenter">
<div class="info-name">结果</div>
<div class="info-value flex1 ellipsis">{{ item["apply_results"] }}</div>
</div>
</div>
<div class="thread-text ellipsis flexflex" v-if="item['type'] == 'thread' || item['type'] == 'ask'">
<div class="ask-label" v-if="item['type'] == 'ask'">回答:</div>
<div class="flex1 ellipsis">{{ item["message"] }}</div>
</div>
<div class="vote-list" v-if="item['type'] == 'vote'">
<div class="vote-item" v-for="(ite, i) in item['option'].slice(0, 2)" :key="i">{{ numberToEnclosed(i) }} &nbsp; {{ ite }}</div>
<div class="vote-item">{{ numberToEnclosed(3) }} &nbsp; …</div>
</div>
</a>
<a v-else class="mj-item flexflex" :class="{ pitch: pitchIndex == index }" @click.stop.prevent="handleItem(item['uniqid'])" :href="`./details/${item['uniqid']}`">
<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>
</template>
</div>
</div>
<!-- <div class="right flex1" @scroll="handleCommentsScroll" v-loading="detailsLoading"> -->
<div class="right flex1" ref="contentRightRef" v-loading="detailsLoading">
<!-- <div class="right-loading"></div> -->
<div class="header">
<div class="titletitle">{{ 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>
<a class="mj-header-right flexacenter" target="_blank" :href="info['threadurl']">
<img class="original-icon" src="@/assets/img/original-icon.png" />
论坛原帖
<!-- <img class="eye-icon" src="@/assets/img/eye-icon.svg" /> -->
<!-- {{ info["views"] }} -->
</a>
</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">
<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" @click="loginJudgment()">“回复/点赞”</div>
后即可查看完整内容
</div>
</div>
</div>
</div>
</div>
</div>
<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>
<!-- 讨论 -->
<div class="comment-box" ref="commentBoxRef">
<div class="comment-title flexacenter">
讨论
<div class="value">{{ commentComments || "" }}</div>
</div>
<div class="post-comment flexacenter" @click="loginJudgment()">
<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" v-model:visible="item['popoverState']">
<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" @click="openAvatarPopover(index)">{{ item["nickname"] }}</div>
<div class="comments-time">{{ handleDate(item["timestamp"]) }}</div>
<div class="comments-identity" v-if="item['isauthor']">作者</div>
<img class="comments-title" v-if="item['groupid'] == 14" src="@/assets/img/title.png" />
</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" title="回复" @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" @click="openAnswerCommentsChild(index)">{{ item["content"] }}</div> -->
<div class="comment-text" @click="openAnswerCommentsChild(index)" v-html="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" v-model:visible="ite['popoverState']">
<template #reference>
<img class="comment-avatar" :src="ite['avatar']" />
</template>
<div class="avatar-box flexflex" v-if="ite['uin']">
<a class="avatar-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" @click="openAvatarPopover(index, i)">{{ ite["nickname"] }}</div>
<div class="comments-time">{{ handleDate(ite["timestamp"]) }}</div>
<div class="comments-identity" v-if="ite['isauthor']">作者</div>
<img class="comments-title" v-if="ite['groupid'] == 14" src="@/assets/img/title.png" />
</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" title="回复" @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" @click="openAnswerCommentsChild(index, i)">
<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'] > 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-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 class="floor-left flexacenter">
<div class="item flexacenter" v-if="isBrowser" style="cursor: auto;">
<img class="icon h8" src="@/assets/img/eye-icon-black.svg" />
{{ info["views"] }}
</div>
<div class="item flexacenter" @click="handleLike">
<img class="icon h16" v-if="islike == 1" src="@/assets/img/like-icon-colours.png" />
<img class="icon h16" v-else src="@/assets/img/like-icon.png" />
{{ info["likenum"] || "" }}
</div>
<div class="item flexacenter" @click="handleScrollComments()"><img class="icon h15" src="@/assets/img/comment-icon.png" />{{ commentComments }}</div>
<ClientOnly>
<div class="item flexacenter" @click="handleCollect()">
<img class="icon h16" v-if="iscollection == 1" src="@/assets/img/collect-icon-colours.svg" />
<img class="icon h16" v-else src="@/assets/img/collect-icon.png" />
{{ info["favnum"] || "收藏" }}
</div>
</ClientOnly>
<ClientOnly>
<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" @click="handleShare"><img class="icon h15" 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>
</ClientOnly>
</div>
<div class="floor-middle flexacenter coin-box">
<div class="coin-content flexacenter flex1" @click="openCoinRankList" :style="{ cursor: info.coins != 0 ? 'pointer' : '' }">
<img class="coin-icon" src="@/assets/img/coin-icon.png" />
<div class="coin-text flex1 flexacenter">
已获
<div class="coin-value">{{ info.coins }}</div>
个寄托币
</div>
</div>
<div class="coin-btn flexcenter" @click="openCoinOperation()">给TA投币</div>
</div>
</div>
</div>
</div>
<Report v-if="reportAlertShow" :reportToken="reportToken"></Report>
</div>
<!-- 投币操作 弹窗 -->
<div class="pop-masking flexcenter" v-if="isInsertCoinsOperationShow">
<div class="slit-pop-box" v-if="coinMybalance > 0" style="border-radius: 11px;">
<div class="slit-left" style="width: 50px;">
<img class="slit-left-icon" src="//app.gter.net/image/gter/offer/imgdetails/u620.png" style="margin-top: -8px;" />
</div>
<div class="slit-box">
<div class="slit-head" style="flex: 1; flex-direction: column; align-items: flex-start;">
<div class="slit-head-title flexflex" style="width: 100%; justify-content: space-between;">
<span>投币</span>
<div class="in-all">
你共有 <span>{{ coinMybalance }}</span> 寄托币
</div>
<!-- <a target="_blank" :href="coinConfig.strategy.url" style="font-weight: 100; font-size: 13px; text-decoration: underline;">{{ coinConfig.strategy.button }}</a> -->
</div>
</div>
<div class="coin-quantity flexacenter">
<div class="coin-quantity-item" :class="{ 'coin-pitch': coinAmount == item }" v-for="(item, index) in coinConfig.list" :key="index" @click="coinSelectAmountDispose(item)">
{{ item }} <span>{{ coinConfig.unit }}</span>
</div>
</div>
<el-input class="slit-input" v-model="coinAmount" placeholder="自定义投币金额" show-word-limit="false"> </el-input>
<div class="message-box">
<div class="message-hint">顺便说点什么</div>
<el-input class="slit-input" style="font-size: 15px;" v-model="coinMessage" placeholder="请输入" maxlength="500" show-word-limit> </el-input>
</div>
<div class="operation">
<div class="operation-item flexcenter" @click="isInsertCoinsOperationShow = !isInsertCoinsOperationShow">取消</div>
<div class="operation-item flexcenter greenBj" @click="postCoinSbmit()">确定</div>
</div>
</div>
</div>
<div class="no-jituobi-pop-box" v-else>
<img class="no-jituobi-close" @click="isInsertCoinsOperationShow = !isInsertCoinsOperationShow" src="@/assets/img/cross-icon.png" />
<div class="no-jituobi-head flexacenter">
<img class="bi-icon" src="//app.gter.net/image/gter/offer/imgdetails/u620.png" style="margin-right: 12px;" />
<span style="margin-top: 10px;">
{{ coinConfig?.strategy?.tips }}
</span>
</div>
<a :href="coinConfig?.strategy?.url" target="_blank">
<div class="strategy-btn greenBj flexcenter">{{ coinConfig?.strategy?.button }}<img class="strategy-icon" src="@/assets/img/strategy-icon.svg" /></div>
</a>
</div>
</div>
<!-- 投币 排行榜 -->
<RankingBox v-if="coinrankingState" :coinrankingList="coinrankingList"></RankingBox>
</template>
<script setup>
import { ElMessage } from "element-plus"
const route = useRoute()
let uniqid = route.params.id
let isNeedLogin = inject("isNeedLogin")
const goLogin = inject("goLogin")
useHead({ script: [{ src: "https://app.gter.net/bottom?tpl=header&menukey=mj" }, { src: "https://app.gter.net/bottom?tpl=footer", body: true }] })
let contentRightRef = ref(null)
let contentRightHeight = ref(null)
onMounted(() => {
window.addEventListener("scroll", handleScroll)
getDetails()
// openObserverBottom()
// 在元素挂载后执行回调函数
nextTick(() => {
// 创建 ResizeObserver 实例
const observer = new ResizeObserver(entries => {
for (const entry of entries) {
// 元素的高度变化
contentRightHeight.value = entry.contentRect.height
}
})
// 监听元素的变化
observer.observe(contentRightRef.value)
})
clearBottom()
})
let floorAreaState = ref(false) // 底部操作显示状态
watch(
() => route.path,
(newValue, oldValue) => {
// 在这里处理route.path的变化
if (typeof window !== "undefined" && route.path) {
if (window._hmt) window._hmt.push(["_trackPageview", route.fullPath])
if (window._czc) {
let location = window.location
let contentUrl = location.pathname + location.hash
let refererUrl = "/"
window._czc.push(["_trackPageview", contentUrl, refererUrl])
window._czc.push(["_setAutoPageview", false])
}
}
}
)
// 开启一个监听最底部是否在可视窗口内
const openObserverBottom = () => {
// 获取目标元素的引用
const target = document.querySelector("section.index-footer")
if (!target) {
openObserverBottom()
return
}
// 创建一个 Intersection Observer 实例
const observer = new IntersectionObserver(
(entries, observer) => {
entries.forEach(entry => {
if (entry.isIntersecting) floorAreaState.value = false
else floorAreaState.value = true
})
},
{
root: null,
threshold: 0.5,
}
)
// 开始观察目标元素
observer.observe(target)
}
// 清除底部的次数
let clearBottomCount = 0
// 清除 底部
const clearBottom = () => {
const indexFooter = document.querySelector("section.index-footer")
if (!indexFooter) {
clearBottomCount++
setTimeout(() => clearBottom(), 200)
return
}
if (clearBottomCount == 5) return
indexFooter.style.display = "none"
}
// 清空全部数据
const clearAllData = () => {
uniqid = route.params.id
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)
setTimeout(() => goToURL("/index.html", false), 1000)
return
}
let data = res.data
token = data["token"]
info.value = data["info"]
seo.value = data.seo
iscollection.value = data.iscollection || 0
isdisplay.value = data.isdisplay
islike.value = data.islike
ismyself.value = data.ismyself
qrcode.value = data["share"]["qrcode"]
// console.log(iscollection.value);
if (relatedlist.value.length == 0) getRelatedlistHttp()
else CalculateSelectedList()
if (JSON.stringify(coinConfig.value) == "{}") getCoinInfo()
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 relatedpage = ref(1)
let relatedloading = false
let pitchIndex = ref(null) // 列表选中 index
const getRelatedlistHttp = () => {
if (relatedloading || relatedpage.value == 0 || !token) return
relatedloading = true
relatedlistHttp({ token, page: relatedpage.value })
.then(res => {
if (res.code != 200) return
let data = res.data
relatedlist.value = relatedlist.value.concat(data.data)
relatedcount.value = data.count
if (relatedlist.value.length >= data["count"]) relatedpage.value = 0
else relatedpage.value++
CalculateSelectedList()
})
.finally(() => {
relatedloading = false
})
}
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
if (commentPage.value != 1) getRelatedlistHttp()
detailsCommentListHttp({
page: commentPage.value,
childlimit: 1,
limit: 10,
token,
})
.then(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
// console.log(data["data"])
// data["data"].forEach(element => {
// console.log("element", element["content"])
// element.content = element["content"].replace(/{:rose:}/g, `<img src="https://bbs.gter.net/static/image/smiley/lxh/rose.gif" />`)
// })
commentList.value = commentList.value.concat(data["data"])
commentComments.value = data["comments"]
if (commentList.value.length == data["count"]) commentPage.value = 0
else commentPage.value++
// https://bbs.gter.net/static/image/smiley/lxh/rose.gif
})
.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
let childData = targetCommentItem.child.concat(data.data)
// 检查当前对象在数组中的第一个索引是否与当前索引相等
const filteredData = childData.filter((obj, index, self) => {
return self.findIndex(item => item.id == obj.id) == index
})
targetCommentItem.child = filteredData
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) => {
if (isNeedLogin.value) {
goLogin()
return
}
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.success(res.message)
})
}
let scrollTopValue = ref(0)
// 监听滚动到底部
const handleScroll = () => {
// return
const scrollTop = document.documentElement.scrollTop || document.body.scrollTop
scrollTopValue.value = scrollTop
// return
const scrollHeight = document.documentElement.scrollHeight
const clientHeight = document.documentElement.clientHeight
// 列表下 滑动到底部 获取新数据
if (scrollTop + clientHeight >= scrollHeight - 40) {
getCommentListHttp()
// 整个页面滚动到底部时 判断左边是否有滚动条 没有则需要加载左边数据的下一页
const mjList = document.querySelector(".content .left .mj-list")
if (!(mjList.scrollHeight > mjList.clientHeight || mjList.scrollWidth > mjList.clientWidth)) getRelatedlistHttp()
}
}
// 打开 回答-评论 的子评论
const openAnswerCommentsChild = (index, i) => {
if (isNeedLogin.value) {
goLogin()
return
}
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) => {
if (isNeedLogin.value) {
goLogin()
return
}
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) {
ElMessage.error(res.message)
return
}
let data = res.data
isdisplay.value = true
if (i != null) {
let targetData = {
id: data["commentid"],
content,
isauthor: 1,
islike: 0,
likenum: 0,
reply: {
nickname: targetCommentList[index]["child"][i]["nickname"],
},
...data,
}
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
}
if (isNeedLogin.value) {
goLogin()
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.success(res.message)
})
}
let topHeadRef = ref(null)
// 点击 收藏
const handleCollect = () => {
if (isNeedLogin.value) {
goLogin()
return
}
topHeadRef.value.count = {}
operateCollectHttp({ token }).then(res => {
if (res.code != 200) {
ElMessage.error(res["message"])
return
}
let data = res.data
info.value["favnum"] = data["count"]
iscollection.value = data["status"]
ElMessage.success(res["message"])
})
}
const router = useRouter()
// 处理点击列表
const handleItem = uni => {
if (uni == route?.params?.id) return
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)
window.scrollTo({
top: 0,
behavior: "smooth",
})
}
// 修改 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 => {
if (isNeedLogin.value) {
goLogin()
return
}
reportToken.value = token
reportAlertShow.value = true
}
provide("reportAlertShow", reportAlertShow)
provide("clearAllData", clearAllData)
provide("getDetails", getDetails)
// 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 => {
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()
}
// 全部的启动到底部
const handleListScroll = e => {
const el = e.target
if (el.scrollHeight - el.scrollTop >= el.clientHeight + 40) return
getRelatedlistHttp()
}
const commentBoxRef = ref(null)
// 点进滚动到评论
const handleScrollComments = () => {
const element = commentBoxRef.value
if (!element) return
window.scrollTo({
top: element.offsetTop - 85 || 0,
behavior: "smooth",
})
return
const rect = element.getBoundingClientRect()
let elementTop = 0
elementTop = rect.top - window.innerHeight / 2
if (rect.top > window.innerHeight) {
elementTop = rect.top - window.innerHeight / 2
window.scrollTo({
top: elementTop || 0,
behavior: "smooth",
})
} else {
elementTop = window.innerHeight / 2 + rect.top / 2
window.scrollTo({
top: elementTop || 0,
behavior: "smooth",
})
}
// window.scrollTo({
// top: elementTop,
// behavior: "smooth",
// })
}
// 打开评论的 信息框
const openAvatarPopover = (index, i) => {
if (i != null) commentList.value[index]["child"][i]["popoverState"] = true
else commentList.value[index]["popoverState"] = true
}
let isInsertCoinsOperationShow = ref(false) // 投票弹窗
let coinMybalance = ref({}) // 我的寄托币数量
let coinConfig = ref({}) // 投币的配置
let coinConnum = ref(0) // 寄托币数量
let coinRanklist = ref({}) // 投币排行榜
let coinAmount = ref(null) // 投币选择的金额
let coinCustomAmount = ref(null) // 投币自定义的金额
let defaultcoinnum = ref(0) // 投币金额默认寄托币数
let coinMessage = ref("") // 投币时的说点什么
let postCoinSbmitState = false // 投币中
// 获取寄托币
const getCoinInfo = () => {
coinHttp({ token }).then(res => {
if (res.code != 200) return
let data = res.data
coinConfig.value = data.config
coinMybalance.value = data.mybalance
coinRanklist.value = data.ranklist
defaultcoinnum.value = data.defaultcoinnum
})
}
// 打开寄托币弹窗
const openCoinOperation = () => {
if (isNeedLogin.value) {
goLogin()
return
}
isInsertCoinsOperationShow.value = true
}
// 处理投币的选择选项
const coinSelectAmountDispose = amount => {
coinAmount.value = amount
}
// 提交寄托币
const postCoinSbmit = () => {
if (postCoinSbmitState) return
postCoinSbmitState = true
coinsubmitHttp({
token,
coinnum: coinAmount.value,
message: coinMessage.value,
})
.then(res => {
if (res.code != 200) {
ElMessage.error(res.message)
return
}
let data = res.data
info.value.coins = info.value.coins + data["coinnum"]
coinMybalance.value = coinMybalance.value - data["coinnum"]
coinAmount.value = null
isInsertCoinsOperationShow.value = false
ElMessage.success(res.message)
if (data.comment) {
const userInfoWin = window.userInfoWin || {}
commentComments.value = data.comment.count
let newComment = {
avatar: userInfoWin["avatar"],
child: [],
childnum: 0,
content: coinMessage.value,
id: parseInt(data.comment.commentid),
...data.comment,
islike: 0,
likenum: 0,
nickname: userInfoWin["nickname"] || "匿名用户",
parentid: 0,
reply: [],
timestamp: generateTime(),
}
commentList.value.unshift(newComment)
}
coinMessage.value = ""
coinrankingList.value = []
})
.finally(() => (postCoinSbmitState = false))
}
let coinrankingList = ref([]) // 投币排行榜数据
let coinrankingState = ref(false) // 投币排行榜 弹窗状态
let coinrankingLoading = false // 投币排行榜加载中
const getCoinranking = () => {
if (coinrankingLoading) return
coinrankingLoading = true
coinrankingHttp({ token })
.then(res => {
if (res.code != 200) return
const data = res.data
coinrankingList.value = data
coinrankingState.value = true
})
.finally(() => (coinrankingLoading = false))
}
// 打开寄托币排行榜
const openCoinRankList = () => {
if (info.value.coins == 0) return
if (coinrankingList.value.length == 0) getCoinranking()
else coinrankingState.value = true
}
// 生成时间
const generateTime = () => {
let date = new Date()
let Y = date.getFullYear() + "-"
let M = (date.getMonth() + 1 < 10 ? "0" + (date.getMonth() + 1) : date.getMonth() + 1) + "-"
let D = (date.getDate() < 10 ? "0" + date.getDate() : date.getDate()) + " "
let h = (date.getHours() < 10 ? "0" + date.getHours() : date.getHours()) + ":"
let m = date.getMinutes() < 10 ? "0" + date.getMinutes() : date.getMinutes()
return "" + Y + M + D + h + m
}
provide("coinrankingState", coinrankingState)
// 处理点击转发统计
const handleShare = () => shareHttp({ token })
// 登录判断
const loginJudgment = () => {
if (isNeedLogin.value) goLogin()
}
// 取消了同页面的收藏
const unbookmarkSamePage = () => {
iscollection.value = 0
info.value.favnum--
}
provide("unbookmarkSamePage", unbookmarkSamePage)
let labelObj = {
offer: "Offer",
vote: "投票",
mj: "面经",
thread: "帖子",
ask: "回答",
}
</script>
<style lang="less" scoped>
.content {
width: 1200px;
margin: 0 auto 60px;
background: #fff;
border-radius: 15px;
// position: sticky;
// top: 30px;
// left: 50%;
// transform: translateX(-50%);
.left {
width: 376px;
border-right: 16px solid #f6f6f6;
padding-top: 30px;
height: calc(100vh - 70px);
overflow: auto;
display: flex;
flex-direction: column;
.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 {
// &::-webkit-scrollbar {
// width: 6px !important;
// }
&::-webkit-scrollbar {
width: 0 !important;
}
scrollbar-width: none;
-ms-overflow-style: none;
margin-right: 9px;
padding: 0 30px 15px;
flex: 1;
overflow: auto;
.mj-item {
flex-direction: column;
margin-bottom: 15px;
padding: 14px 12px;
position: relative;
z-index: 1;
cursor: pointer;
position: relative;
&.recommend {
.mj-header {
display: inline-block;
.label {
// width: 60px;
height: 20px;
background-color: rgba(253, 223, 109, 0.117647058823529);
border: 1px solid rgba(228, 199, 98, 1);
border-radius: 5px;
font-size: 12px;
color: #e4c762;
text-align: center;
display: inline-flex;
margin-right: 10px;
.label-text {
width: 20px;
height: 20px;
background-color: rgba(228, 199, 98, 1);
border-radius: 5px;
font-size: 12px;
color: #ffffff;
}
.label-title {
padding: 0 5px;
height: 100%;
// line-height: 20px;
display: flex;
align-items: center;
}
}
h1 {
display: inline;
font-weight: 650;
font-size: 14px;
color: #000000;
line-height: 26px;
// display: -webkit-box;
-webkit-line-clamp: 2;
-webkit-box-orient: vertical;
overflow: hidden;
}
}
.thread-text {
color: #555555;
font-size: 13px;
.ask-label {
color: #7f7f7f;
}
}
.vote-list {
color: #555555;
font-size: 13px;
.vote-item {
&:not(:last-of-type) {
margin-bottom: 6px;
}
}
}
}
&:hover::after {
content: "";
position: absolute;
background: #f6f6f6;
top: 0;
left: 0;
width: 100%;
height: 100%;
border-radius: 10px;
z-index: -1;
}
&.pitch {
&::before,
&::after {
content: "";
position: absolute;
background: rgb(114, 219, 134);
}
&::after {
top: 0;
left: 0;
width: 100%;
height: 100%;
border-radius: 10px;
z-index: -1;
}
&::before {
top: 50%;
left: 100%;
width: 10px;
height: 10px;
transform: translate(-64%, -50%) rotate(45deg);
}
.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 - 80px);
overflow: auto;
padding: 5px 0;
&::-webkit-scrollbar {
width: 0 !important;
}
scrollbar-width: none;
-ms-overflow-style: none;
position: relative;
.header {
padding: 30px 30px 25px 45px;
border-bottom: 1px solid #ebebeb;
.titletitle {
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 {
color: #333;
font-size: 14px;
cursor: pointer;
.original-icon {
width: 18px;
height: 16px;
margin-right: 7px;
}
// .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;
word-wrap: break-word;
// 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: 180px;
// cursor: pointer;
.unlock-mask {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
background: linear-gradient(to top, rgba(246, 246, 246, 1) 70%, 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;
}
&::-webkit-scrollbar {
width: 0 !important;
}
scrollbar-width: none;
-ms-overflow-style: none;
}
.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;
cursor: pointer;
}
.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;
cursor: pointer;
}
.comments-time {
color: #aaaaaa;
// margin-right: 8px;
margin-right: 10px;
}
.floor-left .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;
margin-right: 10px;
}
}
.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;
min-height: 22px;
cursor: pointer;
.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: 118px;
padding-right: 30px;
}
}
}
.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 {
// width: 373px;
height: 40px;
// background-color: rgba(98, 177, 255, 0.0980392156862745);
border-radius: 150px;
padding: 0 20px;
.item {
cursor: pointer;
color: #aaaaaa;
font-size: 13px;
&:not(:last-of-type) {
margin-right: 40px;
}
.icon {
// width: 16px;
&.h16 {
height: 16px;
}
&.h15 {
height: 15px;
}
&.h8 {
height: 8px;
}
margin-right: 5px;
}
&.operate-item {
position: relative;
display: flex;
justify-content: center;
}
}
}
.floor-middle {
min-width: 247px;
height: 40px;
background-color: rgba(246, 246, 246, 1);
border-radius: 150px;
.coin-content {
padding: 0 20px 0 16px;
height: 100%;
// cursor: pointer;
.coin-icon {
width: 20px;
height: 24px;
margin-right: 5px;
margin-top: -2px;
}
.coin-text {
font-size: 13px;
color: #333333;
.coin-value {
font-family: "Arial-Black", "Arial Black", sans-serif;
font-weight: 900;
margin: 0 5px;
}
}
}
.coin-btn {
width: 80px;
height: 40px;
background-color: rgba(114, 219, 134, 1);
border-radius: 150px;
color: #ffffff;
font-size: 13px;
cursor: pointer;
}
}
.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;
}
.pop-masking {
* {
box-sizing: content-box;
}
width: 100vw;
height: 100vh;
position: fixed;
top: 0;
left: 0;
background: rgba(0, 0, 0, 0.6);
z-index: 10;
.slit-pop-box {
width: 433px;
border: 1px solid #e5e5e5;
background-color: #fff;
border-radius: 20px;
padding: 60px 50px 48px 38px;
display: flex;
-webkit-box-shadow: 0px 0px 15px rgba(0, 0, 0, 0.21);
box-shadow: 0px 0px 15px rgba(0, 0, 0, 0.21);
.slit-left-icon {
width: 50px;
height: 60px;
}
.slit-box {
flex: 1;
margin-left: 15px;
.slit-head {
display: flex;
align-items: center;
justify-content: space-between;
height: 54px;
.slit-head-title {
font-weight: 650;
font-size: 20px;
color: #333;
}
.in-all {
font-size: 13px;
color: #7f7f7f;
font-weight: 400;
& > span {
color: #000;
font-weight: 650;
}
}
}
.coin-quantity {
display: flex;
align-items: center;
margin-bottom: 27px;
margin-top: 20px;
}
.coin-quantity-item {
width: 78px;
height: 46px;
border: 1px solid #d7d7d7;
background-color: #f0f2f5;
border-radius: 5px;
font-size: 20px;
color: #000;
font-weight: 650;
line-height: 46px;
text-align: center;
cursor: pointer;
user-select: none;
& > span {
color: #555;
font-weight: 400;
font-size: 14px;
}
&:not(:last-of-type) {
margin-right: 16px;
}
&.coin-pitch {
background-color: #333333;
border-color: #333333;
color: #fff;
& > span {
color: #fff;
}
}
}
.slit-input {
width: 360px;
height: 38px;
padding-left: 8px;
border: 1px solid #d7d7d7;
outline: none;
border-radius: 8px;
/* 去掉number类型自带的加减按钮 */
overflow: hidden;
&::-webkit-outer-spin-button,
&::-webkit-inner-spin-button {
-webkit-appearance: none;
}
&[type="number"] {
-moz-appearance: textfield;
}
/deep/ .el-input__wrapper {
box-shadow: none;
}
}
.message-box {
display: flex;
flex-direction: column;
.message-hint {
color: #000;
font-size: 14px;
margin-top: 29px;
margin-bottom: 12px;
}
}
.operation {
display: flex;
justify-content: flex-end;
margin-top: 48px;
.operation-item {
width: 120px;
height: 41px;
margin-left: 16px;
font-size: 16px;
color: #000;
border: 1px solid #797979;
border-radius: 45px;
cursor: pointer;
&.greenBj {
color: #fff;
}
}
}
}
}
}
.no-jituobi-pop-box {
width: 520px;
flex-direction: column;
border: 1px solid #e5e5e5;
background-color: #fff;
border-radius: 11px;
display: flex;
-webkit-box-shadow: 0px 0px 15px rgba(0, 0, 0, 0.21);
box-shadow: 0px 0px 15px rgba(0, 0, 0, 0.21);
padding-bottom: 55px;
position: relative;
.no-jituobi-close {
width: 16px;
height: 16px;
cursor: pointer;
position: absolute;
top: 10px;
right: 10px;
}
.no-jituobi-head {
font-size: 15px;
color: #333;
margin: 38px auto 44px;
.bi-icon {
width: 50px;
height: 60px;
}
}
.strategy-btn {
width: 198px;
height: 43px;
color: #fff;
font-size: 16px;
border-radius: 100px;
margin: 0 auto;
cursor: pointer;
.strategy-icon {
width: 16px;
height: 16px;
margin-left: 8px;
}
}
}
.greenBj {
background-color: rgba(114, 219, 134, 1);
border-color: rgba(114, 219, 134, 1) !important;
}
</style>