xg-project-library/html/index.html
2024-10-31 19:03:26 +08:00

476 lines
22 KiB
HTML

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Document</title>
<link rel="stylesheet" href="/css/common.css" />
<link rel="stylesheet" href="/css/index.css" />
<script src="/js/axios.min.js"></script>
<script src="/js/vue.global.js"></script>
<script src="/js/common.js"></script>
<script src="/js/base.js"></script>
<script src="/js/masonry.pkgd.min.js"></script>
<style>
[v-cloak] {
display: none;
}
</style>
</head>
<body>
<div id="app" class="main" v-cloak>
<img class="index-icon" src="/img/index-icon.png" />
<div style="display: flex;" class="header-box flexacenter">
<img class="bj" src="/img/header-bj.svg" />
<div class="search flexacenter">
<div class="input flex1">搜索项目</div>
<img class="search-icon" src="/img/search-icon.svg" />
</div>
<div class="btn flexacenter">
<div class="item flexcenter">
<img class="icon" src="/img/contrast-icon.png" />
项目对比
</div>
<div class="item flexcenter">
<img class="icon" src="/img/contrast-icon.png" />
项目对比
</div>
</div>
</div>
<!-- 筛选 -->
<div style="display: flex;" class="screen flexflex">
<div class="block school">
<div class="title flexacenter">
<div class="icon flexcenter">
<img class="img" src="/img/school-icon.png" />
</div>
按学校查看
</div>
<div class="list">
<div class="item flexcenter" v-for="(item,index) in university" :key="index">{{ item.label }}</div>
</div>
</div>
<div class="block subject flex1">
<div class="title flexacenter">
<div class="icon flexcenter">
<img class="img" src="/img/school-icon.png" />
</div>
按学科查看
</div>
<div class="list flexflex">
<div class="item flexcenter" v-for="(item,index) in discipline">{{ item.label }}</div>
</div>
</div>
</div>
<!-- 缘分 -->
<div class="fate">
<div class="title flexacenter">
<div>今日缘分项目</div>
<div class="btn flexacenter" @click="getFate">
<img class="icon" src="/img/trade-icon.png" />
换一批
</div>
</div>
<div class="list flexflex">
<div class="item flexacenter" v-for="(item,index) in fateProject">
<div class="left">
<div class="name one-line-display">{{ item.name_zh }}</div>
<div class="message flexacenter">
<div class="project one-line-display">{{ item.name_en }}</div>
<span class="virgule">|</span>{{ item.schoolname }}
</div>
</div>
<div v-if="!item?.state" class="btn flexacenter" :class="'add' + item.random" @click="handleClick('fate',item,index)">
<div class="add flexcenter">
<img class="icon" src="/img/add-xiao.svg" />
</div>
加入对比单
</div>
<div v-else class="already flexacenter">
<div class="tick-box flexcenter">
<img class="img-tick" src="/img/tick-icon.svg" />
</div>
已加入
</div>
</div>
</div>
</div>
<!-- 招生官 -->
<div class="recruit">
<div class="title flexacenter">
<img class="img" src="/img/admission-icon.png" />
<div class="btn flexacenter">
招生官频道
<img class="icon" src="/img/arrows-icon.png" />
</div>
</div>
<div class="list flexflex" ref="recruitListRef">
<div class="list-item" v-for="(item,index) in admissionList">
<div class="item flexflex" v-for="(item,i) in item">
<div class="operate flexcenter">
<div v-if="item.contraststatus?.status === 1 && item.contraststatus?.ismanage === 1" class="already flexacenter">
<div class="tick-box flexcenter">
<img class="img-tick" src="/img/tick-icon.svg" />
</div>
已加入
</div>
<div v-else-if="item.contraststatus?.status === 0 || item.contraststatus?.ismanage === 0" class="circle flexcenter" @click="openMoreSelect('admission',index,i)">
<img class="img-dot" src="/img/dot-dot-dot.png" />
</div>
<div v-else class="circle flexcenter" @click="handleClick('admission',item,index,i)" :class="'add' + item.random" >
<img class="img-add" src="/img/add-thick.svg" />
</div>
<div v-if="item.moreState" class="select-mask" @click="closeMoreSelectAll('admission')"></div>
<div class="select flexflex" :class="{'show': item.moreState}">
<div class="title flexacenter">
<div class="dot"></div>
{{ item.contraststatus?.status == 1 ? '该项目已加入对比单,未加入项目管理' : '该项目已加入项目管理,未加入对比单' }}
</div>
<div class="btn flexcenter" @click="handleClick('admission',item,index,i)"><img class="img" src="/img/add-circle.svg" />加入{{ item.contraststatus?.status == 1 ? '项目管理' : '对比单' }}</div>
</div>
</div>
<img class="avatar" :src="item.schoollogo" />
<div class="info">
<div class="school">{{ item.schoolname }}</div>
<div class="name one-line-display">{{ item.name_zh }}</div>
<div class="name-en one-line-display">{{ item.name_en }}</div>
<div class="aq flexacenter">
<div class="text">招生官答疑时间</div>
<div class="value flex1">长期答疑</div>
<img class="icon" src="/img/arrows-long-icon.png" />
</div>
</div>
</div>
</div>
</div>
<div class="indicate flexcenter">
<img class="icon" @click="cutAdmissionPage('left')" :src="reversedMessage('left')" />
<div class="text">{{ admissionPage }}/{{ admissionTotalPage }}</div>
<img class="icon btn-right" @click="cutAdmissionPage('right')" :src="reversedMessage('right')" />
</div>
</div>
<!-- 列表 -->
<div class="data" ref="dataListRef">
<img class="data-item fall" @load="imageFallLoaded" src="/img/25fall.svg" />
<div class="data-item item" v-for="(item,index) in projectList">
<div class="school flexacenter"><img class="img" :src="item.schoollogo" />{{ item.schoolname }}</div>
<div class="name">{{ item.name_zh }}</div>
<div class="name-en">{{ item.name_en }}</div>
<div class="introduce flexacenter">
<div class="flexacenter" v-if="item.rank">
专业排名
<div class="quantity">{{ item.rank }}</div>
</div>
<div class="flexacenter" v-if="item.tuition_fee_text">
<div class="line" v-if="item.rank">|</div>
学费HK$
<div class="quantity">{{ item.tuition_fee_text }}</div>
</div>
</div>
<div class="word" v-if="item.distinctive">{{ item.distinctive }}</div>
<div class="tag flexflex">
<!-- <div class="tag-item admissions">招生官项目</div> -->
<div class="tag-item gray" :class="{'semester': item.semesterState}">{{ item.semester.text }}</div>
<div class="tag-item" v-for="(item,index) in item.tags">{{ item }}</div>
</div>
<div class="operate flexcenter">
<div v-if="item.contraststatus?.status === 1 && item.contraststatus?.ismanage === 1" class="already flexacenter">
<div class="tick-box flexcenter">
<img class="img-tick" src="/img/tick-icon.svg" />
</div>
已加入
</div>
<div v-else-if="item.contraststatus?.status === 0 || item.contraststatus?.ismanage === 0" class="circle flexcenter" @click="openMoreSelect('list',index)">
<img class="img-dot" src="/img/dot-dot-dot.png" />
</div>
<div v-else class="circle flexcenter" :class="'add' + item.random" @click="handleClick('list',item,index)">
<img class="img-add" src="/img/add-thick.svg" />
</div>
<div v-if="item.moreState" class="select-mask" @click="closeMoreSelectAll('list')"></div>
<div class="select flexflex" :class="{'show': item.moreState}">
<div class="top flex1 flexcenter">
<div class="title flexacenter">
<div class="dot"></div>
{{ item.contraststatus?.status == 1 ? '该项目已加入对比单,未加入项目管理' : '该项目已加入项目管理,未加入对比单' }}
</div>
<div class="btn flexcenter" @click="handleClick('list',item,index)"><img class="img" src="/img/add-circle.svg" />加入{{ item.contraststatus?.status == 1 ? '项目管理' : '对比单' }}</div>
</div>
<div class="bottom"></div>
</div>
</div>
</div>
</div>
<!-- 底部 -->
<base-bottom ref="baseRef"></base-bottom>
<div class="my-project">
dfgfdgdfgdfgfd
</div>
</div>
<script>
const { createApp, ref, onMounted, nextTick, onUnmounted } = Vue
const projectIndex = createApp({
setup() {
let dataListRef = ref(null)
onMounted(() => {
window.addEventListener("scroll", handleScroll)
listMasonryInstance = new Masonry(dataListRef.value, {
itemSelector: ".data-item",
gutter: 20,
})
init()
})
let user = ref({})
let university = ref([])
let discipline = ref([])
let contrastcount = ref({})
let encodekey = ref("")
// 初始化
const init = () => {
$ajaxget("/api/project.home/basicData").then(result => {
const data = result.data || {}
user.value = data.user
university.value = data.university
discipline.value = data.discipline
contrastcount.value = data.contrastcount
encodekey.value = data.encodekey
getFate()
getAdmission()
getProjectData()
})
}
// 今日缘分项目
let fateProject = ref([])
const getFate = () => {
$ajaxget("/api/project.home/todayFateProject").then(res => {
if (res.code != 200) return
const data = res.data || []
data.forEach(element => {
element["random"] = randomString(6)
})
fateProject.value = data
})
}
let admissionList = ref([])
let admissionTotalPage = ref(0) // 总页数
// 获取 招生官项目
const getAdmission = () => {
$ajaxget("/api/project.lists", {
limit: 20,
page: 1,
admissionsproject: 1,
}).then(res => {
if (res.code != 200) return
const data = res.data
const list = data.data || []
const targetList = (list || []).map(element => ({
...element,
random: randomString(6),
}))
const chunkArray = (array, size) => {
const result = []
for (let i = 0; i < array.length; i += size) {
result.push(array.slice(i, i + size))
}
return result
}
const groupedAdmissionList = chunkArray(targetList, 4)
admissionList.value = groupedAdmissionList
admissionTotalPage.value = groupedAdmissionList.length
})
}
let admissionPage = ref(1)
let recruitListRef = ref(null)
// 点击切换 招生官 轮播图 滚动
const cutAdmissionPage = type => {
if (type == "left") {
if (admissionPage.value > 1) admissionPage.value--
} else {
if (admissionPage.value < admissionTotalPage.value) admissionPage.value++
}
recruitListRef.value.scrollTo({
left: 1140 * (admissionPage.value - 1),
behavior: "smooth",
})
}
// 计算
const reversedMessage = type => {
if (type == "left") {
if (admissionPage.value == 1) return "/img/arrows-triangle-gray.svg"
else return "/img/arrows-triangle-blue.png"
} else {
if (admissionPage.value == admissionTotalPage.value) return "/img/arrows-triangle-gray.svg"
else return "/img/arrows-triangle-blue.png"
}
}
let projectList = ref([])
let projectPage = 1
// 获取项目数据
const getProjectData = () => {
if (projectPage == 0) return
$ajaxget("/api/project.lists", {
limit: 20,
page: projectPage,
}).then(res => {
if (res.code != 200) return
const data = res.data
const date = new Date()
const month = date.getMonth() + 1
const year = date.getFullYear()
let list = data.data || []
list = list.map(element => ({
...element,
random: randomString(6),
semesterState: month > element.semester.month && year + 1 <= element.semester.year,
tuition_fee_text: formatNumberWithSpaces(element.tuition_fee),
}))
projectList.value = projectList.value.concat(list)
projectPage = data.count > data.limit * data.page ? projectPage + 1 : 0
nextTick(() => {
listMasonryInstance.reloadItems()
listMasonryInstance.layout()
})
})
}
//瀑布实例
let listMasonryInstance = null
const imageFallLoaded = () => {
listMasonryInstance.reloadItems()
listMasonryInstance.layout()
}
const handleScroll = () => {
const scrollHeight = document.documentElement.scrollHeight
const clientHeight = document.documentElement.clientHeight
const scrollTop = window.pageYOffset
if (scrollTop + clientHeight >= scrollHeight) {
getProjectData()
}
}
const baseRef = ref(null)
// 点击事件
const handleClick = (type, item, index, i) => {
const random = item.random
if (item.status == 1) return
$ajax("/api/project.contrast/add", {
projectid: item.id,
}).then(res => {
baseRef.value.calculate(random)
if (type == "fate") fateProject.value[index]["state"] = 1
if (type == "admission") {
admissionList.value[index][i]["contraststatus"] = {
status: 1,
ismanage: 1,
}
admissionList.value[index][i]["moreState"] = false
}
if (type == "list") {
projectList.value[index]["contraststatus"] = {
status: 1,
ismanage: 1,
}
projectList.value[index]["moreState"] = false
}
})
}
const openMoreSelect = (type, index, i) => {
if (type == "admission") {
admissionList.value[index][i]["moreState"] = true
}
if (type == "list") {
console.log(222)
projectList.value[index]["moreState"] = true
}
}
// 关闭所有 状态 选择 弹出框
const closeMoreSelectAll = type => {
if (type == "admission") {
admissionList.value.forEach(element => {
element.forEach(ele => {
ele["moreState"] = false
})
})
}
if (type == "list") {
projectList.value.forEach(element => {
element["moreState"] = false
})
}
}
onUnmounted(() => {
window.removeEventListener("scroll", handleScroll)
})
return {
user,
university,
discipline,
contrastcount,
encodekey,
fateProject,
getFate,
admissionList,
admissionPage,
admissionTotalPage,
cutAdmissionPage,
recruitListRef,
reversedMessage,
projectList,
dataListRef,
imageFallLoaded,
handleClick,
openMoreSelect,
closeMoreSelectAll,
baseRef,
}
},
})
projectIndex.component("base-bottom", base)
projectIndex.mount("#app")
</script>
</body>
</html>