From 73731fbbba5b3fae3426c24ff3a05b8997ee003f Mon Sep 17 00:00:00 2001 From: "DESKTOP-RQ919RC\\Pc" <1300399510@qq.com> Date: Tue, 25 Nov 2025 13:59:12 +0800 Subject: [PATCH] =?UTF-8?q?feat(=E7=AD=BE=E5=88=B0=E7=BB=84=E4=BB=B6):=20?= =?UTF-8?q?=E9=87=8D=E6=9E=84=E7=AD=BE=E5=88=B0=E5=8A=9F=E8=83=BD=E5=B9=B6?= =?UTF-8?q?=E4=BC=98=E5=8C=96=E6=A0=B7=E5=BC=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 添加签到组件到详情页 - 修改签到初始化逻辑,使用SignInComponent代替原有方法 - 优化签到弹窗样式和交互 - 移除调试用的console.log - 更新资源路径为绝对路径 --- component/head-top/head-top.js | 21 +- component/head-top/head-top.txt | 2 +- component/sign-in/sign-in.js | 343 +++++++++++++-------- component/sign-in/sign-in.txt | 80 ++++- details.html | 1 + index.html | 511 ++++++++++++++++---------------- js/details.js | 2 +- js/public.js | 2 - 8 files changed, 555 insertions(+), 407 deletions(-) diff --git a/component/head-top/head-top.js b/component/head-top/head-top.js index 0bb50b9..b5ec901 100644 --- a/component/head-top/head-top.js +++ b/component/head-top/head-top.js @@ -116,16 +116,17 @@ export const headTop = defineComponent({ }, 50); const signIn = () => { - ajax("/v2/api/forum/sign").then((res) => { - if (res.code != 200) { - creationAlertBox("error", res.message); - return; - } + SignInComponent.initComponent(); + // ajax("/v2/api/forum/sign").then((res) => { + // if (res.code != 200) { + // creationAlertBox("error", res.message); + // return; + // } - let data = res.data; - state.value = 1; - creationAlertBox("success", res.message || "签到成功"); - }); + // let data = res.data; + // state.value = 1; + // creationAlertBox("success", res.message || "签到成功"); + // }); }; let pitchState = ref(false); @@ -174,5 +175,5 @@ export const headTop = defineComponent({ return { hotSearchWords, historySearchList, searchEvent, searchInputState, searchHistoryShowState, searchInputFocus, searchInputBlur, page, pitchState, state, signIn, input, currentIndex, pauseCarousel, resumeCarousel }; }, - template: `
大家都在搜:{{ item.keyword }}
大家都在搜:{{ item.keyword }}
历史搜索
{{ item }}
`, + template: `
大家都在搜:{{ item.keyword }}
大家都在搜:{{ item.keyword }}
历史搜索
{{ item }}
`, }); diff --git a/component/head-top/head-top.txt b/component/head-top/head-top.txt index c146532..e8ed4a8 100644 --- a/component/head-top/head-top.txt +++ b/component/head-top/head-top.txt @@ -43,7 +43,7 @@ -
+
已签到,明天再来
diff --git a/component/sign-in/sign-in.js b/component/sign-in/sign-in.js index b419508..8068196 100644 --- a/component/sign-in/sign-in.js +++ b/component/sign-in/sign-in.js @@ -1,5 +1,5 @@ const signTemplate = document.createElement("template"); -signTemplate.innerHTML = `
0
寄托币
签到规则
`; +signTemplate.innerHTML = `
0
寄托币
签到规则
随机奖励
+{{ reward }}
额外奖励
+{{ extra_reward }}
`; class SignInBox extends HTMLElement { static get observedAttributes() { @@ -7,205 +7,286 @@ class SignInBox extends HTMLElement { } constructor() { super(); + this.attachShadow({ mode: "open" }); + this.shadowRoot.appendChild(signTemplate.content.cloneNode(true)); - this._state = { - dayOfWeek: 0, - totalDaysInMonth: 0, - currentDay: 0, - list: [], - showList: [], - showPage: 1, - issign: 0, - }; - this._bindUI(); - this._computeMonth(); - this._init(); - this._getList(); - } - connectedCallback() { - window.signInBox = this; + + this.totalDaysInMonth = 0; + this.currentDay = 0; + this.list = []; + this.showPage = 1; + + this.listEl = this.shadowRoot.querySelector(".signInBox-mask .signInBox-content .sign-in-list"); + this.listNoEl = this.shadowRoot.querySelector(".signInBox-mask .signInBox-content .discuss-list-no"); + this.moreEl = this.shadowRoot.querySelector(".signInBox-mask .signInBox-content .sign-in-more"); + this.finishEl = this.shadowRoot.querySelector(".signInBox-mask .signInBox-content .sign-in-finish"); + + this.bindUI(); + this.computeMonth(); + // this.init(); + // this.getList(); + + this.headerCross = this.shadowRoot.querySelector(".signInBox-mask .signInBox .header-cross"); + + this.headerCross.addEventListener("click", () => { + // document.body.style.overflow = "auto"; + this.shadowRoot.querySelector(".signInBox-mask").style.display = "none"; + }); + + window.signInComponent = this; } + + connectedCallback() {} + attributeChangedCallback(name, oldVal, newVal) { const el = this.shadowRoot.querySelector(`[data-field="${name}"]`); if (el) el.textContent = newVal || "0"; } - setUsers(list) { - const box = this.shadowRoot.querySelector('[data-list="users"]'); - box.innerHTML = list - .map( - (item) => ` -
- - - -
- ` - ) - .join(""); + + renderList(list, type = "push") { + let itemAll = ``; + list.forEach((item) => { + itemAll += `
+ + + +
`; + }); + + if (type == "push") { + this.listEl.innerHTML += itemAll; + } else if (type == "unshift") { + this.listEl.innerHTML = itemAll + this.listEl.innerHTML; + } + this.listEl.style.display = "block"; + + setTimeout(() => { + const itemArr = this.listEl.querySelectorAll(".sign-in-item"); + if (this.list.length > itemArr.length) { + this.moreEl.style.display = "flex"; + this.finishEl.style.display = "none"; + } else { + this.moreEl.style.display = "none"; + this.finishEl.style.display = "flex"; + } + }, 0); } - _bindUI() { + bindUI() { const ruleBtn = this.shadowRoot.querySelector(".bi-rule"); const ruleBox = this.shadowRoot.querySelector(".outer-ring"); ruleBtn.addEventListener("click", () => (ruleBox.hidden = !ruleBox.hidden)); const ruleClose = this.shadowRoot.querySelector(".rule-close"); ruleClose.addEventListener("click", () => (ruleBox.hidden = true)); const signBtn = this.shadowRoot.querySelector('[data-action="sign"]'); - if (signBtn) signBtn.addEventListener("click", () => this._postSign()); + if (signBtn) signBtn.addEventListener("click", () => this.postSign()); } - _pad(n) { + pad(n) { return String(n).padStart(2, "0"); } - _computeMonth() { + computeMonth() { const firstDayOfMonth = new Date(); firstDayOfMonth.setDate(1); - this._state.dayOfWeek = firstDayOfMonth.getDay(); + const dayOfWeek = firstDayOfMonth.getDay(); + const items = []; + for (let i = 0; i < dayOfWeek; i++) { + items.push(`
`); + } + const box = this.shadowRoot.querySelector('[data-list="calendar"]'); + box.innerHTML = items.join(""); const currentDate = new Date(); const currentMonth = currentDate.getMonth() + 1; const currentYear = currentDate.getFullYear(); - this._state.currentDay = currentDate.getDate(); - this._state.totalDaysInMonth = new Date(currentYear, currentMonth, 0).getDate(); + this.currentDay = currentDate.getDate(); + this.totalDaysInMonth = new Date(currentYear, currentMonth, 0).getDate(); } - _init() { - this._fetchGet("https://api.gter.net/v2/api/forum/getSignInfo").then((res) => { + init() { + const mask = this.shadowRoot.querySelector(".signInBox-mask"); + mask.style.display = "none"; + + this.fetchGet("https://api.gter.net/v2/api/forum/getSignInfo").then((res) => { if (res.code != 200) return; + + mask.style.display = "flex"; + const data = res.data || {}; - this._renderCalendar(data.list || {}); - this._setField("integral", Number(data.integral) || 0); - this._setField("signnum", data.signnum || 0); - this._setField("signreward", data.signreward || 0); - this._state.issign = data.issign || 0; + this.renderCalendar(data.list || {}); + this.setField("integral", Number(data.integral) || 0); + this.setField("signnum", data.signnum || 0); + this.setField("signreward", data.signreward || 0); + this.issign = data.issign; + if (data.issign == 1) { + const signBtn = this.shadowRoot.querySelector('[data-action="sign"]'); + signBtn.textContent = "今天已签到,明天记得来哦~"; + signBtn.classList.add("already"); + } + if (data.signnum >= 25) this.shadowRoot.querySelector(".diligent").hidden = false; + const tipsBox = this.shadowRoot.querySelector('[data-list="tips"]'); const tips = data.tips || []; tipsBox.innerHTML = tips .map( (t, i) => ` -
-
- -
-
${t}
-
` +
+
+ +
+
${t}
+
` ) .join(""); + + this.isInit = true; + + this.getList(); }); } - _setField(name, value) { + setField(name, value) { const el = this.shadowRoot.querySelector(`[data-field="${name}"]`); if (el) el.textContent = value; } - _renderCalendar(list) { + renderCalendar(list) { const box = this.shadowRoot.querySelector('[data-list="calendar"]'); const items = []; - for (let i = 1; i <= this._state.totalDaysInMonth; i++) { + for (let i = 1; i <= this.totalDaysInMonth; i++) { let type = 0; let name = ""; - const key = this._pad(i); + const key = this.pad(i); if (list[key]) { type = 2; name = `+${list[key]}`; - } else if (this._state.currentDay > i) type = 1; - else if (this._state.currentDay == i) type = 3; - if (!name) name = this._state.currentDay == i ? "今" : i; + } else if (this.currentDay > i) type = 1; + else if (this.currentDay == i) type = 3; + if (!name) name = this.currentDay == i ? "今" : i; const cls = { 1: "formerly", 2: "already", 3: "today" }[type] || ""; items.push(`
${name}
`); } - box.innerHTML = items.join(""); + box.innerHTML += items.join(""); } - _getList() { - this._fetchGet("https://api.gter.net/v2/api/forum/getSignRankList").then((res) => { + getList() { + this.fetchGet("https://api.gter.net/v2/api/forum/getSignRankList").then((res) => { if (res.code != 200) return; const data = res.data || {}; - this._state.list = data.list || []; - this._state.showList = this._state.list.slice(0, 10); - this.setUsers(this._state.showList); - this._setField("todaycount", data.todaycount || 0); - const more = this.shadowRoot.querySelector(".sign-in-more"); - const finish = this.shadowRoot.querySelector(".sign-in-finish"); - if (this._state.list.length > this._state.showList.length) { - more.hidden = false; - finish.hidden = true; - more.onclick = () => this._moreList(); + + this.list = data.list || []; + let showList = this.list.slice(0, 10) || []; + + if (!Array.isArray(data.my)) { + showList.unshift(data.my); + } + + if (showList.length > 0) this.renderList(showList); + this.setField("todaycount", data.todaycount || 0); + + if (this.list.length > showList.length) { + this.moreEl.style.display = "flex"; + this.finishEl.style.display = "none"; + this.moreEl.onclick = () => this.moreList(); + } else if (this.list.length == 0) { + this.listNoEl.style.display = "flex"; + this.finishEl.style.display = "none"; } else { - more.hidden = true; - finish.hidden = false; + this.moreEl.style.display = "none"; + this.finishEl.style.display = "flex"; } }); } - _moreList() { - const arr = this._state.list.slice(this._state.showPage * 20 - 10, this._state.showPage * 20 + 10); - this._state.showList = this._state.showList.concat(arr); - this._state.showPage++; - this.setUsers(this._state.showList); - const more = this.shadowRoot.querySelector(".sign-in-more"); - const finish = this.shadowRoot.querySelector(".sign-in-finish"); - if (this._state.list.length > this._state.showList.length) { - more.hidden = false; - finish.hidden = true; - } else { - more.hidden = true; - finish.hidden = false; - } + moreList() { + const showList = this.list.slice(this.showPage * 20 - 10, this.showPage * 20 + 10); + this.showPage += 1; + this.renderList(showList); } - _postSign() { + postSign() { + if (this.issign == 1) { + creationAlertBox("error", "今天已签到,明天记得来哦~"); + return; + } + const user = window.userInfoWin; if (!user || (user?.uin <= 0 && user?.uid <= 0)) { creationAlertBox("error", "没有绑定寄托账号"); showWindow("login", "https://passport.gter.net/login/ajax", "get", -1, { cover: true }); return; } - this._fetchPost("https://api.gter.net/v2/api/forum/sign").then((res) => { + + this.fetchPost("https://api.gter.net/v2/api/forum/sign").then((res) => { if (res.code != 200) { creationAlertBox("error", res.message); return; } + // res.data = { + // extra_reward: 0, + // reward: 28, + // rank: 500, + // }; const data = res.data || {}; const rewardT = data.extra_reward * 1 + data.reward * 1 || 0; - this._setField("integral", (Number(this.shadowRoot.querySelector('[data-field="integral"]').textContent) || 0) + rewardT); - this._setField("signnum", (Number(this.shadowRoot.querySelector('[data-field="signnum"]').textContent) || 0) + 1); - this._setField("signreward", (Number(this.shadowRoot.querySelector('[data-field="signreward"]').textContent) || 0) + rewardT); - const myItem = { avatar: user.avatar || "", uniqid: user.uniqid || "", nickname: user.nickname || "匿名用户", rank: data.rank || 1, reward: rewardT, timestamp: this._currentDateTime() }; - this._state.showList.unshift(myItem); - this.setUsers(this._state.showList); - this._cutSucceed(); - localStorage.setItem("signInState", this._currentDate()); + this.setField("integral", (Number(this.shadowRoot.querySelector('[data-field="integral"]').textContent) || 0) + rewardT); + this.setField("signnum", (Number(this.shadowRoot.querySelector('[data-field="signnum"]').textContent) || 0) + 1); + this.setField("signreward", (Number(this.shadowRoot.querySelector('[data-field="signreward"]').textContent) || 0) + rewardT); + const myItem = { avatar: user.avatar || "", uniqid: user.uniqid || "", nickname: user.nickname || "匿名用户", rank: data.rank || 1, reward: rewardT, timestamp: this.currentDateTime() }; + this.renderList([myItem], "unshift"); + this.cutSucceed(data.reward, data.extra_reward); + localStorage.setItem("signInState", this.currentDate()); + + const todayItem = this.shadowRoot.querySelector(".calendar-item.today"); + todayItem.classList.remove("today"); + todayItem.classList.add("already"); + todayItem.innerHTML = `+${rewardT}`; + + this.issign = 1; + + const signBtn = this.shadowRoot.querySelector('[data-action="sign"]'); + signBtn.textContent = "今天已签到,明天记得来哦~"; + signBtn.classList.add("already"); }); } - _cutSucceed() { + cutSucceed(reward, extra_reward) { const mask = this.shadowRoot.querySelector(".succeed-mask"); if (!mask) return; - mask.hidden = false; - setTimeout(() => (mask.hidden = true), 1800); + mask.style.display = "flex"; + if (reward > 0) { + const rewardEl = mask.querySelector(".reward"); + rewardEl.querySelector(".succeed-award-value").textContent = `+${reward}`; + rewardEl.style.display = "flex"; + } + + if (extra_reward > 0) { + const extra_rewardEl = mask.querySelector(".extra_reward"); + extra_rewardEl.querySelector(".succeed-award-value").textContent = `+${extra_reward}`; + extra_rewardEl.style.display = "flex"; + } + setTimeout(() => (mask.style.display = "none"), 1800); } - _currentDate() { + currentDate() { const now = new Date(); - return `${now.getFullYear()}-${this._pad(now.getMonth() + 1)}-${this._pad(now.getDate())}`; + return `${now.getFullYear()}-${this.pad(now.getMonth() + 1)}-${this.pad(now.getDate())}`; } - _currentDateTime() { + currentDateTime() { const d = new Date(); - return `${d.getFullYear()}-${this._pad(d.getMonth() + 1)}-${this._pad(d.getDate())} ${this._pad(d.getHours())}:${this._pad(d.getMinutes())}:${this._pad(d.getSeconds())}`; + return `${d.getFullYear()}-${this.pad(d.getMonth() + 1)}-${this.pad(d.getDate())} ${this.pad(d.getHours())}:${this.pad(d.getMinutes())}:${this.pad(d.getSeconds())}`; } - _fetchPost(url, data = {}) { + fetchPost(url, data = {}) { return new Promise((resolve) => { const xhr = new XMLHttpRequest(); xhr.responseType = "json"; @@ -222,7 +303,7 @@ class SignInBox extends HTMLElement { }); } - _fetchGet(url) { + fetchGet(url) { return new Promise((resolve) => { const xhr = new XMLHttpRequest(); xhr.withCredentials = true; @@ -235,25 +316,37 @@ class SignInBox extends HTMLElement { response = JSON.parse(response); } catch {} resolve(response); + } else if (xhr.status === 401) { + if (typeof ajax_login === "function") ajax_login(); + else window.open("https://passport.gter.net/?referer=" + escape(location.href), "_self"); } }; xhr.send(); }); } + + open() { + // document.body.style.overflow = "hidden"; + if (this.isInit) this.shadowRoot.querySelector(".signInBox-mask").style.display = "flex"; + else { + this.init(); + } + } + + // 静态方法,用于在外部调用组件初始化 type normal 展示正常的投币和列表 unlock 解锁插入币弹窗 或者 币不足 + static initComponent() { + if (window.signInComponent) { + window.signInComponent.open(); + return true; + } + const el = document.createElement("sign-in-box"); + document.body.appendChild(el); + window.signInComponent = el; + el.open(); + return true; + } } if (!customElements.get("sign-in-box")) customElements.define("sign-in-box", SignInBox); -window.signInBoxClass = SignInBox; -// 工厂:按需创建与打开 -(function(){ - let instance = null; - window.signInBox = { - _init(){ - if (!instance){ instance = document.createElement('sign-in-box'); document.body.appendChild(instance); } - const mask = instance.shadowRoot.querySelector('.signInBox-mask'); - if (mask) mask.hidden = false; - instance._init(); - }, - close(){ if (instance){ const mask = instance.shadowRoot.querySelector('.signInBox-mask'); if (mask) mask.hidden = true; } } - }; -})(); + +window.SignInComponent = SignInBox; diff --git a/component/sign-in/sign-in.txt b/component/sign-in/sign-in.txt index 56a091f..8aa9f7e 100644 --- a/component/sign-in/sign-in.txt +++ b/component/sign-in/sign-in.txt @@ -36,6 +36,7 @@ height: 100%; z-index: 10005; background-color: rgba(0, 0, 0, 0.5); + display: none; } .signInBox-mask * { @@ -146,7 +147,7 @@ top: -21px; z-index: 1; width: 522px; - height: 594px; + height: 596px; background-color: #fdda55; padding: 20px; border-radius: 0 0 20px 0; @@ -331,6 +332,12 @@ cursor: pointer; } + .signInBox-mask .signInBox .signInBox-content .left-box .calendar-box .sign-in-btn.already { + background-color: #fdeeb7; + color: #deae07; + font-size: 16px; + } + .signInBox-mask .signInBox .signInBox-content .sign-in-box { margin: 0 15px; border-radius: 20px; @@ -356,6 +363,10 @@ border-bottom: 1px dotted #ebebeb; } + .signInBox-mask .signInBox .signInBox-content .sign-in-box .sign-in-list { + display: none; + } + .signInBox-mask .signInBox .signInBox-content .sign-in-box .sign-in-list .sign-in-item { padding: 11px 0 0 30px; } @@ -429,6 +440,7 @@ color: #d7d7d7; padding-top: 10px; padding-bottom: 10px; + display: none; } .signInBox-mask .signInBox .signInBox-content .sign-in-box .sign-in-more { @@ -437,6 +449,7 @@ padding-top: 10px; padding-bottom: 10px; cursor: pointer; + display: none; } .signInBox-mask .signInBox .signInBox-content .sign-in-box .sign-in-more .sign-in-more-icon { @@ -447,6 +460,7 @@ .signInBox-mask .signInBox .signInBox-content .sign-in-box .discuss-list-no { flex-direction: column; + display: none; } .signInBox-mask .signInBox .signInBox-content .sign-in-box .discuss-list-no .empty-icon { @@ -467,6 +481,7 @@ left: 0; width: 100vw; height: 100vh; + display: none; } .signInBox-mask .succeed-mask .succeed-box { @@ -572,6 +587,10 @@ line-height: 28px; } + .signInBox-mask .succeed-mask .succeed-box .succeed-award-list .succeed-award-item { + display: none; + } + .signInBox-mask .succeed-mask .succeed-box .succeed-award-list .succeed-award-item:not(:last-of-type) { margin-bottom: 12px; } @@ -616,14 +635,14 @@
- - - + + +
- +
0
寄托币
签到规则
@@ -638,21 +657,56 @@
- +
+ +
+
+ + +
+
+
+ +
+
+
+
+
+
+
+ + +
+
+
+
+
随机奖励
+
+{{ reward }}
+
+
+
额外奖励
+
+{{ extra_reward }}
- - -
diff --git a/details.html b/details.html index c871089..e9f9cec 100644 --- a/details.html +++ b/details.html @@ -16,6 +16,7 @@ +
fi88yrHXiDSj
diff --git a/index.html b/index.html index 9361d2a..1f243f3 100644 --- a/index.html +++ b/index.html @@ -1,282 +1,283 @@ -{extend name="forum/base" /} -{block name="link"} - -{/block} + + -{block name="main"} -
- + + + + 论坛首页 + + -
-
-
-
{:html_entity_decode($ad['headerbanner'])}
- -
- -
-
-
- -
话题
-
-
- {{ ongoingbj.title }} - -
-
-
{{ ongoingbj.comments }}
-
人正在讨论
-
-
-
- + + + + + + +
+ + +
按钮
+ + +
+
+ + +
+
+
+ +
话题
+
+
+
{{ ongoingbj.title }}
+
{{ ongoingbj.description }}
+
+
+
{{ ongoingbj.comments }}
+
人正在讨论
+
+
+
+ +
+
- + + +
+ +
+
+
我要发帖
+
-
-
- -
精选
-
- -
-
- -
- - {$operation['bbsindexslide']['title']} + + -
- {foreach :array_slice($operation['bbsindexarticle'],0,4) as $key=>$vo } - - {/foreach} -
-
- {foreach :array_slice($operation['bbsindexarticle'],4,8) as $key=>$vo } - - {/foreach} -
-
-
-
-
- 我要发帖 - -
- {if $ad['custom_2']} -
{:html_entity_decode($ad['custom_2'])}
- {/if} -
-
-
-
{{ item.title }}
-
{{ item.subtitle }}
-
- -
微信扫码
-
-
-
-
- - -
-
- -
- - -
Hello Admission Officer
-
-
- {foreach $OfficerToEnrolNewStudents as $key=>$item} -
- - {$item['name']} - -
- {/foreach} -
-
- -
-
- -
- -
论坛版块
-
- -
-
- - - -
-