diff --git a/css/index.css b/css/index.css index e19d435..b59a554 100644 --- a/css/index.css +++ b/css/index.css @@ -431,6 +431,82 @@ height: 16px; margin-left: 8px; } +.ranking { + width: 1200px; + height: 239px; + background-color: #ffffff; + border-radius: 12px; + padding-left: 30px; +} +.ranking .synthesize { + width: 256px; + margin-right: 65px; +} +.ranking .major { + width: 821px; +} +.ranking .major .head { + justify-content: space-between; +} +.ranking .major .head .more { + font-size: 16px; + color: #333333; + font-weight: 400; +} +.ranking .major .head .more .icon { + width: 16px; + height: 16px; + margin-left: 7px; + transform: rotate(270deg); +} +.ranking .major .list { + flex-wrap: wrap; + justify-content: space-between; +} +.ranking .major .list .item { + width: 371px; +} +.ranking .major .list .item .organ { + font-family: "PingFangSC-Semibold", "PingFang SC Semibold", "PingFang SC", sans-serif; + font-weight: 650; + font-size: 14px; + color: #000000; +} +.ranking .major .list .item .arrows { + width: 12px; + height: 12px; + margin: 0 6px; +} +.ranking .major .list .item .text { + max-width: 195px; +} +.ranking .head { + height: 52px; + line-height: 52px; + font-weight: 650; + font-size: 16px; + color: #000000; + border-bottom: 1px solid #ebebeb; +} +.ranking .list { + padding-top: 11px; +} +.ranking .list .item { + font-size: 14px; + color: #333; + line-height: 24px; +} +.ranking .list .item .dot { + width: 8px; + height: 8px; + background-color: #fddf6d; + border: 1px solid #cab157; + border-radius: 39px; + margin-right: 13px; +} +.ranking .list .item:not(:last-of-type) { + margin-bottom: 8px; +} .recruit { width: 100%; border: 1px solid #ebebeb; diff --git a/css/index.less b/css/index.less index befb238..6fd40d4 100644 --- a/css/index.less +++ b/css/index.less @@ -490,6 +490,88 @@ } } +.ranking { + width: 1200px; + height: 239px; + background-color: rgba(255, 255, 255, 1); + border-radius: 12px; + padding-left: 30px; + .synthesize { + width: 256px; + margin-right: 65px; + } + + .major { + width: 821px; + .head { + justify-content: space-between; + .more { + font-size: 16px; + color: #333333; + font-weight: 400; + .icon { + width: 16px; + height: 16px; + margin-left: 7px; + transform: rotate(270deg); + } + } + } + .list { + flex-wrap: wrap; + justify-content: space-between; + .item { + width: 371px; + .organ { + font-family: "PingFangSC-Semibold", "PingFang SC Semibold", "PingFang SC", sans-serif; + font-weight: 650; + font-size: 14px; + color: #000000; + } + + .arrows { + width: 12px; + height: 12px; + margin: 0 6px; + } + .text { + max-width: 195px; + } + } + } + } + .head { + height: 52px; + line-height: 52px; + font-weight: 650; + font-size: 16px; + color: #000000; + border-bottom: 1px solid #ebebeb; + } + + .list { + padding-top: 11px; + + .item { + .dot { + width: 8px; + height: 8px; + background-color: rgba(253, 223, 109, 1); + border: 1px solid rgba(202, 177, 87, 1); + border-radius: 39px; + margin-right: 13px; + } + font-size: 14px; + color: #333; + line-height: 24px; + + &:not(:last-of-type) { + margin-bottom: 8px; + } + } + } +} + .recruit { width: 100%; // height: 502px; @@ -624,7 +706,6 @@ font-size: 14px; padding: 0 8px; - .img-add { width: 12px; height: 12px; diff --git a/css/projectList.css b/css/projectList.css index ec38d3a..6f47378 100644 --- a/css/projectList.css +++ b/css/projectList.css @@ -126,44 +126,38 @@ color: #000000; width: 62px; } -.boxbox .content .content-left .list .item .info .name { +.boxbox .content .content-left .list .item .info .head { + justify-content: space-between; + align-items: flex-start; +} +.boxbox .content .content-left .list .item .info .head .name { font-weight: 650; font-style: normal; font-size: 16px; color: #000000; margin-bottom: 5px; } +.boxbox .content .content-left .list .item .info .head .grade { + font-size: 14px; + color: #aaaaaa; + text-align: right; + width: max-content; +} +.boxbox .content .content-left .list .item .info .head .grade .sum { + font-weight: 650; + color: #333333; +} .boxbox .content .content-left .list .item .info .name-en { font-size: 13px; line-height: 20px; color: #333333; margin-bottom: 6px; } -.boxbox .content .content-left .list .item .info .city { - font-size: 14px; - color: #7f7f7f; - line-height: 20px; +.boxbox .content .content-left .list .item .info .bottom { + justify-content: space-between; + align-items: flex-start; } -.boxbox .content .content-left .list .item .right { - align-items: flex-end; - position: relative; -} -.boxbox .content .content-left .list .item .grade { - font-size: 14px; - line-height: 28px; - color: #aaaaaa; - margin-bottom: 16px; - text-align: right; - position: absolute; - top: 0; - right: 0; - width: max-content; -} -.boxbox .content .content-left .list .item .grade .sum { - font-weight: 650; - color: #333333; -} -.boxbox .content .content-left .list .item .btn { +.boxbox .content .content-left .list .item .info .bottom .btn { width: 108px; height: 30px; background-color: #f95d5d; @@ -171,11 +165,16 @@ font-size: 14px; color: #ffffff; } -.boxbox .content .content-left .list .item .btn .icon { +.boxbox .content .content-left .list .item .info .bottom .btn .icon { width: 16px; height: 16px; margin-left: 7px; } +.boxbox .content .content-left .list .item .info .bottom .city { + font-size: 14px; + color: #7f7f7f; + line-height: 20px; +} .boxbox .content .screen-box { width: 360px; background-color: #fff; @@ -291,10 +290,30 @@ z-index: -1; } .boxbox .content .screen-box .screen-item.major .major-box .major-list .major-list-list { - margin: 64px 11px 20px; + margin: 64px 0 20px 11px; overflow: auto; height: 400px; } +.boxbox .content .screen-box .screen-item.major .major-box .major-list .major-list-list::-webkit-scrollbar { + width: 0; + height: 0; +} +.boxbox .content .screen-box .screen-item.major .major-box .major-list .initial { + flex-direction: column; + margin-top: 64px; + font-size: 12px; + text-align: center; + line-height: 17px; + color: #aaaaaa; +} +.boxbox .content .screen-box .screen-item.major .major-box .major-list .initial .select { + font-weight: 650; + color: #000000; +} +.boxbox .content .screen-box .screen-item.major .major-box .major-list .initial .item { + padding: 0 7px; + cursor: pointer; +} .boxbox .content .screen-box .screen-item.major .major-box .major-list .major-item { line-height: 26px; font-size: 14px; diff --git a/css/projectList.less b/css/projectList.less index 9ede363..da94846 100644 --- a/css/projectList.less +++ b/css/projectList.less @@ -143,12 +143,34 @@ } .info { - .name { - font-weight: 650; - font-style: normal; - font-size: 16px; - color: #000000; - margin-bottom: 5px; + .head { + justify-content: space-between; + align-items: flex-start; + + .name { + font-weight: 650; + font-style: normal; + font-size: 16px; + color: #000000; + margin-bottom: 5px; + } + + .grade { + font-size: 14px; + // line-height: 28px; + color: #aaaaaa; + // margin-bottom: 16px; + text-align: right; + // position: absolute; + // top: 0; + // right: 0; + width: max-content; + + .sum { + font-weight: 650; + color: #333333; + } + } } .name-en { font-size: 13px; @@ -156,49 +178,36 @@ color: #333333; margin-bottom: 6px; } - .city { - font-size: 14px; - color: #7f7f7f; - line-height: 20px; + + .bottom { + justify-content: space-between; + align-items: flex-start; + .btn { + width: 108px; + height: 30px; + background-color: rgba(249, 93, 93, 1); + border-radius: 95px; + font-size: 14px; + color: #ffffff; + + .icon { + width: 16px; + height: 16px; + margin-left: 7px; + } + } + .city { + font-size: 14px; + color: #7f7f7f; + line-height: 20px; + } } } - .right { - align-items: flex-end; - position: relative; - } - - .grade { - font-size: 14px; - line-height: 28px; - color: #aaaaaa; - margin-bottom: 16px; - text-align: right; - position: absolute; - top: 0; - right: 0; - width: max-content; - - .sum { - font-weight: 650; - color: #333333; - } - } - - .btn { - width: 108px; - height: 30px; - background-color: rgba(249, 93, 93, 1); - border-radius: 95px; - font-size: 14px; - color: #ffffff; - - .icon { - width: 16px; - height: 16px; - margin-left: 7px; - } - } + // .right { + // align-items: flex-end; + // position: relative; + // } } } } @@ -325,9 +334,33 @@ z-index: -1; } .major-list-list { - margin: 64px 11px 20px; + margin: 64px 0 20px 11px; overflow: auto; height: 400px; + + &::-webkit-scrollbar { + width: 0; + height: 0; + } + } + + .initial { + flex-direction: column; + margin-top: 64px; + font-size: 12px; + text-align: center; + line-height: 17px; + color: #aaaaaa; + + .select { + font-weight: 650; + color: #000000; + } + + .item { + padding: 0 7px; + cursor: pointer; + } } .major-item { line-height: 26px; diff --git a/html/index.html b/html/index.html index 568e4ae..e93b3ec 100644 --- a/html/index.html +++ b/html/index.html @@ -20,7 +20,6 @@
-
@@ -226,6 +225,37 @@
+ +
+
+
综合排名
+
+
+
+ QS世界综合排名(2025年) +
+
+
+
+
+ 专业排名 +
+ more + +
+
+
+
+
+
QS
+ +
世界综合排名世界综合排名世界综合排名世界综合排名世界综合排名世界综合排名
+ (2025年) +
+
+
+
+
@@ -475,61 +505,61 @@
diff --git a/html/projectList.html b/html/projectList.html index fa2b3cb..84fe2a8 100644 --- a/html/projectList.html +++ b/html/projectList.html @@ -18,46 +18,67 @@
- 首页 + 首页 - 全部榜单 + 全部榜单 -
QS世界综合排名(2025)
+
+ + +
-
{{ rankingKeyObj[comText.jg] || comText.jg }}世界综合排名({{ comText.year }}年)
-
- QS - - 世界综合排名(2025) -
-
-
- 共 -
{{ comTotal }}
- 个排名 + +
{{ item.rank }}
-
{{ item.name || item.subject }}
+
+
{{ item.name || item.subject }}
+
{{ item.total_score }}
+
{{ item.enname }} {{ item.simple ? `(${ item.simple })` : ''}}
-
{{ item.city || '' }}
-
-
-
{{ item.total_score }}
- - 学校主页 - - +
+
{{ item.city || '' }}
+ + 学校主页 + + +
@@ -86,7 +107,7 @@ 评榜机构
-
{{ item }}
+
{{ rankingKeyObj[item] || item }}
@@ -113,10 +134,13 @@
{{ majChoose.major || '请选择' }}
-
+
-
-
{{ item }}
+
+
{{ item }}
+
+
+
{{ item }}
@@ -127,7 +151,7 @@ 评榜机构
-
{{ item }}
+
{{ rankingKeyObj[item] || item }}
@@ -156,17 +180,46 @@ onMounted(() => { window.addEventListener("scroll", handleScroll); + const params = parseQueryString(location.search) || {}; + if (params.type == "school") { + comDefault.value = { + jg: params.mechanism, + year: params.year, + }; + classifySelect.value = classify.value = params.type; + } else { + majDefault.value = { + major: params.subject, + jg: params.system, + year: params.year, + }; + classifySelect.value = classify.value = params.type; + } + console.log(111, classifySelect.value); getBaseData().then((data) => { const university = JSON.parse(JSON.stringify(data.university || {})); university.forEach((element) => { universityArr.push(element.value); }); - getRankings(); }); }); + const parseQueryString = (queryString) => { + const params = {}; + const query = queryString.substring(1); // 去掉开头的问号 + if (!query) return params; + const pairs = query.split("&"); + for (let i = 0; i < pairs.length; i++) { + const pair = pairs[i].split("="); + const key = decodeURIComponent(pair[0]); + const value = pair[1] ? decodeURIComponent(pair[1]) : null; + params[key] = value; + } + return params; + }; + let universityArr = []; let comOption = ref({}); @@ -186,6 +239,7 @@ let majOption = ref({}); let majDefault = ref({}); + let majText = ref({}); let majChoose = ref({ major: "", jg: "", @@ -203,10 +257,9 @@ $ajax("https://api.gter.net/v1/program/rankings", {}).then((res) => { if (res.code != 200) return; const data = res.data; - console.log(11111, data); const comprehensive = data.comprehensive; - let com = JSON.parse(JSON.stringify(comChoose.value)); + let com = JSON.parse(JSON.stringify(comDefault.value)); for (const key in comprehensive) { let element = comprehensive[key]; @@ -227,7 +280,7 @@ com["token"] = comprehensive[com.jg]?.[com.year] || ""; const discipline = data.discipline; - let maj = JSON.parse(JSON.stringify(majChoose.value)); + let maj = JSON.parse(JSON.stringify(majDefault.value)); const [dOrganizationKey, dOrganizationValue] = Object.entries(discipline)[0]; if (!maj["jg"]) maj["jg"] = dOrganizationKey; if (!maj["major"]) maj["major"] = Object.entries(dOrganizationValue)[0][0]; @@ -253,6 +306,7 @@ let majMajorList = ref([]); let majJgList = ref([]); let majYearList = ref([]); + let initialList = ref([]); const initMaj = () => { const option = majOption.value; const allMajor = Object.values(option).flatMap((institutionData) => Object.keys(institutionData)); @@ -262,6 +316,14 @@ return 0; }); + // 用于记录每个首字母的数量 + let initial = []; + // 为每个对象添加首字母标识并统计首字母数量 + majorList.forEach((item) => { + initial.push(item.charAt(0).toLocaleUpperCase()); + }); + + initialList.value = [...new Set(initial)]; const maj = majDefault.value; // if (maj.jg) { @@ -338,7 +400,12 @@ // 获取 综合排名 数据 const getSynthesizeData = () => { let comChooseObj = comChoose.value || {}; + let comDefaultObj = comDefault.value || {}; + + console.log(comChooseObj["token"] || comDefaultObj["token"]); + + // return $ajaxget("https://api.gter.net/v1/program/comprehensiverankings", { token: comChooseObj["token"] || comDefaultObj["token"], ishongkong: comOnly.value || 0, @@ -361,9 +428,6 @@ if (comChooseObj["token"]) comText.value = JSON.parse(JSON.stringify(comChooseObj)); else comText.value = JSON.parse(JSON.stringify(comDefaultObj)); - - comDefault.value = {}; - classify.value = "school"; }); }; @@ -383,7 +447,10 @@ const scrollHeight = document.documentElement.scrollHeight; const clientHeight = document.documentElement.clientHeight; const scrollTop = window.pageYOffset; - if (scrollTop + clientHeight >= scrollHeight - 50) renderComprehensiveList(); + if (scrollTop + clientHeight >= scrollHeight - 50) { + if (classify.value == "school") renderComprehensiveList(); + else renderDisciplineList(); + } }; const sortedYears = computed(() => { @@ -411,7 +478,10 @@ let majorState = ref(false); // 专业选择状态 // 切换专业选择状态 - const cutMajorState = () => (majorState.value = !majorState.value); + const cutMajorState = () => { + majorState.value = !majorState.value; + if (!majorState.value) initialKey.value = ["A"]; + }; // 选择专业 const selectMajMajor = (value) => { @@ -467,9 +537,14 @@ let text = ""; if (!com.jg) text = "请选择机构"; else if (!com.year) text = "请选择年份"; + console.log("text", text); - if (text) return; + if (text) { + creationAlertBox("error", text); + return; + } comChoose.value["token"] = option[com.jg][com.year]; + comDefault.value = {}; getSynthesizeData(); } else { const option = majOption.value; @@ -478,10 +553,14 @@ if (!maj.major) text = "请选择专业"; else if (!maj.jg) text = "请选择机构"; else if (!maj.year) text = "请选择年份"; + console.log("text", text); - if (text) return; - - majChoose["token"] = option[maj.jg][maj.major][maj.year]; + if (text) { + creationAlertBox("error", text); + return; + } + majChoose.value["token"] = option[maj.jg][maj.major][maj.year]; + majDefault.value = {}; getMajorData(); } }; @@ -520,8 +599,8 @@ majPage.value = 1; renderDisciplineList(); - if (comChooseObj["token"]) comText.value = JSON.parse(JSON.stringify(comChooseObj)); - else comText.value = JSON.parse(JSON.stringify(comDefaultObj)); + if (majChooseObj["token"]) majText.value = JSON.parse(JSON.stringify(majChooseObj)); + else majText.value = JSON.parse(JSON.stringify(majDefaultObj)); classify.value = "subject"; }); @@ -538,7 +617,46 @@ majList.value = majList.value.concat(target); }; - return { majList, majOnly, comOnly, comYearList, comJgList, haveChosen, selectMajYear, selectMajJg, majYearList, majJgList, majMajorList, selectMajMajor, majOption, majChoose, cutMajorState, majorState, selectComJg, selectComYear, sortedYears, classify, classifySelect, cutClassify, rankingKeyObj, comText, comChoose, comList, comTotal, comOption }; + const cutOnlyXg = () => { + comOnly.value = comOnly.value ? 0 : 1; + getSynthesizeData(); + }; + + const majOnlyXg = () => { + majOnly.value = majOnly.value ? 0 : 1; + getMajorData(); + }; + + const majorList = ref(null); + + let initialKey = ref(["A"]); + const majorListScroll = () => { + const itemList = majorList.value.querySelectorAll(".major-item"); + let keyList = []; + itemList.forEach((element) => { + const isVisible = isElementVisibleInScrollContainer(element, majorList.value); + if (isVisible) keyList.push(element.dataset.value); + }); + initialKey.value = [...new Set(keyList)]; + }; + + const isElementVisibleInScrollContainer = (element, container) => { + const elementRect = element.getBoundingClientRect(); + const containerRect = container.getBoundingClientRect(); + return elementRect.top >= containerRect.top && elementRect.bottom <= containerRect.bottom; + }; + + const jumpToIndex = (value) => { + const item = majorList.value.querySelector(`.major-item[data-value=${value}]`); + 3; + const offsetTop = item.offsetTop - 64; + majorList.value.scrollTo({ + top: offsetTop, + behavior: "smooth", + }); + }; + + return { jumpToIndex, initialKey, majorList, majorListScroll, initialList, majOnlyXg, cutOnlyXg, majTotal, majText, majList, majOnly, comOnly, comYearList, comJgList, haveChosen, selectMajYear, selectMajJg, majYearList, majJgList, majMajorList, selectMajMajor, majOption, majChoose, cutMajorState, majorState, selectComJg, selectComYear, sortedYears, classify, classifySelect, cutClassify, rankingKeyObj, comText, comChoose, comList, comTotal, comOption }; }, }); projectIndex.mount("#app");