Files
lunar-mini/mini/pages/home/home.js
T
gouki d5a4244905
Publish Mini Program Dev Version / publish (push) Failing after 12m53s
fix(ci): 修复workflow YAML语法错误导致Actions不触发
notify步骤的多行字符串第二行未缩进,YAML解析失败,
Gitea忽略整个workflow,push不生成run。改为单行命令。
2026-08-08 10:48:50 +00:00

241 lines
7.9 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
const {
getDayInfo, getAlmanacInfo, getMonthCalendar,
getLegalHoliday, isWorkday, getUpcomingFestivals, getNextBuddhistFestival
} = require('../../utils/core/index.js');
const { SOLAR_TERM_TIMES } = require('../../utils/core/data.js');
function pad(n) { return String(n).padStart(2, '0'); }
function fmt(y, m, d) { return `${y}-${pad(m)}-${pad(d)}`; }
const MONTH_SPAN = 2; // 当前月前后各2个月,共5个月
Page({
data: {
statusBarHeight: 20,
navBarHeight: 44,
viewMode: 'day',
dayInfo: {},
almanac: {},
legalHoliday: null,
workday: true,
termTime: '',
isFirstOrFifteen: false,
nextBuddhist: null,
showBuddhist: false,
highlightLunar: true,
upcoming: [],
// 月历 swiper
monthList: [], // [{key, year, month, weeks}]
monthIndex: 2, // 当前居中
currentYear: 0,
currentMonth: 0,
weekHeaders: ['日', '一', '二', '三', '四', '五', '六'],
// 全屏弹窗
zoomVisible: false,
zoomTitle: '',
zoomType: '', // yiji | detail | fest
zoomData: null
},
onLoad() {
const sys = wx.getWindowInfo ? wx.getWindowInfo() : wx.getSystemInfoSync();
const menu = wx.getMenuButtonBoundingClientRect ? wx.getMenuButtonBoundingClientRect() : null;
const statusBarHeight = sys.statusBarHeight || 20;
let navBarHeight = 44;
if (menu && menu.top) navBarHeight = (menu.top - statusBarHeight) * 2 + menu.height;
this.setData({ statusBarHeight, navBarHeight });
this.loadSettings();
this.loadDay(new Date());
this.loadUpcoming();
},
onShow() {
this.loadSettings();
// 设置可能变化,刷新
if (this.data.dayInfo.solarYear) this.refreshDerived();
},
loadSettings() {
const s = wx.getStorageSync('lunar-settings') || {};
this.setData({
showBuddhist: s.showBuddhist === true,
highlightLunar: s.highlightLunar !== false
});
},
onPullDownRefresh() {
if (this.data.viewMode === 'day') {
this.loadDay(new Date());
this.loadUpcoming();
} else {
this.buildMonthList(this.data.currentYear, this.data.currentMonth);
}
wx.stopPullDownRefresh();
},
/** 加载某日的老黄历 */
loadDay(date) {
const y = date.getFullYear();
const m = date.getMonth() + 1;
const d = date.getDate();
const dayInfo = getDayInfo(y, m, d);
const almanac = getAlmanacInfo(y, m, d);
this.setData({ dayInfo, almanac, currentYear: y, currentMonth: m });
this.refreshDerived();
this.loadUpcoming();
},
/** 计算派生数据(节假日/工作日/佛历/初一十五) */
refreshDerived() {
const { dayInfo, showBuddhist, highlightLunar } = this.data;
const { solarYear: y, solarMonth: m, solarDay: d } = dayInfo;
const legalHoliday = getLegalHoliday(y, m, d);
const workday = isWorkday(y, m, d);
const termTime = dayInfo.solarTerm ? (SOLAR_TERM_TIMES[dayInfo.solarTerm] || '') : '';
const isFirstOrFifteen = highlightLunar && (dayInfo.lunarDay === 1 || dayInfo.lunarDay === 15);
const nextBuddhist = showBuddhist ? getNextBuddhistFestival(y, m, d) : null;
this.setData({ legalHoliday, workday, termTime, isFirstOrFifteen, nextBuddhist });
},
loadUpcoming() {
const { dayInfo } = this.data;
const { solarYear: y, solarMonth: m, solarDay: d } = dayInfo;
this.setData({ upcoming: getUpcomingFestivals(5, y, m, d) });
},
prevDay() { this.shiftDay(-1); },
nextDay() { this.shiftDay(1); },
shiftDay(delta) {
const { dayInfo } = this.data;
const date = new Date(dayInfo.solarYear, dayInfo.solarMonth - 1, dayInfo.solarDay + delta);
this.loadDay(date);
},
backToday() {
this.loadDay(new Date());
this.loadUpcoming();
},
/** 切换 日/月 视图 */
toggleView() {
const mode = this.data.viewMode === 'day' ? 'month' : 'day';
this.setData({ viewMode: mode });
if (mode === 'month') {
const { dayInfo } = this.data;
this.buildMonthList(dayInfo.solarYear, dayInfo.solarMonth);
}
},
/** 构建5个月的数据,居中显示 */
buildMonthList(year, month) {
const monthList = [];
for (let i = -MONTH_SPAN; i <= MONTH_SPAN; i++) {
let y = year, m = month + i;
while (m < 1) { m += 12; y--; }
while (m > 12) { m -= 12; y++; }
const weeks = getMonthCalendar(y, m);
monthList.push({ key: `${y}-${m}`, year: y, month: m, weeks });
}
this.setData({ monthList, monthIndex: MONTH_SPAN, currentYear: year, currentMonth: month });
},
/** swiper 切换 */
onMonthSwiperChange(e) {
const index = e.detail.current;
const { monthList } = this.data;
const cur = monthList[index];
this.setData({ monthIndex: index, currentYear: cur.year, currentMonth: cur.month });
// 边缘时向对应方向补一个月,保持可无限滚动
if (index === 0) {
this.prependMonth();
} else if (index === monthList.length - 1) {
this.appendMonth();
}
},
prependMonth() {
const { monthList } = this.data;
const first = monthList[0];
let y = first.year, m = first.month - 1;
if (m < 1) { m = 12; y--; }
const weeks = getMonthCalendar(y, m);
monthList.unshift({ key: `${y}-${m}`, year: y, month: m, weeks });
if (monthList.length > 7) monthList.pop();
this.setData({ monthList, monthIndex: this.data.monthIndex + 1 });
},
appendMonth() {
const { monthList } = this.data;
const last = monthList[monthList.length - 1];
let y = last.year, m = last.month + 1;
if (m > 12) { m = 1; y++; }
const weeks = getMonthCalendar(y, m);
monthList.push({ key: `${y}-${m}`, year: y, month: m, weeks });
if (monthList.length > 7) monthList.shift();
this.setData({ monthList, monthIndex: this.data.monthIndex - 1 });
},
/** 月历点选某天 → 切回日视图 */
selectDay(e) {
const date = e.currentTarget.dataset.date;
const [y, m, d] = date.split('-').map(Number);
this.loadDay(new Date(y, m - 1, d));
this.setData({ viewMode: 'day' });
},
goDetail() {
const { dayInfo } = this.data;
wx.navigateTo({ url: `/pages/day-detail/day-detail?date=${fmt(dayInfo.solarYear, dayInfo.solarMonth, dayInfo.solarDay)}` });
},
/** 跳转到某节日的老黄历 */
goFestival(e) {
const date = e.currentTarget.dataset.date;
const [y, m, d] = date.split('-').map(Number);
this.loadDay(new Date(y, m - 1, d));
this.setData({ viewMode: 'day' });
wx.pageScrollTo && wx.pageScrollTo({ scrollTop: 0, duration: 0 });
},
/** ===== 全屏放大弹窗 ===== */
openZoom(e) {
const type = e.currentTarget.dataset.type;
const { dayInfo, almanac, legalHoliday, termTime } = this.data;
let zoomTitle = '';
let zoomData = null;
if (type === 'yiji') {
zoomTitle = `${dayInfo.solarMonth}${dayInfo.solarDay}日 宜忌`;
zoomData = { recommends: almanac.recommends, avoids: almanac.avoids };
} else if (type === 'detail') {
zoomTitle = `${dayInfo.solarMonth}${dayInfo.solarDay}日 黄历详情`;
zoomData = {
lunar: `${dayInfo.lunarMonthName}${dayInfo.lunarDayName}`,
ganzhi: `${dayInfo.lunarYearGanzhi}${dayInfo.lunarMonthGanzhi}${dayInfo.lunarDayGanzhi}日`,
duty: almanac.duty,
twelveStar: `${almanac.twelveStar.name}${almanac.twelveStar.ecliptic}`,
twentyEightStar: almanac.twentyEightStar.name,
sixStar: almanac.sixStar,
clash: `冲${almanac.clash}${almanac.evilDirection}`,
pengZu: almanac.pengZu,
legalHoliday,
termTime: dayInfo.solarTerm ? `${dayInfo.solarTerm} ${termTime}` : ''
};
} else if (type === 'fest') {
zoomTitle = '近期节日';
zoomData = { upcoming: this.data.upcoming };
}
this.setData({ zoomVisible: true, zoomTitle, zoomType: type, zoomData });
},
closeZoom() {
this.setData({ zoomVisible: false });
},
navTo(e) {
wx.navigateTo({ url: e.currentTarget.dataset.url });
},
noop() {}
});