Refactor Date Calculator UI to Morandi theme and fix logic; fix Index page interaction
This commit is contained in:
@@ -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');
|
||||
|
||||
Reference in New Issue
Block a user