|
|
@@ -10,33 +10,33 @@
|
|
|
<!-- 签到统计 -->
|
|
|
<div class="sign-stats">
|
|
|
<div class="stats-item">
|
|
|
- <span class="value">{{ signInfo?.signedDays || 0 }}</span>
|
|
|
- <span class="label">{{ $t('signIn.signedDays', { count: signInfo?.signedDays || 0 }) }}</span>
|
|
|
+ <span class="value">{{ signInfo?.continuousDays || 0 }}</span>
|
|
|
+ <span class="label">{{ $t('signIn.continuousDays') }}</span>
|
|
|
</div>
|
|
|
<div class="stats-divider"></div>
|
|
|
<div class="stats-item">
|
|
|
- <span class="value">{{ signInfo?.targetDays || 7 }}</span>
|
|
|
- <span class="label">{{ $t('signIn.targetDays', { count: signInfo?.targetDays || 7 }) }}</span>
|
|
|
+ <span class="value">{{ signInfo?.totalDays || 0 }}</span>
|
|
|
+ <span class="label">{{ $t('signIn.totalDays') }}</span>
|
|
|
</div>
|
|
|
</div>
|
|
|
|
|
|
- <!-- 签到日历 -->
|
|
|
+ <!-- 签到日历 (8天循环) -->
|
|
|
<div class="sign-calendar">
|
|
|
<div
|
|
|
class="calendar-day"
|
|
|
- v-for="day in 7"
|
|
|
- :key="day"
|
|
|
+ v-for="item in rewardList"
|
|
|
+ :key="item.day"
|
|
|
:class="{
|
|
|
- signed: day <= (signInfo?.signedDays || 0),
|
|
|
- today: day === (signInfo?.signedDays || 0) + 1 && !signInfo?.todaySigned
|
|
|
+ signed: isSignedDay(item.day),
|
|
|
+ today: isTodayDay(item.day)
|
|
|
}"
|
|
|
>
|
|
|
<div class="day-icon">
|
|
|
- <van-icon v-if="day <= (signInfo?.signedDays || 0)" name="success" />
|
|
|
+ <van-icon v-if="isSignedDay(item.day)" name="success" />
|
|
|
<van-icon v-else name="gift-o" />
|
|
|
</div>
|
|
|
- <div class="day-text">{{ $t('signIn.consecutiveDays', { count: day }) }}</div>
|
|
|
- <div class="day-reward">+{{ getReward(day) }}</div>
|
|
|
+ <div class="day-text">{{ $t('signIn.day') }}{{ item.day }}</div>
|
|
|
+ <div class="day-reward">+{{ item.reward }}</div>
|
|
|
</div>
|
|
|
</div>
|
|
|
|
|
|
@@ -62,54 +62,83 @@
|
|
|
|
|
|
<!-- 签到规则 -->
|
|
|
<div class="sign-rules">
|
|
|
- <div class="rules-title">Sign-in Rules</div>
|
|
|
+ <div class="rules-title">{{ $t('signIn.rules') }}</div>
|
|
|
<div class="rules-content">
|
|
|
- <p>1. Sign in every day to earn rewards</p>
|
|
|
- <p>2. Consecutive sign-ins increase your rewards</p>
|
|
|
- <p>3. Missing a day will reset your streak</p>
|
|
|
- <p>4. Rewards are credited to your balance instantly</p>
|
|
|
+ <p>1. {{ $t('signIn.rule1') }}</p>
|
|
|
+ <p>2. {{ $t('signIn.rule2') }}</p>
|
|
|
+ <p>3. {{ $t('signIn.rule3') }}</p>
|
|
|
+ <p>4. {{ $t('signIn.rule4') }}</p>
|
|
|
</div>
|
|
|
</div>
|
|
|
</div>
|
|
|
</template>
|
|
|
|
|
|
<script setup lang="ts">
|
|
|
-import { ref, onMounted } from "vue";
|
|
|
+import { ref, computed, onMounted } from "vue";
|
|
|
import { useRouter } from "vue-router";
|
|
|
import { useI18n } from "vue-i18n";
|
|
|
import { showToast } from "vant";
|
|
|
-import { requestSignInfo, requestSignIn } from "@/api/user";
|
|
|
+import { requestGetSignInfo, requestDailySignIn } from "@/api/user";
|
|
|
|
|
|
const { t } = useI18n();
|
|
|
const router = useRouter();
|
|
|
|
|
|
-const signInfo = ref<SignInfo | null>(null);
|
|
|
+interface SignInfoData {
|
|
|
+ continuousDays: number;
|
|
|
+ totalDays: number;
|
|
|
+ todaySigned: boolean;
|
|
|
+ signDates: string[];
|
|
|
+ rewards: { day: number; reward: number }[];
|
|
|
+}
|
|
|
+
|
|
|
+const signInfo = ref<SignInfoData | null>(null);
|
|
|
const signing = ref(false);
|
|
|
|
|
|
-const rewards = [0.1, 0.2, 0.3, 0.5, 0.8, 1.0, 2.0];
|
|
|
+// 奖励列表(8天一周期)
|
|
|
+const rewardList = computed(() => {
|
|
|
+ return signInfo.value?.rewards || [
|
|
|
+ { day: 1, reward: 0.10 },
|
|
|
+ { day: 2, reward: 0.20 },
|
|
|
+ { day: 3, reward: 0.40 },
|
|
|
+ { day: 4, reward: 0.80 },
|
|
|
+ { day: 5, reward: 1.60 },
|
|
|
+ { day: 6, reward: 3.20 },
|
|
|
+ { day: 7, reward: 6.40 },
|
|
|
+ { day: 8, reward: 12.80 },
|
|
|
+ ];
|
|
|
+});
|
|
|
+
|
|
|
+// 判断某天是否已签到(基于连续天数在8天循环内的位置)
|
|
|
+const isSignedDay = (day: number) => {
|
|
|
+ const continuousDays = signInfo.value?.continuousDays || 0;
|
|
|
+ const cycleDay = continuousDays % 8 || (continuousDays > 0 ? 8 : 0);
|
|
|
+ return day <= cycleDay && signInfo.value?.todaySigned;
|
|
|
+};
|
|
|
|
|
|
-const getReward = (day: number) => {
|
|
|
- return rewards[day - 1] || 0.1;
|
|
|
+// 判断是否是今天要签到的天数
|
|
|
+const isTodayDay = (day: number) => {
|
|
|
+ if (signInfo.value?.todaySigned) return false;
|
|
|
+ const continuousDays = signInfo.value?.continuousDays || 0;
|
|
|
+ const nextDay = (continuousDays % 8) + 1;
|
|
|
+ return day === nextDay;
|
|
|
};
|
|
|
|
|
|
+// 获取今日奖励
|
|
|
const getTodayReward = () => {
|
|
|
- const nextDay = (signInfo.value?.signedDays || 0) + 1;
|
|
|
- return getReward(Math.min(nextDay, 7));
|
|
|
+ const continuousDays = signInfo.value?.continuousDays || 0;
|
|
|
+ const nextDayIndex = continuousDays % 8;
|
|
|
+ const rewards = rewardList.value;
|
|
|
+ return rewards[nextDayIndex]?.reward || 0.10;
|
|
|
};
|
|
|
|
|
|
const getSignInfo = async () => {
|
|
|
try {
|
|
|
- const res = await requestSignInfo();
|
|
|
+ const res = await requestGetSignInfo();
|
|
|
if (res.code === 200) {
|
|
|
- signInfo.value = res.data;
|
|
|
+ signInfo.value = res.data as any;
|
|
|
}
|
|
|
} catch (e) {
|
|
|
- signInfo.value = {
|
|
|
- signedDays: 3,
|
|
|
- targetDays: 7,
|
|
|
- todaySigned: false,
|
|
|
- todayReward: 0.5
|
|
|
- };
|
|
|
+ console.error('Failed to get sign info:', e);
|
|
|
}
|
|
|
};
|
|
|
|
|
|
@@ -118,21 +147,17 @@ const handleSignIn = async () => {
|
|
|
|
|
|
signing.value = true;
|
|
|
try {
|
|
|
- const res = await requestSignIn();
|
|
|
+ const res = await requestDailySignIn();
|
|
|
if (res.code === 200) {
|
|
|
- const reward = res.data?.reward || getTodayReward();
|
|
|
+ const reward = (res.data as any)?.reward || getTodayReward();
|
|
|
showToast(t('signIn.signInSuccess', { amount: reward }));
|
|
|
getSignInfo();
|
|
|
} else {
|
|
|
- showToast(res.msg || 'Failed');
|
|
|
+ showToast(res.msg || t('signIn.signInFailed'));
|
|
|
}
|
|
|
} catch (e) {
|
|
|
- const reward = getTodayReward();
|
|
|
- showToast(t('signIn.signInSuccess', { amount: reward }));
|
|
|
- if (signInfo.value) {
|
|
|
- signInfo.value.todaySigned = true;
|
|
|
- signInfo.value.signedDays++;
|
|
|
- }
|
|
|
+ console.error('Sign in error:', e);
|
|
|
+ showToast(t('signIn.signInFailed'));
|
|
|
}
|
|
|
signing.value = false;
|
|
|
};
|
|
|
@@ -201,8 +226,8 @@ onMounted(() => {
|
|
|
|
|
|
.sign-calendar {
|
|
|
display: grid;
|
|
|
- grid-template-columns: repeat(7, 1fr);
|
|
|
- gap: 8px;
|
|
|
+ grid-template-columns: repeat(4, 1fr);
|
|
|
+ gap: 10px;
|
|
|
padding: 0 16px;
|
|
|
|
|
|
.calendar-day {
|