diff --git a/component/item-head/item-head.js b/component/item-head/item-head.js
index 330ae90..e0ea088 100644
--- a/component/item-head/item-head.js
+++ b/component/item-head/item-head.js
@@ -167,5 +167,5 @@ export const itemHead = defineComponent({
report,
},
- template: `
{{ item?.user?.nickname || item.nickname || "匿名用户" }}
{{ timestamp }}
公开 匿名
公开发表
匿名发表
{{ item.views }}
举报
{{ item.hidden == 0 ? "隐藏" : "显示" }}
{{ item.recommend == 1 ? "取消" : "" }}推荐
{{ item.best == 1 ? "取消" : "" }}精华
编辑
删除
删除
`,
+ template: `
{{ item?.user?.nickname || item.nickname || "匿名用户" }}
{{ timestamp }}
公开 匿名
公开发表
匿名发表
{{ item.views }}
举报
{{ item.hidden == 0 ? "隐藏" : "显示" }}
{{ item.recommend == 1 ? "取消" : "" }}推荐
{{ item.best == 1 ? "取消" : "" }}精华
编辑
删除
删除
`,
});
diff --git a/component/item-head/item-head.txt b/component/item-head/item-head.txt
index 12f948b..042cc55 100644
--- a/component/item-head/item-head.txt
+++ b/component/item-head/item-head.txt
@@ -62,8 +62,12 @@
diff --git a/js/best.js b/js/best.js
new file mode 100644
index 0000000..d99fc64
--- /dev/null
+++ b/js/best.js
@@ -0,0 +1,266 @@
+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");