feat: 优化响应式布局并添加签到组件

refactor: 重构CSS和LESS文件以支持响应式设计
fix: 修复图片上传和编辑器解析问题
style: 调整搜索框和日历组件的样式
docs: 更新HTML模板中的广告和操作链接
This commit is contained in:
DESKTOP-RQ919RC\Pc
2025-12-04 19:15:08 +08:00
parent e4f97dafb8
commit 40d83d5374
10 changed files with 775 additions and 237 deletions

File diff suppressed because one or more lines are too long

View File

@@ -55,7 +55,7 @@
}
.signInBox-mask .signInBox {
width: 1060px;
width: min(1060px, 95vw);
background-color: #fff;
border-radius: 20px;
position: relative;
@@ -97,11 +97,14 @@
.signInBox-mask .signInBox .signInBox-content {
align-items: flex-start;
height: 595px;
height: auto;
gap: 16px;
flex-wrap: wrap;
}
.signInBox-mask .signInBox .signInBox-content .left-box {
width: 538px;
flex: 1 1 520px;
max-width: 560px;
padding: 20px 30px 40px;
border-right: 1px dotted #d7d7d7;
}
@@ -252,8 +255,8 @@
}
.signInBox-mask .signInBox .signInBox-content .left-box .calendar-box {
width: 477px;
height: 479px;
width: 100%;
height: auto;
background-color: #fbfbfb;
border-radius: 12px;
flex-direction: column;
@@ -277,14 +280,16 @@
.signInBox-mask .signInBox .signInBox-content .left-box .calendar-box .calendar {
margin: 0 0 14px;
flex-wrap: wrap;
display: grid;
grid-template-columns: repeat(7, minmax(32px, 1fr));
column-gap: 12px;
row-gap: 10px;
}
.signInBox-mask .signInBox .signInBox-content .left-box .calendar-box .calendar .calendar-item {
width: 40px;
height: 40px;
width: 100%;
aspect-ratio: 1 / 1;
border-radius: 50%;
margin-bottom: 10px;
font-size: 17px;
color: #aaaaaa;
position: relative;
@@ -292,7 +297,7 @@
}
.signInBox-mask .signInBox .signInBox-content .left-box .calendar-box .calendar .calendar-item:not(:nth-child(7n)) {
margin-right: 25px;
margin-right: 0;
}
.signInBox-mask .signInBox .signInBox-content .left-box .calendar-box .calendar .calendar-item.formerly {
@@ -324,7 +329,7 @@
}
.signInBox-mask .signInBox .signInBox-content .left-box .calendar-box .sign-in-btn {
height: 48px;
min-height: 48px;
border-radius: 219px;
background-color: #f7c308;
color: #fff;
@@ -346,10 +351,31 @@
color: #555555;
font-size: 15px;
flex-direction: column;
height: inherit;
flex: 1 1 420px;
min-height: 320px;
height: auto;
overflow: auto;
}
@media (max-width: 768px) {
.signInBox-mask .signInBox {
width: 95vw;
}
.signInBox-mask .signInBox .signInBox-content {
flex-direction: column;
gap: 12px;
}
.signInBox-mask .signInBox .signInBox-content .left-box {
max-width: 100%;
border-right: none;
border-bottom: 1px dotted #d7d7d7;
}
.signInBox-mask .signInBox .signInBox-content .sign-in-box {
margin: 0;
border-radius: 12px;
}
}
.signInBox-mask .signInBox .signInBox-content .sign-in-box .sign-in-header {
padding: 24px 30px 9px;
font-size: 14px;

View File

@@ -1777,11 +1777,6 @@ body {
display: none;
padding: 5px;
}
@media screen and (max-width: 480px) {
.head-top .head-more {
display: flex;
}
}
.hot-tag {
background-color: #ffffff;
border: 1px solid #e9eef2;
@@ -1970,6 +1965,7 @@ td {
}
.head-pop.head-pop-show {
left: 0;
display: block !important;
}
.head-pop.head-pop-show .head-more-pop {
animation: slide-in-left 0.5s ease-out forwards;
@@ -2097,3 +2093,208 @@ td {
margin: 0 auto;
box-sizing: content-box;
}
@media (max-width: 1200px) {
.head-pop .head-more-pop {
width: 80vw;
}
.head-pop .head-more-pop .head-more-userinfo {
margin-left: 20px;
padding-right: 20px;
}
.head-pop .head-more-pop .tab-list {
padding-right: 20px;
margin-left: 20px;
}
.head-pop .head-more-pop .tab-list .tab-item {
height: 50px;
padding-left: 20px;
font-size: 14px;
}
.head-pop .head-more-pop .head-more-post {
margin: 40px 0 90px;
}
.head-pop .head-more-pop .cross-icon {
left: calc(50% + 40px);
}
}
@media (max-width: 768px) {
.head-pop .head-more-pop {
width: 100vw;
height: 100vh;
}
.head-pop .head-more-pop .head-more-userinfo {
margin-left: 16px;
padding-right: 16px;
}
.head-pop .head-more-pop .head-more-userinfo .head-more-right {
width: auto;
height: auto;
}
.head-pop .head-more-pop .tab-list {
padding-right: 16px;
margin-left: 16px;
}
.head-pop .head-more-pop .tab-list .tab-item {
height: 46px;
padding-left: 16px;
font-size: 13px;
}
.head-pop .head-more-pop .head-more-post {
margin: 36px 0 80px;
font-size: 16px;
}
.head-pop .head-more-pop .head-more-post .head-more-post-icon {
width: 18px;
height: 18px;
margin-right: 6px;
}
.head-pop .head-more-pop .cross-icon {
left: 50%;
transform: translateX(-50%);
bottom: 15px;
}
}
@media (max-width: 480px) {
.head-pop .head-more-pop .head-more-userinfo {
margin-left: 12px;
padding-right: 12px;
}
.head-pop .head-more-pop .head-more-userinfo .head-more-left .head-more-userinfo-avatar {
width: 36px;
height: 36px;
margin-right: 8px;
}
.head-pop .head-more-pop .head-more-userinfo .head-more-left .head-more-userinfo-username {
font-size: 12px;
}
.head-pop .head-more-pop .head-more-userinfo .head-more-right .information-box {
width: 14px;
height: 14px;
}
.head-pop .head-more-pop .head-more-userinfo .head-more-right .information-box .information-icon {
width: 14px;
height: 14px;
}
.head-pop .head-more-pop .head-more-userinfo .head-more-right .loginBtn {
width: 72px;
height: 28px;
font-size: 12px;
}
.head-pop .head-more-pop .tab-list {
padding-right: 12px;
margin-left: 12px;
}
.head-pop .head-more-pop .tab-list .tab-item {
height: 42px;
padding-left: 14px;
font-size: 12px;
}
.head-pop .head-more-pop .head-more-post {
margin: 24px 0 60px;
font-size: 14px;
}
.head-pop .head-more-pop .head-more-post .head-more-post-icon {
width: 16px;
height: 16px;
margin-right: 6px;
}
.head-pop .head-more-pop .head-more-post .head-more-post-icon .head-more-post-img {
width: 8px;
height: 8px;
}
.head-pop .head-more-pop .cross-icon {
width: 10px;
height: 10px;
padding: 12px;
bottom: 12px;
left: 50%;
transform: translateX(-50%);
}
}
@media screen and (max-width: 1200px) {
header.page-header {
min-width: auto !important;
}
header.page-header .box {
width: 100vw;
}
.head-top.flexacenter {
max-width: 1200px !important;
width: initial !important;
margin: 20px 10px 30px !important;
}
.head-top.flexacenter .input-box {
margin-right: 10px;
}
.index-footer {
min-width: inherit !important;
}
}
@media screen and (max-width: 768px) {
header.page-header {
display: none !important;
}
.head-top .head-more {
display: flex;
}
.index-footer {
display: none !important;
}
.head-top .post-list {
display: none !important;
}
#search .search-box {
width: auto !important;
margin: 0 10px 20px;
height: 40px !important;
}
#search .classify {
margin-left: 10px;
margin-right: 10px;
}
#search .matter .matter-content {
margin: 0 10px;
}
#search .matter .sidebar-box {
display: none;
}
#search .matter .search-box {
margin-left: 10px;
margin-right: 10px;
}
.item-box {
padding: 18px 10px 0;
}
.item-box .comment .text {
width: calc(100vw - 122px);
}
.item-box .bottom .bottom-item:not(:last-child) {
margin-right: 30px;
}
}
@media screen and (max-width: 500px) {
#search .classify .item {
min-width: inherit;
font-size: 13px;
height: 28px;
line-height: 28px;
border-radius: 8px;
}
}
@media screen and (max-width: 480px) {
.head-top.flexacenter {
margin-bottom: 10px !important;
}
.item-box .bottom {
height: 55px;
justify-content: space-between;
}
.item-box .bottom .bottom-item:not(:last-child) {
margin-right: 0;
}
}
@media screen and (max-width: 450px) {
#search .classify .item {
padding: 0 5px;
}
}

