729 lines
21 KiB
JavaScript
729 lines
21 KiB
JavaScript
// pages/projectDetails/projectDetails.js
|
|
var miucms = require('../../utils/miucms.js');
|
|
let app = getApp()
|
|
const util = require('../../utils/util')
|
|
const common = require('../../utils/commonMethod')
|
|
|
|
Page({
|
|
|
|
/**
|
|
* 页面的初始数据
|
|
*/
|
|
data: {
|
|
informationState: false, // 授权后可能需要弹出完成信息框 个人背景那些
|
|
islogin: false,
|
|
isloginBtnState: false,
|
|
|
|
isFirstPattern: true,
|
|
screen_data: {},
|
|
totalTopHeight: 82,
|
|
|
|
admissionCurrent: 0, // 招生官 轮播图的下标
|
|
admissionState: false, // 招生官 弹窗的状态
|
|
|
|
stateState: false, // 底部状态显示状态
|
|
|
|
headHeight: 0, // 头部 高度
|
|
rpx150: 150,
|
|
index: 0,
|
|
current: {},
|
|
|
|
headerObj: {
|
|
ranking: "专业排名",
|
|
brief: "简介",
|
|
},
|
|
|
|
info: {},
|
|
|
|
remark: "", // 备注
|
|
keyboardHeight: 0, // 键盘高度
|
|
remarkInput: "", // 备注输入文本
|
|
remarkFocus: false, // 备注输入框焦点状态
|
|
|
|
isadmission: 0, // 是否是招生官项目
|
|
urls: [], // 招生官项目
|
|
|
|
uniqid: "",
|
|
info: {},
|
|
|
|
side: {
|
|
pivotal: "关键信息",
|
|
basic: "基本信息",
|
|
apply: "申请信息",
|
|
attend: "就读信息",
|
|
graduate: "毕业&就业",
|
|
consult: "录取参考",
|
|
issue: "常见问题",
|
|
links: "相关链接",
|
|
},
|
|
|
|
|
|
sideKey: "pivotal", // 侧边栏选中 key
|
|
|
|
course: {}, // 课程
|
|
|
|
scrollTop: 0,
|
|
|
|
contras: {}, //
|
|
|
|
stateObj: {
|
|
0: "待定",
|
|
1: "主申",
|
|
2: "冲刺",
|
|
3: "保底",
|
|
},
|
|
|
|
rankingsObj: {}, // 排名对象
|
|
|
|
studyMode: 'ft', // 学习模式显示状态 ft 全日制 pt 兼读制
|
|
|
|
moldObj: {
|
|
1: "直播",
|
|
2: "回放",
|
|
3: "答疑"
|
|
},
|
|
|
|
isInitFinish: false,
|
|
|
|
sideFixed: false,
|
|
rpx30: 30,
|
|
user: {},
|
|
offerList: []
|
|
},
|
|
|
|
/**
|
|
* 生命周期函数--监听页面加载
|
|
*/
|
|
options: {},
|
|
onLoad(options) {
|
|
this.options = options
|
|
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,
|
|
uniqid: options.uniqid,
|
|
rpx150: util.rpxTopx(150),
|
|
rpx30: util.rpxTopx(30),
|
|
user: app.globalData.user,
|
|
})
|
|
|
|
this.windowHeight = screen_data.windowHeight || 812
|
|
|
|
common.xgBasicData(this, app).then(data => {
|
|
this.setData({
|
|
rankingsObj: data.rankings,
|
|
})
|
|
|
|
this.getData()
|
|
})
|
|
})
|
|
},
|
|
|
|
getData() {
|
|
wx.showLoading({
|
|
title: '加载中...',
|
|
})
|
|
util.wxpost("/api/project.detail", {
|
|
uniqid: this.data.uniqid,
|
|
query: {
|
|
...this.options
|
|
},
|
|
}).then(res => {
|
|
const data = res.data
|
|
common.decodeKey(data.info).then(res => {
|
|
console.log("res", res);
|
|
data.info = res
|
|
|
|
let course = {
|
|
required: [],
|
|
requiredCount: 0,
|
|
elective: [],
|
|
electiveCount: 0,
|
|
}
|
|
|
|
const info = data.info || {}
|
|
|
|
const fields = ['tuition_fee', 'tuition_fee_per_credit', 'application_fee', 'admission_deposit'];
|
|
fields.forEach(field => {
|
|
const textKey = `${field}_text`;
|
|
info[textKey] = common.formatNumberWithSpaces(info[field] || '');
|
|
});
|
|
|
|
const curriculum = info.curriculum || []
|
|
|
|
if (info.language_of_instruction) {
|
|
let strOutput = info.language_of_instruction.join(',');
|
|
info['language_of_instruction_text'] = strOutput
|
|
}
|
|
|
|
curriculum.forEach(element => {
|
|
if (element.credit == 'N/A') element.credit = 0
|
|
element.type === '必修课' ? (course.required.push(element), course.requiredCount += element.credit) : (course.elective.push(element), course.electiveCount += element.credit);
|
|
})
|
|
|
|
let contras = data.contras
|
|
if (Array.isArray(contras)) contras = {}
|
|
const remark = contras.remarks || ''
|
|
// 算出最后申请时间
|
|
info['application_end'] = this.calculateApplicaDeadline(info.nonlocal_application_end || {})
|
|
// 算出面试轮时间
|
|
info['interviewRounds'] = this.calculateInterviewRound(info.nonlocal_application_end || {})
|
|
|
|
if (typeof info.mode_of_study == "string") info.mode_of_study = JSON.parse(info.mode_of_study)
|
|
|
|
let side = this.data.side
|
|
// 判断是否常见问题 ,没有则删除左侧
|
|
if (!info.faq || info.faq.length == 0) delete side.issue
|
|
|
|
// 判断 毕业就业 没有则删除左侧
|
|
if (!info.award_zh && !info.graduation_requirements && !info.domains && !info.employers && !info.positions) delete side.graduate
|
|
|
|
// 判断奖学金文案
|
|
if (info.scholarship) info['scholarshipText'] = this.JudgmentScholarshipText(info.scholarship)
|
|
|
|
if (info.leaflet_url) {
|
|
const leaflet_url = decodeURIComponent(info.leaflet_url)
|
|
const urlWithoutParams = leaflet_url.split('?')[0];
|
|
const urlParts = urlWithoutParams.split('/');
|
|
const fileName = urlParts[urlParts.length - 1];
|
|
info['leaflet_name'] = fileName
|
|
}
|
|
|
|
const isadmission = info.admissionsproject || 0
|
|
if (isadmission == 1) this.getAdmissionList()
|
|
|
|
const date = new Date()
|
|
const month = date.getMonth() + 1
|
|
const year = date.getFullYear()
|
|
const semester = info.semester || {}
|
|
if (month > semester.month && year + 1 <= semester.year) info['semesterState'] = true
|
|
|
|
let scores = info.language_proficiency_scores || []
|
|
console.log(scores);
|
|
const scoresList = scores
|
|
.map(element => {
|
|
let text = ""
|
|
if (["GMAT", "GMAT Focus Edition"].includes(element.name_zh)) text = `Verbal Reasoning ${element.verbal_reasoning} 分以上`
|
|
else if (["IELTS Academic", "TOEFL-iBT", "TOEFL-pBT"].includes(element.name_en)) {
|
|
const fields = {
|
|
total: "总分",
|
|
reading: "阅读",
|
|
speaking: "口语",
|
|
writing: "写作",
|
|
listening: "听力",
|
|
}
|
|
|
|
let scores = [element.reading, element.speaking, element.writing, element.listening]
|
|
|
|
if (scores.length == 4 && scores.every(score => score !== undefined && score > 0 && score === scores[0])) {
|
|
text = `总分 ${element.total} 分以上,各项分数不低于 ${scores[0]} 分`
|
|
} else {
|
|
for (const [key, label] of Object.entries(fields)) {
|
|
if (element[key]) text += `${label} ${element[key]} 分以上、`
|
|
}
|
|
if (text.endsWith("、")) text = text.slice(0, -1)
|
|
}
|
|
|
|
} else if (element.total && /^[A-Za-z]+$/.test(element.total)) text = `等级 ${element.total} 以上`
|
|
else if (element.total) text = `总分 ${element.total} 分以上`
|
|
return text ? {
|
|
name: element.name_zh,
|
|
text
|
|
} : null
|
|
})
|
|
.filter(item => item !== null)
|
|
|
|
info["scoresList"] = scoresList
|
|
|
|
this.getOfferData(info.id)
|
|
|
|
// 判断相关链接
|
|
if (!info.leaflet_url && !info.program_url && !info.catalog_url) delete side.links
|
|
|
|
this.setData({
|
|
info,
|
|
course,
|
|
contras,
|
|
remark,
|
|
side,
|
|
isadmission,
|
|
sideKey: "pivotal", // pivotal
|
|
isInitFinish: true,
|
|
}, () => {
|
|
setTimeout(() => {
|
|
this.getHeadHeight()
|
|
this.getIndexHeight()
|
|
}, 500)
|
|
})
|
|
|
|
}).catch(err => common.toast("出错了,请联系管理员。"))
|
|
}).finally(() => {
|
|
wx.hideLoading()
|
|
})
|
|
},
|
|
|
|
// 判断奖学金文案
|
|
JudgmentScholarshipText(obj) {
|
|
let text = ""
|
|
if (obj.local && obj.nonlocal) text = '均有'
|
|
else if (!obj.local && !obj.nonlocal) text = '均无'
|
|
else if (obj.local && !obj.nonlocal) text = '非本地学生无'
|
|
else if (!obj.local && obj.nonlocal) text = '非本地学生有'
|
|
return text
|
|
},
|
|
|
|
// 计算出外地申请截止时间
|
|
calculateApplicaDeadline(obj) {
|
|
// 初始化变量来存储最大时间点的属性和日期
|
|
let maxDate = null;
|
|
// 遍历对象的属性
|
|
for (const item in obj) {
|
|
// 如果当前日期是最大日期或是第一个日期,则更新最大日期和属性
|
|
if (maxDate === null || obj[item] > maxDate) maxDate = obj[item];
|
|
}
|
|
return maxDate
|
|
},
|
|
|
|
// 计算出面试轮的数组
|
|
calculateInterviewRound(obj) {
|
|
let rounds = [];
|
|
const chineseNumbers = ["一", "二", "三", "四", "五", "六", "七", "八", "九", "十"];
|
|
|
|
const formatTime = (time, index) => {
|
|
return {
|
|
text: `第${chineseNumbers[index]}轮`,
|
|
time,
|
|
};
|
|
};
|
|
|
|
Object.keys(obj).forEach((key, index) => {
|
|
rounds.push(formatTime(obj[key], index));
|
|
});
|
|
|
|
if (rounds.length == 0) rounds = [{}]
|
|
return rounds || [{}]
|
|
},
|
|
|
|
// 切换招生官 轮播图状态
|
|
cutAdmission() {
|
|
this.setData({
|
|
admissionState: !this.data.admissionState
|
|
})
|
|
},
|
|
|
|
// 招生官 轮播图 修改状态
|
|
admissionChange(e) {
|
|
this.setData({
|
|
admissionCurrent: e.detail.current
|
|
})
|
|
},
|
|
|
|
// 获取index的高度
|
|
getIndexHeight() {
|
|
const query = wx.createSelectorQuery();
|
|
query.select('.head-box').boundingClientRect(rect => {
|
|
this.setData({
|
|
headHeight: rect.height,
|
|
})
|
|
if (!this.indexSidebar) this.indexSidebar = this.selectComponent('#index-sidebar')
|
|
}).exec();
|
|
},
|
|
|
|
// 获取头部 高度
|
|
sideHeight: {},
|
|
getHeadHeight() {
|
|
const query = wx.createSelectorQuery();
|
|
query.selectAll('.details-box .side-item').boundingClientRect(rect => {
|
|
if (!rect) return
|
|
let sideHeight = {}
|
|
rect.forEach(element => {
|
|
const type = element.dataset.type
|
|
sideHeight[type] = element.top
|
|
})
|
|
this.sideHeight = sideHeight
|
|
}).exec();
|
|
},
|
|
|
|
onPageScroll(e) {
|
|
if (Math.random() > 0.5) return
|
|
|
|
const scrollTop = e.scrollTop
|
|
|
|
const sideHeight = this.sideHeight
|
|
const sideHeightList = Object.keys(sideHeight) || []
|
|
if (sideHeightList.length == 0) return
|
|
let closestValue = sideHeightList.reduce((a, b) => Math.abs(sideHeight[b] - scrollTop) < Math.abs(sideHeight[a] - scrollTop) ? b : a);
|
|
|
|
const sideKey = closestValue || 'pivotal'
|
|
if (sideKey != this.data.sideKey) {
|
|
this.setData({
|
|
sideKey,
|
|
})
|
|
}
|
|
|
|
const headHeight = this.data.headHeight
|
|
const totalTopHeight = this.data.totalTopHeight
|
|
let sideFixed = false
|
|
if (scrollTop > headHeight - totalTopHeight - 15) sideFixed = true
|
|
if (sideFixed != this.data.sideFixed) {
|
|
this.setData({
|
|
sideFixed,
|
|
})
|
|
}
|
|
|
|
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()
|
|
},
|
|
|
|
// 点击复制
|
|
copy(e) {
|
|
const text = e.currentTarget.dataset.text
|
|
util.copy(text, '复制成功,浏览器打开')
|
|
},
|
|
|
|
// 打开文件
|
|
openFile(e) {
|
|
const url = e.currentTarget.dataset.url
|
|
common.goPage("/pages/webview/webview?url=" + encodeURIComponent(url))
|
|
},
|
|
|
|
// 打开 授权按钮
|
|
openLoginBtnState() {
|
|
this.setData({
|
|
isloginBtnState: true,
|
|
})
|
|
},
|
|
|
|
// 关闭授权登录事件
|
|
popClose() {
|
|
this.setData({
|
|
isloginBtnState: !this.data.isloginBtnState
|
|
})
|
|
},
|
|
|
|
userClickLogin(e) {
|
|
let data = e.detail.data
|
|
this.setData({
|
|
islogin: true,
|
|
isloginBtnState: false,
|
|
informationState: data.regdatastep == 'success' ? false : true,
|
|
})
|
|
this.onLoad(this.options)
|
|
},
|
|
|
|
// 子组件传值 修改 完善信息组件的状态
|
|
revampInformationState() {
|
|
this.setData({
|
|
informationState: false
|
|
})
|
|
},
|
|
|
|
// 打开状态
|
|
cutState() {
|
|
if (!this.data.islogin) {
|
|
this.openLoginBtnState()
|
|
return
|
|
}
|
|
this.setData({
|
|
stateState: !this.data.stateState,
|
|
})
|
|
},
|
|
|
|
//监听键盘
|
|
bindkeyboardheightchange(e) {
|
|
let keyboardHeight = e.detail.height || 0;
|
|
this.setData({
|
|
keyboardHeight,
|
|
});
|
|
},
|
|
|
|
// 监听输入 失去焦点
|
|
bindblur() {
|
|
this.setData({
|
|
keyboardHeight: 0,
|
|
});
|
|
},
|
|
|
|
// 打开备注弹窗
|
|
openRemark() {
|
|
if (!this.data.islogin) {
|
|
this.openLoginBtnState()
|
|
return
|
|
}
|
|
this.setData({
|
|
remarkState: true,
|
|
remarkFocus: false,
|
|
remarkInput: this.data.remark,
|
|
}, () => {
|
|
this.setData({
|
|
remarkFocus: true,
|
|
})
|
|
})
|
|
},
|
|
|
|
// 关闭备注
|
|
closeRemark() {
|
|
this.setData({
|
|
remarkState: false,
|
|
})
|
|
},
|
|
|
|
// 确定备注
|
|
confirmRemark() {
|
|
const contras = this.data.contras
|
|
util.wxpost("/api/project.user/remarks", {
|
|
token: contras.token,
|
|
remarks: this.data.remarkInput,
|
|
}).then(res => {
|
|
common.toast(res.message)
|
|
|
|
this.setData({
|
|
remark: this.data.remarkInput,
|
|
})
|
|
|
|
this.closeRemark()
|
|
})
|
|
},
|
|
// 点击 跳转 公共方法
|
|
goPage(e) {
|
|
const url = e.currentTarget.dataset.url
|
|
common.goPage(url)
|
|
},
|
|
|
|
goMyProject() {
|
|
if (!this.data.islogin) {
|
|
this.openLoginBtnState()
|
|
return
|
|
}
|
|
common.goPage("/pages/projectMy/projectMy?classify=manage")
|
|
},
|
|
|
|
handSide(e) {
|
|
const sideKey = e.currentTarget.dataset.key
|
|
const sideHeight = this.sideHeight
|
|
wx.pageScrollTo({
|
|
scrollTop: sideHeight[sideKey] - this.data.totalTopHeight || 0,
|
|
})
|
|
},
|
|
|
|
indexSidebar: null,
|
|
windowHeight: 812, // 屏幕高度
|
|
|
|
// 修改 项目 状态
|
|
changeType(e) {
|
|
const typeid = e.currentTarget.dataset.typeid
|
|
const contras = this.data.contras
|
|
util.wxpost("/api/project.user/changeType", {
|
|
token: contras.token || '',
|
|
typeid,
|
|
}).then(res => {
|
|
if (res.code != 200) return
|
|
common.toast(res.message)
|
|
contras['typeid'] = typeid
|
|
this.cutState()
|
|
this.setData({
|
|
contras,
|
|
})
|
|
})
|
|
},
|
|
|
|
delete() {
|
|
const contras = this.data.contras
|
|
util.wxpost("/api/project.user/delete", {
|
|
token: contras.token,
|
|
}).then(res => {
|
|
if (res.code != 200) return
|
|
common.toast(res.message)
|
|
contras['ismanage'] = 0
|
|
this.setData({
|
|
contras,
|
|
stateState: false,
|
|
})
|
|
})
|
|
},
|
|
|
|
// 点击加入对比单
|
|
addComparison() {
|
|
if (!this.data.islogin) {
|
|
this.openLoginBtnState()
|
|
return
|
|
}
|
|
|
|
const contras = this.data.contras
|
|
const info = this.data.info
|
|
|
|
util.wxpost("/api/project.contrast/add", {
|
|
projectid: info.id,
|
|
}).then(res => {
|
|
|
|
if (res.code != 200) return
|
|
const data = res.data
|
|
common.toast(res.message)
|
|
contras['status'] = 1
|
|
contras['ismanage'] = 1
|
|
contras['typeid'] = 0 // 默认是待定
|
|
contras['token'] = data.token
|
|
this.setData({
|
|
contras,
|
|
})
|
|
app.globalData.basicData['contrastcount'] = data.count
|
|
}).catch(err => {
|
|
if (err.code == 401) this.openLoginBtnState()
|
|
})
|
|
},
|
|
|
|
cutStudyMode(e) {
|
|
const type = e.currentTarget.dataset.type
|
|
this.setData({
|
|
studyMode: type,
|
|
})
|
|
},
|
|
|
|
// 获取招生官
|
|
getAdmissionList() {
|
|
util.wxget('/miniprogramApi/offer/home').then(res => {
|
|
if (res.code != 200) return
|
|
const data = res.data
|
|
let admissionsOfficer = data.admissionsOfficer || []
|
|
let urls = []
|
|
admissionsOfficer.forEach(element => {
|
|
let mold = null
|
|
if (element.date == null || element.date.indexOf("答疑") >= 0) mold = 3
|
|
else mold = this.isToday(element.date) ? 1 : 2
|
|
|
|
element.urls.forEach(ele => {
|
|
urls.push({
|
|
...ele,
|
|
mold,
|
|
logo: element['logo'],
|
|
})
|
|
})
|
|
})
|
|
|
|
const urlsOne = urls[0] || {}
|
|
|
|
const chunkedArray = [];
|
|
for (let i = 0; i < urls.length; i += 4) {
|
|
chunkedArray.push(urls.slice(i, i + 4));
|
|
}
|
|
|
|
this.setData({
|
|
urls: chunkedArray,
|
|
urlsOne,
|
|
})
|
|
})
|
|
},
|
|
|
|
isToday(dateString) {
|
|
const now = new Date().getTime()
|
|
const date = new Date(dateString).getTime()
|
|
return now <= date
|
|
},
|
|
|
|
getOfferData(projectid) {
|
|
util.wxget("/api/project.other/offerList?limit=2000&projectid=" + projectid, ).then(res => {
|
|
const data = res.data
|
|
const list = data.list || []
|
|
let side = this.data.side
|
|
if (list.length == 0) delete side.consult
|
|
|
|
list.forEach(element => {
|
|
element["timestamp"] = util.strtimeago(element["timestamp"], 3)
|
|
})
|
|
|
|
this.setData({
|
|
offerList: list,
|
|
side,
|
|
})
|
|
})
|
|
},
|
|
|
|
openPreview() {
|
|
wx.previewMedia({
|
|
sources: [{
|
|
url: '//framework.x-php.com/project//img/9dfc-c89f50deb0f906dd751540895bf0e303.jpg'
|
|
}],
|
|
showmenu: true,
|
|
})
|
|
},
|
|
|
|
/**
|
|
* 生命周期函数--监听页面初次渲染完成
|
|
*/
|
|
onReady() {
|
|
|
|
},
|
|
|
|
/**
|
|
* 生命周期函数--监听页面显示
|
|
*/
|
|
onShow() {
|
|
|
|
},
|
|
|
|
/**
|
|
* 生命周期函数--监听页面隐藏
|
|
*/
|
|
onHide() {
|
|
|
|
},
|
|
|
|
/**
|
|
* 生命周期函数--监听页面卸载
|
|
*/
|
|
onUnload() {
|
|
|
|
},
|
|
|
|
/**
|
|
* 页面相关事件处理函数--监听用户下拉动作
|
|
*/
|
|
onPullDownRefresh() {
|
|
wx.stopPullDownRefresh()
|
|
this.getData()
|
|
},
|
|
|
|
/**
|
|
* 页面上拉触底事件的处理函数
|
|
*/
|
|
onReachBottom() {
|
|
|
|
},
|
|
/**
|
|
* 页面相关事件处理函数--监听用户下拉动作
|
|
*/
|
|
onPullDownRefresh() {
|
|
wx.stopPullDownRefresh()
|
|
this.getData()
|
|
},
|
|
|
|
/**
|
|
* 用户点击右上角分享
|
|
*/
|
|
onShareAppMessage() {
|
|
return {
|
|
title: "【寄托港校项目库】 - " + this.data.info.name_zh,
|
|
}
|
|
},
|
|
onShareTimeline() {
|
|
util.statistics({
|
|
name: "share-timeline"
|
|
})
|
|
return {
|
|
title: "【寄托港校项目库】 - " + this.data.info.name_zh,
|
|
}
|
|
},
|
|
}) |