PC-vote/components/MyPopup.vue
2024-01-15 19:02:10 +08:00

514 lines
16 KiB
Vue
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.

<template>
<el-dialog v-model="show" width="750px" align-center class="dialog-box">
<div class="box flexflex">
<img class="cross" src="@/assets/img/cross-icon.png" alt @click="closeDialog()" />
<div class="tab-list flexcenter">
<div class="tab-item flexcenter" :class="{ pitch: MyPopupState == item.type }" v-for="item in tabList" :key="item.type" @click="cutMy(item.type)">
{{ item.name }}
<div class="value">{{ count[item.type] }}</div>
</div>
</div>
<!-- <div class="empty-box flexcenter" v-loading="true" v-if="(MyPopupState == 'collect' && collectLoading) || (MyPopupState == 'mj' && publisloading)"></div> -->
<div class="empty-box flexcenter" v-if="showList.length == 0">
<Empty></Empty>
</div>
<el-scrollbar v-else height="479px">
<div class="content" @scroll="handleListScroll">
<div class="item flexflex" v-for="(item, index) in showList" :key="item.uniqid" @click="goDetails(item['uniqid'] || item?.data?.uniqid)">
<div class="left flexflex">
<div class="name ellipsis">{{ item.title || item.data?.title }}</div>
<div class="message ellipsis">{{ item.message || item.data?.message }}</div>
<div class="data">
{{ item.votes || item.data?.votes || 0 }}人参与 <i>|</i> {{ handleDeadline(item.deadline || item?.data?.deadline) }}结束
<span v-if="item.optionvalue || item?.data?.optionvalue"><i>|</i> 我已投{{ item.optionvalue || item?.data?.optionvalue }}</span>
</div>
</div>
<div class="operate-area flexacenter">
<!-- <div class="anonymous-box flexacenter" v-if="MyPopupState == 'publish'" @click.stop="openAnonymousState(index)"> -->
<template v-if="MyPopupState == 'publish'">
<div class="anonymous-box flexacenter" @click.stop="openAnonymousState(index)">
<div class="text">{{ item["anonymous"] == 1 ? "匿名" : "公开" }}</div>
<img class="arrow-icon" src="@/assets/img/arrow-gray.svg" />
<div class="state-popup flexflex" v-if="item['anonymousState']" @click.stop="">
<div class="state-popup-item flexacenter flex1" :class="{ 'pitch': item['anonymous'] == 0 }" @click="handleAnonymousState(item['token'], index, 0)">
<div class>公开发表</div>
<img class="state-popup-icon" src="@/assets/img/tick-green.svg" />
</div>
<div class="state-popup-item flexacenter flex1" :class="{ 'pitch': item['anonymous'] == 1 }" @click="handleAnonymousState(item['token'], index, 1)">
<div class>匿名发表</div>
<img class="state-popup-icon" src="@/assets/img/tick-green.svg" />
</div>
</div>
</div>
<div class="halving-line"></div>
<img class="delete-icon" @click.stop="openDeleteVote(item['token'], index, item.uniqid || item?.data?.uniqid)" src="@/assets/img/delete-icon.svg" />
</template>
<img class="delete-icon" v-if="MyPopupState == 'collect'" @click.stop="cancelCollection(item['token'], index, item.uniqid || item?.data?.uniqid)" src="@/assets/img/delete-icon.svg" />
</div>
</div>
</div>
</el-scrollbar>
</div>
</el-dialog>
<el-dialog class="options-popup" v-model="deleteState" width="488px" align-center>
<div class="options-popup-text">您要删除投票吗</div>
<div class="options-popup-btn flexflex">
<div class="options-popup-item options-no flexcenter" @click="deleteVote">删除投票</div>
<div class="options-popup-item options-yes flexcenter" @click="deleteState = false">不删除</div>
</div>
</el-dialog>
<!-- </div> -->
</template>
<script setup>
let props = defineProps({
tabList: Array,
})
let deleteState = ref(false) // 确认删除弹窗
let count = inject("count")
let show = ref(false)
const router = useRouter()
const route = useRoute()
let MyPopupState = ref("") // collect takevote publish
onMounted(() => {})
// 展示的 列表数据
let showList = ref([])
let collectList = []
let collectPage = 1
let collectLoading = ref(false)
let collectCount = ref(0)
const getCollect = () => {
if (collectPage == 0 || collectLoading.value) return
collectLoading.value = true
// if (collectPage == 2) return
MyUserCollectHttp({ page: collectPage })
.then(res => {
if (res.code != 200) return
let data = res.data
collectList = collectList.concat(data.data)
showList.value = collectList
// showList.value = showList.value.concat(data.data)
if (collectList.length < data["count"]) collectPage++
else collectPage = 0
collectCount.value = data["count"]
})
.finally(() => (collectLoading.value = false))
}
let publishList = []
let publisPage = 1
let publisloading = ref(false)
const getPublish = () => {
if (publisPage == 0 && !publisloading.value) return
publisloading.value = true
MyUserPublishHttp({ page: publisPage })
.then(res => {
if (res.code != 200) return
let data = res.data
publishList = publishList.concat(data.data)
if (publishList.length < data["count"]) publisPage++
else publisPage = 0
showList.value = publishList
})
.finally(() => (publisloading.value = false))
}
let takevoteList = []
let takevotePage = 1
let takevoteloading = ref(false)
const getTakevote = () => {
if (takevotePage == 0 && !takevoteloading.value) return
takevoteloading.value = true
MyUserTakevoteHttp({ page: takevotePage })
.then(res => {
if (res.code != 200) return
let data = res.data
takevoteList = takevoteList.concat(data.data)
if (takevoteList.length < data["count"]) takevotePage++
else takevotePage = 0
showList.value = takevoteList
})
.finally(() => (takevoteloading.value = false))
}
// 切换 isEmpty 是否清空收藏数据, 因为不确定用户是否有新收藏
const cutMy = (key, isEmpty) => {
if (isEmpty) {
collectList = []
collectPage = 1
collectCount.value = 0
}
if (key == "collect" && collectList.length == 0) getCollect()
else if (key == "takevote" && takevoteList.length == 0) getTakevote()
else if (key == "publish" && publishList.length == 0) getPublish()
if (key == "collect") showList.value = collectList
else if (key == "takevote") showList.value = takevoteList
else if (key == "publish") showList.value = publishList
MyPopupState.value = key
if (MyPopupState.value) show.value = true
}
// 打开匿名弹窗
const openAnonymousState = index => {
publishList.forEach(element => {
element["anonymousState"] = false
})
publishList[index]["anonymousState"] = true
showList.value = [...publishList]
}
// 关闭全部匿名弹窗
const closeAllAnonymousState = () => {
publishList.forEach(element => {
element["anonymousState"] = false
})
showList.value = [...publishList]
}
// 修改匿名状态
const handleAnonymousState = (token, index, anonymous) => {
changeAnonymousHttp({ token, anonymous }).then(res => {
if (res.code != 200) {
ElMessage.error(res.message)
return
}
publishList[index]["anonymous"] = anonymous
showList.value = [...publishList]
closeAllAnonymousState()
ElMessage.success(res.message)
})
}
// 详情页滚动事件
const handleListScroll = e => {
const el = e.target
// 判断滚动到底部
if (el.scrollHeight - el.scrollTop !== el.clientHeight) return
if (MyPopupState.value == "collect") getCollect()
if (MyPopupState.value == "takevote") getTakevote()
if (MyPopupState.value == "publish") getPublish()
}
let clearAllData = inject("clearAllData") || null
let getDetails = inject("getDetails") || null
// 打开详情页
const goDetails = uniqid => {
// return
let path = route["path"] || ""
if (path.indexOf("/details/") != -1) {
clearAllData()
nextTick(() => getDetails())
}
// router.replace(`/details/${uniqid}`)
goToURL(`/details/${uniqid}`, false)
show.value = false
MyPopupState.value = ""
}
//暴露state和play方法
defineExpose({
cutMy,
})
// 关闭弹窗
const closeDialog = () => {
show.value = false
}
// const emit = defineEmits(["cutMy"]);
const unbookmarkSamePage = inject("unbookmarkSamePage")
// 处理取消收藏
const cancelCollection = (token, index, uniqid) => {
const id = route.params["id"]
MyUserDeleteCollectHttp({ token }).then(res => {
if (res.code != 200) {
ElMessage.error(res.message)
return
}
collectList.splice(index, 1)
count.value.collect--
collectCount.value--
showList.value = [...collectList]
if (id == uniqid) unbookmarkSamePage()
})
}
let deleteobj = {}
const openDeleteVote = (token, index, uniqid) => {
deleteobj["token"] = token
deleteobj["index"] = index
deleteobj["uniqid"] = uniqid
deleteState.value = true
}
// 点删除投票
const deleteVote = () => {
const id = route.params["id"]
deleteHttp({ token: deleteobj["token"] }).then(res => {
if (res.code != 200) {
ElMessage.error(res.message)
return
}
count.value.publish--
publishList.splice(deleteobj["index"], 1)
showList.value = [...publishList]
if (id == deleteobj["uniqid"]) unbookmarkSamePage()
ElMessage.success(res.message)
deleteobj = {}
deleteState.value = false
})
}
</script>
<style lang="less" scoped>
.popup-mask {
width: 100vw;
height: 100vh;
background: rgba(0, 0, 0, 0.5);
position: fixed;
top: 0;
left: 0;
max-width: none;
max-height: none;
border: none;
outline: none;
z-index: 1;
}
.box {
width: 750px;
height: 606px;
background-color: rgba(255, 255, 255, 1);
border-radius: 10px;
-moz-box-shadow: 0px 0px 3px rgba(0, 0, 0, 0.117647058823529);
-webkit-box-shadow: 0px 0px 3px rgba(0, 0, 0, 0.117647058823529);
box-shadow: 0px 0px 3px rgba(0, 0, 0, 0.117647058823529);
flex-direction: column;
// padding: 30px 30px 46px;
padding: 30px 8px 46px;
position: relative;
.cross {
position: absolute;
top: 12px;
right: 12px;
width: 12px;
height: 12px;
cursor: pointer;
}
.tab-list {
font-size: 16px;
margin-bottom: 29px;
.tab-item {
color: #aaaaaa;
padding: 0 22px;
cursor: pointer;
position: relative;
&:not(:last-of-type)::after {
content: "";
width: 1px;
height: 16px;
background: #d7d7d7;
position: absolute;
right: 0;
}
.value {
margin-left: 10px;
}
&.pitch {
font-weight: 650;
color: #000000;
.value {
color: #555;
font-weight: 400;
}
}
}
}
.empty-box {
width: calc(100% - 44px);
height: 100%;
background-color: rgba(255, 255, 255, 1);
border: 1px solid rgba(235, 235, 235, 1);
border-radius: 6px;
margin: 0 22px;
}
.content {
width: 100%;
height: 479px;
// height: 100%;
// background: #000000;
overflow: auto;
// padding-right: 13px;
// padding-bottom: 35px;
padding: 22px 22px 35px;
.item {
// flex-direction: column;
border-bottom: 1px dotted #ebebeb;
padding-bottom: 20px;
cursor: pointer;
margin-left: 22px;
margin-bottom: 21px;
.left {
flex-direction: column;
flex: 1;
position: relative;
&::after {
content: "";
position: absolute;
top: 4px;
left: -22px;
width: 5px;
height: 12px;
background-color: rgba(49, 215, 46, 1);
border-radius: 25px;
}
.name {
// font-weight: 650;
color: #000000;
line-height: 20px;
font-size: 14px;
margin-bottom: 10px;
width: 550px;
}
.message {
color: #7f7f7f;
line-height: 22px;
font-size: 13px;
margin-bottom: 6px;
width: 550px;
}
.data {
color: #aaaaaa;
line-height: 22px;
font-size: 12px;
i {
margin: 0 5px;
font-style: normal;
}
}
}
.operate-area {
display: flex;
justify-content: flex-end;
.delete-icon {
width: 12px;
cursor: pointer;
}
.halving-line {
margin: 0 20px;
width: 1px;
height: 13px;
border-right: 1px solid #d7d7d7;
}
.anonymous-box {
.text {
font-size: 13px;
color: #333333;
}
.arrow-icon {
width: 8px;
height: 5px;
margin-left: 6px;
}
position: relative;
.state-popup {
position: absolute;
top: 30px;
right: 0;
width: 140px;
height: 101px;
background-color: rgba(255, 255, 255, 1);
border-radius: 10px;
-moz-box-shadow: 0px 0px 6px rgba(0, 0, 0, 0.203921568627451);
-webkit-box-shadow: 0px 0px 6px rgba(0, 0, 0, 0.203921568627451);
box-shadow: 0px 0px 6px rgba(0, 0, 0, 0.203921568627451);
flex-direction: column;
.state-popup-item {
justify-content: space-between;
color: #555;
font-size: 14px;
padding: 0 10px;
&:hover {
color: #000000;
}
&.pitch {
color: #72db86;
.state-popup-icon {
display: block;
}
}
&:not(:last-of-type) {
border-bottom: 1px dotted #e3e3e3;
}
.state-popup-icon {
width: 11px;
height: 8px;
display: none;
}
}
}
}
}
}
}
}
</style>
<style lang="less">
.dialog-box {
header {
display: none;
}
border-radius: 10px;
.el-dialog__body {
padding: 0;
}
}
</style>