// 1. 创建组件模板和样式(内置到 JS 中,无需外部 HTML/Template) const template = document.createElement("template"); template.innerHTML = `
大家都在搜:{{ item.keyword }}
大家都在搜:{{ item.keyword }}
历史搜索
{{ item }}
`; // 2. 定义组件类 class HeadTopWeb extends HTMLElement { constructor() { super(); } // 监听的属性列表 static get observedAttributes() { return ["coins", "token", "pagetpye", "displaytips"]; } // 属性变化回调 attributeChangedCallback(attrName, oldVal, newVal) { this[attrName] = newVal; // 同步属性值到变量 } init(type) { this.fetchGetData(`https://api.gter.net/v2/api/forum/getCoinConfig`).then((res) => { const data = res.data; const strategy = data.config.strategy.url || 0; const mybalance = data.mybalance || 0; const defaultcoinnum = data.defaultcoinnum || 0; // 替换策略链接 this.strategyEl.href = "https://bbs.gter.net/account.php?a=credit&op=rule"; this.mybalanceEl.textContent = mybalance; this.coinsEl.textContent = this.coins; this.defaultcoinnum = defaultcoinnum; this.input.placeholder = `输入投币数,默认${defaultcoinnum}个币`; this.coinsAreaEl.style.display = "flex"; if (type == "unlock") { if (mybalance >= defaultcoinnum) { this.coinsBoxEl.style.display = "none"; this.coinsNoBi.style.display = "none"; this.coinsUnlock.style.display = "flex"; this.coinsUnlock.querySelector(".coinNum").textContent = defaultcoinnum; this.coinsUnlock.querySelector(".balance").textContent = mybalance; this.coinsUnlock.querySelector(".unlock-insertcoins-btn").addEventListener("click", () => this.coinSubmit(type)); } else { this.coinsBoxEl.style.display = "none"; this.coinsUnlock.style.display = "none"; this.coinsNoBi.style.display = "flex"; } } else { this.coinsUnlock.style.display = "none"; this.coinsNoBi.style.display = "none"; this.coinsBoxEl.style.display = "flex"; } }); if (!this.coinListAreaEl.querySelector(".list")) this.getCoinRankList(); const obj = { offer: "Offer", summary: "总结", mj: "面经", thread: "帖子", vote: "投票", }; this.pagetpyeText.textContent = obj[this.pagetpye]; } getCoinRankList() { this.fetchGetData(`https://api.gter.net/v2/api/forum/getCoinRankList?token=${this.token}&limit=1000`).then((res) => { const data = res.data; this.coinListAreaEl.innerHTML = ""; const coinNubmer = data.nubmer; if (coinNubmer == 0) return; const total = `
${coinNubmer}
人参与投币:
`; const coinList = data.data; let list = coinList .map((item) => { return `
${item.rank}
${item.user.nickname || "匿名用户"}
${item.coins}
`; }) .join(""); list = `
${list}
`; const listHTML = total + list; this.coinListAreaEl.innerHTML = listHTML; }); } coinSubmit() { const num = Number(this.input.value || this.defaultcoinnum) || 0; if (num <= 0) { creationAlertBox("error", "投币数量必须大于0"); return; } this.fetchData(`https://api.gter.net/v2/api/forum/postTopicCoin`, { token: this.token, num, }).then((res) => { if (res.code == 200) creationAlertBox("success", res.message); else creationAlertBox("error", res.message); if (res.code != 200) return; let data = res.data; if (this.displaytips == "coindisplayuser") { setTimeout(() => window.location.reload(), 1000); return; } this.mybalanceEl.textContent = Number(this.mybalanceEl.textContent) - num || 0; this.input.value = ""; const coins = data.coins; this.coinsEl.textContent = coins || 0; if (this.pagetpye == "thread") document.querySelector(".action-bar-item.coins .text").textContent = coins || 0; if (this.pagetpye == "vote") document.querySelector(".coinText").textContent = coins || 0; if (this.pagetpye == "mj") document.querySelector(".coinText").textContent = coins || 0; if (this.pagetpye == "offer") document.querySelector(".broadside-text.cursorpointer.coinText").textContent = (coins || 0) + " 寄托币"; if (this.pagetpye == "summary") document.querySelector(".broadside-text.cursorpointer.coinText").textContent = (coins || 0) + " 寄托币"; this.getCoinRankList(); }); } closeCoinBox() { this.coinsAreaEl.style.display = "none"; } // 静态方法,用于在外部调用组件初始化 type normal 展示正常的投币和列表 unlock 解锁插入币弹窗 或者 币不足 static initComponent(type = "normal") { if (window.headTopWebComponent) { window.headTopWebComponent.init(type); return true; } console.warn("head-top-web组件尚未加载或挂载"); return false; } // 生命周期:组件挂载 connectedCallback() { if (this._mounted) return; this.innerHTML = ""; this.appendChild(template.content.cloneNode(true)); this.coins = this.getAttribute("coins") || this.coins || ""; this.token = this.getAttribute("token") || this.token || ""; this.pagetpye = this.getAttribute("pagetpye") || this.pagetpye || ""; this.displaytips = this.getAttribute("displaytips") || this.displaytips || ""; this.input = this.querySelector(".input") || this.input; window.headTopWebComponent = this; this._mounted = true; } // 生命周期:组件卸载 disconnectedCallback() { console.log(`用户卡片 ${this.getAttribute("username")} 已卸载`); } fetchData(url, data) { return new Promise((resolve, reject) => { var xhr = new XMLHttpRequest(); xhr.responseType = "json"; xhr.withCredentials = true; xhr.open("POST", url, true); xhr.setRequestHeader("Content-Type", "application/json"); if (["127.0.0.1", "localhost", "192.168.18.219"].includes(location.hostname)) xhr.setRequestHeader("Authorization", "3b01343c65e3b2fa3ce32ae26feb3a9b"); xhr.onreadystatechange = function () { if (xhr.readyState === 4 && xhr.status === 200) { let response = xhr.response; resolve(response); } }; xhr.send(JSON.stringify(data)); }); } fetchGetData(url) { return new Promise((resolve, reject) => { const xhr = new XMLHttpRequest(); xhr.withCredentials = true; xhr.open("GET", url, true); if (["127.0.0.1", "localhost", "192.168.18.219"].includes(location.hostname)) xhr.setRequestHeader("Authorization", "3b01343c65e3b2fa3ce32ae26feb3a9b"); xhr.onreadystatechange = function () { if (xhr.readyState === 4 && xhr.status === 200) { let response = xhr.response; resolve(JSON.parse(response)); } }; xhr.send(); }); } $ajax(url) { var data = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; return new Promise(function (resolve, reject) { axios .post(url, data, { emulateJSON: true, withCredentials: true, }) .then(function (res) { var data = typeof res.data == "string" ? JSON.parse(res.data) : res.data; if (data.code == 401) { // 需要登录 showWindow("login", "https://passport.gter.net/login/ajax", "get", -1, { cover: true, }); reject(); } resolve(data); }) .catch((err) => { if (err.response.status == 401) showWindow("login", "https://passport.gter.net/login/ajax", "get", -1, { cover: true, }); }); }); } $ajaxget(url) { var data = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; return new Promise(function (resolve, reject) { axios .get( url, {}, { emulateJSON: true, withCredentials: true, } ) .then(function (res) { var data = typeof res.data == "string" ? JSON.parse(res.data) : res.data; if (data.code == 401) { // 需要登录 showWindow("login", "https://passport.gter.net/login/ajax", "get", -1, { cover: true, }); reject(); } resolve(data); }) .catch((error) => { reject(error); }); }); } } // 3. 注册组件(确保只注册一次) head-top-web if (!customElements.get("head-top-web")) customElements.define("head-top-web", HeadTopWeb); // 4. 导出组件类,以便在外部直接调用 window.HeadTopWebComponent = HeadTopWeb;