feat: 优化签到和绑定邀请码页面,添加数据加载函数,提升用户体验

This commit is contained in:
2026-01-19 17:09:14 +07:00
parent feb8e28a0c
commit 943ea9a263
3 changed files with 78 additions and 10 deletions

View File

@@ -5,17 +5,23 @@ import { checkmarkCircleOutline } from "ionicons/icons";
import { client, safeClient } from "@/api";
const [start, end] = [dayjs().startOf("month"), dayjs().endOf("month")];
const { data } = await safeClient(client.api.checkIns.get({
const { data, execute: fetchCheckIns } = await safeClient(() => client.api.checkIns.get({
query: {
startDate: start.toISOString(),
endDate: end.toISOString(),
},
}));
const { data: current_streak } = await safeClient(client.api.checkIns.current_streak.get());
const { data: total_count } = await safeClient(client.api.checkIns.total_days.get());
const { data: today_checkin } = await safeClient(client.api.checkIns.today.get({ query: { timezone: "IANA" } }));
const { data: current_streak, execute: fetchCurrentStreak } = await safeClient(() => client.api.checkIns.current_streak.get());
const { data: total_count, execute: fetchTotalCount } = await safeClient(() => client.api.checkIns.total_days.get());
const { data: today_checkin, execute: fetchTodayCheckin } = await safeClient(() => client.api.checkIns.today.get({ query: { timezone: "IANA" } }));
function loadData() {
fetchCheckIns();
fetchCurrentStreak();
fetchTotalCount();
fetchTodayCheckin();
}
const checkedInDates = computed(() => {
if (!data.value?.data)
return new Set<string>();
@@ -29,6 +35,7 @@ function isCheckedIn(day: number) {
async function handleSignup() {
await safeClient(client.api.checkIns.post());
loadData();
toastController.create({
message: "签到成功!",
duration: 2000,

View File

@@ -140,9 +140,15 @@ function nextPage() {
<template>
<ion-page>
<ion-toolbar class="ion-toolbar">
<ion-buttons slot="start">
<back-button />
</ion-buttons>
<ion-title>绑定邀请码</ion-title>
</ion-toolbar>
<ion-content :fullscreen="true">
<!-- 顶部横幅 -->
<img src="@/assets/images/invite-banner.jpg" class="w-full object-cover" alt="邀请横幅">
<img src="@/assets/images/invite-banner.jpg" class="w-full object-contain" alt="邀请横幅">
<div class="ion-padding-horizontal">
<!-- 绑定邀请码 -->

View File

@@ -19,6 +19,7 @@ const qrCodeUrl = computed(() => {
return `https://api.qrserver.com/v1/create-qr-code/?size=150x150&data=${encodeURIComponent(inviteLink)}`;
});
const { share, isSupported } = useShare();
const { data: leader } = safeClient(() => client.api.team.leader.get(), { silent: true });
// 复制状态
const copyStatus = ref({
@@ -144,8 +145,32 @@ function handleBindReferralCode() {
</div>
</section>
<!-- 我的上级 -->
<section v-if="userProfile?.referredBy && leader" class="mb-4">
<div class="leader-card rounded-2xl p-4">
<div class="flex items-center gap-3">
<div class="leader-avatar">
<img src="@/assets/images/avatar.jpg" alt="Leader">
</div>
<div class="flex-1">
<div class="flex items-center gap-2 mb-1">
<div class="text-base font-bold text-[#1a1a1a]">
{{ leader?.nickname }}
</div>
<div class="leader-badge">
上级
</div>
</div>
<div class="text-xs text-[#999]">
邀请码{{ leader?.referralCode }}
</div>
</div>
</div>
</div>
</section>
<!-- 绑定邀请码入口 -->
<section class="mb-4">
<section v-if="!userProfile?.referredBy" class="mb-4">
<div class="bind-referral-card rounded-2xl p-4">
<div class="flex items-center justify-between">
<div class="flex items-center gap-3">
@@ -210,12 +235,12 @@ function handleBindReferralCode() {
</ion-button>
</div>
<div class="flex items-center gap-2 mb-3">
<!-- <div class="flex items-center gap-2 mb-3">
<img src="@/assets/images/icon.png" class="size-7">
<div class="text-lg font-bold text-[#1a1a1a]">
推广链接
</div>
</div>
</div> -->
<!-- <div class="mb-5 bg-gray-50 rounded-xl p-4">
<div class="flex items-center justify-between gap-3">
<div class="flex-1 overflow-hidden">
@@ -310,9 +335,9 @@ function handleBindReferralCode() {
<!-- 邀请说明 -->
<section class="mb-5">
<div class="bg-gradient-to-br from-[#fff7f0] to-[#ffe8e8] rounded-2xl p-5">
<h4 class="text-base font-bold text-[#c41e3a] mb-3">
<div class="text-base font-bold text-[#c41e3a] mb-3">
邀请奖励说明
</h4>
</div>
<div class="space-y-2 text-sm text-[#666]">
<div class="flex items-start gap-2">
<div class="w-1.5 h-1.5 rounded-full bg-[#c41e3a] mt-1.5 flex-shrink-0" />
@@ -404,4 +429,34 @@ function handleBindReferralCode() {
.bind-btn::part(native) {
font-weight: 600;
}
.leader-card {
background: linear-gradient(135deg, #f0f9ff 0%, #e0f2fe 100%);
border: 1px solid #bae6fd;
}
.leader-avatar {
width: 56px;
height: 56px;
border-radius: 50%;
overflow: hidden;
border: 3px solid white;
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
flex-shrink: 0;
}
.leader-avatar img {
width: 100%;
height: 100%;
object-fit: cover;
}
.leader-badge {
background: linear-gradient(135deg, #c41e3a 0%, #8b1a2e 100%);
color: white;
font-size: 10px;
padding: 2px 8px;
border-radius: 10px;
font-weight: 600;
}
</style>