feat: 添加项目库组件并优化搜索页面样式和功能

新增项目库组件item-project,包含学校、专业、学费等信息的展示
优化搜索页面样式,调整分类项宽度和间距
修复搜索页面滚动定位问题,完善分页和URL参数处理
添加本地开发服务器脚本serve.ps1
更新public.css和public.less样式文件
This commit is contained in:
DESKTOP-RQ919RC\Pc
2025-11-20 19:11:48 +08:00
parent c9e229a5cd
commit 40d06c180f
14 changed files with 558 additions and 124 deletions

View File

@@ -29,6 +29,8 @@ const watchList = {
"../component/hot-tag/hot-tag.txt": "../component/hot-tag/hot-tag.js",
// 监听 hot-search.txt同步到 hot-search.js
"../component/hot-search/hot-search.txt": "../component/hot-search/hot-search.js",
// 监听 item-project.txt同步到 item-project.js
"../component/item-project/item-project.txt": "../component/item-project/item-project.js",
// 监听 bi.txt同步到 bi.js
"../component/bi/bi.txt": "../component/bi/bi.js",

View File

@@ -1,16 +1,17 @@
const { createApp, ref, onMounted, nextTick, onUnmounted, computed, watch, provide } = Vue;
import { itemForum } from "/component/item-forum/item-forum.js";
import { itemOffer } from "/component/item-offer/item-offer.js";
import { itemSummary } from "/component/item-summary/item-summary.js";
import { itemVote } from "/component/item-vote/item-vote.js";
import { itemMj } from "/component/item-mj/item-mj.js";
import { itemTenement } from "/component/item-tenement/item-tenement.js";
import { headTop } from "/component/head-top/head-top.js";
import { hotTag } from "/component/hot-tag/hot-tag.js";
import { hotSearch } from "/component/hot-search/hot-search.js";
import { slideshowBox } from "/component/slideshow-box/slideshow-box.js";
import { latestList } from "/component/latest-list/latest-list.js";
import { loadBox } from "/component/load-box/load-box.js";
import { itemForum } from "../component/item-forum/item-forum.js";
import { itemOffer } from "../component/item-offer/item-offer.js";
import { itemSummary } from "../component/item-summary/item-summary.js";
import { itemVote } from "../component/item-vote/item-vote.js";
import { itemMj } from "../component/item-mj/item-mj.js";
import { itemTenement } from "../component/item-tenement/item-tenement.js";
import { itemProject } from "../component/item-project/item-project.js";
import { headTop } from "../component/head-top/head-top.js";
import { hotTag } from "../component/hot-tag/hot-tag.js";
import { hotSearch } from "../component/hot-search/hot-search.js";
import { slideshowBox } from "../component/slideshow-box/slideshow-box.js";
import { latestList } from "../component/latest-list/latest-list.js";
import { loadBox } from "../component/load-box/load-box.js";
const appSearch = createApp({
setup() {
@@ -18,7 +19,8 @@ const appSearch = createApp({
let typeValue = ref(null);
let kw = ref("");
onMounted(() => {
// const params = getUrlParams();
const params = getUrlParams();
console.log("params", params);
// kw.value = params.kw || "";
// const urlObj = new URL(location.href);
// const pathParts = urlObj.pathname.split("/").filter((part) => part);
@@ -26,9 +28,11 @@ const appSearch = createApp({
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;
page.value = 1;
getList();
if (kw.value) getList();
else page.value = null;
getUserInfoWin();
@@ -125,6 +129,8 @@ const appSearch = createApp({
if (loading.value || page.value == null) return;
loading.value = true;
const limit = 20;
window.scrollTo(0, 0);
updateUrlParams({ page: page.value });
ajaxGet(`/v2/api/forum/topicLists?type=${tabValue.value == "all" ? "" : tabValue.value}&page=${page.value}&limit=${limit}&keyword=${kw.value}`)
.then((res) => {
if (res.code != 200) {
@@ -133,6 +139,38 @@ const appSearch = createApp({
}
let data = res.data;
data.data.unshift({
id: 20,
program_en: "Master of Laws in Arbitration and Dispute Resolution",
program_zh: "法学硕士(仲裁及争议解决学)",
program_abbr: "LLMARBDR",
program_code: "P41",
award_en: "Master of Laws in Arbitration and Dispute Resolution",
award_zh: "法学硕士(仲裁及争议解决学)",
subject_area_id: 9,
subject_area_name: "Law",
primary_university: "City University of Hong Kong",
primary_university_id: 3,
status: "ACTIVE",
intake_year: 2026,
disciplineid: 9,
distinctive: "毕业生可参与:当事人、辩护人、专家、仲裁员和调解员",
rank: "42",
department: "法律学院",
admissionsproject: "1",
departmentid: 26,
schoolalias: "城大",
schoolname: "香港城市大学",
tags: ["有奖学金", "论文课程", "26fall 提前批", "Top 50", "专业资格认证"],
schoolenname: "City University of Hong Kong",
intake_month: 9,
schoolid: 311,
tuition_fee: null,
uniqid: "tf1yFYMER8-1bY1t5oLbKaNc2FVhOWM0",
type: "programs",
schoollogo: "https://oss.x-php.com/school/J6BSwE-VfCFkCb1SBaR7ec6NYmTA4pRcOalNHJRfNzUxNg~~",
});
list.value = data.data;
if (list.value.length == 0) page.value = null;
@@ -141,7 +179,14 @@ const appSearch = createApp({
maxPage.value = Math.ceil(count.value / limit);
pagination.value = calculatePagination(page.value, maxPage.value);
updateUrlLastPath(kw.value);
let url = `/search/${kw.value}`;
const hostname = location.hostname;
const localHostReg = /^(localhost|127\.0\.0\.1|\[::1\])$/;
if (localHostReg.test(hostname)) url = `/search.html`;
updateUrlLastPath(url);
removeQueryQ();
})
.catch((err) => {
err = err.data;
@@ -227,29 +272,13 @@ const appSearch = createApp({
const sidebarFixed = ref(false);
const matterFixed = ref(false);
const matterBottom = ref(false);
const handleScroll = () => {
matterHeight.value = -(document.querySelector(".matter-content").offsetHeight - window.innerHeight);
sidebarHeight.value = -(document.querySelector(".sidebar-box").offsetHeight - window.innerHeight);
// const scrollTop = document.documentElement.scrollTop || document.body.scrollTop;
// const clientHeight = window.innerHeight;
// const sideHeight = sidebarRef.value.offsetHeight;
// const matterTop = matterRef.value.offsetTop;
// const matterHeight = matterContentRef.value.offsetHeight;
// console.log("sideHeight", sideHeight);
// console.log("matterHeight", matterHeight);
// if (sideHeight < matterHeight) {
// // 侧边栏滚动固定
// if (scrollTop >= matterTop + sideHeight - clientHeight) sidebarFixed.value = true;
// else sidebarFixed.value = false;
// } else {
// if (scrollTop >= matterTop + matterHeight - clientHeight) matterFixed.value = true;
// else matterFixed.value = false;
// }
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);
@@ -259,7 +288,7 @@ const appSearch = createApp({
let sidebarHeight = ref(0);
let matterHeight = ref(0);
return { matterHeight, sidebarHeight, matterFixed, matterContentRef, sidebarFixed, matterRef, sidebarRef, loading, typeValue, kwValue, startSearch, kw, maxPage, prevPage, nextPage, tabValue, cutTab, tabList, count, list, page, pagination, cutPage };
return { 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);
@@ -268,6 +297,7 @@ 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);