min-project/pages/projectComparison/projectComparison.js
DESKTOP-RQ919RC\Pc c811ace0dc fix: 解码URL参数以正确处理特殊字符
在`projectComparison.js`和`projectDetails.js`中,添加了对`options.q`参数的解码逻辑,确保URL中的特殊字符被正确解析。这解决了因未解码参数导致的潜在问题。
2025-04-10 18:41:03 +08:00

653 lines
21 KiB
JavaScript
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

// pages/projectComparison/projectComparison.js
var miucms = require('../../utils/miucms.js');
let app = getApp()
const util = require('../../utils/util')
const common = require('../../utils/commonMethod')
Page({
/**
* 页面的初始数据
*/
data: {
projectState: "", // 项目弹窗的状态 '' replace add
screen_data: {},
totalTopHeight: 86,
islogin: false,
isloginBtnState: false, // 登录弹窗的状态
informationState: false, // 授权后可能需要弹出完成信息框 个人背景那些
briefness: false, // 是否开启头部的简单模式
isquick: false, // 快速保存按钮显示
list: [],
projectList: [],
projectPage: 1,
stateObj: {
0: "待定",
1: "主申",
2: "冲刺",
3: "保底",
},
showObj: {},
loading: true,
isInitFinish: false,
user: {},
rankingsObj: {},
selectState: false,
schoolList: [],
schoolPitch: {},
schoolValue: {},
projectList: [],
projectPitch: {},
projectValue: {},
rankingKey: common.rankingKey,
},
/**
* 生命周期函数--监听页面加载
*/
options: {},
ids: [],
onLoad(options) {
if (options.q) {
let decodedUrl = options.q;
while (decodedUrl !== decodeURIComponent(decodedUrl)) {
decodedUrl = decodeURIComponent(decodedUrl);
}
options.q = decodedUrl
}
this.options = options
if (options.ids) {
let decodedUrl = options.ids;
while (decodedUrl !== decodeURIComponent(decodedUrl)) {
decodedUrl = decodeURIComponent(decodedUrl);
}
options.ids = decodedUrl
}
this.ids = options.ids.split(",") || [];
miucms.pageStart(app).then(() => {
const screen_data = app.globalData.screen_data
this.setData({
screen_data,
totalTopHeight: screen_data.totalTopHeight,
islogin: app.globalData.user.uid > 0 ? true : false,
isInitFinish: true,
user: app.globalData.user,
})
if (!this.indexSidebar) this.indexSidebar = this.selectComponent('#index-sidebar')
common.xgBasicData(this, app).then(data => {
let obj = {}
const discipline = JSON.parse(JSON.stringify(data.discipline))
discipline.forEach(element => {
obj[element.value] = element.label
})
const rankings = data.rankings || {}
let rankingsObj = {}
for (const key in rankings) {
const element = rankings[key] || {}
rankingsObj[element.alias] = element.name
}
this.setData({
rankingsObj,
disciplineObj: obj,
})
this.initData()
})
})
},
initData() {
wx.showLoading({
title: '加载中...',
})
this.setData({
loading: true,
})
let url = "https://api.gter.net/v1/program/contrast"
util.wxpost(url, {
projectid: this.ids,
}).then(res => {
if (res.code != 200) return
const data = res.data
const list = data.data || []
let allArr = []
list.forEach(element => allArr.push(common.decodeKey(element)))
const obj = this.data.disciplineObj
Promise.allSettled(allArr).then(res => {
let list = []
res.forEach(element => list.push(element.status === "fulfilled" ? element.value : {}));
list.forEach(element => {
console.log("element", element);
element['result_date'] = element['admissions']?.[0]?.result_time
if (element.accreditations) {
element['accreditation'] = ""
element.accreditations.forEach(ele => {
element['accreditation'] += '- ' + ele.body_full_zh + '\n'
})
}
element['concentration'] = ""
if (element.features?.has_specialization) {
(element.specialization_options || []).forEach((ele) => {
element["concentration"] += "· " + ele + "\n";
});
}
element["english_proficiency_text"] = ""
if (element.admission_requirements[0]) {
(element.admission_requirements?.[0]?.language_requirements || []).forEach(ele => {
if (ele.language = "ENGLISH") {
ele.proof_methods.forEach(el => {
if (el.type == "test") {
el.tests.forEach((e) => {
let text = "";
if (["GMAT", "GMAT Focus Edition"].includes(e.test_name)) text = `Verbal Reasoning ${e.min_score} 分以上`;
else if (e.grade && e.grade == "Pass") text = `等级 ${e.grade}`;
else if (e.grade) text = `等级 ${e.grade} 以上`;
else if (e.sub_scores.length > 0) {
let allEqual = true;
e.sub_scores.forEach((ee) => {
if (ee.score != e.sub_scores[0].score) allEqual = false;
});
const fields = {
Total: "总分",
Reading: "阅读",
Speaking: "口语",
Writing: "写作",
Listening: "听力",
};
if (allEqual) text = `总分 ${e.min_score} 分以上,各项分数不低于 ${e.sub_scores[0].score}`;
else {
e.sub_scores.forEach((ee) => {
if (fields[ee.subject] && ee.score) text += `${fields[ee.subject]} ${ee.score} 分以上、`;
});
if (text.endsWith("、")) text = text.slice(0, -1);
}
} else if (e.min_score) text = `总分 ${e.min_score} 分以上`;
element["english_proficiency_text"] += `${e.test_name}${text} \n`;
});
}
})
}
})
}
const documentsData = [];
const documentsMap = new Map();
element.documents.forEach((item) => {
const key = `${item.document_id}-${item.is_required}`;
if (documentsMap.has(key)) {
const existingItem = documentsMap.get(key);
existingItem.details += `\n${item.details}`;
} else {
const newItem = {
...item
};
documentsMap.set(key, newItem);
documentsData.push(newItem);
}
});
let documents_required = "";
documentsData.forEach((ele) => {
documents_required += `${ele.document_zh}\n${ele.details} \n`;
});
element["documents_required"] = documents_required;
element['entrance_requirements'] = element.admission_requirements?.[0]?.['basic_requirements']
element['tuition_fee_text'] = common.formatNumberWithSpaces(element.admissions?.[0]?.tuition_fee || '')
element['admission_deposit_text'] = common.formatNumberWithSpaces(element.admissions?.[0]?.admission_deposit || '')
if (element.details?.language_of_instruction) {
let strOutput = element.details.language_of_instruction.join(',');
element['language_of_instruction_text'] = strOutput
}
element['period'] = element.details.full_time_normal_year ? (element.details.full_time_normal_year + '年') : '_'
if (element.details.language_of_instruction) {
let strOutput = element.details.language_of_instruction.join(',');
element['language_of_instruction_text'] = strOutput
}
element['disciplinename'] = obj[element.disciplineid] || ''
})
this.setData({
isquick: data.isquick,
list,
}, () => wx.nextTick(() => this.getAllItemHeight()))
}).catch(err => common.toast("出错了,请联系管理员。"))
const ranking = data.ranking
const project = ranking.project || []
let projectArr = []
project.forEach(element => {
projectArr.push({
system: element.system,
year: element.year,
})
})
const projectList = this.removeDuplicates(projectArr)
const school = ranking.school
let schoolArr = []
school.forEach(element => {
schoolArr.push({
system: element.mechanism,
year: element.year,
})
})
// console.log("schoolArr", schoolArr);
const schoolList = this.removeDuplicates(schoolArr)
this.setData({
projectList,
projectPitch: projectList[0] || {},
schoolList,
schoolPitch: schoolList[0] || {},
ranking,
})
this.getProjectValue()
this.getSchoolPitch()
}).finally(() => {
wx.hideLoading()
this.setData({
loading: false,
})
})
},
getProjectValue() {
const projectPitch = this.data.projectPitch
const ids = this.ids || []
const project = this.data.ranking.project || []
let projectValue = {}
ids.forEach((element, index) => {
project.forEach(ele => {
if (projectPitch.system == ele.system && projectPitch.year == ele.year && ele.projectid == element) {
projectValue[ele.projectid] = {
id: ele.id || "-",
rank: ele.rank || "-",
subject: ele.subject || "-",
}
}
})
})
this.setData({
projectValue,
})
},
getSchoolPitch() {
const schoolPitch = this.data.schoolPitch
const school = this.data.ranking.school || []
let schoolValue = {}
school.forEach(ele => {
if (schoolPitch.system == ele.mechanism && schoolPitch.year == ele.year) {
schoolValue[ele.sid] = {
mechanism: ele.mechanism || "",
year: ele.year || "",
rank: ele.rank || "-",
}
}
})
this.setData({
schoolValue,
})
},
// 去掉重复
removeDuplicates(arr) {
const uniqueSet = new Set();
const uniqueArray = [];
arr.forEach(item => {
const itemString = JSON.stringify(item);
if (!uniqueSet.has(itemString)) {
uniqueSet.add(itemString);
uniqueArray.push(item);
}
});
const order = ["QS", "软科", "ruanke", "Shanghai Ranking", "USNEWS", "US News", "usnews", "泰晤士", "Times Higher Education", "麦考林"];
// 对数组进行排序
uniqueArray.sort((a, b) =>
(order.indexOf(a.system) + 1 || Infinity) - (order.indexOf(b.system) + 1 || Infinity) ||
b.year - a.year
);
return uniqueArray
},
getAllItemHeight() {
this.createSelectorQuery().selectAll(".lump .block").boundingClientRect(data => {
let showObj = {}
data.forEach(element => {
const type = element.dataset?.type
if (type != undefined && element.height > 200) {
showObj[type] = {
show: true,
unfold: true,
}
}
})
this.setData({
showObj
})
}).exec();
},
selectIndex: null, // 选中要替换或增加的 下标
// 点击 顶部的 增加 或者 替换 项目
handleProject(e) {
const type = e.currentTarget.dataset.type
const index = e.currentTarget.dataset.index
this.selectIndex = index
this.setData({
projectState: type,
projectList: [],
projectPage: 1,
})
this.getListData()
},
// 点击 关闭 项目弹窗
closeProject() {
this.setData({
projectState: ""
})
},
// 点击 选择项目
selectProject(e) {
const index = e.currentTarget.dataset.index
const type = this.data.projectState
const projectList = this.data.projectList
const target = projectList[index]
// 替换
if (type == 'replace') this.ids[this.selectIndex] = `${target.projectid}`
else this.ids.push(`${target.projectid}`) // 增加
this.initData()
this.setData({
projectState: "",
})
},
// 点击 删除项目
deleteProject(e) {
const index = e.currentTarget.dataset.index || 0
wx.showModal({
title: "确认删除?",
success: res => {
if (!res.confirm) return
this.ids.splice(index, 1); // 从指定下标删除一个元素
const list = this.data.list
list.splice(index, 1); // 从指定下标删除一个元素
this.setData({
list,
})
}
})
},
// 获取项目列表数据
loading: false,
getListData() {
if (this.data.projectPage == 0 || this.loading) return
this.loading = true
wx.showLoading({
title: '加载中...',
})
util.wxpost("https://api.gter.net/v1/program/user", {
limit: 2000,
}).then(res => {
if (res.code != 200) return
const data = res.data
let list = data.data || []
const ids = this.ids
list = list.filter(obj => obj.status === 1 && !ids.includes(`${obj.projectid}`));
this.setData({
projectList: list,
projectPage: data.count > data.limit * data.page ? this.data.projectPage + 1 : 0,
})
}).finally(() => {
wx.hideLoading()
this.loading = false
})
},
// 点击保存
save() {
if (!this.data.islogin) {
this.setData({
isloginBtnState: true
})
return
}
util.wxpost("https://api.gter.net/v1/program/addQuick", {
projectid: this.ids
}).then(res => {
common.toast(res.message)
this.setData({
isquick: true,
})
app.globalData['isquickState'] = true
})
},
cutShow(e) {
const type = e.currentTarget.dataset.type
let showObj = this.data.showObj
showObj[type]['show'] = !showObj[type]['show']
this.setData({
showObj,
})
},
userClickLogin(e) {
let data = e.detail.data
this.setData({
islogin: true,
isloginBtnState: false,
oneselfUser: app.globalData.user,
informationState: data.regdatastep == 'success' ? false : true,
})
this.onLoad(this.options)
},
// 关闭授权登录事件
popClose() {
this.setData({
isloginBtnState: !this.data.isloginBtnState
})
},
// 子组件传值 修改 完善信息组件的状态
revampInformationState() {
this.setData({
informationState: false
})
},
/**
* 生命周期函数--监听页面初次渲染完成
*/
onReady() {
},
/**
* 生命周期函数--监听页面显示
*/
onShow() {},
/**
* 生命周期函数--监听页面隐藏
*/
onHide() {
},
/**
* 生命周期函数--监听页面卸载
*/
onUnload() {
},
/**
* 页面相关事件处理函数--监听用户下拉动作
*/
onPullDownRefresh() {
wx.stopPullDownRefresh()
this.initData()
},
/**
* 页面上拉触底事件的处理函数
*/
onReachBottom() {
},
indexSidebar: null,
windowHeight: 812,
onPageScroll(e) {
const scrollTop = e.scrollTop
let briefness = true
if (scrollTop < 10) briefness = false
// 如果和 data 值 是一样的则 return
if (this.data.briefness == briefness) return
this.setData({
briefness
})
let sidebarState = this.indexSidebar.data.sidebarState
if (scrollTop > this.windowHeight * 3 && sidebarState !== 3) sidebarState = 3
if (scrollTop < this.windowHeight * 3 && sidebarState == 3) sidebarState = 2
// 同一搜集 修改的 sidebarState
if (sidebarState !== this.indexSidebar.data.sidebarState) {
this.indexSidebar.setData({
sidebarState
})
}
this.indexSidebar.openSidebarTwoHide()
},
getShareTitle() {
const list = this.data.list || []
let title = "港校项目对比:"
list.forEach((element, index) => {
title += "【" + element.schoolalias + " | " + element.name_zh + '】' + (index != list.length - 1 ? 'VS' : '')
})
return title
},
getPath() {
let ids = []
const list = this.data.list || []
list.forEach(element => ids.push(element.id))
return `/pages/projectComparison/projectComparison?ids=${ids}`
},
/**
* 用户点击右上角分享
*/
onShareAppMessage() {
return {
title: this.getShareTitle(),
path: this.getPath(),
}
},
onShareTimeline() {
return {
title: this.getShareTitle(),
path: this.getPath(),
}
},
openSelectRank(e) {
const type = e.currentTarget.dataset.type
this.setData({
selectState: true,
selectType: type,
})
},
closeSelectRank() {
this.setData({
selectState: false,
selectType: "",
})
},
handleSelectType(e) {
const index = e.currentTarget.dataset.index
const selectType = this.data.selectType
let target = {}
if (selectType == "rank") target = this.data.projectList[index]
else target = this.data.schoolList[index]
this.setData({
[selectType == "rank" ? 'projectPitch' : 'schoolPitch']: target,
selectType: "",
selectState: false,
})
selectType == "rank" ? this.getProjectValue() : this.getSchoolPitch()
},
goProjectList(e) {
const id = e.currentTarget.dataset.value?.id || ''
if (!id) return
const project = this.data.ranking.project || []
let target = project.find(element => element.id == id);
if (!target) return
const major = encodeURIComponent(target.subject)
const organ = encodeURIComponent(target.system)
common.goPage(`/pages/projectList/projectList?type=subject&system=${organ}&subject=${major}&year=${target.year}`)
},
goProjectSchoolList(e) {
const target = e.currentTarget.dataset.value || ""
if (!target) return
const mechanism = encodeURIComponent(target.mechanism)
common.goPage(`/pages/projectList/projectList?type=school&mechanism=${mechanism}&year=${target.year}`)
},
})