xg-project-library/html/index.html
2024-11-13 19:16:00 +08:00

880 lines
43 KiB
HTML
Raw 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.

<!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 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>
</div>
</div>
<!-- 底部 -->
<base-bottom ref="baseRef"></base-bottom>
<div class="my-project flexacenter" v-if="false">
<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>
<div class="btn flexcenter" :class="{'btn-forbid': isPitchExceedThree, 'btn-normal': item.pitch }" @click="cutSelect(index)">
<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>
<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>
<div v-if="manageEmpty" class="empty-box flexcenter">
<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">
<div class="item" v-if="item.ismanage == 1" :class="'item' + index">
<div class="top flexacenter">
<div class="info flex1">
<div class="name">{{ item.name_zh }}</div>
<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">
<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>
<div v-if="item.state" class="state-list-box flexacenter">
<div class="state-list flexacenter">
<div class="state-item" :class="{'pitch': item.typeid == key}" v-for="(it,key) in stateObj" @click.stop="cutManageState(key, index)">{{ it }}</div>
</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>
<textarea class="input flex1" v-model="item.remarks" placeholder="添加备注…" maxlength="100" @blur="inputblur(index)" @input="inputInput(index)"></textarea>
<img class="drag-icon" src="/img/drag-icon.png" />
</div>
</div>
</template>
</div>
</div>
</div>
</div>
</div>
</div>
<script>
const { createApp, ref, onMounted, nextTick, onUnmounted, computed } = 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/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()
getMyInit()
})
}
// 今日缘分项目
let fateProject = ref([])
const getFate = () => {
$ajaxget("/api/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/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/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/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)
})
let contrastList = ref([])
const stateObj = ref({
0: "待定",
1: "主申",
2: "冲刺",
3: "保底",
})
let manageHintState = ref(false)
let classify = ref("vs")
// 我的项目的初始化
const getMyInit = () => {
console.log(localStorage.getItem("PMState"))
manageHintState.value = localStorage.getItem("PMState") || false
getList().then(res => {
const data = res.data || {}
data.nums = {
contrast: 0,
manage: 10,
}
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) => {
if (element.ismanage == 1) {
const textarea = manageListRef.value.querySelector(`.item${index} textarea`)
textarea.style.height = "auto"
textarea.style.height = textarea.scrollHeight + "px"
}
})
})
}
const manageEmpty = computed(() => {
return typeList.value[typeIndex.value]["count"] == 0
})
const isPitchExceedOne = computed(() => {
return contrastList.value.filter(item => item.pitch).length >= 1
})
const isPitchExceedTwo = computed(() => {
return contrastList.value.filter(item => item.pitch).length >= 2
})
const isPitchExceedThree = computed(index => {
console.log("index", index)
return contrastList.value.filter(item => item.pitch).length >= 3
})
// 点击选择项目
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 = () => {
$ajaxget("/api/contrast/getQuickList", {}).then(res => {
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]
$ajax("/api/contrast/deleteQuick", {
id: data.id,
}).then(res => {
quickList.value.splice(index, 1)
})
}
// 点击 删除 我的对比
const contrastDelete = () => {
contrastList.value.forEach((element, index) => {
if (element["pitch"]) {
$ajax("/api/contrast/delete", {
projectid: element.projectid,
}).then(res => {
contrastList.value[index]["status"] = false
})
}
})
}
// 公共的获取列表 方法
const getList = (obj = {}) => {
return new Promise((resolve, reject) => {
$ajax("/api/user", {
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 => {
const textarea = manageListRef.value.querySelector(`.item${index} textarea`)
textarea.style.height = "auto"
textarea.style.height = textarea.scrollHeight + "px"
}
const inputblur = index => {
const target = manageList.value[index]
$ajax("/api/user/remarks", {
token: target.token,
remarks: target.remarks,
}).then(res => {
console.log("message", res.message)
})
}
// 关闭 底部提示框
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()
}
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] || {}
$ajax("/api/user/changeType", {
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
}
})
}
return {
user,
university,
discipline,
contrastcount,
encodekey,
fateProject,
getFate,
admissionList,
admissionPage,
admissionTotalPage,
cutAdmissionPage,
recruitListRef,
reversedMessage,
projectList,
dataListRef,
imageFallLoaded,
handleClick,
openMoreSelect,
closeMoreSelectAll,
baseRef,
stateObj,
contrastList,
projectCount,
cutSelect,
isPitchExceedOne,
isPitchExceedTwo,
isPitchExceedThree,
quickList,
quickShowHideDelete,
quickDelete,
contrastDelete,
classify,
manageList,
manageEmpty,
cutClassify,
typeList,
typeid,
typeIndex,
inputblur,
inputInput,
manageListRef,
manageHintState,
manageClose,
cutTypeid,
cutManageStateShow,
cutManageState,
}
},
})
projectIndex.component("base-bottom", base)
projectIndex.mount("#app")
</script>
</body>
</html>