diff --git a/miniprogram/pages/daily/daily.ts b/miniprogram/pages/daily/daily.ts index e69de29..db4071a 100644 --- a/miniprogram/pages/daily/daily.ts +++ b/miniprogram/pages/daily/daily.ts @@ -0,0 +1,189 @@ +// 定义日历日期类型 +interface CalendarDay { + type: 'current' | 'empty'; // current:当月日期, empty:空占位(上月/下月) + day: number; // 日期数字 + date: string; // 完整日期(YYYY-MM-DD) + isChecked: boolean; // 是否已签到 + isToday: boolean; // 是否是今天 +} + +Page({ + data: { + currentYear: new Date().getFullYear(), // 当前年 + currentMonth: new Date().getMonth(), // 当前月(0-11) + calendarDays: [] as CalendarDay[], // 日历日期列表 + checkinHistory: [] as string[], // 签到历史(存储YYYY-MM-DD格式日期) + continuousCheckinDays: 0, // 连续签到天数 + totalCheckinDays: 0, // 本月总签到天数 + isCheckedToday: false, // 今日是否已签到 + isAnimating: false // 是否正在执行签到动画 + }, + + onLoad() { + // 从本地缓存加载签到历史 + this.loadCheckinHistory(); + // 生成当月日历数据 + this.generateCalendarDays(); + // 计算签到统计数据 + this.calculateCheckinStats(); + }, + + /** + * 从本地缓存加载签到历史 + */ + loadCheckinHistory() { + const history = wx.getStorageSync('checkinHistory') || []; + this.setData({ checkinHistory: history }); + + // 检查今日是否已签到 + const today = this.formatDate(new Date()); + const isCheckedToday = history.includes(today); + this.setData({ isCheckedToday }); + }, + + /** + * 生成当月日历数据 + */ + generateCalendarDays() { + const { currentYear, currentMonth, checkinHistory } = this.data; + const calendarDays: CalendarDay[] = []; + + // 获取当月第一天是星期几(0=周日,1=周一...6=周六) + const firstDayOfMonth = new Date(currentYear, currentMonth, 1).getDay(); + // 获取当月总天数 + const totalDaysOfMonth = new Date(currentYear, currentMonth + 1, 0).getDate(); + // 获取今日日期(YYYY-MM-DD) + const today = this.formatDate(new Date()); + + // 添加上月残留日期(空占位) + for (let i = 0; i < firstDayOfMonth; i++) { + calendarDays.push({ + type: 'empty', + day: 0, + date: '', + isChecked: false, + isToday: false + }); + } + + // 添加当月日期 + for (let day = 1; day <= totalDaysOfMonth; day++) { + const date = new Date(currentYear, currentMonth, day); + const dateStr = this.formatDate(date); + const isChecked = checkinHistory.includes(dateStr); + const isToday = dateStr === today; + + calendarDays.push({ + type: 'current', + day, + date: dateStr, + isChecked, + isToday + }); + } + + // 添加下月占位日期(确保日历满6行,共42个格子) + const totalCells = 42; // 6行×7列=42个格子 + const remainingCells = totalCells - calendarDays.length; + for (let i = 0; i < remainingCells; i++) { + calendarDays.push({ + type: 'empty', + day: 0, + date: '', + isChecked: false, + isToday: false + }); + } + + this.setData({ calendarDays }); + }, + + /** + * 计算签到统计数据 + */ + calculateCheckinStats() { + const { checkinHistory, currentYear, currentMonth } = this.data; + const today = new Date(); + + // 计算本月总签到天数 + const monthStart = new Date(currentYear, currentMonth, 1); + const monthEnd = new Date(currentYear, currentMonth + 1, 0); + const monthStartStr = this.formatDate(monthStart); + const monthEndStr = this.formatDate(monthEnd); + + const monthlyCheckins = checkinHistory.filter(date => { + return date >= monthStartStr && date <= monthEndStr; + }); + + // 计算连续签到天数 + let continuousDays = 0; + const sortedHistory = [...checkinHistory].sort(); + + // 从今天开始往前查连续签到 + const checkDate = new Date(today); + while (true) { + const dateStr = this.formatDate(checkDate); + if (sortedHistory.includes(dateStr)) { + continuousDays++; + // 往前推一天 + checkDate.setDate(checkDate.getDate() - 1); + } else { + break; + } + } + + this.setData({ + totalCheckinDays: monthlyCheckins.length, + continuousCheckinDays: continuousDays + }); + }, + + /** + * 处理签到逻辑 + */ + handleCheckin() { + if (this.data.isCheckedToday || this.data.isAnimating) return; + + // 开始动画 + this.setData({ isAnimating: true }); + + // 记录当前日期 + const today = this.formatDate(new Date()); + const { checkinHistory } = this.data; + + // 添加到签到历史 + const newHistory = [...checkinHistory, today]; + wx.setStorageSync('checkinHistory', newHistory); + + // 更新数据 + setTimeout(() => { + this.setData({ + checkinHistory: newHistory, + isCheckedToday: true, + isAnimating: false + }); + + // 更新日历和统计 + this.generateCalendarDays(); + this.calculateCheckinStats(); + + // 显示成功提示 + wx.showToast({ + title: '签到成功!', + icon: 'success', + duration: 1500 + }); + }, 1000); // 动画持续1秒 + }, + + /** + * 格式化日期为YYYY-MM-DD + */ + formatDate(date: Date): string { + const year = date.getFullYear(); + const month = String(date.getMonth() + 1).padStart(2, '0'); + const day = String(date.getDate()).padStart(2, '0'); + return `${year}-${month}-${day}`; + } +}); + \ No newline at end of file diff --git a/miniprogram/pages/daily/daily.wxml b/miniprogram/pages/daily/daily.wxml index 0bdb597..c33aaf6 100644 --- a/miniprogram/pages/daily/daily.wxml +++ b/miniprogram/pages/daily/daily.wxml @@ -1 +1,107 @@ -daily \ No newline at end of file + + + + {{currentYear}}年{{currentMonth + 1}}月 + + + {{continuousCheckinDays}} + 连续签到 + + + {{totalCheckinDays}} + 本月签到 + + + + + + + + + {{isCheckedToday ? '今日已完成签到,明天继续哦~' : '点击按钮完成今日签到,领取奖励'}} + + + + + + 签到日历 + + + + + + + + + + + + + + + + {{item.type !== 'empty' ? item.day : ''}} + + + + + + + + + + + 签到奖励 + + + 连续签到3天 + + 获得10积分 + + + 已达成 + + + + 连续签到7天 + + 获得30积分 + 优惠券 + + + 已达成 + + + + 连续签到15天 + + 获得50积分 + 专属权益 + + + 已达成 + + + + + + \ No newline at end of file diff --git a/miniprogram/pages/daily/daily.wxss b/miniprogram/pages/daily/daily.wxss index e69de29..166ec96 100644 --- a/miniprogram/pages/daily/daily.wxss +++ b/miniprogram/pages/daily/daily.wxss @@ -0,0 +1,271 @@ +/* 全局样式 */ +page { + background-color: #f7f8fa; + font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif; + min-height: 100vh; +} + +/* 容器样式 */ +.checkin-container { + padding: 20rpx; + box-sizing: border-box; +} + +/* 顶部信息区 */ +.header { + background-color: #51bdb6; + border-radius: 20rpx; + padding: 30rpx; + color: #fff; + margin-bottom: 30rpx; + box-shadow: 0 8rpx 16rpx rgba(81, 189, 182, 0.2); +} + +.month-info { + font-size: 32rpx; + font-weight: 500; + margin-bottom: 20rpx; + text-align: center; +} + +.checkin-stats { + display: flex; + justify-content: space-around; + align-items: center; +} + +.stat-item { + display: flex; + flex-direction: column; + align-items: center; +} + +.stat-value { + font-size: 48rpx; + font-weight: bold; + line-height: 1; + margin-bottom: 10rpx; +} + +.stat-label { + font-size: 24rpx; + opacity: 0.9; +} + +/* 签到按钮区 */ +.checkin-button-area { + display: flex; + flex-direction: column; + align-items: center; + margin-bottom: 40rpx; +} + +.checkin-btn { + width: 240rpx; + height: 240rpx; + border-radius: 50%; + background-color: #51bdb6; + color: #fff; + font-size: 34rpx; + font-weight: 500; + display: flex; + justify-content: center; + align-items: center; + margin-bottom: 20rpx; + box-shadow: 0 10rpx 20rpx rgba(81, 189, 182, 0.3); + transition: all 0.3s ease; + border: none; + padding: 0; +} + +.checkin-btn.checked { + background-color: #e6f7f6; + color: #51bdb6; + box-shadow: 0 5rpx 15rpx rgba(81, 189, 182, 0.2); +} + +.checkin-btn.animating { + animation: pulse 1s ease-in-out; +} + +@keyframes pulse { + 0% { transform: scale(1); } + 50% { transform: scale(1.1); } + 100% { transform: scale(1); } +} + +.btn-content { + display: flex; + flex-direction: column; + align-items: center; +} + +/* 签到按钮内部的对勾图标样式控制 */ +.checkin-btn .check-icon { + width: 40rpx; + height: auto; + margin-top: 10rpx; + display: none; /* 默认隐藏 */ +} + +.checkin-btn.checked .check-icon { + display: block; /* 仅在已签到状态下显示 */ +} + +.checkin-tip { + font-size: 26rpx; + color: #666; + text-align: center; + line-height: 1.5; +} + +/* 日历签到区 - 核心修复区域 */ +.calendar-section { + background-color: #fff; + border-radius: 20rpx; + padding: 30rpx; + margin-bottom: 30rpx; + box-shadow: 0 4rpx 12rpx rgba(0, 0, 0, 0.05); +} + +.section-title { + font-size: 30rpx; + font-weight: 500; + color: #333; + margin-bottom: 25rpx; + padding-left: 10rpx; + border-left: 6rpx solid #51bdb6; +} + +.weekdays { + display: flex; + margin-bottom: 15rpx; +} + +.weekday { + flex: 1; + text-align: center; + font-size: 26rpx; + color: #999; + padding: 10rpx 0; +} + +.calendar-grid { + display: flex; + flex-wrap: wrap; + width: 100%; +} + +/* 日期格子容器 */ +.calendar-day { + width: 14.2857%; /* 7天平均分配宽度 */ + aspect-ratio: 1; /* 宽高比1:1 */ + display: flex; + justify-content: center; + align-items: center; + position: relative; + padding: 8rpx; + box-sizing: border-box; +} + +/* 日期数字和圆圈 - 重点修复 */ +.day-number { + width: 60rpx; + height: 60rpx; + border-radius: 50%; + display: flex; + justify-content: center; + align-items: center; + font-size: 28rpx; + font-weight: 500; + position: relative; + line-height: 1; + color: #333; /* 默认颜色 */ +} + +/* 已签到状态 - 关键修复,确保数字可见 */ +.calendar-day.checked .day-number { + background-color: #51bdb6; /* 绿色背景 */ + color: #ffffff; /* **纯白色文字,解决覆盖问题** */ + font-weight: 600; + box-shadow: 0 2rpx 8rpx rgba(81, 189, 182, 0.4); +} + +/* 今日未签到状态 */ +.calendar-day.today .day-number { + border: 2rpx solid #51bdb6; + color: #51bdb6; + font-weight: 600; +} + +/* 空日期(上月/下月) */ +.calendar-day.empty .day-number { + color: #eee; + background: transparent; +} + +/* 签到对勾 - 调整位置 */ +.check-mark { + position: absolute; + /* 将对勾放在圆圈的右下角作为修饰 */ + right: 15rpx; + bottom: 10rpx; + width: 24rpx !important; + height: 24rpx !important; + opacity: 0.9; + z-index: 10; +} + +/* 奖励区 */ +.rewards-section { + background-color: #fff; + border-radius: 20rpx; + padding: 30rpx; + box-shadow: 0 4rpx 12rpx rgba(0, 0, 0, 0.05); +} + +.rewards-list { + display: flex; + flex-direction: column; + gap: 20rpx; +} + +.reward-item { + display: flex; + align-items: center; + padding: 25rpx; + border-radius: 12rpx; + background-color: #f7f8fa; + transition: all 0.3s ease; +} + +.reward-item.achieved { + background-color: #e6f7f6; + border-left: 6rpx solid #51bdb6; +} + +.reward-days { + font-size: 28rpx; + color: #333; + width: 160rpx; +} + +.reward-separator { + font-size: 24rpx; + color: #ccc; + margin: 0 10rpx; +} + +.reward-content { + font-size: 28rpx; + color: #666; + flex: 1; +} + +.reward-status { + display: flex; + align-items: center; + font-size: 24rpx; + color: #51bdb6; + gap: 8rpx; +} \ No newline at end of file diff --git a/miniprogram/pages/user/user.ts b/miniprogram/pages/user/user.ts index 3bfb7c2..6153e42 100644 --- a/miniprogram/pages/user/user.ts +++ b/miniprogram/pages/user/user.ts @@ -179,7 +179,9 @@ Component({ }); }, gotoDaily(){ - + wx.navigateTo({ + url: `/pages/daily/daily?id=${this.data.userinfo.uid}`, + }); }