const { createApp, ref, onMounted, nextTick, onUnmounted, computed, watch, provide } = Vue; (async function () { 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 { itemProject } = await import(withVer("../component/item-project/item-project.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 kwValue = ref(null); let typeValue = ref(null); let kw = ref(""); onMounted(() => { const params = getUrlParams(); // kw.value = params.kw || ""; // const urlObj = new URL(location.href); // const pathParts = urlObj.pathname.split("/").filter((part) => part); // kw.value = decodeURIComponent(pathParts.pop()); kw.value = kwValue.value.innerText; const tab = typeValue.value.innerText; if (tab) tabValue.value = tab; if (params.page) page.value = params.page; else page.value = 1; if (kw.value) { getList(); isNoSearch.value = false; nextTick(() => { const preLoader = document.getElementById("pre-loader"); if (preLoader) preLoader.style.display = "none"; }); } else { page.value = null; isEmptySearch.value = true; getRecommendList(); } getUserInfoWin(); window.addEventListener("scroll", handleScroll); getTagList(); getSearchList(); document.querySelectorAll(".vuehide").forEach((item) => (item.style.display = "none")); window.addEventListener("popstate", () => { const urlObj = new URL(location.href); const pathParts = urlObj.pathname.split("/").filter((part) => part); const keyword = pathParts[1] ? decodeURIComponent(pathParts[1]) : ""; // /search/keyword... if (keyword) { kw.value = keyword; page.value = 1; list.value = []; getList(true); } else { kw.value = ""; page.value = null; isNoSearch.value = true; getRecommendList(); nextTick(() => { document.querySelectorAll(".vuehide").forEach((item) => (item.style.display = "none")); }); } }); }); let isLogin = ref(false); let realname = ref(0); // 是否已经实名 let userInfoWin = ref({}); let permissions = ref([]); let isme = ref(false); 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 || []; // if (user.uid == 500144) isme.value = true; }; 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 (tabValue.value == type) return; page.value = 1; list.value = []; count.value = 0; tabValue.value = type; pagination.value = []; updateUrlParams({ type: type == "all" ? null : type }); getList(); }; const fetchPageData = (pathname) => { console.log("pathname", pathname); const lastSegment = pathname.split("/").filter(Boolean).pop() || "index"; console.log("当前路径:", pathname, ",最后一段:", lastSegment); }; let tabList = ref({ all: "全部", thread: "论坛", offer: "Offer", offer_summary: "总结", interviewexperience: "面经", vote: "投票", xg: "港校项目", }); let tabValue = ref("all"); let uniqid = ""; const init = () => { ajaxGet(`https://offer.gter.net/miniprogramApi/offer/search`).then((res) => { if (res.code != 200) { creationAlertBox("error", res.message); page.value = 0; return; } }); }; let loading = ref(false); let page = ref(0); let maxPage = ref(0); let count = ref(0); let total = ref(0); let list = ref([]); let pagination = ref([]); const getList = (isHistoryBack = false) => { if (loading.value || page.value == null) return; isNoSearch.value = false; loading.value = true; isEmptySearch.value = false; const limit = 20; window.scrollTo(0, 0); if (!isHistoryBack) updateUrlParams({ page: page.value }); let postHead = null; if (tabValue.value == "xg") { postHead = ajax(`https://api.gter.net/v1/program/getList`, { page: page.value, keyword: kw.value, }); } else postHead = ajaxGet(`/v2/api/forum/topicLists?type=${tabValue.value == "all" ? "" : tabValue.value}&page=${page.value}&limit=${limit}&keyword=${kw.value}`); let historySearchList = JSON.parse(localStorage.getItem("history-search")) || []; historySearchList.unshift(kw.value); historySearchList = [...new Set(historySearchList)]; if (historySearchList.length > 10) historySearchList = historySearchList.splice(0, 10); localStorage.setItem("history-search", JSON.stringify(historySearchList)); postHead .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; total.value = data.total || data.count; count.value = data.count; loading.value = false; maxPage.value = Math.ceil(count.value / limit); pagination.value = calculatePagination(page.value, maxPage.value); if (location.hostname != '127.0.0.1') updateUrlLastPath(`/search/${kw.value}`, true); removeQueryQ(); }) .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; list.value = []; pagination.value = []; getList(); }; const nextPage = () => { page.value += 1; list.value = []; pagination.value = []; getList(); }; const startSearch = (value) => { if (value) kw.value = value; if (kw.value == "") { creationAlertBox("error", "请输入搜索关键词"); return; } page.value = 1; list.value = []; count.value = 0; pagination.value = []; getList(); }; const sidebarFixed = ref(false); const matterFixed = ref(false); const matterBottom = ref(false); const handleScroll = () => { matterHeight.value = -(matterContentRef.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 sidebarRef = ref(null); const matterContentRef = ref(null); let sidebarHeight = ref(0); let matterHeight = ref(0); let isEmptySearch = ref(false); let tagList = ref([]); const getTagList = () => { ajaxGet("/v2/api/forum/getHotTags?limit=20").then((res) => { const data = res.data; tagList.value = data || []; }); }; let placeholder = ref(""); let searchList = ref([]); const getSearchList = () => { ajaxGet("/v2/api/forum/getHotSearchWords?limit=20").then((res) => { const data = res.data || []; searchList.value = data; if (data.length) placeholder.value = data[Math.floor(Math.random() * data.length)].keyword || ""; }); }; let isNoSearch = ref(true); let recommendList = ref([]); // 推荐阅读 const getRecommendList = () => { if (recommendList.value?.length != 0) return; ajaxGet("/v2/api/forum/getRecommendRead").then((res) => { const data = res.data || []; recommendList.value = data || []; }); }; return { placeholder, recommendList, isNoSearch, searchList, tagList, isme, isEmptySearch, total, matterHeight, sidebarHeight, matterBottom, matterFixed, matterContentRef, sidebarFixed, matterRef, sidebarRef, loading, typeValue, kwValue, startSearch, kw, maxPage, prevPage, nextPage, 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("itemProject", itemProject); 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"); })();