用户登录后自动弹框,放在app.vue注册全局弹框组件
<template>
<div ref="modal" class="classmodal">
<a-modal v-model:visible="dialogVisible" v-if="Login && dialogVisible" centered width="340px" @cancel="cancelM"
:mask="false" :footer="null" :closable="false" :getContainer="() => $refs.modal">
<div class="slices">
<div class="title">签到成功,恭喜获得{{ info.id }}</div>
<div class="tip">
<div class="tip-1">获得<span>+{{ listData?.num || '0' }}</span>云豆</div>
<span class="tip-2">连续签到奖励更丰富</span>
<span class="tip-3">再签到{{ listData?.continue_days || '0' }}天可领{{ listData?.give_num || '150' }}云豆</span>
<div class="btn" @click="cancelM">开心收下</div>
</div>
</div>
</a-modal>
</div>
</template>
js逻辑
/** 签到弹框 */
<script setup>
import { ref, watch } from 'vue'
import { signIn } from '../api/user'
import { storeToRefs } from 'pinia'
import { useUserStore } from '../store/user'
const Login = localStorage.getItem('token')
const dialogVisible = ref(false)
const listData = ref({})
const userInfo = useUserStore()
const { info } = storeToRefs(userInfo)
// 获取用户信息
const Newtime = new Date(new Date(new Date().toLocaleDateString()).getTime() + 24 * 60 * 60 * 1000)//第二天开始时间
const Nowtime = Date.parse(new Date())//当前时间
// 转换时分秒的方法-便于查看
// const getData = (n) => {
// let now = new Date(n),
// y = now.getFullYear(),
// m = now.getMonth() + 1,
// d = now.getDate();
// return y + "-" + (m < 10 ? "0" + m : m) + "-" + (d < 10 ? "0" + d : d) + " " + now.toTimeString().substr(0, 8);
// }
// console.log(getData(Nowtime), getData(Newtime), getData(Date.parse(localStorage.getItem('Newtime'))));
/** 签到 */
const signInfn = () => {
signIn((res) => {
listData.value = res
dialogVisible.value = true
localStorage.setItem('Newtime', Newtime)//签到成功给第二天时间
})
}
/** 这个方法是为了防止用户切换账号登录,但本地已经存在下次签到时间,不允许签到的情况,并且全局方法中pinia数据无法第一时间加载,所以需要一秒延时来获取用户账号id并存储本地 */
setTimeout(() => {
// let ids = Object.values(localStorage.getItem('ids') || '')//获取本地数据,如果不存在本地数据就为空数组
let ids = localStorage.getItem('ids').split('==') || []//获取本地数据,如果不存在本地数据就为空数组
let b = ids.some((value) => { //过滤数据,用户是否重复登录,如果重复登录 b 就为true
return value == info.value?.id
})
// 是否允许签到判断
if (!Date.parse(localStorage.getItem('Newtime'))) { //不存在有过签到数据可以签到
signInfn()
} else if (Nowtime > Date.parse(localStorage.getItem('Newtime'))) { //到了新一天可以签到,并移除设备id
signInfn()
localStorage.removeItem('ids')
} else if (b == false) {//当b为false的时候代表用户登录了新账号,允许进行签到
ids.push(info.value?.id)
localStorage.setItem('ids', ids.join('=='))
signInfn()
}
}, 1000);
const cancelM = () => {
dialogVisible.value = false
}
</script>
样式代码
<style lang="scss" scoped>
.classmodal ::v-deep(.ant-modal-content) {
border-radius: 12px;
}
.classmodal ::v-deep(.ant-modal-body) {
height: 400px;
padding: 0px;
background-image: url('../assets/img/pop-up/slices/slices.png');
background-size: 100% 100%;
}
.slices {
width: 100%;
height: 100%;
position: relative;
.title {
width: 100%;
position: absolute;
top: 30px;
text-align: center;
color: #FFF5E8;
font-size: 20px;
line-height: 1;
}
.tip {
position: absolute;
bottom: 0;
width: 100%;
display: flex;
flex-direction: column;
align-items: center;
.tip-1 {
font-size: 26px;
color: #595F6C;
line-height: 1;
span {
padding: 0 10px;
color: #FF6E2A;
font-size: 44px;
}
}
.tip-2 {
line-height: 1;
margin: 17px 0 8px;
font-size: 16px;
color: #7A5F5F;
}
.tip-3 {
line-height: 1;
font-size: 12px;
color: #7A5F5F;
}
.btn {
width: 236px;
height: 54px;
border-radius: 54px;
display: flex;
align-items: center;
justify-content: center;
font-size: 17px;
color: #FAFAFA;
margin: 10px 0 18px;
background-image: linear-gradient(to right, #ff9126, #ff6a2b);
cursor: pointer;
}
.btn:hover {
background-image: linear-gradient(to right, #ff9126, #ed5415);
}
}
}
</style>