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
+64
View File
@@ -0,0 +1,64 @@
const { calculatePlumBlossom, calculateBoneWeight, HEAVEN_STEMS, EARTH_BRANCHES, LUNAR_MONTH_NAMES, LUNAR_DAY_NAMES, HOUR_NAMES } = require('../../utils/core/index.js');
Page({
data: {
plumDate: new Date().toISOString().split('T')[0],
plumTime: '12:00',
plumResult: null,
yearGanzhiList: [],
monthList: LUNAR_MONTH_NAMES,
dayList: LUNAR_DAY_NAMES,
hourList: HOUR_NAMES,
boneYearIndex: 0,
boneMonthIndex: 0,
boneDayIndex: 0,
boneHourIndex: 0,
boneResult: null
},
onLoad() {
const yearGanzhiList = [];
for (let i = 0; i < 60; i++) {
yearGanzhiList.push(HEAVEN_STEMS[i % 10] + EARTH_BRANCHES[i % 12]);
}
this.setData({ yearGanzhiList });
},
onPlumDateChange(e) {
this.setData({ plumDate: e.detail.value });
},
onPlumTimeChange(e) {
this.setData({ plumTime: e.detail.value });
},
calcPlum() {
const { plumDate, plumTime } = this.data;
const [year, month, day] = plumDate.split('-').map(Number);
const [hour] = plumTime.split(':').map(Number);
const result = calculatePlumBlossom(year, month, day, hour);
this.setData({ plumResult: result });
},
onBoneYearChange(e) {
this.setData({ boneYearIndex: e.detail.value });
},
onBoneMonthChange(e) {
this.setData({ boneMonthIndex: e.detail.value });
},
onBoneDayChange(e) {
this.setData({ boneDayIndex: e.detail.value });
},
onBoneHourChange(e) {
this.setData({ boneHourIndex: e.detail.value });
},
calcBone() {
const { boneYearIndex, boneMonthIndex, boneDayIndex, boneHourIndex } = this.data;
const result = calculateBoneWeight(boneYearIndex, boneMonthIndex + 1, boneDayIndex + 1, boneHourIndex);
this.setData({ boneResult: result });
}
});
+4
View File
@@ -0,0 +1,4 @@
{
"navigationBarTitleText": "占卜",
"enablePullDownRefresh": false
}
+110
View File
@@ -0,0 +1,110 @@
<view class="container">
<!-- 梅花易数 -->
<view class="card">
<view class="section-title">梅花易数</view>
<view class="form-item">
<text class="form-label">起卦时间</text>
<picker mode="date" value="{{plumDate}}" bindchange="onPlumDateChange">
<view class="picker-input">{{plumDate}}</view>
</picker>
</view>
<view class="form-item">
<text class="form-label">时辰</text>
<picker mode="time" value="{{plumTime}}" bindchange="onPlumTimeChange">
<view class="picker-input">{{plumTime}}</view>
</picker>
</view>
<view class="btn-primary" bindtap="calcPlum">起卦</view>
</view>
<!-- 梅花易数结果 -->
<view class="card" wx:if="{{plumResult}}">
<view class="section-title">卦象</view>
<view class="hexagram-display">
<view class="trigram-row">
<text class="trigram-symbol">{{plumResult.upperTrigram.symbol}}</text>
<text class="trigram-name">{{plumResult.upperTrigram.name}}{{plumResult.upperTrigram.element}}</text>
</view>
<view class="trigram-row">
<text class="trigram-symbol">{{plumResult.lowerTrigram.symbol}}</text>
<text class="trigram-name">{{plumResult.lowerTrigram.name}}{{plumResult.lowerTrigram.element}}</text>
</view>
</view>
<view class="mt-2">
<text class="text-lg font-bold">{{plumResult.originalHexagram.name}}</text>
<text class="text-sm text-muted block mt-1">第{{plumResult.changingLine}}爻动</text>
</view>
<view class="mt-2 p-2 bg-page rounded">
<text class="text-sm">{{plumResult.originalHexagram.judgment}}</text>
</view>
<view class="mt-2 p-2 bg-page rounded">
<text class="text-sm">{{plumResult.originalHexagram.image}}</text>
</view>
<view class="mt-2" wx:if="{{plumResult.transformedHexagram}}">
<text class="text-base font-medium">变卦:{{plumResult.transformedHexagram.name}}</text>
</view>
<view class="mt-2 text-sm text-muted">
体用关系:{{plumResult.relationship}}
</view>
</view>
<!-- 称骨算命 -->
<view class="card mt-2">
<view class="section-title">称骨算命</view>
<view class="form-item">
<text class="form-label">出生年份(干支)</text>
<picker mode="selector" range="{{yearGanzhiList}}" value="{{boneYearIndex}}" bindchange="onBoneYearChange">
<view class="picker-input">{{yearGanzhiList[boneYearIndex]}}</view>
</picker>
</view>
<view class="form-item">
<text class="form-label">农历月份</text>
<picker mode="selector" range="{{monthList}}" value="{{boneMonthIndex}}" bindchange="onBoneMonthChange">
<view class="picker-input">{{monthList[boneMonthIndex]}}</view>
</picker>
</view>
<view class="form-item">
<text class="form-label">农历日期</text>
<picker mode="selector" range="{{dayList}}" value="{{boneDayIndex}}" bindchange="onBoneDayChange">
<view class="picker-input">{{dayList[boneDayIndex]}}</view>
</picker>
</view>
<view class="form-item">
<text class="form-label">时辰</text>
<picker mode="selector" range="{{hourList}}" value="{{boneHourIndex}}" bindchange="onBoneHourChange">
<view class="picker-input">{{hourList[boneHourIndex]}}</view>
</picker>
</view>
<view class="btn-primary" bindtap="calcBone">算命</view>
</view>
<!-- 称骨结果 -->
<view class="card" wx:if="{{boneResult}}">
<view class="section-title">称骨结果</view>
<view class="text-center">
<text class="text-3xl font-bold">{{boneResult.totalLiang}}两{{boneResult.totalQian}}钱</text>
<text class="badge {{boneResult.fortune.includes('上') ? 'badge-lucky' : boneResult.fortune.includes('下') ? 'badge-unlucky' : 'badge-outline'}} ml-2">{{boneResult.fortune}}</text>
</view>
<view class="mt-2 p-3 bg-page rounded">
<text class="text-base">{{boneResult.interpretation}}</text>
</view>
<view class="grid grid-cols-4 gap-2 mt-2">
<view class="text-center">
<text class="text-xs text-muted">年</text>
<text class="text-base font-medium block">{{boneResult.yearWeight}}钱</text>
</view>
<view class="text-center">
<text class="text-xs text-muted">月</text>
<text class="text-base font-medium block">{{boneResult.monthWeight}}钱</text>
</view>
<view class="text-center">
<text class="text-xs text-muted">日</text>
<text class="text-base font-medium block">{{boneResult.dayWeight}}钱</text>
</view>
<view class="text-center">
<text class="text-xs text-muted">时</text>
<text class="text-base font-medium block">{{boneResult.hourWeight}}钱</text>
</view>
</view>
</view>
</view>
+52
View File
@@ -0,0 +1,52 @@
.container {
padding: 20rpx;
}
.section-title {
font-size: 28rpx;
font-weight: 600;
margin-bottom: 16rpx;
color: #C41E3A;
}
.form-item {
margin-bottom: 24rpx;
}
.form-label {
font-size: 24rpx;
color: #6B5E53;
margin-bottom: 8rpx;
display: block;
}
.picker-input {
padding: 20rpx;
background: #FFFBF5;
border-radius: 12rpx;
border: 1rpx solid #E8D5C4;
}
.hexagram-display {
display: flex;
flex-direction: column;
align-items: center;
padding: 24rpx;
background: #FFFBF5;
border-radius: 16rpx;
}
.trigram-row {
display: flex;
align-items: center;
gap: 16rpx;
margin: 8rpx 0;
}
.trigram-symbol {
font-size: 64rpx;
}
.trigram-name {
font-size: 28rpx;
}