View File

@@ -2140,14 +2140,6 @@ body {
}
}
@media screen and (max-width: 480px) {
.head-top {
.head-more {
display: flex;
}
}
}
.hot-tag {
background-color: rgba(255, 255, 255, 1);
border: 1px solid rgba(233, 238, 242, 1);
@@ -2369,6 +2361,7 @@ td {
&.head-pop-show {
left: 0;
display: block !important;
.head-more-pop {
animation: slide-in-left 0.5s ease-out forwards;
@@ -2515,5 +2508,238 @@ td {
margin: 0 auto;
box-sizing: content-box;
}
// 响应式断点1200 / 768 / 480
@media (max-width: 1200px) {
width: 80vw;
.head-more-userinfo {
margin-left: 20px;
padding-right: 20px;
}
.tab-list {
padding-right: 20px;
margin-left: 20px;
.tab-item {
height: 50px;
padding-left: 20px;
font-size: 14px;
}
}
.head-more-post {
margin: 40px 0 90px;
}
.cross-icon {
left: calc(50% + 40px);
}
}
@media (max-width: 768px) {
width: 100vw;
height: 100vh;
.head-more-userinfo {
margin-left: 16px;
padding-right: 16px;
.head-more-right {
width: auto;
height: auto;
}
}
.tab-list {
padding-right: 16px;
margin-left: 16px;
.tab-item {
height: 46px;
padding-left: 16px;
font-size: 13px;
}
}
.head-more-post {
margin: 36px 0 80px;
font-size: 16px;
.head-more-post-icon {
width: 18px;
height: 18px;
margin-right: 6px;
}
}
.cross-icon {
left: 50%;
transform: translateX(-50%);
bottom: 15px;
}
}
@media (max-width: 480px) {
.head-more-userinfo {
margin-left: 12px;
padding-right: 12px;
.head-more-left {
.head-more-userinfo-avatar {
width: 36px;
height: 36px;
margin-right: 8px;
}
.head-more-userinfo-username {
font-size: 12px;
}
}
.head-more-right {
.information-box {
width: 14px;
height: 14px;
.information-icon {
width: 14px;
height: 14px;
}
}
.loginBtn {
width: 72px;
height: 28px;
font-size: 12px;
}
}
}
.tab-list {
padding-right: 12px;
margin-left: 12px;
.tab-item {
height: 42px;
padding-left: 14px;
font-size: 12px;
}
}
.head-more-post {
margin: 24px 0 60px;
font-size: 14px;
.head-more-post-icon {
width: 16px;
height: 16px;
margin-right: 6px;
.head-more-post-img {
width: 8px;
height: 8px;
}
}
}
.cross-icon {
width: 10px;
height: 10px;
padding: 12px;
bottom: 12px;
left: 50%;
transform: translateX(-50%);
}
}
}
}
@media screen and (max-width: 1200px) {
header.page-header {
min-width: auto !important;
.box {
width: 100vw;
}
}
.head-top.flexacenter {
max-width: 1200px !important;
width: initial !important;
margin: 20px 10px 30px !important;
.input-box {
margin-right: 10px;
}
}
.index-footer {
min-width: inherit !important;
}
}
// 媒体查询 最大宽度 768px 时
@media screen and (max-width: 768px) {
header.page-header {
display: none !important;
}
.head-top {
.head-more {
display: flex;
}
}
.index-footer {
display: none !important;
}
.head-top .post-list {
display: none !important;
}
#search {
.search-box {
width: auto !important;
margin: 0 10px 20px;
height: 40px !important;
}
.classify {
margin-left: 10px;
margin-right: 10px;
}
.matter {
.matter-content {
margin: 0 10px;
}
.sidebar-box {
display: none;
}
.search-box {
margin-left: 10px;
margin-right: 10px;
}
}
}
.item-box {
padding: 18px 10px 0;
.comment .text {
width: calc(100vw - 122px);
}
.bottom .bottom-item:not(:last-child) {
margin-right: 30px;
}
}
}
@media screen and (max-width: 500px) {
#search .classify .item {
min-width: inherit;
font-size: 13px;
height: 28px;
line-height: 28px;
border-radius: 8px;
}
}
@media screen and (max-width: 480px) {
.head-top.flexacenter {
margin-bottom: 10px !important;
}
.item-box .bottom {
height: 55px;
justify-content: space-between;
.bottom-item:not(:last-child) {
margin-right: 0;
}
}
}
@media screen and (max-width: 450px) {
#search .classify .item {
padding: 0 5px;
}
}

View File

@@ -1,5 +1,5 @@
#search {
width: 1200px;
max-width: 1200px;
margin: 0 auto;
}
#search .search-box {

View File

