<template> <el-dialog v-model="show" width="750px" align-center class="dialog-box"> <!-- <div class="popup-mask flexcenter"> --> <div class="box flexflex"> <img class="cross" src="@/assets/img/cross-icon.png" alt @click="closeDialog()" /> <div class="tba-list flexcenter"> <div class="tab-item flexcenter" :class="{ pitch: MyPopupState == 'collect' }" @click="cutMy('collect')"> 我的收藏 <div class="value">{{ collectCount > 0 ? collectCount : count["collect"] }}</div> </div> <div class="tab-item flexcenter" :class="{ pitch: MyPopupState == 'mj' }" @click="cutMy('mj')"> 我的面经 <div class="value">{{ count["publish"] }}</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-else-if="showList.length == 0"> <Empty></Empty> </div> <div class="content" v-else @scroll="handleListScroll"> <div class="item flexflex" v-for="(item, index) in showList" :key="index" @click="goDetails(item['uniqid'] || item?.data?.uniqid)"> <div class="left flexflex"> <div class="name">{{ item["school"] || item["data"]["school"] }}</div> <div class="info-box flexflex"> <div class="info-item flexacenter" v-if="item['profession'] || item?.['data']?.['profession']"> <div class="info-item-name">专业</div> <div class="info-item-value">{{ item["profession"] || item["data"]["profession"] }}</div> </div> <div class="info-item flexacenter" v-if="item['project'] || item?.data?.project"> <div class="info-item-name">项目</div> <div class="info-item-value">{{ item["project"] || item?.data?.project }}</div> </div> </div> <div class="text-box flexacenter"> <div class="text-time" v-if="item?.releasetime">{{ handleDate(item?.releasetime) }}发布</div> <div class="text-message flex1 ellipsis">{{ item["message"] || item["data"]["message"] }}</div> </div> </div> <div class="operate-area flexacenter"> <img class="delete-icon" v-if="MyPopupState == 'collect'" @click.stop="cancelCollection(item['token'], index, item?.data?.uniqid)" src="@/assets/img/delete-icon.svg" /> <div class="anonymous-box flexacenter" v-else @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> </div> </div> </div> </el-dialog> <!-- </div> --> </template> <script setup> // let props = defineProps({ // // MyPopupState: String, // collect mj // count: Object, // }) let count = inject("count") let show = ref(false) const router = useRouter() const route = useRoute() let MyPopupState = ref("") // collect mj onMounted(() => { // if (MyPopupState.value == "collect") getCollect(); // else if (MyPopupState.value == "mj") getPublish(); }) // 展示的 列表数据 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 MyUserCollectHttp({ page: collectPage }) .then(res => { if (res.code != 200) return let data = res.data collectList = collectList.concat(data.data) showList.value = collectList if (collectList.length < data["count"]) collectPage++ else collectPage = 0 collectCount.value = data["count"] // MyPopupState.value = "collect" // show.value = true }) .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 // MyPopupState.value = "mj" // show.value = true }) .finally(() => (publisloading.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 == "mj" && publishList.length == 0) getPublish() if (key == "collect") showList.value = collectList else if (key == "mj") 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) 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 == "mj") getPublish() } let clearAllData = inject("clearAllData") || null let getDetails = inject("getDetails") || null // 打开详情页 const goDetails = uniqid => { 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) showList.value = [...collectList] count.value.collect-- collectCount.value-- if (id == uniqid) unbookmarkSamePage() }) } </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; position: relative; .cross { position: absolute; top: 12px; right: 12px; width: 12px; height: 12px; cursor: pointer; } .tba-list { font-size: 16px; margin-bottom: 29px; .tab-item { color: #aaaaaa; padding: 0 22px; cursor: pointer; position: relative; &:first-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: 100%; height: 100%; background-color: rgba(255, 255, 255, 1); border: 1px solid rgba(235, 235, 235, 1); border-radius: 6px; margin: 0 auto; } .content { width: 100%; height: 100%; // background: #000000; overflow: auto; padding-right: 10px; padding-bottom: 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; // padding-left: 22px; 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; font-size: 14px; color: #000000; margin-bottom: 10px; } .info-box { flex-direction: column; margin-bottom: 7px; .info-item { line-height: 24px; &:not(:last-of-type) { margin-bottom: 3px; } .info-item-name { color: #7f7f7f; font-size: 13px; margin-right: 12px; } .info-item-value { font-size: 13px; color: #333333; } } } .text-box { width: 580px; height: 45px; line-height: 45px; background-color: rgba(246, 246, 246, 1); border-radius: 5px; color: #000000; font-size: 13px; padding: 0 16px; .text-time { color: #7f7f7f; padding-right: 16px; position: relative; &::after { content: "|"; position: absolute; right: 8px; color: #d7d7d7; } } } } .operate-area { flex: 1; display: flex; justify-content: flex-end; .delete-icon { width: 12px; cursor: pointer; } .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>