xg-project-library/html/index.html

992 lines
48 KiB
HTML
Raw Normal View History

2024-10-28 10:59:51 +00:00
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Document</title>
2024-10-31 04:27:27 +00:00
<link rel="stylesheet" href="/css/common.css" />
<link rel="stylesheet" href="/css/index.css" />
2024-10-31 11:03:26 +00:00
<script src="/js/axios.min.js"></script>
2024-10-31 06:46:33 +00:00
<script src="/js/vue.global.js"></script>
2024-10-31 11:03:26 +00:00
<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>
2024-10-28 10:59:51 +00:00
</head>
2024-10-31 11:03:26 +00:00
2024-10-28 10:59:51 +00:00
<body>
2024-10-31 11:03:26 +00:00
<div id="app" class="main" v-cloak>
2024-10-28 10:59:51 +00:00
<img class="index-icon" src="/img/index-icon.png" />
2024-10-31 06:46:33 +00:00
<div style="display: flex;" class="header-box flexacenter">
2024-10-28 10:59:51 +00:00
<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>
<!-- 筛选 -->
2024-10-31 06:46:33 +00:00
<div style="display: flex;" class="screen flexflex">
2024-10-28 10:59:51 +00:00
<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">
2024-10-31 11:03:26 +00:00
<div class="item flexcenter" v-for="(item,index) in university" :key="index">{{ item.label }}</div>
2024-10-28 10:59:51 +00:00
</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">
2024-10-31 11:03:26 +00:00
<div class="item flexcenter" v-for="(item,index) in discipline">{{ item.label }}</div>
2024-10-28 10:59:51 +00:00
</div>
</div>
</div>
<!-- 缘分 -->
2024-10-31 11:03:26 +00:00
<div class="fate">
2024-10-28 10:59:51 +00:00
<div class="title flexacenter">
<div>今日缘分项目</div>
2024-10-31 11:03:26 +00:00
<div class="btn flexacenter" @click="getFate">
2024-10-28 10:59:51 +00:00
<img class="icon" src="/img/trade-icon.png" />
换一批
</div>
</div>
<div class="list flexflex">
2024-10-31 11:03:26 +00:00
<div class="item flexacenter" v-for="(item,index) in fateProject">
2024-10-28 10:59:51 +00:00
<div class="left">
2024-10-31 11:03:26 +00:00
<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>
2024-10-28 10:59:51 +00:00
</div>
2024-10-31 11:03:26 +00:00
<div v-if="!item?.state" class="btn flexacenter" :class="'add' + item.random" @click="handleClick('fate',item,index)">
2024-10-28 10:59:51 +00:00
<div class="add flexcenter">
<img class="icon" src="/img/add-xiao.svg" />
</div>
加入对比单
</div>
2024-10-31 11:03:26 +00:00
<div v-else class="already flexacenter">
<div class="tick-box flexcenter">
<img class="img-tick" src="/img/tick-icon.svg" />
2024-10-28 10:59:51 +00:00
</div>
2024-10-31 11:03:26 +00:00
已加入
2024-10-28 10:59:51 +00:00
</div>
</div>
</div>
</div>
<!-- 招生官 -->
2024-10-31 11:03:26 +00:00
<div class="recruit">
2024-10-28 10:59:51 +00:00
<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>
2024-10-31 11:03:26 +00:00
<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">
2024-10-29 11:14:25 +00:00
<div class="operate flexcenter">
2024-10-31 11:03:26 +00:00
<div v-if="item.contraststatus?.status === 1 && item.contraststatus?.ismanage === 1" class="already flexacenter">
2024-10-29 11:14:25 +00:00
<div class="tick-box flexcenter">
<img class="img-tick" src="/img/tick-icon.svg" />
</div>
已加入
2024-10-28 10:59:51 +00:00
</div>
2024-10-31 11:03:26 +00:00
<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" />
2024-10-28 10:59:51 +00:00
</div>
2024-11-01 11:12:06 +00:00
<div v-else class="circle flexcenter" @click="handleClick('admission',item,index,i)" :class="'add' + item.random">
2024-10-31 11:03:26 +00:00
<img class="img-add" src="/img/add-thick.svg" />
2024-10-28 10:59:51 +00:00
</div>
2024-10-31 11:03:26 +00:00
<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>
2024-10-28 10:59:51 +00:00
</div>
</div>
2024-10-31 11:03:26 +00:00
<img class="avatar" :src="item.schoollogo" />
2024-10-28 10:59:51 +00:00
<div class="info">
2024-10-31 11:03:26 +00:00
<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>
2024-10-28 10:59:51 +00:00
<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">
2024-10-31 11:03:26 +00:00
<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')" />
2024-10-28 10:59:51 +00:00
</div>
</div>
<!-- 列表 -->
2024-10-31 11:03:26 +00:00
<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>
2024-10-29 11:14:25 +00:00
<div class="introduce flexacenter">
2024-10-31 11:03:26 +00:00
<div class="flexacenter" v-if="item.rank">
2024-10-29 11:14:25 +00:00
专业排名
2024-10-31 11:03:26 +00:00
<div class="quantity">{{ item.rank }}</div>
2024-10-29 11:14:25 +00:00
</div>
2024-10-31 11:03:26 +00:00
<div class="flexacenter" v-if="item.tuition_fee_text">
<div class="line" v-if="item.rank">|</div>
2024-10-29 11:14:25 +00:00
学费HK$
2024-10-31 11:03:26 +00:00
<div class="quantity">{{ item.tuition_fee_text }}</div>
2024-10-29 11:14:25 +00:00
</div>
</div>
2024-10-31 11:03:26 +00:00
<div class="word" v-if="item.distinctive">{{ item.distinctive }}</div>
2024-10-29 11:14:25 +00:00
<div class="tag flexflex">
<!-- <div class="tag-item admissions">招生官项目</div> -->
2024-10-31 11:03:26 +00:00
<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>
2024-10-29 11:14:25 +00:00
</div>
<div class="operate flexcenter">
2024-10-31 11:03:26 +00:00
<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>
已加入
2024-10-29 11:14:25 +00:00
</div>
2024-10-31 11:03:26 +00:00
<div v-else-if="item.contraststatus?.status === 0 || item.contraststatus?.ismanage === 0" class="circle flexcenter" @click="openMoreSelect('list',index)">
2024-10-29 11:14:25 +00:00
<img class="img-dot" src="/img/dot-dot-dot.png" />
</div>
2024-11-01 11:12:06 +00:00
<div v-else class="circle flexcenter" :class="'add' + item.random" @click="handleClick('list',item,index)">
2024-10-31 11:03:26 +00:00
<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}">
2024-10-29 11:14:25 +00:00
<div class="top flex1 flexcenter">
<div class="title flexacenter">
<div class="dot"></div>
2024-10-31 11:03:26 +00:00
{{ item.contraststatus?.status == 1 ? '该项目已加入对比单,未加入项目管理' : '该项目已加入项目管理,未加入对比单' }}
2024-10-29 11:14:25 +00:00
</div>
2024-10-31 11:03:26 +00:00
<div class="btn flexcenter" @click="handleClick('list',item,index)"><img class="img" src="/img/add-circle.svg" />加入{{ item.contraststatus?.status == 1 ? '项目管理' : '对比单' }}</div>
2024-10-29 11:14:25 +00:00
</div>
<div class="bottom"></div>
</div>
</div>
2024-11-13 11:16:00 +00:00
<!-- <div class="type flexflex" wx:if="{{ item.admissionsproject }}"> -->
<div class="type flexcenter" v-if="item.admissionsproject">
<img class="type-icon" src="/img/angle.svg" />
<img class="type-name" src="/img/admission-icon.png" />
</div>
2024-10-29 11:14:25 +00:00
</div>
</div>
2024-10-28 10:59:51 +00:00
2024-10-29 11:14:25 +00:00
<!-- 底部 -->
2024-10-31 11:03:26 +00:00
<base-bottom ref="baseRef"></base-bottom>
2024-11-15 10:59:31 +00:00
<div class="my-project flexacenter">
2024-11-01 11:12:06 +00:00
<div class="my-box">
<div class="head flexacenter">
<div class="item flexcenter" :class="{'pitch': classify == 'vs'}" @click="cutClassify('vs')">
<img class="icon" src="/img/contrast-icon.png" />
<img class="bj bj-left" src="/img/left-icon.svg" />
项目对比
</div>
<div class="item flexcenter" :class="{'pitch': classify == 'manage'}" @click="cutClassify('manage')">
<img class="icon" src="/img/manage-icon.png" />
<img class="bj bj-right" src="/img/left-icon.svg" />
项目管理
</div>
</div>
<div v-if="classify == 'vs'" class="contrast-box flexflex">
<div class="left" :class="{'left1': quickList.length == 0 }">
<div class="hint flexacenter">
<div class="text">选择2~3个项目开始对比</div>
<div class="btn flexacenter">
<div class="delete flexcenter" @click="contrastDelete" :class="{'have': isPitchExceedOne}">删除</div>
<div class="begin flexcenter" :class="{'have': isPitchExceedTwo}">开始对比</div>
</div>
</div>
<div v-if="false" class="empty-box flexcenter">
<img class="icon" src="/img/empty-icon.png" />
<span class="text">把你感兴趣的项目加进来,</span>
<span class="text">可以做项目对比哦!</span>
</div>
<div class="list">
<template v-for="(item, index) in contrastList" :key="item.projectid">
<div v-if="item.status == 1" class="item flexacenter">
<div class="left">
<div class="name">{{ item.name_zh }}</div>
<div class="english">{{ item.name_en }}</div>
<div class="message flexacenter">
<img class="icon" :src="item.schoollogo" />
{{ item.schoolalias }}
<template v-if="item.ismanage == 1">
<div class="line">|</div>
<div class="state-text">{{ stateObj[item.typeid] }}</div>
</template>
</div>
</div>
2024-11-04 08:24:44 +00:00
<div class="btn flexcenter" :class="{'btn-forbid': isPitchExceedThree, 'btn-normal': item.pitch }" @click="cutSelect(index)">
2024-11-01 11:12:06 +00:00
<img v-if="item.pitch" class="icon" src="/img/tick-circle-green.svg" />
<img v-else class="icon" src="/img/tick-circle-gray-hollow.svg" />
</div>
</div>
</template>
</div>
</div>
2024-10-31 11:03:26 +00:00
2024-11-01 11:12:06 +00:00
<div v-if="quickList.length != 0" class="right">
<div class="hint">快速对比({{ quickList.length }}</div>
<div class="list">
<div class="item flexacenter" v-for="(item, index) in quickList">
<div class="project-list">
<div class="project-item flexacenter" v-for="item in item.data">
<img class="icon" mode="widthFix" :src="item.schoollogo" />
{{ item.schoolalias }}
<img class="arrows" src="/img/arrows-circle-yellow-green.svg" mode="widthFix" />
<view class="text one-line-display">{{ item.name_zh }}</view>
</div>
</div>
<div class="btn flexcenter">
<img class="icon" src="/img/arrows-long-white.svg" />
</div>
<img @click="quickShowHideDelete(index)" class="dot" src="/img/dot-dot-dot-gray.png" />
<div v-if="item.deleteState" @click="quickDelete(index)" class="delete flexcenter">删除</div>
<div v-if="item.deleteState" @click="quickShowHideDelete(index)" class="delete-mask flexcenter"></div>
</div>
</div>
</div>
</div>
<div v-else class="manage-box">
<div class="tab-list flexflex">
<div class="item" :class="{'pitch': index == typeIndex }" v-for="(item,index) in typeList" @click="cutTypeid(index)">{{ item.name }} {{ item.count }}</div>
</div>
2024-11-04 08:24:44 +00:00
<div v-if="manageEmpty" class="empty-box flexcenter">
2024-11-01 11:12:06 +00:00
<img class="icon" src="/img/empty-icon.png" />
<span class="text">暂无项目</span>
</div>
<div v-else class="list">
<div class="hint flexacenter" v-if="!manageHintState">
<div class="text">加入对比单的项目会同步进入项目管理当中;两者独立管理,删除操作互不影响。</div>
<img @click="manageClose()" class="icon" src="/img/close-icon.png" />
</div>
<div class="list-box flexflex" ref="manageListRef">
<template v-for="(item,index) in manageList">
2024-11-18 08:58:17 +00:00
<!-- <div class="item" v-if="item.ismanage == 1" :class="'item' + index" :data-index="index" :style="{'top':item.top,'left': item.left,}" @dragstart="dragStart(index)" @dragenter.prevent="dragEnter(index)" @dragend="dragEnd"> -->
<div class="item" v-if="item.ismanage == 1" :class="{'load': item.load}" :data-index="index" :style="{'top':item.top + 'px','left': item.left + 'px' }" @mousemove="dragging(index)" @mouseup="endDrag">
2024-11-01 11:12:06 +00:00
<div class="top flexacenter">
<div class="info flex1">
2024-11-18 08:58:17 +00:00
<div class="name">{{ item.name_zh }}{{item.top}},{{ item.left}}</div>
2024-11-01 11:12:06 +00:00
<div class="english">{{ item.name_en }}</div>
<div class="school flexacenter">
<img class="icon" :src="item.schoollogo" />
{{ item.schoolalias }}
</div>
</div>
<div class="state-box">
2024-11-04 08:24:44 +00:00
<div class="btn flexcenter" :class="{'undetermined': item.typeid == 0}" @click.stop="cutManageStateShow(index)">{{ stateObj[item.typeid] }}<img class="icon" src="/img/arrows-triangle-white.svg" /></div>
2024-11-01 11:12:06 +00:00
2024-11-04 08:24:44 +00:00
<div v-if="item.state" class="state-list-box flexacenter">
2024-11-01 11:12:06 +00:00
<div class="state-list flexacenter">
2024-11-04 08:24:44 +00:00
<div class="state-item" :class="{'pitch': item.typeid == key}" v-for="(it,key) in stateObj" @click.stop="cutManageState(key, index)">{{ it }}</div>
2024-11-01 11:12:06 +00:00
</div>
<div class="delete flexcenter">
<img class="delete-icon" src="/img/delete-icon.svg" />
</div>
</div>
</div>
</div>
<div class="bottom flexflex">
<div class="edit flexcenter">
<img class="icon" src="/img/u1434.png" />
</div>
2024-11-18 09:25:58 +00:00
<textarea class="manage-input flex1" :style="{height: item.inputHeight}" v-model="item.remarks" placeholder="添加备注…" maxlength="100" @blur="inputblur(index)" @input="inputInput(index)"></textarea>
2024-11-18 08:58:17 +00:00
<img class="drag-icon" src="/img/drag-icon.png" @mousedown="startDrag(index)" />
2024-11-01 11:12:06 +00:00
</div>
</div>
</template>
</div>
</div>
</div>
</div>
</div>
2024-10-28 10:59:51 +00:00
</div>
<script>
2024-11-18 08:58:17 +00:00
const { createApp, ref, onMounted, nextTick, onUnmounted, computed, getCurrentInstance } = Vue
2024-10-31 06:46:33 +00:00
const projectIndex = createApp({
setup() {
2024-11-18 08:58:17 +00:00
const { proxy } = getCurrentInstance()
2024-10-31 11:03:26 +00:00
let dataListRef = ref(null)
2024-10-31 06:46:33 +00:00
onMounted(() => {
2024-10-31 11:03:26 +00:00
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 = () => {
2024-11-13 11:16:00 +00:00
$ajaxget("/api/home/basicData").then(result => {
2024-10-31 11:03:26 +00:00
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()
2024-11-01 11:12:06 +00:00
getMyInit()
2024-10-31 11:03:26 +00:00
})
}
// 今日缘分项目
let fateProject = ref([])
const getFate = () => {
2024-11-13 11:16:00 +00:00
$ajaxget("/api/home/todayFateProject").then(res => {
2024-10-31 11:03:26 +00:00
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 = () => {
2024-11-13 11:16:00 +00:00
$ajaxget("/api/lists", {
2024-10-31 11:03:26 +00:00
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
2024-11-13 11:16:00 +00:00
$ajaxget("/api/lists", {
2024-10-31 11:03:26 +00:00
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)
2024-11-01 11:12:06 +00:00
2024-10-31 11:03:26 +00:00
// 点击事件
const handleClick = (type, item, index, i) => {
const random = item.random
if (item.status == 1) return
2024-11-13 11:16:00 +00:00
$ajax("/api/contrast/add", {
2024-10-31 11:03:26 +00:00
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)
2024-10-31 06:46:33 +00:00
})
2024-10-31 11:03:26 +00:00
2024-11-01 11:12:06 +00:00
let contrastList = ref([])
const stateObj = ref({
0: "待定",
1: "主申",
2: "冲刺",
3: "保底",
})
let manageHintState = ref(false)
let classify = ref("vs")
// 我的项目的初始化
const getMyInit = () => {
manageHintState.value = localStorage.getItem("PMState") || false
getList().then(res => {
const data = res.data || {}
2024-11-04 08:24:44 +00:00
data.nums = {
contrast: 0,
manage: 10,
}
2024-11-01 11:12:06 +00:00
const nums = data.nums || {}
classify.value = "vs"
if (nums["contrast"] == 0 && nums["manage"] != 0) {
classify.value = "manage"
handleUserProjectData(res)
} else {
getQuickList()
handleProjectListData(res)
}
})
}
let projectCount = ref(0)
handleProjectListData = res => {
const data = res.data
let list = data.data || []
let count = 0
list.forEach(element => {
if (element.status == 1) count++
})
projectCount.value = count
contrastList.value = list
}
let typeid = ref("")
let typeIndex = ref(0)
let typeList = ref([])
// 获取项目管理
const getUserProject = () => {
getList({
page: 1,
typeid: typeid.value,
}).then(res => {
handleUserProjectData(res)
})
}
const getProjectList = () => {
getList({
page: 1,
}).then(res => {
handleProjectListData(res)
})
}
let manageList = ref([])
const handleUserProjectData = res => {
const data = res.data
let list = data.data || []
list.forEach((element, index) => {
element["sortKey"] = index
})
typeList.value = data.typeList
manageList.value = list
nextTick(() => {
manageList.value.forEach((element, index) => {
2024-11-15 10:59:31 +00:00
if (element.ismanage == 1 && element.remarks) {
2024-11-18 10:53:26 +00:00
console.log("element", element)
2024-11-18 08:58:17 +00:00
const textarea = manageListRef.value.querySelector(`.item[data-index="${index}"] textarea`)
element["inputHeight"] = textarea.scrollHeight + "px"
2024-11-01 11:12:06 +00:00
}
})
2024-11-15 10:59:31 +00:00
nextTick(() => {
if (manageList.value.length != 0) getAllHeight()
})
})
}
const getAllHeight = () => {
const all = manageListRef.value.querySelectorAll(".item") || []
all.forEach(element => {
2024-11-18 08:58:17 +00:00
const index = element.getAttribute("data-index") * 1
manageList.value[index]["height"] = element.offsetHeight + 20
2024-11-15 10:59:31 +00:00
})
2024-11-18 08:58:17 +00:00
calculateWaterfall()
2024-11-15 10:59:31 +00:00
}
2024-11-18 08:58:17 +00:00
const calculateWaterfall = () => {
let list = JSON.parse(JSON.stringify(manageList.value)) || []
list.sort((a, b) => a.sortKey - b.sortKey)
2024-11-15 10:59:31 +00:00
let topLeft = 0
let topRigth = 0
2024-11-18 08:58:17 +00:00
for (let i = 0; i < list.length; i++) {
const element = list[i]
2024-11-15 10:59:31 +00:00
if (element.ismanage == 1) {
2024-11-18 08:58:17 +00:00
const height = element.height
2024-11-15 10:59:31 +00:00
let top = 0
let side = topLeft <= topRigth ? "left" : "right"
let left = 0
if (side == "left") {
top = topLeft
topLeft += height
} else {
top = topRigth
topRigth += height
left = 440
}
2024-11-18 08:58:17 +00:00
if (!element.load) {
element["top"] = top
element["left"] = left
}
2024-11-15 10:59:31 +00:00
element["height"] = height
}
2024-11-18 08:58:17 +00:00
}
2024-11-15 10:59:31 +00:00
manageList.value = list
2024-11-01 11:12:06 +00:00
}
2024-11-04 08:24:44 +00:00
const manageEmpty = computed(() => {
2024-11-13 11:16:00 +00:00
return typeList.value[typeIndex.value]["count"] == 0
2024-11-04 08:24:44 +00:00
})
2024-11-01 11:12:06 +00:00
const isPitchExceedOne = computed(() => {
return contrastList.value.filter(item => item.pitch).length >= 1
})
const isPitchExceedTwo = computed(() => {
return contrastList.value.filter(item => item.pitch).length >= 2
})
2024-11-04 08:24:44 +00:00
const isPitchExceedThree = computed(index => {
console.log("index", index)
return contrastList.value.filter(item => item.pitch).length >= 3
})
2024-11-01 11:12:06 +00:00
// 点击选择项目
const cutSelect = index => {
const item = contrastList.value[index]
const state = item["pitch"] || false
if (!state && contrastList.value.filter(item => item["pitch"]).length >= 3) return
item["pitch"] = !item["pitch"]
}
let quickList = ref([])
// 获取快速列表
const getQuickList = () => {
2024-11-13 11:16:00 +00:00
$ajaxget("/api/contrast/getQuickList", {}).then(res => {
2024-11-01 11:12:06 +00:00
if (res.code != 200) return
const data = res.data
quickList.value = data || []
})
}
// 快速列表点击 显示删除 按钮
const quickShowHideDelete = index => {
quickList.value[index]["deleteState"] = !quickList.value[index]["deleteState"]
}
// 点击删除快速对比
const quickDelete = index => {
const data = quickList.value[index]
2024-11-13 11:16:00 +00:00
$ajax("/api/contrast/deleteQuick", {
2024-11-01 11:12:06 +00:00
id: data.id,
}).then(res => {
quickList.value.splice(index, 1)
})
}
// 点击 删除 我的对比
const contrastDelete = () => {
contrastList.value.forEach((element, index) => {
if (element["pitch"]) {
2024-11-13 11:16:00 +00:00
$ajax("/api/contrast/delete", {
2024-11-01 11:12:06 +00:00
projectid: element.projectid,
}).then(res => {
contrastList.value[index]["status"] = false
})
}
})
}
// 公共的获取列表 方法
const getList = (obj = {}) => {
return new Promise((resolve, reject) => {
2024-11-13 11:16:00 +00:00
$ajax("/api/user", {
2024-11-01 11:12:06 +00:00
limit: 2000,
page: obj.page || 1,
typeid: obj.typeid || "",
}).then(res => resolve(res))
})
}
// 切换查看类型
const cutClassify = type => {
// const classify = e.currentTarget.dataset.type
if (type == classify.value) return
classify.value = type
if (classify.value == "manage") {
typeid.value = ""
manageList.value = []
getUserProject()
}
if (classify.value == "vs") {
quickList.value = []
contrastList.value = []
getProjectList()
getQuickList()
}
}
const manageListRef = ref(null)
const inputInput = index => {
2024-11-18 08:58:17 +00:00
const textarea = manageListRef.value.querySelector(`.item[data-index="${index}"] textarea`)
manageList.value[index]["inputHeight"] = textarea.scrollHeight + "px"
2024-11-01 11:12:06 +00:00
}
const inputblur = index => {
const target = manageList.value[index]
2024-11-13 11:16:00 +00:00
$ajax("/api/user/remarks", {
2024-11-01 11:12:06 +00:00
token: target.token,
remarks: target.remarks,
}).then(res => {
console.log("message", res.message)
2024-11-15 10:59:31 +00:00
getAllHeight()
2024-11-01 11:12:06 +00:00
})
}
// 关闭 底部提示框
const manageClose = () => {
manageHintState.value = true
localStorage.setItem("PMState", 1)
}
// 点击头部 tab
const cutTypeid = index => {
typeIndex.value = index
typeid.value = typeList.value[index].value
manageList.value = []
getUserProject()
}
2024-11-04 08:24:44 +00:00
const cutManageStateShow = index => {
manageList.value.forEach(element => (element["state"] = false))
manageList.value[index]["state"] = !manageList.value[index]["state"]
}
const cutManageState = (typeid, index) => {
const target = manageList.value[index] || {}
2024-11-13 11:16:00 +00:00
$ajax("/api/user/changeType", {
2024-11-04 08:24:44 +00:00
token: target.token,
typeid,
}).then(res => {
if (res.code != 200) return
const stateNameFront = stateObj.value[target.typeid] // 修改前的状态
const stateNameAfter = stateObj.value[typeid] // 修改后的状态
typeList.value.forEach(element => {
if (element.name == stateNameFront) element.count--
if (element.name == stateNameAfter) element.count++
})
manageList.value[index]["typeid"] = typeid
manageList.value[index]["state"] = false
if (typeIndex.value != 0) {
manageList.value[index]["ismanage"] = 0
manageList.value[index]["height"] = 0
}
})
}
2024-11-18 08:58:17 +00:00
let isDragging = ref(null)
const startDrag = index => {
isDragging.value = index
const target = manageList.value[index]
manageList.value[index]["load"] = true
}
let timer = null
const dragging = index => {
if (isDragging.value != index) return
manageList.value[index]["left"] += event.movementX
manageList.value[index]["top"] += event.movementY
const list = JSON.parse(JSON.stringify(manageList.value))
let maxOverlapArea = 0
let maxOverlapElement = null
const target = list[index]
for (let i = 0; i < list.length; i++) {
const element = list[i]
if (index !== i) {
const overlapArea = Math.max(0, Math.min(target.left + 420, element.left + 420) - Math.max(target.left, element.left)) * Math.max(0, Math.min(target.top + target.height, element.top + element.height) - Math.max(target.top, element.top))
// 计算重叠面积是否超过另一个元素的一半面积
const halfArea = (420 * element.height) / 2
if (overlapArea > halfArea && overlapArea > maxOverlapArea) {
maxOverlapArea = overlapArea
maxOverlapElement = i
}
}
}
if (maxOverlapElement != null) {
const over1 = JSON.parse(JSON.stringify(list[maxOverlapElement]))
const over2 = JSON.parse(JSON.stringify(list[isDragging.value]))
2024-11-18 10:53:26 +00:00
2024-11-18 08:58:17 +00:00
list[maxOverlapElement]["sortKey"] = over2.sortKey
list[isDragging.value]["sortKey"] = over1.sortKey
manageList.value = list
calculateWaterfall()
isDragging.value = maxOverlapElement
}
}
const endDrag = () => {
if (isDragging.value == null) return
isDragging.value = null
manageList.value.forEach(element => {
element["load"] = false
})
calculateWaterfall()
}
2024-10-31 11:03:26 +00:00
return {
user,
university,
discipline,
contrastcount,
encodekey,
fateProject,
getFate,
admissionList,
admissionPage,
admissionTotalPage,
cutAdmissionPage,
recruitListRef,
reversedMessage,
projectList,
dataListRef,
imageFallLoaded,
handleClick,
openMoreSelect,
closeMoreSelectAll,
baseRef,
2024-11-01 11:12:06 +00:00
stateObj,
contrastList,
projectCount,
cutSelect,
isPitchExceedOne,
isPitchExceedTwo,
2024-11-04 08:24:44 +00:00
isPitchExceedThree,
2024-11-01 11:12:06 +00:00
quickList,
quickShowHideDelete,
quickDelete,
contrastDelete,
classify,
manageList,
2024-11-04 08:24:44 +00:00
manageEmpty,
2024-11-01 11:12:06 +00:00
cutClassify,
typeList,
typeid,
typeIndex,
inputblur,
inputInput,
manageListRef,
manageHintState,
manageClose,
cutTypeid,
2024-11-04 08:24:44 +00:00
cutManageStateShow,
cutManageState,
2024-11-18 08:58:17 +00:00
startDrag,
dragging,
endDrag,
isDragging,
2024-10-31 11:03:26 +00:00
}
2024-10-31 06:46:33 +00:00
},
})
2024-10-31 11:03:26 +00:00
projectIndex.component("base-bottom", base)
2024-10-31 06:46:33 +00:00
projectIndex.mount("#app")
2024-10-28 10:59:51 +00:00
</script>
</body>
</html>