feat: 祈福小助手万年历小程序第一期

This commit is contained in:
gouki
2026-08-06 08:47:09 +00:00
commit a3e6aa9c01
136 changed files with 16597 additions and 0 deletions
+86
View File
@@ -0,0 +1,86 @@
const { getMonthCalendar } = require('../../utils/core/index.js');
Page({
data: {
year: new Date().getFullYear(),
month: new Date().getMonth() + 1,
weekHeaders: ['日', '一', '二', '三', '四', '五', '六'],
calendarDays: [],
selectedDay: null,
showMonthPicker: false,
years: [],
months: [1,2,3,4,5,6,7,8,9,10,11,12],
pickerValue: [0, 0]
},
onLoad() {
const years = [];
for (let y = 1900; y <= 2100; y++) years.push(y);
this.setData({ years });
this.loadCalendar();
},
loadCalendar() {
const { year, month } = this.data;
const weeks = getMonthCalendar(year, month);
const calendarDays = [];
weeks.forEach(week => {
week.forEach(day => calendarDays.push(day));
});
this.setData({ calendarDays });
},
prevMonth() {
let { year, month } = this.data;
month--;
if (month < 1) { month = 12; year--; }
this.setData({ year, month }, () => this.loadCalendar());
},
nextMonth() {
let { year, month } = this.data;
month++;
if (month > 12) { month = 1; year++; }
this.setData({ year, month }, () => this.loadCalendar());
},
showPicker() {
const { year, month } = this.data;
this.setData({
showMonthPicker: true,
pickerValue: [year - 1900, month - 1]
});
},
hidePicker() {
this.setData({ showMonthPicker: false });
},
pickerChange(e) {
this.setData({ pickerValue: e.detail.value });
},
confirmPicker() {
const { pickerValue, years, months } = this.data;
this.setData({
year: years[pickerValue[0]],
month: months[pickerValue[1]],
showMonthPicker: false
}, () => this.loadCalendar());
},
selectDay(e) {
const date = e.currentTarget.dataset.date;
const day = this.data.calendarDays.find(d => d.solarDate === date);
this.setData({ selectedDay: day });
},
goDetail() {
const { selectedDay } = this.data;
if (selectedDay) {
wx.navigateTo({ url: `/pages/day-detail/day-detail?date=${selectedDay.solarDate}` });
}
},
noop() {}
});
+4
View File
@@ -0,0 +1,4 @@
{
"navigationBarTitleText": "日历",
"enablePullDownRefresh": false
}
+60
View File
@@ -0,0 +1,60 @@
<view class="container">
<!-- 年月选择器 -->
<view class="card flex justify-between items-center">
<view class="btn-ghost" bindtap="prevMonth"></view>
<view class="text-xl font-bold" bindtap="showPicker">{{year}}年{{month}}月</view>
<view class="btn-ghost" bindtap="nextMonth"></view>
</view>
<!-- 星期头 -->
<view class="grid grid-cols-7 gap-1 mb-1">
<view class="text-center text-sm text-muted" wx:for="{{weekHeaders}}" wx:key="*this">{{item}}</view>
</view>
<!-- 日历网格 -->
<view class="grid grid-cols-7 gap-1">
<view
class="day-cell {{item.isToday ? 'today' : ''}} {{item.solarMonth !== month ? 'other-month' : ''}}"
wx:for="{{calendarDays}}"
wx:key="solarDate"
bindtap="selectDay"
data-date="{{item.solarDate}}"
>
<text class="day-number">{{item.solarDay}}</text>
<text class="day-lunar {{item.lunarFestival || item.solarFestival ? 'festival' : ''}}">
{{item.lunarFestival || item.solarFestival || item.lunarDayName}}
</text>
<view class="day-dot" wx:if="{{item.isTermDay}}"></view>
</view>
</view>
<!-- 选中日期详情 -->
<view class="card mt-2" wx:if="{{selectedDay}}">
<view class="flex justify-between items-center">
<view>
<text class="text-lg font-bold">{{selectedDay.solarDate}}</text>
<text class="text-sm text-muted block">{{selectedDay.lunarMonthName}}{{selectedDay.lunarDayName}}</text>
</view>
<view class="btn-primary" bindtap="goDetail">详情</view>
</view>
</view>
</view>
<!-- 年月选择弹窗 -->
<view class="picker-mask {{showMonthPicker ? 'show' : ''}}" bindtap="hidePicker">
<view class="picker-panel" catchtap="noop">
<view class="picker-header">
<text bindtap="hidePicker">取消</text>
<text class="font-bold">选择年月</text>
<text bindtap="confirmPicker">确定</text>
</view>
<picker-view class="picker-view" value="{{pickerValue}}" bindchange="pickerChange">
<picker-view-column>
<view wx:for="{{years}}" wx:key="*this" class="picker-item">{{item}}年</view>
</picker-view-column>
<picker-view-column>
<view wx:for="{{months}}" wx:key="*this" class="picker-item">{{item}}月</view>
</picker-view-column>
</picker-view>
</view>
</view>
+92
View File
@@ -0,0 +1,92 @@
.container {
padding: 20rpx;
}
.day-cell {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
padding: 12rpx 4rpx;
background: #FFFFFF;
border-radius: 12rpx;
min-height: 100rpx;
}
.day-cell.today {
background: #C41E3A;
color: #FFFFFF;
}
.day-cell.today .day-lunar {
color: rgba(255,255,255,0.8);
}
.day-cell.other-month {
opacity: 0.4;
}
.day-number {
font-size: 28rpx;
font-weight: 500;
}
.day-lunar {
font-size: 20rpx;
color: #9E8E7E;
margin-top: 4rpx;
}
.day-lunar.festival {
color: #C41E3A;
font-weight: 500;
}
.day-dot {
width: 8rpx;
height: 8rpx;
border-radius: 50%;
background: #C41E3A;
margin-top: 4rpx;
}
.picker-mask {
position: fixed;
top: 0;
left: 0;
right: 0;
bottom: 0;
background: rgba(0,0,0,0.5);
z-index: 100;
display: none;
}
.picker-mask.show {
display: block;
}
.picker-panel {
position: absolute;
bottom: 0;
left: 0;
right: 0;
background: #FFFFFF;
border-radius: 24rpx 24rpx 0 0;
}
.picker-header {
display: flex;
justify-content: space-between;
padding: 24rpx;
border-bottom: 1rpx solid #E8D5C4;
}
.picker-view {
height: 400rpx;
}
.picker-item {
text-align: center;
line-height: 68rpx;
font-size: 32rpx;
}