const { createApp, ref, onMounted, nextTick, onUnmounted, computed, watch, provide } = Vue; 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 { hotTag } = await import(withVer("../component/hot-tag/hot-tag.js")); const { hotSearch } = await import(withVer("../component/hot-search/hot-search.js")); const { slideshowBox } = await import(withVer("../component/slideshow-box/slideshow-box.js")); const { latestList } = await import(withVer("../component/latest-list/latest-list.js")); const { loadBox } = await import(withVer("../component/load-box/load-box.js")); const appSearch = createApp({ setup() { let tag = ref(""); let tagValue = ref(null); let typeValue = ref(null); onMounted(() => { // const params = getUrlParams(); // tag.value = params.tag || ""; // const urlObj = new URL(location.href); // const pathParts = urlObj.pathname.split("/").filter((part) => part); // tag.value = pathParts.pop(); tag.value = tagValue.value.innerText; const type = typeValue.value.innerText; if (type) tabValue.value = type; // init(); getList(); getUserInfoWin(); window.addEventListener("scroll", handleScroll); const preLoader = document.getElementById("pre-loader"); if (preLoader) preLoader.style.display = "none"; }); let isLogin = ref(false); let realname = ref(0); // 是否已经实名 let userInfoWin = ref({}); let permissions = ref([]); const getUserInfoWin = () => { const checkUser = () => { const user = window.userInfoWin; if (!user) return; document.removeEventListener("getUser", checkUser); realname.value = user.realname; userInfoWin.value = user; if (user?.uin > 0 || user?.uid > 0) isLogin.value = true; permissions.value = user?.authority || []; }; document.addEventListener("getUser", checkUser); }; const openAttest = () => { const handleAttestClose = () => { document.removeEventListener("closeAttest", handleAttestClose); realname.value = window.userInfoWin?.realname || 0; }; // 启动认证流程时添加监听 document.addEventListener("closeAttest", handleAttestClose); loadAttest(2); }; // 跳转登录 const goLogin = () => { if (typeof window === "undefined") return; if (window["userInfoWin"] && Object.keys(window["userInfoWin"]).length !== 0) { if (window["userInfoWin"]["uid"]) isLogin.value = true; else ajax_login(); } else ajax_login(); }; provide("isLogin", isLogin); provide("userInfoWin", userInfoWin); provide("realname", realname); provide("openAttest", openAttest); provide("goLogin", goLogin); const cutTab = (type) => { if (!uniqid) return; if (tabValue.value == type) return; page.value = 1; list.value = []; count.value = 0; tabValue.value = type; pagination.value = []; updateUrlParams({ type: type == "all" ? null : type }); getList(); }; let tabList = ref({ all: "全部", thread: "论坛", offer: "Offer", offer_summary: "总结", interviewexperience: "面经", vote: "投票", }); let tabValue = ref("all"); let uniqid = ""; const init = () => { ajaxGet(`/v2/api/forum/tagDetails?name=${tag.value}`).then((res) => { if (res.code != 200) { creationAlertBox("error", res.message); page.value = null; return; } const data = res.data; uniqid = data.uniqid; page.value = 1; console.log("data", data); getList(); }); }; let loading = ref(false); let page = ref(1); let maxPage = ref(0); let count = ref(0); let list = ref([]); let pagination = ref([]); const getList = () => { console.log("page.value", page.value); if (loading.value || page.value == 0) return; loading.value = true; // https://api.gter.net/v2/api/forum/topicLists?type=thread&page=1&limit=20&best=1 const limit = 20; window.scrollTo(0, 0); console.log("getList"); ajaxGet(`/v2/api/forum/topicLists?type=${tabValue.value == "all" ? "" : tabValue.value}&page=${page.value}&limit=${limit}&best=1`) .then((res) => { if (res.code != 200) { creationAlertBox("error", res.message); return; } let data = res.data; list.value = data.data; if (list.value.length == 0) page.value = null; count.value = data.count; loading.value = false; maxPage.value = Math.ceil(count.value / limit); pagination.value = calculatePagination(page.value, maxPage.value); }) .catch((err) => { err = err.data; if (err.code == 401) goLogin(); loading.value = false; }); }; const calculatePagination = (currentPage, totalPages, visibleCount = 3) => { // 处理特殊情况:总页数小于等于1时,无需显示分页 if (totalPages <= 1) { return []; } const pages = []; // 始终显示第一页 pages.push(1); // 计算中间需要显示的页码范围 let startPage = Math.max(2, currentPage - Math.floor(visibleCount / 2)); let endPage = Math.min(totalPages - 1, startPage + visibleCount - 1); // 调整起始页码,确保显示足够数量的页码 startPage = Math.max(2, endPage - visibleCount + 1); // 前面的省略号:如果第一页和起始页之间有间隔 if (startPage > 2) { pages.push("..."); } // 添加中间的页码 for (let i = startPage; i <= endPage; i++) { pages.push(i); } // 后面的省略号:如果最后一页和结束页之间有间隔 if (endPage < totalPages - 1) { pages.push("..."); } // 始终显示最后一页(如果总页数大于1) if (totalPages > 1) { pages.push(totalPages); } return pages; }; const cutPage = (value) => { if (value == "...") return; if (value == page.value) return; page.value = value; list.value = []; getList(); }; const prevPage = () => { page.value -= 1; pagination.value = []; list.value = []; getList(); }; const nextPage = () => { page.value += 1; pagination.value = []; list.value = []; getList(); }; const sidebarFixed = ref(false); const handleScroll = () => { // const scrollTop = document.documentElement.scrollTop || document.body.scrollTop; // const clientHeight = window.innerHeight; // // 侧边栏滚动固定 // if (scrollTop >= matterRef.value.offsetTop + sidebarRef.value.offsetHeight - clientHeight) sidebarFixed.value = true; // else sidebarFixed.value = false; matterHeight.value = -(contentRef.value.offsetHeight - window.innerHeight); sidebarHeight.value = -(sidebarRef.value.offsetHeight - window.innerHeight); if (matterHeight.value > 0) matterHeight.value = 12; if (sidebarHeight.value > 0) sidebarHeight.value = 12; }; const matterRef = ref(null); const contentRef = ref(null); const sidebarRef = ref(null); let sidebarHeight = ref(0); let matterHeight = ref(0); return { sidebarHeight, matterHeight, sidebarFixed, contentRef, matterRef, sidebarRef, loading, tagValue, typeValue, maxPage, prevPage, nextPage, tag, tabValue, cutTab, tabList, count, list, page, pagination, cutPage }; }, }); appSearch.component("item-forum", itemForum); appSearch.component("itemOffer", itemOffer); appSearch.component("itemSummary", itemSummary); appSearch.component("itemVote", itemVote); appSearch.component("itemMj", itemMj); appSearch.component("itemTenement", itemTenement); appSearch.component("head-top", headTop); appSearch.component("hot-tag", hotTag); appSearch.component("hot-search", hotSearch); appSearch.component("slideshow-box", slideshowBox); appSearch.component("latest-list", latestList); appSearch.component("load-box", loadBox); appSearch.mount("#search-tag");