@@ -1,5 +1,5 @@
#search {
width: 1200px;
max-width: 1200px;
margin: 0 auto;
.search-box {

View File

@@ -156,6 +156,7 @@
<script src="./js/axios.min.js"></script>
<script src="./js/public.js"></script>
<script type="module" src="./js/homepage-other.js"></script>
<script src="./component/sign-in/sign-in.js"></script>
</body>
</html>

View File

@@ -20,62 +20,13 @@
<body>
<div class="container" id="appIndex">
<!-- <head-top></head-top> -->
<div class="head-top flexacenter">
<a href="/" class="flexacenter" target="_blank">
<img class="logo" src="https://oss.gter.net/logo" alt="" />
</a>
<div class="flex1"></div>
<div class="input-box flexacenter">
<!-- <div class="placeholder" v-if="!searchInputState && !input"> -->
<div class="placeholder">
<div class="placeholder-box" :style="{transform: 'translateY(-' + currentIndex * 36 + 'px)', transition: 'transform .3s ease'}">
<!-- <div class="item one-line-display" v-for="(item,index) in hotSearchWords" :key="index">大家都在搜:{{ item.keyword }}</div>
<div class="item one-line-display" v-for="(item,index) in hotSearchWords.slice(0, 2)" :key="'copy-' + index">大家都在搜:{{ item.keyword }}</div> -->
</div>
</div>
<input class="input flex1" type="text" maxlength="140" /> <img class="icon" onclick="searchEvent()" src="/img/search-icon.svg" />
<div class="search-box-history">
<div class="search-box-history-title">历史搜索</div>
<div class="search-box-history-list">
</div>
</div>
</div>
<div class="post-list flexacenter"><a href="/publish" target="_blank" style="margin-right: 10px"> <img class="post-item" src="/img/post-thread.png" /> </a> <a href="https://offer.gter.net/post" target="_blank" style="margin-right: 10px"> <img class="post-item" src="/img/post-offer.png" /> </a> <a href="https://offer.gter.net/post/summary" target="_blank" style="margin-right: 10px"> <img class="post-item" src="/img/post-summary.png" /> </a> <a href="https://interviewexperience.gter.net/publish" target="_blank" style="margin-right: 10px"> <img class="post-item" src="/img/post-mj.png" /> </a> <a href="https://vote.gter.net/publish" target="_blank" style="margin-right: 10px"> <img class="post-item" src="/img/post-vote.png" /> </a> </div>
<div class="sign-in sign-in-no flexacenter">
<div class="sign-in-no-box" onclick="headSignIn()">
<img class="sign-in-bj" src="/img/sign-in-bj.svg" /><img class="coin-bj" src="/img/coin-bj.svg" />
<img class="coin-icon" src="/img/coin-icon.png" /><span class="text flex1">签到领寄托币</span>
<div class="sign-go flexcenter">
<img class="sign-go-bj" src="/img/sign-go.svg" /> GO
</div>
<img class="petal1" src="/img/petal1.png" />
<img class="petal2" src="/img/petal2.png" />
<img class="petal3" src="/img/petal3.png" />
</div>
<div class="sign-in-already-box">
<img class="sign-icon" src="/img/sign-icon.png" />
<span>已签到,明天再来</span>
</div>
</div>
</div>
<!-- <head-top-web></head-top-web> -->
<bi-card coins="20" token="_TXzU0MGGjdPFL8RR-Qmja2gGEbUCNPUddwAdczWPJctueas3yXWMkYCvr96dc95-Wu_WCMXYd1kHBCRMdIeydneWA5hsg4_a8hkH5tGKdrxdc_OPQtzsCPybE62xK9rPRFsdPwzQI9pqQYthZYqcANTqof0CpHcMS3yUP1NIvFnJ602njRjNTY~"></bi-card>
<!-- <head-top page="index"></head-top> -->
<div class="header-content-box flexflex">
<div class="header-content-left">
<div class="adv-list flexacenter">
<a class="adv-item" target="_blank">
<img class="adv-img" src="https://o.x-php.com/bbs/common/cf/144405a5pqst6fakct81t8.gif" />
</a>
<a class="adv-item" target="_blank">
<img class="adv-img" src="https://o.x-php.com/bbs/common/cf/144405a5pqst6fakct81t8.gif" />
</a>
<div class="headerbanner adv-item">{:html_entity_decode($ad['headerbanner'])}</div>
<div class="subnavbanner adv-item">{:html_entity_decode($ad['subnavbanner'])}</div>
</div>
<!-- 话题和精选 -->
<div class="topic-and-selectives flexflex">
@@ -84,12 +35,14 @@
<img class="icon" src="https://app.gter.net/image/miniApp/offer/well-white.svg" />
<div class="text">话题</div>
</div>
<div class="topic-head flexflex" bind:tap="goDetails" data-uniqid="{{ ongoingbj.uniqid }}">
<div class="title one-line-display">{{ ongoingbj.title }}</div>
<div class="hint one-line-display">{{ ongoingbj.description }}</div>
<div class="topic-head flexflex">
<a class="title one-line-display vuehide" :href="'/details/' + ongoingbj.uniqid" target="_blank"></a>
<a class="title one-line-display" :href="'/details/' + ongoingbj.uniqid" target="_blank" v-cloak>{{ ongoingbj.title }}</a>
<a class="hint one-line-display" :href="'/details/' + ongoingbj.uniqid" target="_blank"></a>
<div class="people flexacenter">
<div class="left flexacenter">
<div class="number">{{ ongoingbj.comments }}</div>
<div class="number vuehide"></div>
<div class="number" v-cloak>{{ ongoingbj.comments }}</div>
<div class="text">人正在讨论</div>
</div>
<div class="right flexacenter">
@@ -100,9 +53,9 @@
</div>
</div>
<div class="topic-list">
<a class="item flexacenter" v-for="(item, index) in pastList" :key="index" :href="'http://14.22.79.19:9551/?tpl=forum/details&uniqid=' + item.uniqid" target="_blank">
<a class="item flexacenter" v-for="(item, index) in pastList" :key="index" :href="'/details/' + item.uniqid" target="_blank">
<img class="img" src="https://app.gter.net/image/miniApp/offer/well-yellow.svg" />
<div class="text one-line-display flex1">{{ item.title }}</div>
<div class="text one-line-display flex1" v-html="item.title"></div>
</a>
</div>
</div>
@@ -113,131 +66,187 @@
<div class="text">精选</div>
</div>
<div class="list flexflex">
<a class="item flexacenter" v-for="(item, index) in topicHandpickedList" :key="index" :href="'http://14.22.79.19:9551/?tpl=forum/details&uniqid=' + item.uniqid" target="_blank">
<a class="item flexacenter" v-for="(item, index) in topicHandpickedList" :key="index" :href="'/details/' + item.uniqid" target="_blank">
<div class="dot"></div>
<div class="text one-line-display">{{ item.title }}</div>
<div class="text one-line-display" v-html="item.title"></div>
</a>
</div>
</div>
</div>
<div class="header-left-bottom-box flexflex">
<a class="adv flexacenter" data-x-event="bbsindexslide" href="https://bbs.gter.net/thread-1663824-1-1.html" title="26Fall祈福求offer得offer" target="_blank">
<img class="adv-icon" src="https://o.x-php.com/Zvt57TuJSUvkyhw-xG_Y2l-U_potcXiB1NFX9ddrB-ebU2ybYKMuA2kGH_7R-9lU990IXj3X-Q7x4Cg0NDI5" alt="26Fall祈福求offer得offer" />
<a class="adv flexacenter" data-x-event="bbsindexslide" href="{$operation['bbsindexslide']['url']}" title="{$operation['bbsindexslide']['title']}" target="_blank">
<img class="adv-icon" src="{$operation['bbsindexslide']['image']}" alt="{$operation['bbsindexslide']['title']}" />
</a>
<div class="list">
<div class="item flexacenter" v-for="(item, index) in 4" :key="index">
{foreach :array_slice($operation['bbsindexarticle'],0,4) as $key=>$vo }
<div class="item flexacenter">
<div class="icon dot-gray"></div>
<a class="one-line-display text flex1" href="https://offer.gter.net/details/XynvPnSnX1KL" target="_blank">26Fall-香港理工大学 MSc Offer</a>
<a class="one-line-display text flex1" href="{$vo['url']}" target="_blank">{$vo['title']}</a>
</div>
{/foreach}
</div>
<div class="list list2">
<div class="item flexacenter" v-for="(item, index) in 4" :key="index">
{foreach :array_slice($operation['bbsindexarticle'],4,8) as $key=>$vo }
<div class="item flexacenter">
<div class="icon dot-gray"></div>
<a class="one-line-display text flex1" href="https://offer.gter.net/details/y9KbiuzHXbmr" target="_blank">26Fall-香港科技大学 MSc Offer</a>
<a class="one-line-display text flex1" href="{$vo['url']}" target="_blank">{$vo['title']}</a>
</div>
{/foreach}
</div>
</div>
</div>
<div class="header-content-right">
<div class="post-entrance">
<div class="entrance-top flexacenter"><img class="icon" src="./img/forum.png" />我要发帖</div>
<a class="entrance-top flexacenter" href="/publish" target="_blank" @click="handleCheckAttest"><img class="icon" src="./img/forum.png" />我要发帖</a>
<div class="entrance-bottom flexacenter">
<a class="item flexcenter" href="https://offer.gter.net/post" target="_blank" style="position: relative">
<img class="icon" src="./img/offer.svg" style="width: 16px" />
<a class="item flexcenter" href="https://offer.gter.net/post" @click="handleCheckAttest" target="_blank">
<div class="icon-box">
<img class="icon" src="{@img/offer-icon-V2.svg}" />
</div>
<span class="text">报Offer</span>
</a>
<a class="item flexcenter" href="https://offer.gter.net/post/summary" target="_blank" style="position: relative">
<img class="icon" src="./img/summarize.png" style="width: 16px" />
<a class="item flexcenter" href="https://offer.gter.net/post/summary" @click="handleCheckAttest" target="_blank">
<div class="icon-box">
<img class="icon" src="{@img/summary-icon-V2.svg}" />
</div>
<span class="text">写总结</span>
</a>
<a class="item flexcenter" href="https://interviewexperience.gter.net/publish" target="_blank" style="position: relative">
<img class="icon" src="./img/mj.png" style="width: 16px" />
<a class="item flexcenter" href="https://interviewexperience.gter.net/publish" @click="handleCheckAttest" target="_blank">
<div class="icon-box">
<img class="icon" src="{@img/mj-icon-V2.svg}" />
</div>
<span class="text">写面经</span>
</a>
<a class="item flexcenter" href="https://vote.gter.net/publish" target="_blank" style="position: relative">
<img class="icon" src="./img/vote.svg" style="width: 16px" />
<a class="item flexcenter" href="https://vote.gter.net/publish" @click="handleCheckAttest" target="_blank">
<div class="icon-box">
<img class="icon" src="{@img/vote-icon-V2.svg}" />
</div>
<span class="text">发起投票</span>
</a>
</div>
</div>
<a class="adv-broadside" ref="custom_2AdvRef">
<img class="adv-broadside-img" src="https://o.x-php.com/bbs/common/cf/152158dpf5eh7pqpaealiq.gif" />
</a>
{if $ad['custom_2']}
<div class="custom_2 adv" ref="custom_2AdvRef">{:html_entity_decode($ad['custom_2'])}</div>
{/if}
<div class="group-box">
<div class="group flexflex">
<div class="group-item flexcenter" v-for="(item, index) in popList" :key="index">
<div class="title">{{ item.title }}</div>
<div class="subtitle">{{ item.subtitle }}</div>
<div class="group-item flexcenter">
<div class="title">26FALL</div>
<div class="subtitle">申请群</div>
<div class="QRcode-box flexcenter">
<img class="QRcode" :src="item.img" />
<img class="QRcode" src="https://o.x-php.com/Zvt57TuJSUvkyhw-xG7Y2l-c-5kpcnzqqsgFptxhcq_cQnrlJKN1WgxCBq_D-81qNDQyOQ~~" />
<div class="text">微信扫码</div>
</div>
</div>
<div class="group-item flexcenter">
<div class="title">申请求助</div>
<div class="subtitle">寄托院校君</div>
<div class="QRcode-box flexcenter">
<img class="QRcode" src="https://u.gter.net/assistantwxqrcode.png" />
<div class="text">微信扫码</div>
</div>
</div>
<div class="group-item flexcenter">
<div class="title">香港租房</div>
<div class="subtitle">交流群</div>
<div class="QRcode-box flexcenter">
<img class="QRcode" src="https://o.x-php.com/Zvt57TuJSUvkyhw-xG7Y2l-c-5kpcnzqqsgFptxhcq_cQnrlJKN1WgxCBq_D-81qNDQyOQ~~" />
<div class="text">微信扫码</div>
</div>
</div>
<div class="group-item flexcenter">
<div class="title">香港租房顾问</div>
<div class="subtitle">寄托方同学</div>
<div class="QRcode-box flexcenter">
<img class="QRcode" src="https://o.x-php.com/Zvt57TuJSUvkyhw-xG7Y2l-d_JkpcHnqqsgFptxhcq_cQnrlcaF2WQQQBq_D-81qNDQyOQ~~" />
<div class="text">微信扫码</div>
</div>
</div>
</div>
</div>
<div class="offer-box" :class="{'small': custom_2AdvRef}" id="offer-box" @mouseover="offerMouseover" @mouseout="offerMouseout">
<div class="offer-box" :class="{'big': !custom_2AdvRef}" id="offer-box" @mouseover="offerMouseover" @mouseout="offerMouseout">
<div class="offer-list" id="offer-list" ref="offerListRef" :style="{'margin-top': -offerMargin + 'px'}">
<a class="item flexflex" :href="item['url']" target="_blank" v-cloak v-for="(item, index) in offerlist" :key="index">
<div class="avatar" :style="{backgroundImage: `url(${item['avatar']})`}"></div>
<a class="item flexflex" :href="item['url']" target="_blank" v-for="(item, index) in offerlist" :key="index">
<div class="avatar" :style="{backgroundImage: `url(${item.user['avatar']})`}"></div>
<div class="">
<div class="condition one-line-display">{{ item["date"] }} {{ item['type'] }}</div>
<div class="titletitle one-line-display">{{ item["content"] }}</div>
<div class="condition one-line-display" v-cloak style="height: 17px;">{{ item["date"] }} {{ item['type_label'] }}</div>
<div class="titletitle one-line-display" v-cloak style="height: 20px;">{{ item["content"] }}</div>
</div>
</a>
</div>
</div>
</div>
</div>
<div class="matter flexflex">
<div class="admission">
<a class="admission-header flexflex" target="_blank" href="https://admissionofficer.gter.net">
<img class="admission-header-icon" src="/img/admission-officer-icon.png">
<div class="admission-header-name flexflex">Hello Admission Officer</div>
</a>
<div class="admission-list flexflex">
{foreach $OfficerToEnrolNewStudents as $key=>$item}
<div class="admission-item flexcenter">
<a class="admission-img" href="{$item['url']}" target="_blank">
<img src="{$item['image']}" alt="{$item['name']}" />
</a>
</div>
{/foreach}
</div>
</div>
<div class="matter flexflex" ref="matterRef">
<div class="matter-content flex1">
<!-- 论坛板块列表 -->
<div class="forum-sections-list">
<img class="img" src="./img/sections-left.svg" />
<img class="img" src="{@img/sections-left.svg}" />
<div class="title">论坛版块</div>
<div class="list">
<template v-for="(item, index) in sectionList" :key="index">
<div class="line flexacenter">
<a class="item flexacenter" v-for="(item, index) in item" :key="index" target="_blank" :href="`/section-index.html?section=${item.uniqid}`">{{ item.name }}</a>
<a class="item flexacenter" v-for="(item, index) in item" :key="index" target="_blank" :href="`/section/${item.uniqid}`">{{ item.name }}</a>
</div>
</template>
</div>
</div>
<div class="list-load-box flexcenter">
<img class="list-load-icon" src="./img/load-icon.svg" />
<div class="list-load-text">加载中</div>
</div>
<item-forum :itemdata="item" v-for="(item, index) in list" :key="index"></item-forum>
</div>
<div class="sidebar" :style="{'top': sidebarHeight + 'px'}" ref="sidebarRef">
<a class="ad-item flexacenter" href="" target="_blank">
<img class="adv-icon" src="https://o.x-php.com/bbs/common/cf/1709075xdbbbvjd8cbxvdd.jpg" alt="26Fall祈福求offer得offer" />
</a>
<a class="ad-item flexacenter" href="" target="_blank">
<img class="adv-icon" src="https://o.x-php.com/bbs/common/cf/1709075xdbbbvjd8cbxvdd.jpg" alt="26Fall祈福求offer得offer" />
</a>
<!-- <item-forum :itemdata="item" v-for="(item, index) in list" :key="index"></item-forum> -->
<template v-for="(item,index) in list" :key="index">
<item-offer v-if=" item.type == 'offer'" :itemdata="item"></item-offer>
<item-summary v-else-if="item.type == 'offer_summary'" :itemdata="item"></item-summary>
<item-vote v-else-if="item.type == 'vote'" :itemdata="item"></item-vote>
<item-mj v-else-if="item.type == 'interviewexperience'" :itemdata="item"></item-mj>
<item-tenement v-else-if="item.type == 'tenement'" :itemdata="item"></item-tenement>
<item-project v-else-if="item.type == 'programs' || tabValue == 'xg'" :itemdata="item"></item-project>
<item-forum v-else :itemdata="item"></item-forum>
</template>
<load-box :loading="loading"></load-box>
</div>
<div class="sidebar" ref="sidebarRef" :style="{'top': sidebarHeight + 'px'}">
{if $ad['custom_1']} <div class="custom_1 ad-item">{:html_entity_decode($ad['custom_1'])}</div> {/if}
{if $ad['custom_3']} <div class="custom_3 ad-item">{:html_entity_decode($ad['custom_3'])}</div> {/if}
<!-- offer -->
<div class="offer-side-box side-box" v-if="offer.length != 0">
<div class="side-header flexacenter">
<div class="left flexacenter">
<img class="header-icon" src="./img/offer-index-icon.png" />
<img class="header-icon" src="{@img/offer-index-icon.png}" />
<div class="title">Offer</div>
</div>
<a class="more flexacenter" href="https://offer.gter.net" target="_blank">
<span>more</span>
<img class="more-icon" src="./img/right-arrow-black.svg" />
<img class="more-icon" src="{@img/right-arrow-black.svg}" />
</a>
</div>
<div class="box">
<a class="item flexflex" v-cloak v-for="item in offer" :key="item" :href="'/details/' + item['uniqid']" target="_blank">
<img class="school-img" :src="item.data['schoollogo']" />
<div class="school-detail flex1 flexflex">
<div class="school-name one-line-display">{{ item.data['schoolname'] }}</div>
<div class="school-name one-line-display vuehide"></div>
<div v-cloak class="school-name one-line-display">{{ item.data['schoolname'] }}</div>
<div class="school-brief one-line-display">{{ item.data['professional'] }}</div>
<div class="school-offer flexacenter">
<span>{{ item.data['degree'] }}</span>
@@ -248,8 +257,8 @@
</div>
</div>
</a>
<a class="add-btn flexcenter" style="position: relative" href="https://offer.gter.net/post" target="_blank" v-cloak>
<img class="add-icon" src="./img/add-btn-black.svg" />
<a class="add-btn flexcenter" @click="handleCheckAttest" style="position: relative" href="https://offer.gter.net/post" target="_blank" v-cloak>
<img class="add-icon" src="{@img/add-btn-black.svg}" />
<div>报Offer</div>
<div v-if="realname == 0 && userInfo.uin > 0" class="open-attest-btn" @click.prevent="openAttest"></div>
</a>
@@ -260,21 +269,21 @@
<div class="vote-side-box side-box" v-if="vote.length != 0">
<div class="side-header flexacenter">
<div class="left flexacenter">
<img class="header-icon" src="./img/vote-index-icon.png" />
<img class="header-icon" src="{@img/vote-index-icon.png}" />
<div class="title">投票</div>
</div>
<a class="more flexacenter" target="_blank" href="https://vote.gter.net">
<span>more</span>
<img class="more-icon" src="./img/right-arrow-black.svg" />
<img class="more-icon" src="{@img/right-arrow-black.svg}" />
</a>
</div>
<div class="box">
<a class="item flexflex" v-cloak v-for="item in vote" :key="item" target="_blank" :href="'https://vote.gter.net/details/' + item['uniqid']">
<a class="item flexflex" v-cloak v-for="item in vote" :key="item" target="_blank" :href="'/details/' + item['uniqid']">
<div class="name one-line-display">{{item['title']}}</div>
<div class="brief">{{ item['message'] }}</div>
<div class="brief">{{ item['content'] }}</div>
</a>
<a class="add-btn flexcenter" style="position: relative" v-cloak target="_blank" href="https://vote.gter.net/publish">
<img class="add-icon" src="./img/add-btn-black.svg" />
<a class="add-btn flexcenter" @click="handleCheckAttest" style="position: relative" v-cloak target="_blank" href="https://vote.gter.net/publish">
<img class="add-icon" src="{@img/add-btn-black.svg}" />
<div>发起投票</div>
<div v-if="realname == 0 && userInfo.uin > 0" class="open-attest-btn" @click.prevent="openAttest"></div>
</a>
@@ -285,25 +294,25 @@
<div class="interviewexperience-side-box side-box" v-if="interviewexperience.length != 0">
<div class="side-header flexacenter">
<div class="left flexacenter">
<img class="header-icon" src="./img/mj-index-icon.png" />
<img class="header-icon" src="{@img/mj-index-icon.png}" />
<div class="title">面经</div>
</div>
<a class="more flexacenter" href="https://interviewexperience.gter.net/" target="_blank">
<span>more</span>
<img class="more-icon" src="./img/right-arrow-black.svg" />
<img class="more-icon" src="{@img/right-arrow-black.svg}" />
</a>
</div>
<div class="box">
<a class="item flexflex" v-cloak v-for="(item,index) in interviewexperience" :key="item" :href="'https://interviewexperience.gter.net/details/' + item['uniqid']" target="_blank">
<a class="item flexflex" v-cloak v-for="(item,index) in interviewexperience" :key="item" :href="'/details/' + item['uniqid']" target="_blank">
<div class="school one-line-display">{{ item.data['schoolname'] }}</div>
<div class="major one-line-display" v-if="item.data['profession']">{{ item.data['profession'] }}</div>
<div class="major one-line-display">{{ item.data['profession'] || item.data['project'] }}</div>
<div class="info">
<img class="icon" :src="item.user['avatar']" />
<span class="text">{{ item['content'] }}</span>
</div>
</a>
<a class="add-btn flexcenter" style="position: relative" href="https://interviewexperience.gter.net/publish" target="_blank" v-cloak>
<img class="add-icon" src="./img/add-btn-black.svg" />
<a class="add-btn flexcenter" @click="handleCheckAttest" style="position: relative" href="https://interviewexperience.gter.net/publish" target="_blank" v-cloak>
<img class="add-icon" src="{@img/add-btn-black.svg}" />
<div>写面经</div>
<div v-if="realname == 0 && userInfo.uin > 0" class="open-attest-btn" @click.prevent="openAttest"></div>
</a>
@@ -484,7 +493,11 @@
startCarousel();
</script>
<script src="./component/sign-in/sign-in.js"></script>
</body>
</html>

View File

@@ -65,7 +65,6 @@ const editApp = createApp({
isLogin.value = true;
}
});
let imageLength = 10;
@@ -173,7 +172,6 @@ const editApp = createApp({
info.value = infoTarget;
token.value = data.token;
initEditor();
})
.catch((err) => {
@@ -211,6 +209,7 @@ const editApp = createApp({
onInsertedImage(imageNode) {
const { src, alt, url, href } = imageNode;
},
async parseImageSrc(src) {
// 如果图片链接中已经包含了 ?aid= ,则说明是本站图片,直接返回,无需处理
if (src.includes("?aid=")) return src;
@@ -233,8 +232,15 @@ const editApp = createApp({
}
} catch (e) {
console.error("Transform network image failed", e);
return "";
}
},
checkImage: (src, alt, url) => {
if (src.indexOf("http") !== 0) {
return "图片网址必须以 http/https 开头";
}
return true;
}, // 也支持 async 函数
},
["uploadImage"]: {
@@ -251,6 +257,8 @@ const editApp = createApp({
async customUpload(file, insertFn) {
try {
const img = await uploading(file, file.name, "image");
console.log("img", img);
insertFn(`${img.url}?aid=${img.aid}`);
} catch (err) {
console.error("上传出错:", err);
@@ -261,7 +269,6 @@ const editApp = createApp({
["insertVideo"]: {
onInsertedVideo(videoNode) {
if (videoNode == null) return;
// console.log(videoNode);
const { src } = videoNode;
// console.log("inserted video", src);
@@ -423,6 +430,7 @@ const editApp = createApp({
// 定义图片处理函数
const processImg = (aid, width, height, href) => {
console.log("processImg", aid, width, height, href);
const image = imageList.find((img) => String(img.aid) === String(aid));
if (!image) return "";
@@ -433,7 +441,7 @@ const editApp = createApp({
let style = "";
const formatStyleVal = (val) => {
if (!val) return null;
if (String(val).endsWith('%')) return val;
if (String(val).endsWith("%")) return val;
const num = Number(val);
return num > 0 ? `${num}px` : null;
};
@@ -445,7 +453,7 @@ const editApp = createApp({
if (wStyle) styleParts.push(`width: ${wStyle}`);
if (hStyle) styleParts.push(`height: ${hStyle}`);
if (styleParts.length > 0) style = `style="${styleParts.join('; ')};"`;
if (styleParts.length > 0) style = `style="${styleParts.join("; ")};"`;
let dataHref = href ? ` data-href="${href}"` : "";
return `<img src="${image.url}?aid=${aid}" data-aid="${aid}"${dataHref} ${style}>`;
@@ -464,6 +472,41 @@ const editApp = createApp({
return imgTag || match;
});
html = html.replace(/\[url=([^\]]+)\]\[img(?:=([0-9.%]+)(?:,([0-9.%]+))?)?\]([^\]]+)\[\/img\]\[\/url\]/gi, (match, href, w, h, inner) => {
if (/^\d+$/.test(inner)) return match;
const formatStyleVal = (val) => {
if (!val) return null;
if (String(val).endsWith("%")) return val;
const num = Number(val);
return num > 0 ? `${num}px` : null;
};
const wStyle = formatStyleVal(w);
const hStyle = formatStyleVal(h);
let styleParts = [];
if (wStyle) styleParts.push(`width: ${wStyle}`);
if (hStyle) styleParts.push(`height: ${hStyle}`);
const styleAttr = styleParts.length > 0 ? ` style="${styleParts.join("; ")};"` : "";
const dataHref = href ? ` data-href="${href}"` : "";
return `<img src="${inner}"${dataHref}${styleAttr}>`;
});
html = html.replace(/\[img(?:=([0-9.%]+)(?:,([0-9.%]+))?)?\]([^\]]+)\[\/img\]/gi, (match, w, h, inner) => {
if (/^\d+$/.test(inner)) return match;
const formatStyleVal = (val) => {
if (!val) return null;
if (String(val).endsWith("%")) return val;
const num = Number(val);
return num > 0 ? `${num}px` : null;
};
const wStyle = formatStyleVal(w);
const hStyle = formatStyleVal(h);
let styleParts = [];
if (wStyle) styleParts.push(`width: ${wStyle}`);
if (hStyle) styleParts.push(`height: ${hStyle}`);
const styleAttr = styleParts.length > 0 ? ` style="${styleParts.join("; ")};"` : "";
return `<img src="${inner}"${styleAttr}>`;
});
// 6. [attachimg] (兼容旧格式)
html = html.replace(/\[attachimg\](\d+)\[\/attachimg\]/gi, (match, aid) => {
const imgTag = processImg(aid, 0, 0, null);
@@ -507,16 +550,16 @@ const editApp = createApp({
__c.innerHTML = html;
// 确保所有顶层元素都是块级元素 (Slate/WangEditor 要求)
const blockTags = ['P', 'DIV', 'H1', 'H2', 'H3', 'H4', 'H5', 'H6', 'BLOCKQUOTE', 'UL', 'OL', 'PRE', 'TABLE', 'FIGURE', 'HR'];
const newContainer = document.createElement('div');
const blockTags = ["P", "DIV", "H1", "H2", "H3", "H4", "H5", "H6", "BLOCKQUOTE", "UL", "OL", "PRE", "TABLE", "FIGURE", "HR"];
const newContainer = document.createElement("div");
let currentInlineNodes = [];
let lastWasBlock = false;
const flushInlines = () => {
if (currentInlineNodes.length > 0) {
if (currentInlineNodes.length > 0) {
const p = document.createElement('p');
currentInlineNodes.forEach(node => p.appendChild(node));
const p = document.createElement("p");
currentInlineNodes.forEach((node) => p.appendChild(node));
newContainer.appendChild(p);
}
currentInlineNodes = [];
@@ -532,7 +575,7 @@ const editApp = createApp({
newContainer.appendChild(node);
// 记录最后添加的是块级元素
lastWasBlock = true;
} else if (node.nodeName === 'BR') {
} else if (node.nodeName === "BR") {
if (currentInlineNodes.length > 0) {
flushInlines();
lastWasBlock = false; // 刚刚结束了一个段落,不算紧挨着块级
@@ -542,8 +585,8 @@ const editApp = createApp({
// 忽略
lastWasBlock = false; // 消耗掉块级后的换行状态,避免连续 BR 被吞
} else {
const p = document.createElement('p');
p.innerHTML = '<br>';
const p = document.createElement("p");
p.innerHTML = "<br>";
newContainer.appendChild(p);
lastWasBlock = false;
}
@@ -585,7 +628,7 @@ const editApp = createApp({
// 提交
const submit = (status) => {
if (location.hostname == "127.0.0.1") status = 0
if (location.hostname == "127.0.0.1") status = 0;
if (realname.value == 0 && userInfoWin.value?.uin > 0) {
openAttest();
@@ -600,7 +643,12 @@ const editApp = createApp({
const infoTarget = { ...info.value } || {};
let content = editor.getHtml();
const obj = formatContent(content);
content = obj.content;
const images = extractImages(editorRef.value);
// const images = obj.images;
const videos = extractVideos(editorRef.value);
infoTarget.attachments = infoTarget.attachments || {};
@@ -611,16 +659,11 @@ const editApp = createApp({
info.value["attachments"]["images"] = images;
info.value["attachments"]["videos"] = videos;
// console.log("原始html", content);
content = formatContent(content);
// console.log("最终html", content);
const data = {
...infoTarget,
content,
};
// console.log("data", data);
ajax("/v2/api/forum/postPublishTopic", {
info: data,
token: token.value,
@@ -643,6 +686,8 @@ const editApp = createApp({
};
const formatContent = (html) => {
let images = [];
if (!html) return "";
// <p><br></p> 转换为单个换行符
html = html.replace(/<p><br><\/p>/gi, "\n");
@@ -671,63 +716,65 @@ const editApp = createApp({
// 4. 处理图片 [img]
html = html.replace(/<img[^>]*>/gi, (imgTag) => {
let aid = "";
// 尝试从 src 中获取 aid
const srcMatch = imgTag.match(/src="([^"]+)"/i);
if (srcMatch) {
const aidMatch = srcMatch[1].match(/[?&]aid=(\d+)/);
if (aidMatch) aid = aidMatch[1];
}
// 尝试从 data-aid 中获取 aid
if (!aid) {
const dataAid = imgTag.match(/data-aid="(\d+)"/i);
if (dataAid) aid = dataAid[1];
}
if (!srcMatch) return "";
const srcUrl = srcMatch[1];
const cleanUrl = srcUrl.split("?")[0];
const aidMatch = srcUrl.match(/[?&]aid=(\d+)/);
if (aidMatch) aid = aidMatch[1];
if (!aid) return ""; // 无法获取 aid跳过
// 获取宽高 (支持 px 和 %)
let w = 0,
h = 0;
const styleMatch = imgTag.match(/style="([^"]+)"/i);
if (styleMatch) {
// 匹配数字+单位 (px或%)
const wMatch = styleMatch[1].match(/width:\s*([\d.]+(?:px|%)?)/i);
const hMatch = styleMatch[1].match(/height:\s*([\d.]+(?:px|%)?)/i);
if (wMatch) {
// 如果是百分比,直接保留字符串;如果是纯数字默认视为 px如果是 px 去掉单位
let val = wMatch[1];
if (val.endsWith('%')) w = val; // 保留百分比字符串
else w = parseFloat(val); // 转为数字 (px)
if (val.endsWith("%")) w = val;
else w = parseFloat(val);
}
if (hMatch) {
let val = hMatch[1];
if (val.endsWith('%')) h = val;
if (val.endsWith("%")) h = val;
else h = parseFloat(val);
}
}
// 兼容 width/height 属性 (通常只有数字)
if (!w) {
const wAttr = imgTag.match(/\swidth="(\d+)"/i);
if (wAttr) w = Number(wAttr[1]);
}
if (!h) {
const hAttr = imgTag.match(/\sheight="(\d+)"/i);
if (hAttr) h = Number(hAttr[1]);
}
const inner = aid ? aid : cleanUrl;
let result = "";
if (w || h) { // 只要有一个有值
if (w || h) {
const formatVal = (val) => {
if (typeof val === 'string' && val.endsWith('%')) return val;
if (typeof val === "string" && val.endsWith("%")) return val;
return val ? parseFloat(Number(val).toFixed(2)) : 0;
};
result = `[img=${formatVal(w)},${formatVal(h)}]${aid}[/img]`;
result = `[img=${formatVal(w)},${formatVal(h)}]${inner}[/img]`;
if (aid) {
images.push({ url: cleanUrl, aid: Number(aid) });
} else {
images.push({ url: cleanUrl });
}
} else {
result = `[img]${aid}[/img]`;
result = `[img]${inner}[/img]`;
if (aid) {
images.push({ url: cleanUrl, aid: Number(aid) });
} else {
images.push({ url: cleanUrl });
}
}
// 处理 data-href包裹在 [url] 中
const hrefMatch = imgTag.match(/data-href="([^"]+)"/i);
if (hrefMatch && hrefMatch[1]) result = `[url=${hrefMatch[1]}]${result}[/url]`;
@@ -785,9 +832,13 @@ const editApp = createApp({
"&quot;": '"',
"&apos;": "'",
};
html = html.replace(/&[a-z]+;/gi, (match) => entities[match] || match);
return html.trim();
return {
content: html.trim(),
images,
};
};
const extractImages = (dom) => {
@@ -802,11 +853,12 @@ const editApp = createApp({
const aid = urlObj.searchParams.get("aid");
const queryIndex = url.indexOf("?");
const cleanUrl = queryIndex !== -1 ? url.substring(0, queryIndex) : url;
images.push({
url: cleanUrl,
aid: Number(aid),
});
if (Number(aid)) {
images.push({
url: cleanUrl,
aid: Number(aid),
});
}
});
return images;

View File

@@ -1,12 +1,23 @@
const { createApp, ref, onMounted, nextTick, onUnmounted, computed, watch, provide } = Vue;
import { headTop } from "../component/head-top/head-top.js";
import { itemForum } from "../component/item-forum/item-forum.js";
import { latestList } from "../component/latest-list/latest-list.js";
import { loadBox } from "../component/load-box/load-box.js";
const { itemForum } = await import(withVer("../component/item-forum/item-forum.js"));
const { itemOffer } = await import(withVer("../component/item-offer/item-offer.js"));
const { itemSummary } = await import(withVer("../component/item-summary/item-summary.js"));
const { itemVote } = await import(withVer("../component/item-vote/item-vote.js"));
const { itemMj } = await import(withVer("../component/item-mj/item-mj.js"));
const { itemTenement } = await import(withVer("../component/item-tenement/item-tenement.js"));
const { headTop } = await import(withVer("../component/head-top/head-top.js"));
const { loadBox } = await import(withVer("../component/load-box/load-box.js"));
const { itemProject } = await import(withVer("../component/item-project/item-project.js"));
const { latestList } = await import(withVer("../component/latest-list/latest-list.js"));
const appIndex = createApp({
setup() {
onMounted(() => getUserInfoWin());
onMounted(() => {
getUserInfoWin();
// const preLoader = document.getElementById("pre-loader");
// if (preLoader) preLoader.style.display = "none";
});
let isLogin = ref(false);
let realname = ref(0); // 是否已经实名
@@ -62,6 +73,8 @@ const appIndex = createApp({
getTalkingRecommend();
getTopicHandpicked();
getTopicLatest();
document.querySelectorAll(".vuehide").forEach((item) => (item.style.display = "none"));
});
let ongoingbj = ref({}); // 话题数据
@@ -70,14 +83,21 @@ const appIndex = createApp({
ajaxGet("/v2/api/forum/talkingRecommend").then((res) => {
if (res.code != 200) return;
let data = res["data"] || [];
const ongoing = data.ongoing || [];
ongoing.forEach((item) => {
if (Array.isArray(item.commentUser)) item.commentUser = item.commentUser.slice(0, 4);
});
const getTargetItem = (arr) => {
const target = arr.find((item) => item.state === 1);
return target !== undefined ? target : arr.length > 0 ? arr[0] : null;
return target !== undefined ? target : arr.length > 0 ? arr[Math.floor(Math.random() * arr.length)] : null; // 随机返回一个
};
ongoingbj.value = getTargetItem(data.ongoing || []);
pastList.value = data.past || [];
ongoingbj.value = getTargetItem(ongoing || []) || {};
console.log("ongoingbj", ongoingbj.value);
const past = data.past || [];
pastList.value = past.sort(() => Math.random() - 0.5).slice(0, 5);
});
};
@@ -138,11 +158,11 @@ const appIndex = createApp({
// 处理 offer 列表滚动
const offerListScrolling = (data) => {
ajax("https://forum.gter.net/api/index/dynamic").then((res) => {
ajaxGet("https://api.gter.net/v2/api/forum/getDynamic").then((res) => {
if (res.code == 200) {
let data = res["data"] || [];
data.forEach((item) => (item.date = strtimeago(item.date)));
data.forEach((item) => (item.date = strtimeago(item.created_at)));
let targetValue = [];
targetValue = [...data, ...data.slice(0, 6)];
@@ -168,7 +188,7 @@ const appIndex = createApp({
if (scrollup) return;
scrollup = new ScrollText("offer-box");
scrollup.LineHeight = 55;
scrollup.LineHeight = 56;
scrollup.Amount = 1;
scrollup.Delay = 1;
scrollup.Start();
@@ -185,29 +205,6 @@ const appIndex = createApp({
if (!event.relatedTarget || !event.currentTarget.contains(event.relatedTarget)) autoOfferListScroll();
};
const popList = [
{
title: "26FALL",
subtitle: "申请群",
img: "https://o.x-php.com/Zvt57TuJSUvkyhw-xG7Y2l-c-5kpcnzqqsgFptxhcq_cQnrlJKN1WgxCBq_D-81qNDQyOQ~~",
},
{
title: "申请求助",
subtitle: "寄托院校君",
img: "https://u.gter.net/assistantwxqrcode.png",
},
{
title: "香港租房",
subtitle: "交流群",
img: "https://o.x-php.com/Zvt57TuJSUvkyhw-xG7Y2l-c-5kpcnzqqsgFptxhcq_cQnrlJKN1WgxCBq_D-81qNDQyOQ~~",
},
{
title: "香港租房顾问",
subtitle: "寄托方同学",
img: "https://o.x-php.com/Zvt57TuJSUvkyhw-xG7Y2l-d_JkpcHnqqsgFptxhcq_cQnrlcaF2WQQQBq_D-81qNDQyOQ~~",
},
];
let sectionList = ref([]);
const getSectionList = () => {
ajaxGet("/v2/api/forum/getSectionList").then((res) => {
@@ -238,7 +235,7 @@ const appIndex = createApp({
const getList = () => {
if (loading.value || page.value == 0) return;
loading.value = true;
ajaxGet(`/v2/api/forum/topicLists?type=thread&page=${page.value || 1}`)
ajaxGet(`/v2/api/forum/topicLists?page=${page.value || 1}`)
.then((res) => {
if (res.code != 200) return;
let data = res.data;
@@ -259,12 +256,34 @@ const appIndex = createApp({
let sidebarHeight = ref(0);
return { sidebarHeight, matterRef, sidebarFixed, sidebarRef, loading, interviewexperience, vote, offer, topicHandpickedList, list, sectionList, popList, custom_2AdvRef, ongoingbj, pastList, offerMouseover, offerMouseout, offerlist, offerListRef };
const handleCheckAttest = (e) => {
if (!isLogin.value) {
goLogin();
e.preventDefault(); // 阻止默认跳转(即使 href 为链接,也强制拦截)
return;
}
if (realname.value === 0 && userInfoWin.value?.uin > 0) {
openAttest();
e.preventDefault(); // 阻止默认跳转(即使 href 为链接,也强制拦截)
}
};
onMounted(() => {
SignInComponent.initComponent()
})
return { handleCheckAttest, sidebarHeight, matterRef, sidebarFixed, sidebarRef, loading, interviewexperience, vote, offer, topicHandpickedList, list, sectionList, custom_2AdvRef, ongoingbj, pastList, offerMouseover, offerMouseout, offerlist, offerListRef };
},
});
appIndex.component("headTop", headTop);
appIndex.component("itemForum", itemForum);
appIndex.component("itemOffer", itemOffer);
appIndex.component("itemSummary", itemSummary);
appIndex.component("itemVote", itemVote);
appIndex.component("itemMj", itemMj);
appIndex.component("itemTenement", itemTenement);
appIndex.component("itemProject", itemProject);
appIndex.component("latestList", latestList);
appIndex.component("load-box", loadBox);