Files
PC-Light-Forum/details.html
DESKTOP-RQ919RC\Pc c9e229a5cd fix(bi): 添加投币数量必须大于0的校验
feat(item-bottom): 实现二维码弹窗自适应右侧边界
添加判断逻辑使二维码弹窗在靠近右侧边界时向左弹出

refactor(public.js): 优化ajax请求配置和登录跳转逻辑
统一设置axios默认配置,提取登录跳转函数

style(public.css): 调整QRcode-box.right的定位
修复二维码弹窗靠近右侧时的显示问题

fix(details.js): 修复粗体标记正则匹配多行内容
使用[\s\S]*?匹配可能的多行内容

refactor(index.js): 优化列表加载和滚动逻辑
移除模拟数据,添加加载状态,调整滚动加载阈值

chore: 更新html模板中的唯一标识和广告类名
2025-11-19 19:27:43 +08:00

490 lines
33 KiB
HTML
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.

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>版块首页</title>
<link rel="stylesheet" href="./css/public.css" />
<link rel="stylesheet" href="./css/details.css" />
<script src="./js/vue.global.js"></script>
<style>
[v-cloak] {
display: none;
}
</style>
</head>
<body>
<div class="container" id="details" v-cloak>
<div class="templateValue" ref="uniqidRef">uzP1eSyPjvvD</div>
<div class="head-top flexacenter">
<img class="logo" src="https://oss.gter.net/logo" alt="" />
<div class="flex1"></div>
<div class="input-box flexacenter">
<input class="input flex1" type="text" placeholder="大家都在搜:屯特" />
<img class="icon" />
</div>
<div class="post-list flexacenter">
<img class="post-item" src="./img/post-thread.png" />
<img class="post-item" src="./img/post-offer.png" />
<img class="post-item" src="./img/post-summary.png" />
<img class="post-item" src="./img/post-mj.png" />
<img class="post-item" src="./img/post-vote.png" />
</div>
</div>
<div class="head-navigation flexacenter">
<img class="icon" src="./img/index-icon.png" />
<a class="text textA" target="_blank" href="./">首页</a>
<img class="arrows" src="./img/arrows-gray.svg" />
<div class="text one-line-display">{{ info.title || info.content }}</div>
</div>
<div class="matter flexflex">
<div class="matter-left">
<div class="block">
<div class="matter-head flexacenter">
<img class="avatar" :src="authorInfo?.avatar" alt="" />
<div class="content flex1 flexflex">
<div class="name flexacenter" bind:tap="goPersonalHomepage">
<div>{{ authorInfo.nickname || '匿名用户' }}</div>
{{ authorInfo.group?.image }}
<img v-if="authorInfo.group?.image" class="icon" :src="authorInfo.group?.image" />
</div>
<div class="time">{{ timestamp }}</div>
</div>
<div class="operate flexacenter">
<div class="view flexacenter">
<img class="icon" src="./img/eye-icon.svg" />
<div class="text">{{ info.views || 0 }}</div>
</div>
<div class="btn flexcenter" bind:tap="cutShow">
<img class="icon" src="./img/dot-dot-dot-gray.png" />
</div>
</div>
</div>
<div class="label flexflex" v-if="sectionn.length || tags.length || info.recommend == 1 || info.best == 1">
<img class="item icon" v-if="info.recommend == 1 && info.best != 1" src="./img/recommend-icon.png" />
<img class="item icon" v-if="info.best == 1" src="./img/essence-icon.png" />
<div class="item blue" v-for="(item, index) in sectionn" :key="item">{{ item }}</div>
<div class="item" v-for="(item, index) in tags" :key="item">{{ item }}</div>
</div>
<div class="title" v-if="info.title">{{ info.title }}</div>
<div class="html" v-html="info.content"></div>
<div class="last-time">最后编辑:{{ updatedTime || timestamp }}</div>
<div class="action-bar flexacenter">
<div class="action-bar-item flexacenter" @click="likeClick()">
<img v-if="islike" class="icon" src="./img/like-red-icon.png" />
<img v-else class="icon" src="./img/like-black-icon.png" />
<div class="text">{{ info.likes || "赞" }}</div>
</div>
<div class="action-bar-item flexacenter" @click="collectClick()">
<img v-if="iscollect" class="icon" src="./img/collect-golden.svg" />
<img v-else class="icon" src="./img/collect-black-icon.png" />
<div class="text">{{ info.collections || "收藏" }}</div>
</div>
<div class="action-bar-item flexacenter" @click="openDiscuss">
<img class="icon" src="./img/discuss-black-icon.png" />
<div class="text">{{ info.comments || "讨论" }}</div>
</div>
<div class="action-bar-item flexacenter" @click="openCoinBox">
<img class="icon" src="./img/bi-black-icon.png" />
<div class="text">{{ info.coins || "投币" }}</div>
</div>
<div class="action-bar-item flexacenter">
<img class="icon" src="./img/share-black-icon.png" />
<div class="text">转发</div>
</div>
</div>
</div>
<div class="block related" v-if="relatedList.length > 0">
<div class="related-head flexacenter">
<div class="text">相关帖子</div>
<div class="time">Updated by {{ relatedTime }}</div>
</div>
<div class="list flexflex">
<div class="item flexacenter" v-for="item in relatedList" :key="item.id">
<div class="dot"></div>
<div class="text one-line-display">{{ item.title || '无标题' }}</div>
</div>
</div>
</div>
<div class="answer-discuss">
<!-- <el-dialog title="提示" :visible.sync="dialogVisible" width="30%">
<span>确定删除该讨论吗?</span>
<span slot="footer" class="dialog-footer">
<el-button @click="dialogVisible = false">取 消</el-button>
<el-button type="primary" @click="confirmCommentDelete">确 定</el-button>
</span>
</el-dialog> -->
<div v-if="emojiMaskState" class="emoji-box-mask" @click="closeEmoji()"></div>
<!-- 大图 -->
<div class="detail-image-mask flexcenter" v-if="dialogSrc" @click="dialogSrc = ''">
<div class="detail-image flexcenter">
<img class="detail-img" :src="dialogSrc" />
</div>
</div>
<!-- 编辑评论 -->
<div v-if="editCommentState" class="edit-comment flexcenter">
<div class="box">
<div class="text">编辑评论</div>
<div class="input-box">
<div class="top flexflex">
<textarea ref="editInputRef" class="input-textarea flex1" maxlength="500" v-model="editInput" @focus="judgeLogin" @input="autoResize" @paste="handleInputPaste" placeholder="说说你的想法或疑问…"></textarea>
</div>
<div class="picture-box flexacenter" v-if="editPicture.length != 0">
<div class="picture" v-for="(item, index) in editPicture" :key="item.url">
<img class="close" @click="closeEditFileUpload(item.aid)" src="./img/close-icon.png" />
<img class="img" @click="handleAnswerText" :src="item.url" />
</div>
</div>
<div class="bottom flexacenter">
<div class="operate flexacenter">
<div class="item" :class="{ 'pitch': editEmojiState }" style="z-index: 2">
<img class="icon" src="./img/smiling-face.png" @click="openEditEmoji()" alt="" />
<div v-if="editEmojiState" class="emoji-edit-box-mask" @click="closeEditEmoji()"></div>
<div class="emoji-box">
<div class="emoji-icon" v-for="item in emojiData" :key="item" @click="selectEditEmoji(item)">{{ item }}</div>
</div>
</div>
<div class="item flexacenter" @click="handleEditFile()">
<input class="file" type="file" @change="handleFileUpload($event)" accept=".png, .jpg, .jpeg" />
<img class="icon" style="border-radius: 0" src="./img/picture-icon.png" alt="" />
<span class="file-hint">最多可上传1张图片支持在输入框中直接粘贴图片。</span>
</div>
</div>
</div>
</div>
<div class="btn-list flexacenter">
<div class="btn" @click="closeEdit()">取消</div>
<div class="btn send" @click="postEditComment()">发送</div>
</div>
</div>
</div>
<div class="header flexacenter">
讨论
<span class="num">{{ commentTotalCount || "" }}</span>
</div>
<div class="input-box">
<div class="top flexflex">
<img class="avatar" v-if="userInfoWin.avatar" :src="userInfoWin.avatar" />
<textarea ref="input-textarea" class="input-textarea flex1" maxlength="500" @focus="judgeLogin" v-model="inputTextarea" @input="autoResize" @paste="handleInputPaste" placeholder="说说你的看法…"></textarea>
</div>
<div class="picture-box flexacenter" v-if="picture.length != 0">
<div class="picture" v-for="(item, index) in picture" :key="index">
<img class="close" @click="closePictureUpload(index)" src="./img/close-icon.png" />
<img class="img" @click="handleAnswerText" :src="item.url" />
</div>
</div>
<div class="bottom flexacenter">
<div class="operate flexacenter">
<div class="item" :class="{ 'pitch': emojiState }" style="z-index: 2">
<img class="icon" src="./img/smiling-face.png" @click="openEmoji()" alt="" />
<div class="emoji-box">
<div class="emoji-icon" v-for="item in emojiData" :key="item" @click="selectEmoji(item)">{{ item }}</div>
</div>
</div>
<div class="item flexacenter" @click="judgeLogin()">
<input class="file" type="file" @change="handleFileUpload($event)" accept=".png, .jpg, .jpeg" />
<img class="icon" style="border-radius: 0" src="./img/picture-icon.png" />
<span class="file-hint">最多可上传1张图片支持在输入框中直接粘贴图片。</span>
</div>
</div>
<div class="btn" @click="submitAnswerComments()">发送</div>
</div>
</div>
<div class="comments-box" v-if="commentTotalCount != 0">
<div class="comments-item" v-for="(item, index) in commentList" :key="index">
<div class="comments-header flexacenter">
<div class="comments-header-left flexacenter">
<img class="comments-avatar" @click="openUserInfo(index)" :src="item.avatar || item.user['avatar']" />
<div class="comments-username" @click="openUserInfo(index)">{{ item.nickname || item.user["nickname"] || "匿名用户" }}</div>
<div class="comments-time">{{ item["timestamp"] }}</div>
<div class="comments-identity" v-if="item['isauthor'] == 1">作者</div>
<img class="comments-title" v-if="item.groupimage || item?.user?.groupimage" :src="item.groupimage || item?.user?.groupimage" :alt="item?.user?.grouptitle" style="height: 18px" />
<div class="avatar-box flexflex" v-if="item['avatarState']">
<a class="avatar-item flexcenter" target="_blank" @click.prevent="sendMessage(item.uin || item.user['uin'])">
<img class="avatar-icon" src="./img/send-messages-icon.png" />
发送信息
</a>
<a class="avatar-item flexcenter" target="_blank" @click.prevent="TAHomePage(item.uin || item.user['uin'])">
<img class="avatar-icon" src="./img/homepage-icon.png" />
TA的主页
</a>
<div class="avatar-mask" @click="closeUserInfo(index)"></div>
</div>
</div>
<div class="comments-header-right flexacenter">
<div class="menu-box flexacenter">
<img class="menu-icon" src="./img/menu-icon-gray.svg" />
<!-- <div class="report-box flexcenter">举报</div> -->
<div class="operate-box">
<div class="item flexcenter" @click="commentReport(item['token'])">举报</div>
<div class="item flexcenter" v-if="permissions.includes('comment.edit')" @click="openEdit(item['token'], index)">编辑</div>
<div class="item flexcenter" v-if="permissions.includes('comment.delete')" @click="commentDelete(item['token'], index)">删除</div>
</div>
</div>
<img class="comment-icon" @click="openAnswerCommentsChild(index)" src="./img/comment-icon-gray.svg" />
<div class="flexacenter like-box" @click="operateAnswerCommentsLike(item.token, index)">
<img class="like-icon" v-if="item['islike'] == 0" src="./img/like-icon-gray.png" />
<img class="like-icon" v-else src="./img/like-red-pitch.png" />
<div class="like-quantity">{{ item["likenum"] || "" }}</div>
</div>
</div>
</div>
<div class="comments-content">
<div class="comments-text" v-if="item['content']" v-html="item['content']"></div>
<div class="comments-img-box">
<img class="comments-img" v-for="(item, index) in item.attachments.images" @click="handleAnswerText" :src="item.thumb || item.url" />
</div>
<div class="input-box" v-if="item['childState']">
<img class="cross" @click="closeAnswerCommentsChild(index)" src="./img/cross-icon.png" />
<div class="top flexflex">
<textarea class="input-textarea flex1" maxlength="500" placeholder="说说你的看法…" @focus="judgeLogin" v-model="item['commentInput']" @input="autoResize" @paste="handleInputPaste($event, index)"></textarea>
</div>
<div class="picture-box flexacenter" v-if="item?.picture?.length != 0">
<div class="picture" v-for="it in item.picture" :key="it.url">
<img class="close" @click="closeFileUpload(it.aid, index)" src="./img/close-icon.png" />
<img class="img" @click="handleAnswerText" :src="it.url" />
</div>
</div>
<div class="bottom flexacenter">
<div class="operate flexacenter">
<div class="item" :class="{ 'pitch': item.emojiState }" style="z-index: 2">
<img class="icon" src="./img/smiling-face.png" @click="openEmoji(index)" alt="" />
<div class="emoji-box">
<div class="emoji-icon" v-for="item in emojiData" :key="item" @click="selectEmoji(item, index)">{{ item }}</div>
</div>
</div>
<div class="item flexacenter" @click="judgeLogin()">
<input class="file" type="file" @change="handleFileUpload($event, index)" accept=".png, .jpg, .jpeg" />
<img class="icon" style="border-radius: 0" src="./img/picture-icon.png" />
<span class="file-hint">最多可上传1张图片支持在输入框中直接粘贴图片。</span>
</div>
</div>
<div class="btn" @click="submitAnswerComments(index)">发送</div>
</div>
</div>
</div>
<div class="child-comments" v-if="item['child'].length != 0">
<div class="comments-item" v-for="(ite, i) in item['child']" :key="ite.id">
<div class="comments-header flexacenter">
<div class="comments-header-left flexacenter">
<img class="comments-avatar" @click="openUserInfo(index, i)" :src="ite.avatar || ite.user['avatar']" />
<div class="comments-username" @click="openUserInfo(index, i)">{{ ite.nickname || ite.user["nickname"] || "匿名用户" }}</div>
<div class="comments-time">{{ ite["timestamp"] }}</div>
<div class="comments-identity" v-if="ite['isauthor'] == 1">作者</div>
<img class="comments-title" v-if="ite.groupimage || ite.user?.groupimage" :src="ite.groupimage || ite.user?.groupimage" :alt="ite?.user?.grouptitle" style="height: 18px" />
<div class="avatar-box flexflex" v-if="ite['avatarState']">
<a class="avatar-item flexcenter" target="_blank" @click.prevent="sendMessage(ite.uin || ite.user['uin'])">
<img class="avatar-icon" src="./img/send-messages-icon.png" />
发送信息
</a>
<a class="avatar-item flexcenter" target="_blank" @click.prevent="TAHomePage(ite.uin || ite.user['uin'])">
<img class="avatar-icon" src="./img/homepage-icon.png" />
TA的主页
</a>
<div class="avatar-mask" @click="closeUserInfo(index, i)"></div>
</div>
</div>
<div class="comments-header-right flexacenter">
<div class="menu-box flexacenter">
<img class="menu-icon" src="./img/menu-icon-gray.svg" />
<div class="operate-box">
<div class="item flexcenter" @click="commentReport(ite['token'])">举报</div>
<div class="item flexcenter" v-if="permissions.includes('comment.edit')" @click="openEdit(ite['token'], index, i)">编辑</div>
<div class="item flexcenter" v-if="permissions.includes('comment.delete')" @click="commentDelete(ite['token'], index, i)">删除</div>
</div>
</div>
<img class="comment-icon" @click="openAnswerCommentsChild(index, i)" src="./img/comment-icon-gray.svg" />
<div class="flexacenter like-box" @click="operateAnswerCommentsLike(ite.token, index, i)">
<img class="like-icon" v-if="ite['islike'] == 0" src="./img/like-icon-gray.png" />
<img class="like-icon" v-else src="./img/like-red-pitch.png" />
<div class="like-quantity">{{ ite["likenum"] || "" }}</div>
</div>
</div>
</div>
<div class="comments-content">
<div class="comments-text" v-if="ite['content']">
<div class="comments-reply" v-if="ite?.reply?.nickname">@{{ ite["reply"]["nickname"] || "匿名用户" }}</div>
<span v-html="ite['content']"></span>
</div>
<div class="comments-img-box">
<img class="comments-img" v-for="(item, index) in ite.attachments.images" @click="handleAnswerText" :src="item.thumb || item.url" />
</div>
<div class="input-box" v-if="ite['childState']">
<img class="cross" @click="closeAnswerCommentsChild(index)" src="./img/cross-icon.png" />
<div class="top flexflex">
<textarea class="input-textarea flex1" maxlength="500" v-model="ite['commentInput']" @focus="judgeLogin" :placeholder="'回复“' + (ite.nickname || ite.user['nickname'] || '匿名用户') + '”:'" @input="autoResize" @paste="handleInputPaste($event, index, i)"></textarea>
</div>
<div class="picture-box flexacenter" v-if="ite.picture?.length != 0">
<div class="picture" v-for="it in ite.picture" :key="it.url">
<img class="close" @click="closeFileUpload(it.aid, index, i)" src="./img/close-icon.png" />
<img class="img" @click="handleAnswerText" :src="it.url" />
</div>
</div>
<div class="bottom flexacenter">
<div class="operate flexacenter">
<div class="item" :class="{ 'pitch': ite.emojiState }" style="z-index: 2">
<img class="icon" src="./img/smiling-face.png" @click="openEmoji(index, i)" alt="" />
<div class="emoji-box">
<div class="emoji-icon" v-for="item in emojiData" :key="item" @click="selectEmoji(item, index, i)">{{ item }}</div>
</div>
</div>
<div class="item flexacenter" @click="judgeLogin()">
<input class="file" type="file" @change="handleFileUpload($event, index, i)" accept=".png, .jpg, .jpeg" />
<img class="icon" style="border-radius: 0" src="./img/picture-icon.png" />
<span class="file-hint">最多可上传1张图片支持在输入框中直接粘贴图片。</span>
</div>
</div>
<div class="btn" @click="submitAnswerComments(index, i)">发送</div>
</div>
</div>
</div>
</div>
<div class="comments-also flexacenter" v-if="item['childnum'] > item['child'].length" @click="alsoCommentsData(index, i)">
<div class>还有{{ item["childnum"] - item.child.length }}条回复</div>
<img class="also-icon" src="./img/arrow-circular-gray.png" />
</div>
</div>
</div>
</div>
<div class="no-discussion-box flexcenter" v-else>
<img src="./img/no-discussion.png" class="no-discussion-icon" />
<div class="no-discussion-text">缺少你的留言,我的世界是黑白的</div>
</div>
</div>
</div>
<div class="sidebar-box">
<a class="adv">
<img class="adv-img" src="https://o.x-php.com/bbs/common/cf/1709075xdbbbvjd8cbxvdd.jpg" />
</a>
<div class="sidebar-item">
<div class="sidebar-header">手机查看该帖子</div>
<div class="sidebar-content flexcenter">
<img src="https://o.x-php.com/qrcode/eunKLTiKLX4O" class="sidebar-QRCode" />
<div class="hint flexacenter">
<img class="saoma-icon" src="./img/u161.png" />
微信扫一扫
</div>
</div>
</div>
<div class="sidebar-item">
<div class="sidebar-header">关于作者</div>
<div class="sidebar-content flexcenter">
<div class="author-box flexacenter">
<img class="avatar" :src="authorInfo?.avatar" alt="" />
<div class="author-content">
<div class="author-name flexacenter">
{{ authorInfo.nickname || '匿名用户' }}
<img v-if="authorInfo.group?.image" class="group" :src="authorInfo.group?.image" />
</div>
<div class="author-info flexacenter">
<div class="amount">{{ count }}</div>
个创作,获得
<div class="amount">100</div>
个赞
</div>
</div>
</div>
<div class="medal" v-if="medal.length > 0">
<div class="medal-title">勋章 {{ medal.length }}</div>
<div class="medal-list flexflex">
<img class="medal-item" v-for="item in medal" :key="item" :src="item.image" alt="" />
</div>
</div>
<div class="recently" v-if="recentlyList.length > 0">
<div class="recently-title">最近发布</div>
<div class="recently-list flexflex">
<div v-for="item in recentlyList" :key="item" class="recently-item one-line-display flexacenter">
<div class="dot"></div>
<div class="text one-line-display flex1">{{ item.title || '无标题' }}</div>
</div>
</div>
</div>
</div>
</div>
<latest-list></latest-list>
<slideshow-box></slideshow-box>
</div>
</div>
<div class="coins-area flexcenter" v-if="coinsState">
<div class="coins-box flexcenter">
<img class="fork" @click="closeCoinBox" src="./img/fork-icon.png" />
<div class="coins-head flexacenter">
<img class="icon" src="./img/bi-icon.png" />
<div class="text flexacenter">
该帖子已获得
<div class="sum">{{ info.coins }}</div>
个寄托币
</div>
</div>
<div class="coins-input flexacenter">
<input class="input flex1" type="number" placeholder="输入投币数" v-model="coinAmount" />
<div class="btn" @click="coinSubmit">投币</div>
</div>
<div class="coins-info flexacenter">
<img class="icon" src="./img/bi-black-icon.png" />
你当前共有
<div class="sum">{{ mybalance }}</div>
寄托币
<a class="strategy" target="_blank" :href="strategy">[挣币攻略]</a>
</div>
<div class="coins-list-area flexflex" v-if="coinList.length != 0">
<div class="coins-total flexacenter">
<div class="sum">{{ coinNubmer }}</div>
人参与投币:
</div>
<div class="list flex1">
<div class="item flexacenter" v-for="(item,index) in coinList" :key="index">
<div class="serial">{{ item.rank }}</div>
<div class="user flex1 flexacenter">
<img class="avatar" :src="item.user.avatar" alt="" />
<div class="username one-line-display flex1">{{ item.user.nickname || '匿名用户' }}</div>
</div>
<div class="amount flexacenter">
{{ item.coins }}
<div class="text"></div>
</div>
</div>
</div>
</div>
</div>
</div>
<like v-if="isLikeGif"></like>
</div>
<script src="./js/axios.min.js"></script>
<script src="./js/public.js"></script>
<script type="module" src="./js/details.js"></script>
</body>
</html>