需求:
- 后端提供接口返回用户签到信息。
- 应用启动或重新展示时,若用户未签到,需要弹出签到弹窗;已签到则不弹。
- 签到成功后自动关闭弹窗。
思路:
- 用
App.vue的onShow生命周期做全局判断,确保在任意页面激活时都能检查签到状态。 - 在签到弹窗页
pages/checkIn/checkIn.vue中负责: 拉取签到详情、渲染奖励列表、调用签到接口并在成功后自动关闭。
实现步骤:
- 封装接口调用方法
js
// 获取签到信息
getSigninInfoApi(data) {
return http.get("/api/sign_in/info", { params: data || {} });
},
// 执行签到
signInApi(data) {
return http.post("/api/sign_in/sign", { data: data || {} });
},
- 全局入口检查签到状态 (App.vue)
js
import { loginApi } from '@/api/login.js';
const checkSigninStatus = async () => {
// Step 1. 检查 token 是否存在,没有登录用户不触发签到逻辑
const token = uni.getStorageSync('token');
if (!token) return;
try {
// Step 2. 请求签到状态接口
const res = await loginApi.getSigninInfoApi({});
if (res?.code !== 1) return; // 接口异常直接退出
const hasSignedToday = !!res?.data?.is_signed_today;
if (hasSignedToday) return; // 已签到则不弹窗
// Step 3. 打开签到弹窗(防止重复跳转)
const openPopup = () => {
const pages = getCurrentPages();
const currentPage = pages[pages.length - 1];
if (!currentPage || currentPage.route === 'pages/checkIn/checkIn') return;
// 轻微延迟防止路由冲突
uni.navigateTo({
url: '/pages/checkIn/checkIn'
});
};
setTimeout(openPopup, 300);
} catch (e) {
console.error('检查签到状态失败:', e);
}
};
// 在 App.vue 的 onShow 生命周期中触发
onShow(() => {
checkSigninStatus();
});
- 签到弹窗逻辑 (pages/checkIn/checkIn.vue)
- 页面加载时展示签到按钮。
- 点击"签到"后调用
loginApi.signInApi()。 - 签到成功后弹出提示并自动关闭弹窗。
js
// pages/checkIn/checkIn.vue
import { loginApi } from '@/api/login.js';
const loading = ref(false); // 按钮加载状态
const isSignedToday = ref(false); // 是否已签到
// 页面加载时拉取签到状态
onShow(async () => {
const res = await loginApi.getSigninInfoApi({});
if (res?.code === 1) {
isSignedToday.value = !!res.data.is_signed_today;
}
});
// 点击"立即签到"按钮
const handleSignIn = async () => {
if (loading.value) return;
loading.value = true;
try {
const res = await loginApi.signInApi({});
if (res?.code === 1) {
uni.showToast({
title: '签到成功',
icon: 'success'
});
// 延迟关闭弹窗
setTimeout(() => {
uni.navigateBack(); // 返回上一个页面(即关闭弹窗)
}, 800);
} else {
uni.showToast({
title: res?.msg || '签到失败,请稍后再试',
icon: 'none'
});
}
} catch (err) {
console.error('签到请求失败:', err);
uni.showToast({
title: '网络异常,请稍后再试',
icon: 'none'
});
} finally {
loading.value = false;
}
};