// shared_cjs_prodExports.hasOwn; <!-- 新增的回答款需要输入图片 --> <template> <div id="append_parent"></div> <div id="ajaxwaitid"></div> <div> <Head> <Title>{{ `${seo["title"] || "问答"} - 寄托天下出国留学网` }}</Title> <Meta name="keyword" :content="seo['keyword']" /> <Meta name="description" :content="seo['description']" /> </Head> <div class id="answer-app"> <header class="flexacenter" id="pageHeader"> <div class="flexacenter top"> <a href="./index.html"> <img class="logo" @click="handleLogo" alt="寄托问答" src="./img/logo.png" /> </a> <div class="right flexacenter flex1"> <div class="searchInput flexacenter"> <input class="input flex1" placeholder="输入搜索关键词" v-model="keyword" @keydown.enter="searchClick()" @focus="searchFocus" @blur="searchBlur" /> <div class="clear-search flexacenter" v-if="isSearchMode"> <img class="cross-circle-black" @click="handleClickClear()" src="./img/cross-circle-black.png" /> <div class="halving-line"></div> </div> <img class="input-icon" src="./img/input-icon.png" @click="searchClick()" /> <div class="history-box" v-if="historicalSearchState" @click.stop> <div class="history-title">历史搜索</div> <div class="history-list"> <div class="history-item ellipsis" v-for="(item, index) in historicalSearchList" :key="index" @click.stop="handleClickHistoricalItem(item)">{{ item }}</div> </div> </div> </div> <div class="btn-list flexacenter"> <div class="item flex1" @click="handleMy('collect')">我的收藏</div> <div class="item flex1" @click="handleMy('questions')">我的提问</div> <!-- <div class="item flex1" @click="handleMy('answers')">我的回答</div> --> </div> <div class="add-btn flexcenter" @click="questionsInit()"> <img class="add-icon" src="./img/add-icon.svg" /> 我要提问 </div> </div> </div> <div class="tab-box flexcenter" :class="{ 'tab-list-fixed': tabListFixeState }"> <div class="tab-list flexacenter"> <!-- <div class="item flexcenter" :class="{ pitch: typePitch == null }" @click="cutType(null)">All</div> --> <template v-for="(item, index) in typeList" :key="index"> <div v-if="index !== 0" class="halving-line">|</div> <div class="item flexcenter" :class="{ pitch: typePitch == it['id'] }" v-for="it in item" :key="it" @click="cutType(it.id)">{{ it["name"] }}</div> </template> </div> </div> </header> <div class="main flexflex" :class="{ 'mode-list': type == 'list' }"> <div class="list-box" @scroll="handleListScroll" :style="{ paddingRight: type == 'list' ? 0 : '15px' }"> <div class="main-header" :style="{ paddingLeft: type == 'list' ? 0 : 'calc((100vw - 1210px) / 2)' }"> <div class="flexacenter"> <template v-if="myModelState"> <div class="search-keyword flexacenter" @click="closeMyModel()"> <div class="ellipsis">我的收藏/提问</div> <img class="search-keyword-cross" src="./img/cross-circle-icon.png" /> </div> </template> <template v-else-if="isSearchMode"> <div class="search-keyword flexacenter" @click="handleClickClear()"> <div class="ellipsis">{{ keywordText }}</div> <img class="search-keyword-cross" src="./img/cross-circle-icon.png" /> </div> <div class="total grid-item" @click="cut">共 {{ total }} 条搜索结果</div> </template> <div v-else class="total grid-item" @click="cut">共 {{ total }} 条问答</div> </div> <!-- <div class="look-only flexcenter" v-if="type != 'details'" @click="handleLookOnly"> <img class="look-icon" v-if="zeroreply == 0" src="@/img/tick-no.svg" /> <img class="look-icon" v-else src="@/img/tick-option.svg" /> 只看0回答 </div> --> </div> <div class="list" id="list" :style="[listStyle(), { height: listHeight + 'px' }]"> <template v-for="(item, index) in list" :key="item.uniqid"> <a v-if="item['isrecom'] && type != 'list'" class="item grid-item flexflex" :style="itemStyle(index, item['content'], item['type'])" :class="{ pitch: index === pitchIndex, upLevel: index === pitchIndex - 1 }" target="_blank" :href="item['url']"> <!-- <a v-if="item['isrecom']" class="item grid-item flexflex" :style="itemStyle(index, item['content'], item['type'])" :class="{ pitch: index === pitchIndex, upLevel: index === pitchIndex - 1 }" target="_blank" :href="item['url']"> --> <img class="dot" src="./img/dot.svg" /> <div class="content" :style="{ width: type == 'list' ? '531px' : '430px' }"> <div class="issue-title flexcenter"> <div class="recommend flexcenter">推荐阅读</div> <div class="issue ellipsis flex1">{{ item["title"] }}</div> </div> <template v-if="item['type'] == 'thread'"> <div class="answer ellipsis" v-if="item['message']">{{ item["message"] }}</div> </template> <div class="answer" style="height: auto" v-else-if="item['type'] == 'vote'"> <div v-for="(ite, i) in item['option'].slice(0, 2)" :key="i">{{ replaceNumberObj[i] + ite }}</div> <div>{{ replaceNumberObj[2] }} …</div> </div> <template v-else> <div class="answer ellipsis flexacenter"> <div class="value-value" v-if="item['profession'] || item['professional']">{{ item["profession"] || item["professional"] }}</div> <div class="value-value" v-if="item['project'] || item['degree']">{{ item["project"] || item["degree"] }}</div> <div class="value-value" v-if="item['interviewtime'] || item['semester']">{{ item["interviewtime"] || item["semester"] }}</div> <div class="value-value" v-if="item['apply_results']">{{ item["apply_results"] }}</div> </div> </template> <div class="bottom flexacenter"> <div class="typename flexcenter">{{ item["typename"] }}</div> </div> </div> </a> <a v-else class="item grid-item flexflex" :style="itemStyle(index, item['content'])" :class="[{ pitch: index === pitchIndex, upLevel: index === pitchIndex - 1 }, `item${index}`]" :href="setItemUrl(item['uniqid'])" @click.stop.prevent="getDetails(item['uniqid'], index)"> <img class="dot" src="./img/dot.svg" /> <div class="content" :style="{ width: type == 'list' ? '531px' : '430px' }"> <div class="issue-title flexcenter"> <img class="hot-icon" v-if="item['ishot'] == 1" src="./img/hot-icon.png" /> <div class="issue ellipsis flex1">{{ item["title"] }}</div> </div> <div class="answer ellipsis" v-if="item['content']">{{ item["content"] }}</div> <div class="bottom flexacenter"> <div class="typename flexcenter" v-if="item['typename']">{{ item["typename"] }}</div> <div v-else></div> <div class="flexacenter"> <div class="quantity">{{ handleDate(item.publicationdate, false) }}提问</div> <div class="amount flexacenter"> <img class="amount-icon" src="/img/comment-icon-gray.svg" alt="" /> {{ item.answers }} </div> <!-- <div class="longString"></div> <div class="quantity">{{ item["answers"] == 0 ? "暂无回答" : "共" + item["answers"] + "个回答" }}</div> <template v-if="type == 'list'"> <div class="longString"></div> <div class="answer-btn" @click.stop.prevent="openListIAnswer(index)">我来回答</div> </template> --> </div> </div> </div> </a> </template> </div> <div class="bottom-tps" :style="bottomTpsStyle()" v-if="inTheEndState">- 到底了 -</div> <div class="bottom-tps" :style="bottomTpsStyle()" v-if="myModelState"></div> <div class="empty-box flexcenter" v-if="isListEmptyState && list.length == 0"> <div class="dot-list flexacenter"> <img class="item" src="./img/dot-yellow.svg" /> <img class="item" src="./img/dot-yellow.svg" /> <img class="item" src="./img/dot-yellow.svg" /> <img class="item" src="./img/dot-gray.svg" /> <img class="item" src="./img/dot-gray.svg" /> <img class="item" src="./img/dot-gray.svg" /> </div> <img class="empty-icon" src="./img/empty-icon.png" /> <div class="empty-hint" v-if="isSearchMode">没有找到相关结果,请更换搜索关键词</div> <div class="empty-hint" v-else>暂无数据</div> </div> </div> <div class="details-area-box flexflex" v-if="type == 'details'" @scroll="handleDetailsScroll"> <div class="details-box flexflex"> <!-- 加载 --> <div class="loading-bj flexcenter" v-if="detailLoading"> <svg t="1642133548066" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="2597" width="200" height="200"> <path d="M512 249.5c-22.5 0-37.5-15-37.5-37.5V99.5c0-22.5 15-37.5 37.5-37.5s37.5 15 37.5 37.5V212c0 22.5-15 37.5-37.5 37.5z m0 712.5c-22.5 0-37.5-15-37.5-37.5V812c0-22.5 15-37.5 37.5-37.5s37.5 15 37.5 37.5v112.5c0 22.5-15 37.5-37.5 37.5zM212 549.5H99.5C77 549.5 62 534.5 62 512s15-37.5 37.5-37.5H212c22.5 0 37.5 15 37.5 37.5s-15 37.5-37.5 37.5z m712.5 0H812c-22.5 0-37.5-15-37.5-37.5s15-37.5 37.5-37.5h112.5c22.5 0 37.5 15 37.5 37.5s-15 37.5-37.5 37.5z m-153.75-150c-11.25 0-26.25-7.5-33.75-18.75-11.25-18.75-3.75-41.25 15-52.5L849.5 272c18.75-11.25 41.25-3.75 52.5 15s3.75 41.25-15 52.5l-97.5 56.25c-3.75 3.75-11.25 3.75-18.75 3.75z m-615 356.25c-11.25 0-26.25-7.5-33.75-18.75-11.25-18.75-3.75-41.25 15-52.5l97.5-56.25c18.75-11.25 41.25-3.75 52.5 15s3.75 41.25-15 52.5L174.5 752c-7.5 3.75-15 3.75-18.75 3.75z m506.25-465c-7.5 0-11.25 0-18.75-3.75-18.75-11.25-22.5-33.75-15-52.5L684.5 137c11.25-18.75 33.75-22.5 52.5-15 18.75 11.25 22.5 33.75 15 52.5L695.75 272c-7.5 11.25-22.5 18.75-33.75 18.75z m-356.25 615c-7.5 0-11.25 0-18.75-3.75-18.75-11.25-22.5-33.75-15-52.5l56.25-97.5c11.25-15 33.75-22.5 52.5-11.25s22.5 33.75 15 52.5L339.5 887c-7.5 11.25-22.5 18.75-33.75 18.75z m-52.5-506.25c-7.5 0-15 0-18.75-3.75L137 339.5c-18.75-11.25-26.25-33.75-15-52.5s33.75-22.5 52.5-15l97.5 56.25c18.75 11.25 22.5 33.75 11.25 52.5-3.75 11.25-18.75 18.75-30 18.75z m615 356.25c-7.5 0-11.25 0-18.75-3.75L752 695.75c-18.75-11.25-22.5-33.75-15-52.5 11.25-18.75 33.75-22.5 52.5-15L887 684.5c18.75 11.25 22.5 33.75 15 52.5-7.5 11.25-18.75 18.75-33.75 18.75zM362 290.75c-11.25 0-26.25-7.5-33.75-18.75L272 174.5c-7.5-18.75-3.75-41.25 15-52.5s41.25-3.75 52.5 15l56.25 97.5c7.5 18.75 3.75 41.25-15 48.75-7.5 3.75-11.25 7.5-18.75 7.5z m356.25 615c-11.25 0-26.25-7.5-33.75-18.75l-56.25-97.5c-11.25-18.75-3.75-41.25 15-52.5s41.25-3.75 52.5 15L752 849.5c11.25 18.75 3.75 41.25-15 52.5-7.5 3.75-11.25 3.75-18.75 3.75z" p-id="2598" fill="#26d79f" /> </svg> </div> <div v-if="emojiMaskState" class="emoji-box-mask" @click="closeEmojiMask()"></div> <div class="close-box"> <div class="close-circle flexcenter" @click="closeDetailMode()"> <img class="close-icon" src="./img/close-icon.svg" /> <img class="details-cross-icon" src="./img/cross-icon.png" /> </div> </div> <!-- 提问信息 --> <div class="details-issue"> <!-- <div class="icon q flexcenter">Q</div> --> <!-- <img class="qq" src="@/img/Q.png" /> --> <div class="label" v-if="detailsInfo.typename">{{ detailsInfo.typename }}</div> <div class="titletitle">{{ detailsInfo["title"] }}</div> <div class="hint" @click="handleAnswerText" v-if="detailsInfo['content']" v-html="detailsInfo['content']"></div> <div class="info-box flexacenter"> <div class="user-info flexacenter" @click="openUserInfo()"> <img class="avatar" v-if="detailsInfo['avatar']" :src="detailsInfo['avatar']" /> <div class="user-name">{{ detailsInfo["nickname"] }}</div> <div class="avatar-box flexflex" v-if="avatarState"> <a class="avatar-item flexcenter" target="_blank" @click.prevent="sendMessage(detailsInfo['uin'])"> <img class="avatar-icon" src="@/img/send-messages-icon.png" /> 发送信息 </a> <a class="avatar-item flexcenter" target="_blank" @click.prevent="TAHomePage(detailsInfo['uin'])"> <img class="avatar-icon" src="@/img/homepage-icon.png" /> TA的主页 </a> <div class="avatar-mask"></div> </div> <div class="time">{{ handleDate(detailsInfo["publicationdate"]) }}</div> </div> <div class="operate-item flexacenter" style="cursor: auto"> <img class="operate-icon operate-collect-icon" style="width: 13px; height: 8px" src="./img/view-icon.svg" /> {{ detailsInfo["viewnum"] || 0 }} </div> </div> <div class="operate-box flexacenter"> <div class="operate-list flexacenter"> <div class="operate-item flexacenter" @click="operateLike()"> <img class="operate-icon operate-like-icon" v-if="islike == 0" src="/img/like-icon.png" /> <img class="operate-icon operate-like-icon" v-else src="/img/like-icon-colours.png" /> {{ detailsInfo.likenum || "赞" }} </div> <ClientOnly> <div class="operate-item flexacenter" @click="operateCollect()"> <img class="operate-icon operate-collect-icon" v-if="detailsIscollection == 0" src="./img/collect-icon.png" /> <img class="operate-icon operate-collect-icon" v-else src="./img/collect-icon-colours.svg" /> {{ detailsInfo["collectionnum"] > 0 ? detailsInfo["collectionnum"] : "收藏" }} </div> </ClientOnly> <div class="operate-item flexacenter operate-transmit" @mouseenter.stop="closeTransmitState()" @mouseleave.stop="closeAllTransmitState()"> <img class="operate-icon operate-transmit-icon" src="./img/transmit-icon.png" /> 转发 <div class="transmit-box flexflex" v-if="questionsTransmitState" @click.stop style="z-index: 10"> <img class="cross-icon" @click.stop="closeAllTransmitState()" src="./img/cross-icon.png" /> <div class="transmit-left transmit-web"> <div class="transmit-title">转发网页版</div> <div class="transmit-content"> <div class="transmit-headline">{{ detailsInfo["title"] }}</div> <div class="transmit-url">{{ getCurrentUrl() }}</div> </div> <div class="transmit-web-btn flexcenter" @click="copyText(detailsInfo['title'] + getCurrentUrl())">复制链接</div> </div> <div class="transmit-right transmit-mini"> <div class="transmit-title">转发小程序版</div> <div class="transmit-content flexcenter"> <img class="transmit-mini-img" :src="detailShare['qrcode']" /> <div class="flexcenter"> <img class="give-sweep" src="./img/give-sweep.png" /> 扫码转发该问答 </div> </div> </div> </div> </div> </div> </div> </div> <commentList ref="commentListRef" v-if="isCommentList" @updateAnswers="handleUpdateAnswers"></commentList> <div class="mobile-phone-check flexcenter"> <img class="QRCode-icon" src="./img/QRCode-icon.svg" alt /> 手机查看该问答 <div class="QRCode-pop flexcenter"> <img class="offer-mini-QRcode" :src="detailShare['qrcode']" /> <div class="QRCode-hint flexacenter"> <img class="QRCode-img" src="./img/give-sweep.png" /> 微信扫一扫 </div> </div> </div> </div> </div> </div> <!-- 我的弹窗 --> <div class="popover-mask my-popover flexcenter" v-if="myType"> <div class="popover-box flexflex"> <img class="cross-icon" src="./img/cross-icon.png" @click="myType = ''" /> <div class="tab-list flexcenter"> <div class="tab-item flexacenter" :class="{ pitch: myType == 'collect' }" @click="handleMy('collect')"> 我的收藏 <div class="quantity">{{ myCollectionCount || myCount["collect"] || 0 }}</div> </div> <div class="long-string"></div> <div class="tab-item flexacenter" :class="{ pitch: myType == 'questions' }" @click="handleMy('questions')"> 我的提问 <div class="quantity">{{ myQuestionsCount || myCount["questions"] || 0 }}</div> </div> <!-- <div class="long-string"></div> <div class="tab-item flexacenter" :class="{ pitch: myType == 'answers' }" @click="handleMy('answers')"> 我的回答 <div class="quantity">{{ myAnswerCount || myCount["answer"] || 0 }}</div> </div> --> </div> <div class="empty-box flexcenter" v-if="(myType == 'collect' && myCollectionList.length == 0) || (myType == 'answers' && myAnswerList.length == 0) || (myType == 'questions' && myQuestionsList.length == 0)"> <div class="dot-list flexacenter"> <img class="item" src="./img/dot-yellow.svg" /> <img class="item" src="./img/dot-yellow.svg" /> <img class="item" src="./img/dot-yellow.svg" /> <img class="item" src="./img/dot-gray.svg" /> <img class="item" src="./img/dot-gray.svg" /> <img class="item" src="./img/dot-gray.svg" /> </div> <img class="empty-icon" src="./img/empty-icon.png" /> <div class="empty-hint">暂无内容</div> </div> <div class="content-box collect-list" v-if="myType == 'collect' && myCollectionList.length != 0" @scroll="handleCollectionScroll"> <div class="item flexflex" v-for="(item, index) in myCollectionList" :key="item" @click.stop="myOpenDetails(item.data['uniqid'])"> <template v-if="item.type == 'askanswercollection'"> <div class="icon a flexcenter">A</div> <div class="centre flexflex flex1"> <div class="titletitle ellipsis" v-html="item['data']['content']"></div> <div class="text ellipsis">提问:{{ item["data"]["title"] }}</div> </div> <div class="delete-box flexacenter"> <img class="delete-icon" @click.stop="cancelCollection(item['token'], index)" src="./img/delete-icon.png" /> </div> </template> <template v-else> <div class="icon q flexcenter">Q</div> <div class="centre flexflex flex1"> <div class="titletitle ellipsis">{{ item["data"]["title"] }}</div> <div class="text ellipsis"> {{ item["data"]["answers"] > 0 ? "共" + item["data"]["answers"] + "个回答&讨论" : "暂无回答&讨论" }} </div> </div> <div class="delete-box flexacenter"> <img class="delete-icon" @click.stop="cancelCollection(item['token'], index)" src="./img/delete-icon.png" /> </div> </template> </div> </div> <div class="content-box answers-list" v-if="myType == 'answers' && myAnswerList.length != 0" @scroll="handleAnswersScroll"> <div class="item flexflex" v-for="(item, index) in myAnswerList" :key="item" @click.stop="myOpenDetails(item['uniqid'])"> <div class="icon a flexcenter">A</div> <div class="centre flexflex flex1"> <div class="info flexacenter"> <div class="name">{{ item["nickname"] }}</div> <div class="time">{{ handleDate(item["publicationdate"]) }}</div> </div> <div class="titletitle ellipsis" v-html="item['content']"></div> <div class="text ellipsis">提问:{{ item["title"] }}</div> </div> <div class="operate-box flexacenter"> <div class="state-box flexacenter" @click.stop="cutAnswerPopupState(index)"> <div class="text">{{ item["anonymous"] == 0 ? "公开" : "匿名" }}</div> <img class="arrows" src="./img/arrows-icon.svg" /> <div class="state-popup flexflex" v-if="item['popupState']"> <!-- <div class="state-popup-mask" @click.stop="cutAnswerPopupState(index)"></div> --> <div class="state-popup-item flexacenter flex1" :class="{ pitch: item['anonymous'] == 0 }" @click.stop="changeAnonymous(item['token'], 0, index)"> <div class>公开发表</div> <img class="state-popup-icon" src="./img/tick-orange.svg" /> </div> <div class="state-popup-item flexacenter flex1" :class="{ pitch: item['anonymous'] == 1 }" @click.stop="changeAnonymous(item['token'], 1, index)"> <div class>匿名发表</div> <img class="state-popup-icon" src="./img/tick-orange.svg" /> </div> </div> </div> <img class="edit-icon" @click.stop="openIAnswer(index, 'my')" src="./img/edit-icon.png" /> </div> </div> </div> <div class="content-box questions-list" v-if="myType == 'questions' && myQuestionsList.length != 0" @scroll="handleQuestionsScroll"> <div class="item flexflex" v-for="(item, index) in myQuestionsList" :key="item" @click.stop="myOpenDetails(item['uniqid'])"> <div class="icon q flexcenter">Q</div> <div class="centre flexflex flex1"> <div class="info flexacenter"> <div class="name">{{ item["nickname"] }}</div> <div class="time">{{ handleDate(item["publicationdate"]) }}</div> </div> <div class="titletitle ellipsis">{{ item["title"] }}</div> <div class="text flexacenter"> <div class="new-answer flexacenter" v-if="item['authornewnum'] > 0"> 有{{ item["authornewnum"] }}个新回答&讨论 <div class="long-string"></div> </div> {{ item["answers"] == 0 ? "暂无回答&讨论" : "共" + item["answers"] + "个回答&讨论" }} </div> </div> <div class="operate-box flexacenter"> <div class="state-box flexacenter" @click.stop="cutQuestionsPopupState(index)"> <div class="text">{{ item["anonymous"] == 0 ? "公开" : "匿名" }}</div> <img class="arrows" src="./img/arrows-icon.svg" /> <div class="state-popup flexflex" v-if="item['popupState']"> <div class="state-popup-item flexacenter flex1" :class="{ pitch: item['anonymous'] == 0 }" @click.stop="changeAnonymousQuestions(item['token'], 0, index)"> <div class>公开发表</div> <img class="state-popup-icon" src="./img/tick-orange.svg" /> </div> <div class="state-popup-item flexacenter flex1" :class="{ pitch: item['anonymous'] == 1 }" @click.stop="changeAnonymousQuestions(item['token'], 1, index)"> <div class>匿名发表</div> <img class="state-popup-icon" src="./img/tick-orange.svg" /> </div> </div> </div> </div> </div> </div> </div> </div> <!-- 我要提问 --> <div class="popover-mask flexcenter issue-box" v-if="questionsSetp" @click="cutQuestionsSetp(0)"> <!-- 第一步 --> <div class="choosing-theme" v-if="questionsSetp == 1" @click.stop> <div class="titletitle">选择提问所属主题</div> <div class="theme-list flexflex"> <div class="theme-stair-box flexflex" v-for="(item, index) in questionsTypeList" :key="index"> <div class="theme-item flexcenter" v-for="item in item" :key="item.id" @click="choosingTheme(item.id)">{{ item.name }}</div> </div> </div> </div> <!-- 第二步 --> <div class="issue-form" v-else @click.stop> <div class="issue-bj"> <svg version="1.1" xmlns:xlink="http://www.w3.org/1999/xlink" width="727px" height="526px" xmlns="http://www.w3.org/2000/svg"> <defs> <mask fill="white" id="clip598"> <path d="M 1 510 L 0.999871317552845 19.7966825002877 C 3.4185524978235 21.8045610459778 6.54626184609054 23 10 23 C 17.84 23 24 16.8399999999999 24 9 C 24 5.54542319048073 22.8039804094246 2.41703354202741 20.7929431454809 0 L 711 0 C 716.6 0 721 4.40000000000009 721 10 L 721 510 C 721 515.6 716.6 520 711 520 L 11 520 C 5.39999999999998 520 1 515.6 1 510 Z " fill-rule="evenodd" /> </mask> <filter x="1126px" y="8991px" width="727px" height="526px" filterUnits="userSpaceOnUse" id="filter599"> <feOffset dx="0" dy="0" in="SourceAlpha" result="shadowOffsetInner" /> <feGaussianBlur stdDeviation="1.5" in="shadowOffsetInner" result="shadowGaussian" /> <feComposite in2="shadowGaussian" operator="atop" in="SourceAlpha" result="shadowComposite" /> <feColorMatrix type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.117647058823529 0 " in="shadowComposite" /> </filter> <g id="widget600"> <path d="M 1 510 L 0.999871317552845 19.7966825002877 C 3.4185524978235 21.8045610459778 6.54626184609054 23 10 23 C 17.84 23 24 16.8399999999999 24 9 C 24 5.54542319048073 22.8039804094246 2.41703354202741 20.7929431454809 0 L 711 0 C 716.6 0 721 4.40000000000009 721 10 L 721 510 C 721 515.6 716.6 520 711 520 L 11 520 C 5.39999999999998 520 1 515.6 1 510 Z " fill-rule="nonzero" fill="#ffffff" stroke="none" transform="matrix(1 0 0 1 1129 8994 )" /> <path d="M 1 510 L 0.999871317552845 19.7966825002877 C 3.4185524978235 21.8045610459778 6.54626184609054 23 10 23 C 17.84 23 24 16.8399999999999 24 9 C 24 5.54542319048073 22.8039804094246 2.41703354202741 20.7929431454809 0 L 711 0 C 716.6 0 721 4.40000000000009 721 10 L 721 510 C 721 515.6 716.6 520 711 520 L 11 520 C 5.39999999999998 520 1 515.6 1 510 Z " stroke-width="2" stroke="#ebebeb" fill="none" transform="matrix(1 0 0 1 1129 8994 )" mask="url(#clip598)" /> </g> </defs> <g transform="matrix(1 0 0 1 -1126 -8991 )"> <use xlink:href="#widget600" filter="url(#filter599)" /> <use xlink:href="#widget600" /> </g> </svg> </div> <div class="flexcenter q">Q</div> <img class="cross-icon" @click="cutQuestionsSetp(0)" src="./img/cross-icon.png" /> <div class="issue-input"> <textarea v-model="questionsObj.title" placeholder="一句话描述问题,以问号结尾"></textarea> </div> <textarea class="issue-replenish" v-model="questionsObj.content" placeholder="欢迎补充,清晰表达问题的关键点,可获得更有效的解答(非必填)"></textarea> <div class="issue-bottom flexacenter"> <div class="option-box flexacenter" @click="cutAnonymous" style="color: #333"> <img class="option-icon" v-if="questionsObj.anonymous == 0" src="./img/tick-no.svg" /> <img class="option-icon" v-else src="./img/tick-option.svg" /> 匿名发表 <div class style="color: #aaa">(发布后只能修改是否匿名)</div> </div> <div class="issue-btn flexcenter" @click="postingIssue">发布问题</div> </div> </div> </div> <!-- 提示框 --> <transition name="msg" appear v-show="msg['state']"> <div class="box-item" :class="boxClass()" :style="{ top: 20 + 'px' }"> <div class="msg-container">{{ msg["text"] }}</div> </div> </transition> <!-- 大图 --> <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 class="alert-form" v-show="alertShow"> <div class="comments reports"> <div class="head"> <span style="display: flex; align-items: center"> <img style="width: 25px; margin-right: 7px" src="//app.gter.net/image/gter/offer/img/exclamationpoint.png?v=4.2.08_331040000" /> 举报投诉 </span> <div class="close icon-close iconfont" @click="alertShow = false"></div> </div> <div class="form"> <div class="radio-area flexacenter"> <div class="radio-area-item flexacenter" :class="{ pitch: checkList.includes(s) }" v-for="(s, i) in reasonList" :key="i" @click="selectRadio(s)"> <div class="radio-area-frame"></div> {{ s }} </div> </div> <div class="text-box"> <textarea placeholder="请输入举报原因" v-model="alertText" maxlength="200"></textarea> <div class="text-num">{{ 200 - alertText.length }}</div> </div> <div class="footer"> <button type="button" @click="alertShow = false">取消</button> <button type="submit" :disabled="checkList.length == 0" @click="alertSubmit">提交</button> </div> </div> </div> </div> <!-- <RespondPop v-if="respondPopState" :respondDetail="respondDetail" :respondPopObj="respondPopObj" @closePopList="closePopList" @selectEomji="selectEomji"></RespondPop> --> </div> </div> </template> <script> // let userInfoWin = { // "username": "", // "uid": 256624, // "uin": 4171117, // "avatar": "https://oss.gter.net/avatar/97KwEWQHYuMQGDnFqkimXF9SHKuGwVV5zW-tYWFjYQ~~?istype=1&random=nDW5aKmb89WC", // "messagenum": 0, // "newprompt": 0, // "todaysigned": 0 // } import { onMounted, onUnmounted, ref, nextTick, watchEffect, watch, provide } from "vue"; import axios from "axios"; export default { name: "#answer-app", async setup() { const author = "a37009134499cce160254db1bc9ccb94"; if (process.env.NODE_ENV !== "production" && document) document.cookie = "miucms_session=" + author; const $ajax = (url, data) => { url = url.indexOf("//") > -1 ? url : baseURL + url; return new Promise(function (resolve, reject) { axios .post(url, data, { emulateJSON: true, withCredentials: true, headers: { authorization: process.env.NODE_ENV !== "production" && author, // 头部标记 }, }) .then(function (res) { var data = null; try { data = typeof res.data == "string" ? JSON.parse(res.data) : res.data; if (data["code"] == 401) goLogin(); if (data["code"] != 200) handleMsg("error", data["message"] || "报错了,请重试!!!"); } catch (error) {} resolve(data); }) .catch((err) => { if (err?.response?.status == 401) goLogin(); resolve(err.response.data); }); }); }; const $ajaxGET = (url, data) => { url = url.indexOf("//") > -1 ? url : baseURL + url; return new Promise(function (resolve, reject) { axios .get(url, data, { emulateJSON: true, withCredentials: true, headers: { authorization: process.env.NODE_ENV !== "production" && author, // 头部标记 }, }) .then(function (res) { var data = null; try { data = typeof res.data == "string" ? JSON.parse(res.data) : res.data; if (data["code"] == 401) { goLogin(); // isNeedLogin.value = true; } if (data["code"] != 200) handleMsg("error", data["message"] || "报错了,请重试!!!"); } catch (error) {} resolve(data); }) .catch((err) => { if (err?.response?.status == 401) { goLogin(); // isNeedLogin.value = true; } resolve(err.response.data); }); }); }; provide("$ajax", $ajax); provide("$ajaxGET", $ajaxGET); let isNeedLogin = ref(true); // 是否需要有登录 provide("isNeedLogin", isNeedLogin); let emojiMaskState = ref(false); provide("emojiMaskState", emojiMaskState); // 跳转登录 const goLogin = () => { if (typeof window === "undefined") return; if (Object.keys(window["userInfoWin"]).length !== 0) { if (window["userInfoWin"]["uid"] || window["userInfoWin"]["uin"]) isNeedLogin.value = false; else if (!document.querySelector("#append_parent #fwin_login")) ajax_login(); } else if (!document.querySelector("#append_parent #fwin_login")) ajax_login(); }; provide("goLogin", goLogin); const route = useRoute(); // let detailsInfoDataVuex = useState("detailsInfoData", () => {}); const baseURL = "https://ask.gter.net"; let type = ref("list"); // list details onMounted(() => { // setTimeout(() => { // window["userInfoWin"] = { // "username": "", // "uid": 256624, // "uin": 4171117, // "avatar": "https://oss.gter.net/avatar/97KwEWQHYuMQGDnFqkimXF9SHKuGwVV5zW-tYWFjYQ~~?istype=1&random=nDW5aKmb89WC", // "messagenum": 0, // "newprompt": 0, // "todaysigned": 0 // } // }, 400); // 判断一下是否登录 if (process.env.NODE_ENV !== "production") isNeedLogin.value = false; else determineIsLogin(); getListClass(); window.addEventListener("scroll", handleScroll); getHistoricalSearchList(); if (isNeedScrollMiddle) scrollLeftInMiddle(); if (process.client) originUrl.value = window.location.origin; listenPageBack(); // console.log("detailsInfoDataVuex.value",detailsInfoDataVuex.value); // if (detailsInfoDataVuex.value) hanleServerRequestData(); initState.value++; const params = route.query; if (params["uniqid"]) { type.value = "details"; getDetails(params["uniqid"]); } // getDetails(params.uniqid) // 是否直接打开提问 setTimeout(() => { if (params["ispublish"]) questionsInit(); }, 500); const isLoginValue = params["islogin"]; if (isLoginValue == 1) getUserInfoWin(); else realname.value = 1; }); let realname = ref(0); // 是否已经实名 const getUserInfoWin = () => { const checkUser = () => { const user = window.userInfoWin; if (!user) { setTimeout(checkUser, 100); return; } userInfoWin.value = user; realname.value = user.realname || 0; }; setTimeout(checkUser, 100); }; const openAttest = () => { const handleAttestClose = () => { document.removeEventListener("closeAttest", handleAttestClose); realname.value = window.userInfoWin?.realname || 0; }; // 启动认证流程时添加监听 document.addEventListener("closeAttest", handleAttestClose); loadAttest(2); }; provide("realname", realname); provide("openAttest", openAttest); // 处理在服务端已经请求了详情接口 数据 const hanleServerRequestData = () => { const params = route.query; type.value = "details"; let data = detailsInfoDataVuex.value; detailsInfo.value = data["info"] || {}; detailsIsanswered.value = data["isanswered"] || 0; detailsIscollection.value = data["iscollection"] || 0; detailsIsmyself.value = data["ismyself"] || 0; detailsToken = data["token"] || ""; detailShare.value = data["share"] || {}; type.value = "details"; answerList.value = []; answerPage.value = 1; closeAllTransmitState(); replaceState({ uniqid: params["uniqid"] }); seo.value = data.seo; closeBottom(); }; // 是否是后退 状态 let isBackState = false; // 监听页面后退效果 重新获取 url 请求 const listenPageBack = () => { window.addEventListener("popstate", function (event) { const params = route.query; if (params["keyword"]) keyword.value = params["keyword"]; if (params["tid"]) typePitch.value = params["tid"]; if (params["uniqid"]) { isBackState = true; getDetails(params["uniqid"]); } else { type.value = "list"; openBottom(); pitchIndex.value = null; seo.value = {}; } }); }; let user = ref({}); provide("user", user); // 判断是否登录状态 const determineIsLogin = () => { let count = 0; let timer = setInterval(() => { if (window["userInfoWin"] && Object.keys(window["userInfoWin"]).length !== 0) { clearInterval(timer); user.value = window["userInfoWin"]; if (window["userInfoWin"]["uid"] || window["userInfoWin"]["uin"]) isNeedLogin.value = false; } count++; if (count >= 10) clearInterval(timer); }, 100); }; let originUrl = ref(""); onUnmounted(() => { window.removeEventListener("keydown", handleKeydown); window.removeEventListener("scroll", handleScroll); }); // 获取当前url 专门 分享的url const getCurrentUrl = () => { return `${window.location["origin"]}?uniqid=${detailsInfo.value["uniqid"] || ""}`; }; // 我的 数据 数量 let myCount = ref({}); // // 获取用户数据 const getUserData = (key) => { $ajax("/api/user").then((res) => { if (res.code != 200) return; let data = res.data; myCount.value = data.count; handleMy(key); }); }; // 是否是搜索模式 let isSearchMode = ref(false); // 获取历史记录方法 const getHistoricalSearchList = () => { const list = localStorage.getItem("historical-Search"); if (list) historicalSearchList.value = JSON.parse(list) || []; else historicalSearchList.value = []; }; // 存入历史记录 随便去重 和 限制长度 方法 const setHistoricalSearchList = () => { if (!keyword.value) return; historicalSearchList.value.unshift(keyword.value); historicalSearchList.value = [...new Set(historicalSearchList.value)]; historicalSearchList.value = historicalSearchList.value.slice(0, 10); localStorage.setItem("historical-Search", JSON.stringify(historicalSearchList.value)); }; // 搜索点击事件 const searchClick = () => { setHistoricalSearchList(); page = 1; list.value = []; backupsList = []; listHeight.value = 0; type.value = "list"; pitchIndex.value = null; openBottom(); myModelState.value = false; deleteState(["uniqid"]); replaceState({ keyword: keyword.value, }); searchBlur(); getList(); }; // 搜索获取焦点 const searchFocus = () => { if (historicalSearchList.value.length == 0) return; historicalSearchState.value = true; }; // 搜索失去焦点 const searchBlur = () => { setTimeout(() => (historicalSearchState.value = false), 300); }; // 点击历史记录 item const handleClickHistoricalItem = (value) => { keyword.value = value; searchClick(); }; // 点击清除搜索 const handleClickClear = () => { keyword.value = ""; page = 1; list.value = []; backupsList = []; listHeight.value = 0; type.value = "list"; openBottom(); pitchIndex.value = null; getList(); deleteState(["keyword"]); }; let historicalSearchState = ref(false); // 历史记录弹窗状态 let historicalSearchList = ref([]); // 历史记录数据 let tabListFixeState = ref(false); // 顶部 类型的 固定状态 const handleScroll = () => { const scrollTop = document.documentElement.scrollTop || document.body.scrollTop; const scrollHeight = document.documentElement.scrollHeight; const clientHeight = document.documentElement.clientHeight; // 列表下 滑动到底部 获取新数据 if (scrollTop + clientHeight >= scrollHeight - 40 && type.value == "list") getList(); // 列表下 滚动到顶部 触发类型的固定状态 if (scrollTop > 115) tabListFixeState.value = true; else tabListFixeState.value = false; }; let keyword = ref(""); // 搜索的值 let keywordText = ref(""); // 搜索的文本 let list = ref([]); // 列表数据 let backupsList = []; // 备份列表数据 let page = 1; let total = ref(0); // 回答总数 let loading = ref(false); let inTheEndState = ref(false); // 到底了状态 let isListEmptyState = ref(); // 列表是否为空的状态 let zeroreply = ref(0); // 只看0条回答状态 // 获取列表数据 const getList = () => { if (page == 0 || loading.value) return; loading.value = true; $ajax("/api/lists", { page, limit: 20, keyword: keyword.value, type: typePitch.value, zeroreply: zeroreply.value, }) .then((res) => { if (res.code == 401) goLogin(); if (res.code != 200) return; let data = res.data; data.data.forEach((element) => { element["content"] = element["content"].replace(/<[^>]*>/g, ""); element["content"] = element["content"].replace(/ /g, ""); }); list.value = list.value.concat(data.data || []); backupsList = backupsList.concat(data.data || []); total.value = data.count || 0; keywordText.value = keyword.value || ""; // page++ if (list.value.length >= data["count"]) page = 0; else page++; if (page == 0 && list.value.length != 0) inTheEndState.value = true; else inTheEndState.value = false; if (list.value.length == 0) isListEmptyState.value = true; else isListEmptyState.value = false; if (keyword.value) isSearchMode.value = true; else isSearchMode.value = false; if (type.value == "details") handleInsertRelatedlist(); if (list.value.length == 0) type.value = "list"; }) .finally(() => (loading.value = false)); }; let typeList = ref([]); let typePitch = ref(null); // 获取分类数据 列表分类 const getListClass = () => { typeList.value = []; $ajaxGET("/api/common/typeList").then((res) => { if (res.code != 200) return; let data = res.data; typeList.value = data; typeList.value.unshift([{ id: null, name: "All" }]); getPageHeight(); }); }; let pageHeaderHeight = ref(0); // 头部的高度 let pageListHeight = ref(0); // 底部列表的高度 const getPageHeight = () => { let pageHeader = document.querySelector("#pageHeader"); pageHeaderHeight.value = pageHeader.clientHeight + 10; pageListHeight.value = window.innerHeight - pageHeaderHeight.value; }; let isCommentList = ref(false); let detailsInfo = ref({}); // 详情信息 let detailsIsanswered = ref(0); // 详情信息 let detailsIscollection = ref(0); // 详情信息 let detailsIsmyself = ref(0); // 详情信息 let detailsToken = ""; // 详情信息 let detailsToken2 = ref(""); // 详情信息 let detailShare = ref({}); // 详情信息 let detailLoading = ref(false); // 详情加载 provide("detailLoading", detailLoading); provide("detailsToken", detailsToken2); // 获取详情 const getDetails = (uniqid, index, isOpenAnswer) => { if (detailLoading.value) return; detailLoading.value = true; // process.env.NODE_ENV !== "production" && (uniqid = "fCSyLDDa0r1q") // 标记1一下 8yr1m1fOH5CS fubm5CnD05qj fCSyLDDa0r1q detailsInfo.value = {}; answerList.value = []; answerPage.value = 0; $ajax("/api/details", { uniqid }) .then((res) => { if (res.code != 200) { type.value = "list"; openBottom(); pitchIndex.value = null; return; } let data = res.data; data["info"]["uniqid"] = uniqid; detailsInfo.value = data["info"] || {}; detailsIsanswered.value = data["isanswered"] || 0; detailsIscollection.value = data["iscollection"] || 0; detailsIsmyself.value = data["ismyself"] || 0; detailsToken = data["token"] || ""; detailsToken2.value = data["token"] || ""; detailShare.value = data["share"] || {}; islike.value = data["islike"] || 0; type.value = "details"; closeBottom(); if (index !== null && index !== undefined) cut(index); else calculateListIndex(data.info, uniqid); answerList.value = []; answerPage.value = 1; closeAllTransmitState(); if (isOpenAnswer) openIAnswer(); // 非后退状态才可以 修改 url if (!isBackState) replaceState({ uniqid }); isBackState = false; seo.value = data.seo; // 初始化 我来回答的框 yourAnswer.value = { text: "", anonymous: 0, }; // 默认 详情 div 滚动到顶部 nextTick(() => detailsAreaScrollTop()); handleInsertRelatedlist(uniqid); isCommentList.value = true; // console.log("list", list.value, "detailsInfo", detailsInfo.value) }) .finally(() => (detailLoading.value = false)); }; // 默认 详情 div 滚动到顶部 预防用户在 列表重复点击 const detailsAreaScrollTop = () => { let detailsArea = document.querySelector(".details-area-box"); detailsArea.scrollTo({ top: 0, behavior: "smooth", }); }; const calculateListIndex = (info, uniqid) => { let targetList = [...list.value]; if (targetList.length == 0 && isSearchMode.value == false && myModelState.value == false) { setTimeout(() => calculateListIndex(info, uniqid), 200); return; } let valve = false; list.value.forEach((element, index) => { if (element["uniqid"] == uniqid) { cut(index); pitchIndex.value = index; valve = true; } }); if (!valve) { let content = ""; if (info?.["content"]?.indexOf("<img") == -1) content = info["content"]; content = content.replace(/<[^>]*>/g, ""); content = content.replace(/ /g, ""); const obj = { answers: info["answers"], content, publicationdate: info["publicationdate"], title: info["title"], typename: info["typename"], uniqid, }; list.value.unshift(obj); // if (!myModelState.value) backupsList.unshift(obj) cut(0); } }; let answerList = ref([]); // 回答列表数据 let answerPage = ref(1); // 回答列表页数 // 操作 - 点赞 const operateLike = () => { if (realname.value == 0 && user.value.uin > 0) { openAttest(); return; } if (isNeedLogin.value) { goLogin(); return; } $ajax("/api/operate/like", { token: detailsToken }).then((res) => { if (res.code != 200) return; let data = res.data; islike.value = data.status || 0; detailsInfo.value["likenum"] = data.count || 0; handleMsg("success", res["message"] || "操作成功"); }); }; let isNeedNewColletData = false; // 是否需要获取新的收藏数据 ,顶部的我的弹窗需要 // 操作 - 收藏 const operateCollect = (token = detailsToken, index) => { if (isNeedLogin.value) { goLogin(); return; } $ajax("/api/operate/collect", { token, }).then((res) => { if (res.code != 200) return; let data = res.data; isNeedNewColletData = true; myCollectionPage = 1; myCollectionList.value = []; if (data["type"] == "askquestioncollection") { detailsIscollection.value = data["status"]; detailsInfo.value["collectionnum"] = data["count"]; } else { answerList.value[index]["iscollection"] = data["status"]; answerList.value[index]["collectionnum"] = data["count"]; } handleMsg("success", res["message"] || "操作成功"); if (data["status"]) myCount.value["collect"]++; else myCount.value["collect"]--; }); }; let IAnswerState = ref(false); // 我来回答-弹窗的状态 let IAnswerEditState = ref(false); // 编辑回答-弹窗的状态 let IAnswerInfo = ref({}); // 我来回答-弹窗的信息 // 修改我来回答的匿名状态 const amendIAnswer = () => { IAnswerInfo.value["anonymous"] = IAnswerInfo.value["anonymous"] == 0 ? 1 : 0; }; // 打开回答的评论 const openCommentState = (index) => { if (answerList.value[index]["commentState"]) answerList.value[index]["commentState"] = false; else answerList.value[index]["commentState"] = true; if (answerList.value[index]["commentList"].length == 0 && answerList.value[index]["commentnum"] != 0) getAnswerCommentList(index); }; // 获取回答评论的数据 const getAnswerCommentList = (index) => { getAnswerCommentPublic(index, 2).then((res) => { let data = res.data; answerList.value[index]["commentList"] = answerList.value[index]["commentList"].concat(data.data); answerList.value[index]["commentCount"] = data["count"]; }); }; // 获取全部评论 const handleAllComment = (index) => { answerCommentLimit = 1000; getAnswerCommentPublic(index, 1000).then((res) => { if (res.code != 200) return; let data = res.data; let slice3 = data.data.slice(1); let merged1 = [...answerList.value[index]["commentList"], ...slice3.filter((item2) => !answerList.value[index]["commentList"].find((item1) => item1.id == item2.id))]; answerList.value[index]["commentList"] = merged1; answerList.value[index]["showOneCommentState"] = false; }); }; // 获取评论数据的公共接口 const getAnswerCommentPublic = (index, limit) => { return new Promise((resolve, reject) => { $ajax("/api/comment/lists", { token: answerList.value[index]["token"], limit, childlimit: 1, }).then((res) => { if (res.code != 200) return; resolve(res); }); }); }; let myType = ref(""); // collect answers questions // 专门处理 我的 弹窗数据 const handleMy = (key) => { if (isNeedLogin.value) { goLogin(); return; } if (Object.keys(myCount.value).length === 0) { getUserData(key); return; } if (key == "collect") { myCollectionList.value = []; myCollectionPage = 1; getMyCollection(); } else if (key == "answers") { myAnswerList.value = []; myAnswerPage = 1; getMyAnswer(); } else if (key == "questions") { myQuestionsList.value = []; myQuestionsPage = 1; getMyQuestions(); } }; let myCollectionList = ref([]); // 我的收藏列表 let myCollectionCount = ref(0); // 我的收藏数量 let myCollectionPage = 1; // 我的收藏页数 let myCollectionLading = false; // 我的收藏加载中 // 获取我的收藏 const getMyCollection = () => { if (myCollectionPage == 0 || myCollectionLading) return; myCollectionLading = true; $ajax("/api/user/collect", { limit: 20, page: myCollectionPage, }) .then((res) => { if (res.code != 200) return; let data = res.data; myType.value = "collect"; isNeedNewColletData = false; data.data.forEach((element) => { if (element["type"] == "askanswercollection") { let content = element["data"]["content"]; element["data"]["content"] = processHtml(content); } }); myCollectionList.value = myCollectionList.value.concat(data.data); myCollectionCount.value = data.count; if (myCollectionList.value.length != data["count"]) myCollectionPage++; else myCollectionPage = 0; }) .finally(() => (myCollectionLading = false)); }; const processHtml = (html) => { var parser = new DOMParser(); var doc = parser.parseFromString(html, "text/html"); var img = doc.querySelector("img"); if (img) return `<img src="${img.src}">`; else return doc.body.textContent; }; // 取消收藏 const cancelCollection = (token, index) => { $ajax("/api/user/deleteCollect", { token }).then((res) => { if (res.code == 200) { myCollectionList.value.splice(index, 1); myCollectionCount.value--; myCount.value["collect"]--; handleMsg("success", res["message"] || "操作成功"); } }); }; // 监听 我的收藏滚动到底部 const handleCollectionScroll = (e) => { const el = e.target; if (el.scrollHeight - el.scrollTop >= el.clientHeight + 10) return; getMyCollection(); }; let myAnswerList = ref([]); // 我的回答数据 let myAnswerCount = ref(0); // 我的回答数量 let myAnswerPage = 1; let myAnswerloadimg = false; // 获取我的回答 const getMyAnswer = () => { if (myAnswerPage == 0 || myAnswerloadimg) return; myAnswerloadimg = true; $ajax("/api/user/answer", { limit: 20, page: myAnswerPage, }) .then((res) => { if (res.code != 200) return; let data = res.data; data.data.forEach((element) => { element["popupState"] = false; }); data.data.forEach((element) => { let content = element["content"]; element["content"] = processHtml(content); }); myAnswerList.value = myAnswerList.value.concat(data.data); myAnswerCount.value = data.count; if (myAnswerList.value.length != data["count"]) myAnswerPage++; else myAnswerPage = 0; myType.value = "answers"; }) .finally(() => (myAnswerloadimg = false)); }; // 我的回答 的滚动到底部事件 const handleAnswersScroll = (e) => { const el = e.target; // 判断滚动到底部 if (el.scrollHeight - el.scrollTop >= el.clientHeight + 10) return; getMyAnswer(); }; let answerIndexOld = null; // 切换 我的提问的公开匿名 弹窗状态 const cutAnswerPopupState = (index) => { myAnswerList.value[index]["popupState"] = true; if (answerIndexOld == index) { myAnswerList.value[index]["popupState"] = false; answerIndexOld = null; } else { myAnswerList.value[index]["popupState"] = true; if (answerIndexOld != null) myAnswerList.value[answerIndexOld]["popupState"] = false; answerIndexOld = index; } }; // 更改匿名状态 const changeAnonymous = (token, anonymous, index) => { $ajax("/api/publish/changeAnonymous", { token, anonymous, }).then((res) => { if (res.code != 200) return; let data = res.data; myAnswerList.value[index]["anonymous"] = anonymous; cutAnswerPopupState(index); handleMsg("success", res["message"] || "操作成功"); }); }; let myQuestionsList = ref([]); // 我的提问数据 let myQuestionsCount = ref(0); // 我的提问数量 let myQuestionsPage = 0; // 我的提问页数 let myQuestionsloading = false; // 我的提问页数 // 获取我的提问 const getMyQuestions = () => { if (myQuestionsPage == 0 || myQuestionsloading) return; myQuestionsloading = true; $ajax("/api/user/questions", { limit: 20, page: myQuestionsPage, }) .then((res) => { if (res.code != 200) return; let data = res.data; myQuestionsList.value = myQuestionsList.value.concat(data.data); myQuestionsCount.value = data.count; myType.value = "questions"; if (myQuestionsList.value.length != data["count"]) myQuestionsPage++; else myQuestionsPage = 0; }) .finally(() => (myQuestionsloading = false)); }; // 我的提问 的滚动到底部 事件 const handleQuestionsScroll = (e) => { const el = e.target; // 判断滚动到底部 if (el.scrollHeight - el.scrollTop >= el.clientHeight + 10) return; getMyQuestions(); }; let questionsIndexOld = null; // 切换 我的提问的公开匿名 弹窗状态 const cutQuestionsPopupState = (index) => { myQuestionsList.value[index]["popupState"] = true; if (questionsIndexOld == index) { myQuestionsList.value[index]["popupState"] = false; questionsIndexOld = null; } else { myQuestionsList.value[index]["popupState"] = true; if (questionsIndexOld != null) myQuestionsList.value[questionsIndexOld]["popupState"] = false; questionsIndexOld = index; } }; // 更改匿名状态 const changeAnonymousQuestions = (token, anonymous, index) => { $ajax("/api/publish/changeAnonymous", { token, anonymous, }).then((res) => { if (res.code != 200) return; myQuestionsList.value[index]["anonymous"] = anonymous; cutQuestionsPopupState(index); handleMsg("success", res["message"] || "操作成功"); }); }; let questionsSetp = ref(0); // 提问的步骤 // 切换提问步骤 const cutQuestionsSetp = (value) => (questionsSetp.value = value); let questionsTypeList = ref([]); // 提问的类型主题 let questionsObj = ref({ // 提问的内容 token: "", title: "", content: "", tags: "", tid: "", anonymous: 0, }); // 报 提问的初始化 const questionsInit = () => { if (isNeedLogin.value) { goLogin(); return; } deleteState(["ispublish"]); $ajax("/api/publish/questions").then((res) => { if (res.code != 200) return; let data = res.data; questionsObj.value["token"] = data["token"]; questionsTypeList.value = data["typeList"] || []; cutQuestionsSetp(1); }); }; // 选择提问主题 const choosingTheme = (id) => { questionsObj.value.tid = id; cutQuestionsSetp(2); }; // 切换匿名状态 const cutAnonymous = () => { questionsObj.value.anonymous = questionsObj.value.anonymous == 0 ? 1 : 0; }; // 发布问题 const postingIssue = () => { if (isNeedLogin.value) { goLogin(); return; } $ajax("/api/publish/questionsSubmit", questionsObj.value).then((res) => { if (res.code == 200) { myCount.value["questions"]++; questionsSetp.value = 0; questionsObj.value = { token: "", title: "", content: "", tags: "", tid: "", anonymous: 0, }; handleMsg("success", res["message"] || "操作成功"); let data = res.data; getDetails(data["uniqid"]); return; } handleMsg("error", res["message"] || "刷新重试!!!"); }); }; let pitchIndex = ref(null); // 选中的下标 // 切换 滚动列表 const cut = (index) => { pitchIndex.value = index; setTimeout(() => scrollLeftInMiddle(), 350); }; // 是否需要在 onMounted 滚动左边在中间 let isNeedScrollMiddle = false; // 滚动左边在中间 const scrollLeftInMiddle = () => { if (typeof document === "undefined") { isNeedScrollMiddle = true; return; } let list = document.querySelector(".list-box"); let item = list.querySelector(`.item${pitchIndex.value}`); // 136 分为 两个68,一个是item高度的一半,另一个是列表顶部的 数量 let top = item.offsetTop - pageListHeight.value / 2 + 136; list.scrollTo({ top, behavior: "smooth", }); isNeedScrollMiddle = false; }; const listStyle = () => { const newtype = type.value; let width = ""; let margin = ""; let height = ""; if (newtype == "list") { width = "1200px"; margin = "0 auto"; } else { width = "calc((100vw - 1200px) / 2 + 512px)"; margin = "initial"; } return { width, margin, height, }; }; let listHeight = ref(0); let itemHeightLeft = 0; let itemHeightRight = 0; const itemStyle = (index, content, typetype) => { if (index == 0) { itemHeightLeft = 0; itemHeightRight = 0; } const newtype = type.value; let obj = {}; if (newtype == "list") { if (itemHeightLeft <= itemHeightRight) { obj["top"] = itemHeightLeft + "px"; itemHeightLeft += content == "" ? 107 : 137; obj["left"] = 0; } else { obj["top"] = itemHeightRight + "px"; itemHeightRight += content == "" ? 107 : 137; obj["left"] = 649 + "px"; } } else { obj["position"] = "relative"; if (!typetype) { itemHeightLeft += content == "" ? 107 : 137; obj["height"] = content == "" ? 107 + "px" : 137 + "px"; } else { itemHeightLeft += typetype == "vote" ? 170 : 137; obj["height"] = typetype == "vote" ? 170 + "px" : 137 + "px"; } obj["width"] = "100%"; obj["paddingLeft"] = "calc((100vw - 1210px) / 2)"; } // 通过最后一个 算 列表的高度 if (index + 1 == list.value.length) listHeight.value = Math.max(itemHeightLeft, itemHeightRight); // console.log("obj", obj); return obj; }; const bottomTpsStyle = (index, content) => { const newtype = type.value; let obj = {}; if (newtype == "list") { } else { obj["width"] = "calc(50vw - 88px)"; obj["height"] = `calc(100vh - ${list.value.length * 128}px - 268px)`; obj["paddingLeft"] = "calc((100vw - 1200px) / 2)"; obj["borderRight"] = "1px solid #ebebeb"; obj["background"] = "#fff"; } return obj; }; // list-box const listBoxStyle = () => { const newtype = type.value; let obj = {}; if (newtype == "list") obj["overflow"] = "visible"; else obj["height"] = pageListHeight.value + "px"; return obj; }; // 处理时间 const handleDate = (dateTimeStamp = new Date(), ishour = true) => { dateTimeStamp = dateTimeStamp ? dateTimeStamp : null; var timestamp = new Date(dateTimeStamp); timestamp = timestamp.getTime(); var minute = 1000 * 60; var hour = minute * 60; var day = hour * 24; var now = new Date().getTime(); var diffValue = now - timestamp; var result; if (diffValue < 0) return "刚刚"; var dayC = diffValue / day; var hourC = diffValue / (hour + 1); var minC = diffValue / minute; if (dayC >= 7) { let date = new Date(timestamp); 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(); if (ishour) result = "" + Y + M + D + h + m; else result = "" + Y + M + D; } else if (dayC >= 1) result = "" + Math.round(dayC) + "天前"; else if (hourC >= 1) result = "" + Math.round(hourC) + "小时前"; else if (minC >= 1) result = "" + Math.round(minC) + "分钟前"; else result = "刚刚"; return result; }; provide("handleDate", handleDate); let questionsTransmitState = ref(false); // 问题的转发 弹窗状态 let questionsTransmitMaskState = ref(false); // 问题的转发 弹窗蒙版状态状态 // 关闭转发状态 const closeTransmitState = () => { questionsTransmitState.value = true; questionsTransmitMaskState.value = true; countForwardingTimes(detailsToken); }; // 关闭全部转发状态 const closeAllTransmitState = () => { answerList.value.forEach((element) => { element["transmitState"] = false; }); questionsTransmitState.value = false; questionsTransmitMaskState.value = false; }; // 开启和关闭回答的转发状态 type open close const handleAnswerTransmitList = (Iindex, type) => { answerList.value[Iindex]["transmitState"] = true; questionsTransmitMaskState.value = true; countForwardingTimes(answerList.value[Iindex]["token"]); }; // 统计转发次数 const countForwardingTimes = (token) => { process.env.NODE_ENV === "production" && $ajaxGET("/api/operate/share?token=" + token); }; // 关闭详情模式 const closeDetailMode = () => { deleteState(["uniqid"]); if (myModelState.value) { closeMyModel(); return; } type.value = "list"; openBottom(); pitchIndex.value = null; seo.value = {}; list.value = JSON.parse(JSON.stringify(backupsList)); }; // 全部的启动到底部 const handleListScroll = (e) => { const el = e.target; if (el.scrollHeight - el.scrollTop >= el.clientHeight + 40 || myModelState.value) return; getList(); }; // 处理 回答弹窗的复制图片 type:you 为 您的答案 const handlePaste = (event, type) => { const items = (event.clipboardData || event.originalEvent.clipboardData).items; for (const item of items) { if (item.type.indexOf("image") === 0) { // 如果包含图片,阻止默认行为 event.preventDefault(); handleMsg("warning", "上传图片中"); const file = item.getAsFile(); const reader = new FileReader(); reader.onload = (e) => { const base64 = e.target.result; uploadImg(base64).then((res) => { let questionTextarea = null; if (type == "you") questionTextarea = document.querySelector(".your-answer-textarea"); else questionTextarea = document.querySelector(".question-textarea"); let imgNode = document.createElement("img"); imgNode.setAttribute("src", res.url); imgNode.setAttribute("data-aid", res.aid); questionTextarea.appendChild(imgNode); if (type == "you") handleInputYou(); else handleInput(); handleMsg("success", "上传成功"); }); }; reader.readAsDataURL(file); } } }; // 上传图片 获取图片url const uploadImg = (base64) => { return new Promise((resolve, reject) => { detailLoading.value = true; $ajax("/api/common/upload", { data: base64, }) .then((res) => { if (res.code != 200) { handleMsg("error", res.message || "上传失败"); return; } let data = res.data; resolve(data); }) .finally(() => (detailLoading.value = false)); }); }; provide("uploadImg", uploadImg); // 回答 的 placeholder 状态 let questionPlaceholderState = ref(false); let yourAnswerPlaceholderState = ref(true); // 您的答案的 placeholder 状态 // 回答的输入事件 判断是否显示 placeholder 用 const handleInput = () => { const questionTextarea = document.querySelector(".question-textarea"); const html = questionTextarea.innerHTML; if (html) questionPlaceholderState.value = false; else questionPlaceholderState.value = true; }; const handleInputYou = () => { const questionTextarea = document.querySelector(".your-answer-textarea"); const html = questionTextarea.innerHTML; if (html) yourAnswerPlaceholderState.value = false; else yourAnswerPlaceholderState.value = true; }; let msg = ref({}); // 提示文本的对象 state 类型 type success warning error 显示状态 text 内容 // 调用 提示框方法 const handleMsg = (type, text) => { msg.value["state"] = true; msg.value["type"] = type; msg.value["text"] = text; }; provide("handleMsg", handleMsg); // 修改提示框类型 const boxClass = () => { msgShowTimer(); return type ? `box-item-${msg.value["type"]}` : ""; }; let msgTimer = null; const msgShowTimer = () => { clearTimeout(msgTimer); msgTimer = setTimeout(() => { msg.value["state"] = false; }, 1000); }; // 复制 let copyText = (text) => { if (navigator.clipboard) { copyText = () => { navigator.clipboard.writeText(text); handleMsg("success", "复制成功"); }; } else { copyText = () => { var tempInput = document.createElement("input"); tempInput.value = text; document.body.appendChild(tempInput); tempInput.select(); document.execCommand("copy"); document.body.removeChild(tempInput); handleMsg("success", "复制成功"); }; } copyText(); }; // 修改 url const replaceState = (obj = {}) => { if (typeof window === "undefined") return; const location = JSON.parse(JSON.stringify(window.location)); // 获取当前URL参数 let params = new URLSearchParams(window.location.search); for (const key in obj) { params.set(key, obj[key]); } // 替换当前URL,但不刷新页面 if (window.location.pathname.indexOf("index.html") == -1) window.history.pushState({}, "", `${window.location.pathname}index.html?${params}`); else window.history.pushState({}, "", `${window.location.pathname}?${params}`); if (location.search.indexOf(obj.uniqid) == -1) XSTAT.trackNewPage(); // let location = window.location; // let contentUrl = location.pathname + location.search; // if (window._hmt) window._hmt.push(["_trackPageview", contentUrl]) // 用于发送某个URL的PV统计请求 // if (window._czc) window._czc.push(["_trackPageview", contentUrl]) }; // 删除 url 参数的key const deleteState = (keys = []) => { if (typeof window === "undefined") return; let params = new URLSearchParams(window.location.search); keys.forEach((key) => { params.delete(key); }); window.history.pushState({}, "", `${window.location.pathname}?${params}`); }; let myModelState = ref(false); // 我的模式状态 let myModelList = ref([]); // 我的模式列表 let temporaryData = {}; // 临时存放 // 我的打开 详情 const myOpenDetails = (uniqid) => { if (!uniqid) { handleMsg("error", "没有找到相关提问"); return; } deleteState(["keyword"]); if (!myModelState.value) { temporaryData = { total: total.value, keywordText: keywordText.value, isSearchMode: isSearchMode.value, inTheEndState: inTheEndState.value, type: type.value, pitchIndex: pitchIndex.value, listlist: JSON.parse(JSON.stringify(list.value)), }; isSearchMode.value = false; inTheEndState.value = false; keyword.value = ""; list.value = JSON.parse(JSON.stringify(myModelList.value)); myModelState.value = true; pitchIndex.value = null; } getDetails(uniqid); myType.value = ""; }; // 关闭我的模式 const closeMyModel = () => { myModelList.value = JSON.parse(JSON.stringify(list.value)); isSearchMode.value = temporaryData["isSearchMode"]; keywordText.value = temporaryData["keywordText"]; keyword.value = temporaryData["keywordText"]; total.value = temporaryData["total"]; type.value = temporaryData["type"]; pitchIndex.value = temporaryData["pitchIndex"]; inTheEndState.value = temporaryData["inTheEndState"]; list.value = JSON.parse(JSON.stringify(temporaryData.listlist)); myModelState.value = false; if (pitchIndex.value !== null && pitchIndex.value !== undefined) { let uniqid = list.value[pitchIndex.value]["uniqid"]; getDetails(uniqid); } }; // 详情页滚动事件 const handleDetailsScroll = (e) => { const el = e.target; // 判断滚动到底部 if (el.scrollHeight - el.scrollTop !== el.clientHeight) return; }; let dialogSrc = ref(""); // 大图的src // 处理点击答案图片 展开大图 const handleAnswerText = (e) => { if (e.target.tagName === "IMG") { var src = e.target.getAttribute("src"); dialogSrc.value = src; window.addEventListener("keydown", handleKeydown); } }; provide("handleAnswerText", handleAnswerText); // 大图的监听 esc 键盘按钮 const handleKeydown = (event) => { if (event.key !== "Escape") return; dialogSrc.value = ""; window.removeEventListener("keydown", handleKeydown); // 取消监听 }; // 切换顶部的 type const cutType = (id) => { typePitch.value = id; page = 1; list.value = []; backupsList = []; listHeight.value = 0; myModelState.value = false; type.value = "list"; openBottom(); pitchIndex.value = null; if (id != null) { replaceState({ tid: id, }); deleteState(["uniqid"]); } else deleteState(["tid", "uniqid"]); getList(); // 创新请求 设置列表的高度 为0 listHeight.value = 0; }; // 打开举报 const handleMenuState = (token) => { reportToken = token; alertShow.value = true; }; provide("handleMenuState", handleMenuState); // 举报 token let reportToken = ""; const reasonList = ["广告", "辱骂", "重复发送", "不良信息", "其他"]; let checkList = ref([]); let alertShow = ref(false); let alertText = ref(""); const selectRadio = (value) => { const index = checkList.value.indexOf(value); if (index === -1) checkList.value.push(value); else checkList.value.splice(index, 1); }; // 举报提交 const alertSubmit = () => { checkList.value.push(alertText.value); $ajax("/api/operate/report", { message: checkList.value, token: reportToken, }).then((res) => { checkList.value = []; reportToken = ""; alertShow.value = false; handleMsg("success", "举报成功"); }); }; onMounted(() => { watchEffect(() => { if (questionsSetp.value || myType.value || IAnswerEditState.value || IAnswerState.value || dialogSrc.value) document.body.style.overflow = "hidden"; else document.body.style.overflow = "auto"; }); }); let recommendList = []; // 推荐相关的数据 let recommendPage = 1; // 获取推荐数据 const getRecommend = (uniqid) => { $ajax("/api/details/relatedlist", { page: recommendPage, limit: 20, }).then((res) => { if (res.code != 200) return; let obj = { offer: "Offer", mj: "面经", vote: "投票", thread: "帖子", }; let data = res.data; // 替换 类名 data.forEach((element) => { element["typename"] = obj[element["type"]]; element["isrecom"] = true; }); recommendList = recommendList.concat(data); recommendPage++; handleInsertRelatedlist(uniqid); }); }; // 处理插入推荐数据 const handleInsertRelatedlist = (uniqid) => { if (myModelState.value) return; // 计算需要插入元素的数量 let insertCount = Math.ceil(backupsList.length / 5); // 检查数组B的长度是否足够 if (recommendList.length < insertCount) { getRecommend(uniqid); return; } let target = JSON.parse(JSON.stringify(backupsList)); let result = []; let j = 0; for (let i = 0; i < target.length; i++) { result.push(target[i]); if ((i + 1) % 4 === 0 && j < recommendList.length) { result.push(recommendList[j]); j++; } } list.value = JSON.parse(JSON.stringify(result)); // 加入 推荐阅读后 重新计算下标 和 滚动 nextTick(() => { if (uniqid) { result.forEach((element, index) => { if (element["uniqid"] == uniqid) { pitchIndex.value = index; scrollLeftInMiddle(); } }); } }); }; const replaceNumberObj = ["①", "②", "③"]; let seo = ref({}); let initState = ref(0); let islike = ref(0); // 是否点赞 try { const params = route.query; if (params["keyword"]) keyword.value = params["keyword"]; if (params["tid"]) typePitch.value = params["tid"]; // if (process.server && params["uniqid"]) { // await axios // .post(baseURL + "/api/details", { uniqid: params["uniqid"] }) // .then(response => { // let res = response.data // let data = res.data // data["info"]["uniqid"] = params["uniqid"] // detailsInfoDataVuex.value = data // detailsInfo.value = data["info"] || {} // detailsIsanswered.value = data["isanswered"] || 0 // detailsIscollection.value = data["iscollection"] || 0 // detailsIsmyself.value = data["ismyself"] || 0 // detailsToken = data["token"] || "" // detailShare.value = data["share"] || {} // islike.value = data["islike"] || 0 // type.value = "details" // // calculateListIndex(data.info, params["uniqid"]); // answerList.value = [] // answerPage.value = 1 // getAnswerList() // closeAllTransmitState() // replaceState({ uniqid: params["uniqid"] }) // seo.value = data.seo // }) // .catch(error => console.error(error)) // } await $ajax("/api/lists", { page, limit: 20, keyword: keyword.value, type: typePitch.value, }).then((res) => { if (res.code != 200) return; let data = res.data; data.data.forEach((element) => { element["content"] = element["content"].replace(/<[^>]*>/g, ""); element["content"] = element["content"].replace(/ /g, ""); }); list.value = data.data; backupsList = data.data; total.value = data.count || 0; keywordText.value = keyword.value || ""; if (list.value.length != data["count"]) page++; else page = 0; if (page == 0 && list.value.length != 0) inTheEndState.value = true; else inTheEndState.value = false; if (list.value.length == 0) isListEmptyState.value = true; else isListEmptyState.value = false; if (keyword.value) isSearchMode.value = true; else isSearchMode.value = false; nextTick(() => { if (list.value.length == 0) type.value = "list"; }); }); // await $ajax("/api/details/relatedlist", { page: 1, limit: 20 }).then(res => { // if (res.code != 200) return // let obj = { // offer: "Offer", // mj: "面经", // vote: "投票", // thread: "帖子", // } // let data = res.data // // // 替换 类名 // data.forEach(element => { // element["typename"] = obj[element["type"]] // element["isrecom"] = true // }) // recommendList = recommendList.concat(data) // recommendPage++ // if (params["uniqid"]) { // let target = JSON.parse(JSON.stringify(backupsList)) // let result = [] // let j = 0 // for (let i = 0; i < target.length; i++) { // result.push(target[i]) // if ((i + 1) % 4 === 0 && j < recommendList.length) { // result.push(recommendList[j]) // j++ // } // } // list.value = JSON.parse(JSON.stringify(result)) // initState.value++ // } // }) } catch (error) { console.error(error); } // 这个是监听 初始化的 推荐接口 和 onmount 都运行完成后 滚动 item ,不让冲突 watch(initState, (newValue, oldValue) => { if (newValue === 2) { const params = route.query; // calculateListIndex(detailsInfo.value, params["uniqid"]) } }); const setItemUrl = (uniqid) => { let url = `./index.html?uniqid=${uniqid}`; let query = route.query; for (const key in query) { if (key != "uniqid") url += `&${key}=${query[key]}`; } return url; }; // 处理点击 logo const handleLogo = () => { window.location.href = window.location.origin + window.location.pathname; }; // 您的答案 let yourAnswer = ref({ text: "", anonymous: 0, }); // 切换您的答案 匿名状态 const cutYourAnswerAnonymous = () => { yourAnswer.value["anonymous"] = yourAnswer.value["anonymous"] ? 0 : 1; }; let isDirectlyListIAnswer = false; // 是否是直接打开列表的我来回答 // 专门处理列表状态的 我来回答 const openListIAnswer = (index) => { if (isNeedLogin.value) { goLogin(); return; } let targetData = list.value[index]; IAnswerInfo.value = { title: targetData["title"], content: targetData["content"], token: targetData["token"], uniqid: targetData["uniqid"], anonymous: 0, index, }; isDirectlyListIAnswer = true; IAnswerState.value = true; nextTick(() => handleInput()); }; // 头像框的状态 let avatarState = ref(false); // 开启头像框 const openUserInfo = () => { if (detailsInfo.value["uin"] > 0) avatarState.value = !avatarState.value; }; // 点击发送信息 const sendMessage = (uin) => { if (uin && typeof messagePrivateItem == "function") { messagePrivateItem({ uin: uin }); return; } else 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}`); }; provide("TAHomePag", TAHomePage); // 跳转 url const redirectToExternalWebsite = (url) => { const link = document.createElement("a"); link.href = url; link.target = "_blank"; link.click(); }; // 详情模式下关闭底部 const closeBottom = () => { if (process.server) return; const footer = document.querySelector("body .index-footer"); if (footer) footer.style.display = "none"; else setTimeout(() => closeBottom(), 1000); }; const openBottom = () => { const footer = document.querySelector("body .index-footer"); if (footer) footer.style.display = "block"; else setTimeout(() => openBottom(), 1000); }; // 处理点击 只看 const handleLookOnly = () => { zeroreply.value = zeroreply.value == 0 ? 1 : 0; page = 1; list.value = []; backupsList = []; listHeight.value = 0; getList(); }; const commentList = ref([]); const commentListRef = ref(null); const closeEmojiMask = () => { if (commentListRef.value) commentListRef.value.closeEmoji(); }; // 讨论后修改列表的讨论数量 const handleUpdateAnswers = (value) => { list.value.forEach((element) => { if (element.uniqid == detailsInfo.value["uniqid"]) element["answers"] = value; }); backupsList.forEach((element) => { if (element.uniqid == detailsInfo.value["uniqid"]) element["answers"] = value; }); }; return { handleUpdateAnswers, commentListRef, closeEmojiMask, emojiMaskState, isCommentList, commentList, islike, handleLookOnly, zeroreply, replaceNumberObj, closeMyModel, myModelList, myModelState, listHeight, bottomTpsStyle, TAHomePage, sendMessage, avatarState, openUserInfo, isNeedLogin, handleInputYou, openListIAnswer, isListEmptyState, cutYourAnswerAnonymous, yourAnswer, handleLogo, inTheEndState, setItemUrl, seo, originUrl, handleMenuState, reasonList, checkList, alertShow, alertText, selectRadio, alertSubmit, cutType, dialogSrc, answerPage, handleDetailsScroll, replaceState, copyText, boxClass, questionPlaceholderState, yourAnswerPlaceholderState, handleInput, handlePaste, itemStyle, listStyle, listBoxStyle, myType, type, pitchIndex, cut, list, keyword, keywordText, getList, total, typeList, typePitch, getDetails, detailsInfo, detailsIsanswered, detailsIscollection, detailsIsmyself, detailShare, detailLoading, answerList, operateLike, operateCollect, IAnswerState, IAnswerEditState, IAnswerInfo, amendIAnswer, openCommentState, handleAllComment, myCollectionList, myCollectionCount, myQuestionsList, myQuestionsCount, myAnswerList, myAnswerCount, cutAnswerPopupState, handleDate, handleCollectionScroll, handleAnswersScroll, handleQuestionsScroll, cancelCollection, getMyCollection, questionsSetp, questionsObj, cutAnonymous, cutQuestionsSetp, cutQuestionsPopupState, questionsTypeList, postingIssue, choosingTheme, handleMy, changeAnonymous, changeAnonymousQuestions, pageHeaderHeight, pageListHeight, questionsTransmitState, questionsTransmitMaskState, closeAllTransmitState, closeTransmitState, handleAnswerTransmitList, closeDetailMode, tabListFixeState, handleListScroll, historicalSearchState, historicalSearchList, searchFocus, searchBlur, searchClick, handleClickHistoricalItem, handleClickClear, isSearchMode, questionsInit, myCount, msg, myOpenDetails, handleAnswerText, getCurrentUrl, loading }; }, }; </script> <style> @import url(/css/index.css); @import url(/css/indexVice.css); </style>