Refactor Date Calculator UI to Morandi theme and fix logic; fix Index page interaction

This commit is contained in:
2026-02-07 20:25:50 +08:00
parent a21716e772
commit 19c762b3fa
11 changed files with 1636 additions and 479 deletions

View File

@@ -1,16 +1,40 @@
// pages/date-calc/date-calc.ts
import { solarToLunar, lunarToSolar, getSolarTerm, getFestival, getLunarFestival } from '../../utils/lunar';
Page({
data: {
currentTab: 0,
startDate: '',
startWeekday: '', // 新增:开始日期的星期
startWeekday: '',
endDate: '',
days: 0, // 可以为空字符串以便清空输入框,但 input type number 会处理
days: 0,
resultDate: '',
resultWeekday: '',
resultLunar: '',
intervalDays: 0,
intervalWeeks: 0,
intervalRemainingDays: 0
intervalRemainingDays: 0,
intervalMonths: 0,
intervalExtraDays: 0,
// 农历转换相关
lunarDirection: 'toL', // 'toL' 公历→农历, 'toS' 农历→公历
lunarSolarDate: '',
lunarResult: null as any,
lunarFestivalText: '',
solarTermText: '',
solarFestivalText: '',
// 农历→公历
lunarPickerRange: [[] as string[], [] as string[], [] as string[]],
lunarPickerValue: [0, 0, 0],
lunarPickerDisplay: '',
lunarToSolarResult: '',
lunarToSolarWeekday: '',
// 今日信息
todaySolar: '',
todayLunar: '',
todayGanZhi: '',
todayAnimal: '',
todayTerm: ''
},
onLoad() {
@@ -21,15 +45,23 @@ Page({
endDate: dateStr,
resultDate: dateStr,
resultWeekday: this.getWeekday(today),
startWeekday: this.getWeekday(today)
startWeekday: this.getWeekday(today),
lunarSolarDate: dateStr
});
// 初始化农历相关
this.initLunarPicker();
this.updateTodayInfo();
this.convertSolarToLunar(dateStr);
this.updateResultLunar(today);
},
switchTab(e: any) {
wx.vibrateShort({ type: 'light' }).catch(() => {});
this.setData({
currentTab: parseFloat(e.currentTarget.dataset.index)
});
this.calculate(); // 切换时重新计算
this.calculate();
},
bindDateChange(e: any) {
@@ -38,9 +70,8 @@ Page({
[field]: e.detail.value
});
// 如果修改的是开始日期,同步更新星期显示
if (field === 'startDate') {
const d = new Date(e.detail.value);
const d = new Date(e.detail.value.replace(/-/g, '/'));
this.setData({ startWeekday: this.getWeekday(d) });
}
@@ -49,7 +80,6 @@ Page({
bindDaysInput(e: any) {
const val = e.detail.value;
// 允许输入负号
if (val === '-' || val === '') {
this.setData({ days: val });
return;
@@ -61,6 +91,7 @@ Page({
},
setDays(e: any) {
wx.vibrateShort({ type: 'light' }).catch(() => {});
const days = parseInt(e.currentTarget.dataset.days);
this.setData({ days: days });
this.calculate();
@@ -68,20 +99,16 @@ Page({
calculate() {
if (this.data.currentTab === 0) {
// 日期推算
// 注意:直接使用 new Date('2023-10-01') 在 iOS 上可能不兼容,应替换为 '/'
const start = new Date(this.data.startDate.replace(/-/g, '/'));
// days 可能是字符串或数字
const dayOffset = typeof(this.data.days) === 'number' ? this.data.days : parseInt(this.data.days || '0');
const target = new Date(start.getTime() + dayOffset * 24 * 60 * 60 * 1000);
this.setData({
resultDate: this.formatDate(target),
resultWeekday: this.getWeekday(target)
});
} else {
// 日期通过 (Interval)
this.updateResultLunar(target);
} else if (this.data.currentTab === 1) {
const start = new Date(this.data.startDate.replace(/-/g, '/'));
const end = new Date(this.data.endDate.replace(/-/g, '/'));
const diffTime = Math.abs(end.getTime() - start.getTime());
@@ -89,15 +116,184 @@ Page({
const weeks = Math.floor(diffDays / 7);
const remainingDays = diffDays % 7;
const months = Math.floor(diffDays / 30);
const extraDays = diffDays % 30;
this.setData({
intervalDays: diffDays,
intervalWeeks: weeks,
intervalRemainingDays: remainingDays
intervalRemainingDays: remainingDays,
intervalMonths: months,
intervalExtraDays: extraDays
});
}
},
// 更新推算结果的农历信息
updateResultLunar(date: Date) {
try {
const lunar = solarToLunar(date.getFullYear(), date.getMonth() + 1, date.getDate());
this.setData({
resultLunar: lunar.monthName + lunar.dayName
});
} catch (e) {
this.setData({ resultLunar: '' });
}
},
// === 农历转换相关 ===
setLunarDirection(e: any) {
wx.vibrateShort({ type: 'light' }).catch(() => {});
this.setData({ lunarDirection: e.currentTarget.dataset.dir });
},
toggleLunarDirection() {
wx.vibrateShort({ type: 'light' }).catch(() => {});
this.setData({
lunarDirection: this.data.lunarDirection === 'toL' ? 'toS' : 'toL'
});
},
onLunarSolarDateChange(e: any) {
const dateStr = e.detail.value;
this.setData({ lunarSolarDate: dateStr });
this.convertSolarToLunar(dateStr);
},
convertSolarToLunar(dateStr: string) {
try {
const parts = dateStr.split('-');
const year = parseInt(parts[0]);
const month = parseInt(parts[1]);
const day = parseInt(parts[2]);
const result = solarToLunar(year, month, day);
const term = getSolarTerm(year, month, day);
const solarFest = getFestival(month, day);
const lunarFest = getLunarFestival(result.month, result.day);
this.setData({
lunarResult: result,
solarTermText: term || '',
solarFestivalText: solarFest || '',
lunarFestivalText: lunarFest || ''
});
} catch (e) {
console.error('农历转换出错:', e);
}
},
// 初始化农历选择器
initLunarPicker() {
const years: string[] = [];
for (let y = 1901; y <= 2099; y++) {
years.push(y + '年');
}
const months: string[] = [];
for (let m = 1; m <= 12; m++) {
months.push(this.getLunarMonthLabel(m));
}
const days: string[] = [];
for (let d = 1; d <= 30; d++) {
days.push(this.getLunarDayLabel(d));
}
const today = new Date();
// Calculate today's lunar date to set default picker value
const result = solarToLunar(today.getFullYear(), today.getMonth() + 1, today.getDate());
const yearIdx = result.year - 1901;
const monthIdx = result.month - 1;
const dayIdx = result.day - 1;
const display = `${result.year}${result.monthName} ${result.dayName}`;
this.setData({
lunarPickerRange: [years, months, days],
lunarPickerValue: [yearIdx >= 0 ? yearIdx : 0, monthIdx, dayIdx],
lunarPickerDisplay: display
});
// Also init the reverse calculation result
this.calcLunarToSolar(result.year, result.month, result.day);
},
getLunarMonthLabel(m: number): string {
const names = ['正月', '二月', '三月', '四月', '五月', '六月', '七月', '八月', '九月', '十月', '冬月', '腊月'];
return names[m - 1];
},
getLunarDayLabel(d: number): string {
const names = [
'初一', '初二', '初三', '初四', '初五', '初六', '初七', '初八', '初九', '初十',
'十一', '十二', '十三', '十四', '十五', '十六', '十七', '十八', '十九', '二十',
'廿一', '廿二', '廿三', '廿四', '廿五', '廿六', '廿七', '廿八', '廿九', '三十'
];
return names[d - 1];
},
onLunarColumnChange(e: any) {
// 列变化时可以联动更新(简化处理)
},
onLunarPickerChange(e: any) {
const val = e.detail.value;
const year = 1901 + val[0];
const month = val[1] + 1;
const day = val[2] + 1;
const display = `${year}${this.getLunarMonthLabel(month)} ${this.getLunarDayLabel(day)}`;
this.setData({
lunarPickerValue: val,
lunarPickerDisplay: display,
});
this.calcLunarToSolar(year, month, day);
},
calcLunarToSolar(year: number, month: number, day: number) {
try {
const result = lunarToSolar(year, month, day, false);
const solarDate = new Date(result.year, result.month - 1, result.day);
const solarStr = this.formatDate(solarDate);
this.setData({
lunarToSolarResult: solarStr,
lunarToSolarWeekday: this.getWeekday(solarDate)
});
} catch (e) {
this.setData({
lunarToSolarResult: '无效日期',
lunarToSolarWeekday: ''
});
}
},
// 今日信息
updateTodayInfo() {
const today = new Date();
const y = today.getFullYear();
const m = today.getMonth() + 1;
const d = today.getDate();
try {
const lunar = solarToLunar(y, m, d);
const term = getSolarTerm(y, m, d);
this.setData({
todaySolar: `${y}${m}${d}${this.getWeekday(today)}`,
todayLunar: lunar.monthName + lunar.dayName,
todayGanZhi: lunar.ganZhi + '年',
todayAnimal: lunar.animal,
todayTerm: term || ''
});
} catch (e) {
console.error('获取今日信息出错:', e);
}
},
formatDate(date: Date): string {
const y = date.getFullYear();
const m = (date.getMonth() + 1).toString().padStart(2, '0');