Files
lunar-mini/mini/pages/wiki/wiki.js
T
gouki 2a68eae999
Build and Publish Server / build (push) Successful in 2m8s
Publish Mini Program Dev Version / publish (push) Failing after 11m17s
feat(home): 修复swiper动画、宜忌布局、月历显示、节日速查
1. 修复swiper箭头点击动画丢失问题
   - 改用固定7天窗口,滑动到边缘时整体滚动数据
   - 保持dayIndex连续,确保swiper平滑动画

2. 修复宜忌两行显示压在一起
   - 设置item固定高度32rpx和行距12rpx
   - 超出2行显示...省略号

3. 修复月历数字竖向排列问题
   - 修正wxml嵌套结构,让42个格子正确排成6行7列
   - 压缩格子高度,放大数字字体

4. 节日速查功能优化
   - 默认显示3条,右侧添加更多
2026-08-10 23:07:47 +00:00

191 lines
9.1 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 { SOLAR_TERMS, LUNAR_FESTIVALS, SOLAR_FESTIVALS, HEAVEN_STEMS, EARTH_BRANCHES, ZODIACS } = require('../../utils/core/data.js');
const { request } = require('../../utils/request.js');
const CATEGORIES = [
{ key: 'all', name: '全部' },
{ key: 'term', name: '二十四节气' },
{ key: 'lunarFest', name: '农历节日' },
{ key: 'solarFest', name: '公历节日' },
{ key: 'ganzhi', name: '干支生肖' },
{ key: 'termExplain', name: '黄历术语' },
{ key: 'other', name: '其他' }
];
// 服务端分类 key 到展示名的映射
const CAT_NAMES = {
term: '节气', lunarFest: '农历节日', solarFest: '公历节日',
ganzhi: '干支生肖', termExplain: '术语', other: '其他'
};
const TERM_BRIEFS = {
'立春': '春季开始,万物复苏', '雨水': '降雨增多,气温回升', '惊蛰': '春雷惊醒蛰伏动物',
'春分': '昼夜平分,春季过半', '清明': '天气晴朗,草木繁茂', '谷雨': '雨生百谷,播种时节',
'立夏': '夏季开始,万物生长', '小满': '麦类籽粒开始饱满', '芒种': '有芒作物成熟,忙于播种',
'夏至': '白昼最长,盛夏来临', '小暑': '天气开始炎热', '大暑': '一年中最热的时期',
'立秋': '秋季开始,暑去凉来', '处暑': '暑气结束,秋意渐浓', '白露': '天气转凉,出现露水',
'秋分': '昼夜平分,秋季过半', '寒露': '露水更凉,秋意更浓', '霜降': '开始降霜,天气渐冷',
'立冬': '冬季开始,万物收藏', '小雪': '开始降雪,气温下降', '大雪': '降雪增多,天气更冷',
'冬至': '白昼最短,数九开始', '小寒': '天气寒冷,但未到极点', '大寒': '一年中最冷的时期'
};
const TERM_EXPLAINS = [
{ title: '干支纪年', brief: '天干地支组合纪年法', content: '天干有十:甲乙丙丁戊己庚辛壬癸;地支有十二:子丑寅卯辰巳午未申酉戌亥。两者按顺序两两组合,形成六十甲子循环,用于纪年、纪月、纪日、纪时。' },
{ title: '建除十二神', brief: '建、除、满、平、定、执、破、危、成、收、开、闭', content: '建除十二神又称十二值日,是古代择日的重要依据。以月建起建,按地支顺序排列。建日宜出行,除日宜疗病,满日宜嫁娶,平日宜修造,定日宜祈福,执日宜祭祀,破日宜破屋,危日宜安床,成日宜开市,收日宜纳财,开日宜开光,闭日宜安葬。' },
{ title: '黄道吉日', brief: '青龙、明堂、金匮、天德、玉堂、司命为黄道', content: '黄道黑道是古代择日术语。黄道日(青龙、明堂、金匮、天德、玉堂、司命值日)诸事皆宜;黑道日(天刑、朱雀、白虎、天牢、玄武、勾陈值日)宜避凶就吉。' },
{ title: '二十八宿', brief: '古代天文学家将黄道附近的星宿分为二十八组', content: '二十八宿分东方青龙(角亢氐房心尾箕)、北方玄武(斗牛女虚危室壁)、西方白虎(奎娄胃昴毕觜参)、南方朱雀(井鬼柳星张翼轸)四象,每象七宿。古人用二十八宿来判断日子的吉凶。' },
{ title: '六曜', brief: '先胜、友引、先负、佛灭、大安、赤口', content: '六曜起源于中国,后传入日本并广泛流行。大安日诸事皆吉;先胜日上午吉;友引日早晚吉;先负日上午凶;佛灭日大凶;赤口日午凶。以农历月日之和除以六取余数确定。' },
{ title: '彭祖百忌', brief: '每日天干地支对应的禁忌事项', content: '彭祖百忌是古代择日学的重要内容,根据每日的天干地支组合给出相应的禁忌。如"甲不开仓财物耗散,子不问卜自惹祸殃"等,共六十条对应六十甲子。' },
{ title: '冲煞', brief: '日支与某生肖相冲,该生肖之人需谨慎', content: '冲煞指日支与某地支相冲(如子午相冲、丑未相冲等),对应的生肖之人在当日需谨慎行事。煞方指当日凶煞所在的方位,不宜在该方位动土或远行。' },
{ title: '纳音五行', brief: '六十甲子与五行的配合', content: '纳音是将六十甲子与五行相配,每两组干支合为一种纳音,共三十种。如甲子乙丑海中金、丙寅丁卯炉中火等,用于命理分析。' },
{ title: '月相', brief: '朔、上弦、望、下弦的月相变化', content: '农历初一为朔(新月),初七初八为上弦月,十五为望(满月),廿二廿三为下弦月。月相变化影响潮汐,也被古人用于判断吉凶。' },
{ title: '胎神方位', brief: '孕妇需避开的方位', content: '胎神是传统民俗中保护胎儿的神灵,每日所在方位不同。孕妇不宜在胎神方位动土、钉钉或搬动重物,以免惊动胎神。' }
];
function buildEntries() {
const entries = [];
// 二十四节气
SOLAR_TERMS.forEach(name => {
entries.push({
cat: 'term', catName: '节气', title: name,
brief: TERM_BRIEFS[name] || '二十四节气之一',
content: TERM_BRIEFS[name] || '二十四节气之一,是古人根据太阳在黄道上的位置划分的时令节点。',
open: false
});
});
// 农历节日
const seenLunar = new Set();
Object.entries(LUNAR_FESTIVALS).forEach(([key, name]) => {
if (seenLunar.has(name)) return;
seenLunar.add(name);
const [m, d] = key.split('-');
entries.push({
cat: 'lunarFest', catName: '农历节日', title: name,
brief: `农历${m}${d}日`,
content: `${name},农历${m}${d}日,是中国传统农历节日。`,
open: false
});
});
// 公历节日
const seenSolar = new Set();
Object.entries(SOLAR_FESTIVALS).forEach(([key, name]) => {
if (seenSolar.has(name)) return;
seenSolar.add(name);
const [m, d] = key.split('-');
entries.push({
cat: 'solarFest', catName: '公历节日', title: name,
brief: `公历${m}${d}日`,
content: `${name},公历${m}${d}日。`,
open: false
});
});
// 干支生肖
HEAVEN_STEMS.forEach((s, i) => {
entries.push({
cat: 'ganzhi', catName: '天干', title: s,
brief: `十天干之第${i + 1}位`,
content: `${s}为十天干之第${i + 1}位,五行属${['木','木','火','火','土','土','金','金','水','水'][i]},属${i % 2 === 0 ? '阳' : '阴'}。`,
open: false
});
});
EARTH_BRANCHES.forEach((b, i) => {
entries.push({
cat: 'ganzhi', catName: '地支', title: `${b}${ZODIACS[i]}`,
brief: `十二地支之第${i + 1}位,生肖属${ZODIACS[i]}`,
content: `${b}为十二地支之第${i + 1}位,生肖属${ZODIACS[i]},五行属${['水','土','木','木','土','火','火','土','金','金','土','水'][i]}。`,
open: false
});
});
// 黄历术语
TERM_EXPLAINS.forEach(t => {
entries.push({ cat: 'termExplain', catName: '术语', ...t, open: false });
});
return entries;
}
Page({
data: {
categories: CATEGORIES,
activeCat: 'all',
keyword: '',
entries: [],
filteredEntries: []
},
onLoad() {
const entries = buildEntries();
this.setData({ entries, filteredEntries: entries });
this.loadServerEntries();
},
/** 从服务端加载百科条目(管理后台可维护),与本地数据合并:同标题以服务端为准,新增条目追加 */
loadServerEntries() {
request({ url: '/api/wiki/entries' })
.then(res => {
if (!res || res.code !== 0 || !res.data || !res.data.list) return;
const merged = [...this.data.entries];
const titleIndex = {};
merged.forEach((e, i) => { titleIndex[e.title] = i; });
res.data.list.forEach(s => {
const entry = {
cat: s.category,
catName: CAT_NAMES[s.category] || s.category,
title: s.title,
brief: s.brief,
content: s.content,
open: false
};
if (titleIndex[s.title] !== undefined) {
merged[titleIndex[s.title]] = entry; // 服务端内容覆盖本地
} else {
merged.push(entry);
}
});
this.setData({ entries: merged }, () => this.filter());
})
.catch(() => { /* 网络失败时使用本地内置数据 */ });
},
switchCat(e) {
this.setData({ activeCat: e.currentTarget.dataset.key }, () => this.filter());
},
onSearch(e) {
this.setData({ keyword: e.detail.value.trim() }, () => this.filter());
},
filter() {
const { entries, activeCat, keyword } = this.data;
let list = entries;
if (activeCat !== 'all') list = list.filter(t => t.cat === activeCat);
if (keyword) list = list.filter(t => t.title.includes(keyword) || t.brief.includes(keyword) || t.content.includes(keyword));
this.setData({ filteredEntries: list });
},
toggleEntry(e) {
const index = e.currentTarget.dataset.index;
const key = `filteredEntries[${index}].open`;
this.setData({ [key]: !this.data.filteredEntries[index].open });
},
onShareAppMessage() {
return {
title: '黄历百科 - 传统文化知识',
path: '/pages/wiki/wiki'
};
},
onShareTimeline() {
return {
title: '黄历百科 - 传统文化知识'
};
}
});