feat: 祈福小助手万年历小程序第一期
This commit is contained in:
@@ -0,0 +1,78 @@
|
||||
const { birthInfoToBazi, analyzeElementBalance } = require('../../utils/core/index.js');
|
||||
|
||||
Page({
|
||||
data: {
|
||||
gender: 'male',
|
||||
birthDate: '1990-01-01',
|
||||
birthTime: '12:00',
|
||||
ziSect: 'lateZiNextDay',
|
||||
bazi: null,
|
||||
pillars: [],
|
||||
elements: [],
|
||||
elementAnalysis: {}
|
||||
},
|
||||
|
||||
onLoad() {
|
||||
// 尝试从本地存储恢复
|
||||
const saved = wx.getStorageSync('lunar-bazi-input');
|
||||
if (saved) {
|
||||
this.setData(saved);
|
||||
}
|
||||
},
|
||||
|
||||
setGender(e) {
|
||||
this.setData({ gender: e.currentTarget.dataset.g });
|
||||
},
|
||||
|
||||
setZiSect(e) {
|
||||
this.setData({ ziSect: e.currentTarget.dataset.s });
|
||||
},
|
||||
|
||||
onDateChange(e) {
|
||||
this.setData({ birthDate: e.detail.value });
|
||||
},
|
||||
|
||||
onTimeChange(e) {
|
||||
this.setData({ birthTime: e.detail.value });
|
||||
},
|
||||
|
||||
calculate() {
|
||||
const { gender, birthDate, birthTime, ziSect } = this.data;
|
||||
const [year, month, day] = birthDate.split('-').map(Number);
|
||||
const [hour, minute] = birthTime.split(':').map(Number);
|
||||
|
||||
const bazi = birthInfoToBazi({ year, month, day, hour, minute, gender, ziSect });
|
||||
const elementAnalysis = analyzeElementBalance(bazi.eightChar);
|
||||
|
||||
const pillars = [
|
||||
{ label: '年柱', ...bazi.eightChar.yearPillar },
|
||||
{ label: '月柱', ...bazi.eightChar.monthPillar },
|
||||
{ label: '日柱', ...bazi.eightChar.dayPillar },
|
||||
{ label: '时柱', ...bazi.eightChar.hourPillar }
|
||||
];
|
||||
|
||||
const total = elementAnalysis.total || 1;
|
||||
const elements = [
|
||||
{ name: '木', count: elementAnalysis.wood, percent: Math.round(elementAnalysis.wood / total * 100) },
|
||||
{ name: '火', count: elementAnalysis.fire, percent: Math.round(elementAnalysis.fire / total * 100) },
|
||||
{ name: '土', count: elementAnalysis.earth, percent: Math.round(elementAnalysis.earth / total * 100) },
|
||||
{ name: '金', count: elementAnalysis.metal, percent: Math.round(elementAnalysis.metal / total * 100) },
|
||||
{ name: '水', count: elementAnalysis.water, percent: Math.round(elementAnalysis.water / total * 100) }
|
||||
];
|
||||
|
||||
this.setData({ bazi, pillars, elements, elementAnalysis });
|
||||
|
||||
// 保存输入
|
||||
wx.setStorageSync('lunar-bazi-input', { gender, birthDate, birthTime, ziSect });
|
||||
// 保存八字供运势页使用
|
||||
wx.setStorageSync('lunar-user-bazi', bazi);
|
||||
},
|
||||
|
||||
reset() {
|
||||
this.setData({ bazi: null });
|
||||
},
|
||||
|
||||
goFortune() {
|
||||
wx.switchTab({ url: '/pages/fortune/fortune' });
|
||||
}
|
||||
});
|
||||
@@ -0,0 +1,4 @@
|
||||
{
|
||||
"navigationBarTitleText": "八字排盘",
|
||||
"enablePullDownRefresh": false
|
||||
}
|
||||
@@ -0,0 +1,104 @@
|
||||
<view class="container">
|
||||
<!-- 输入表单 -->
|
||||
<view class="card" wx:if="{{!bazi}}">
|
||||
<view class="section-title">输入出生信息</view>
|
||||
|
||||
<view class="form-item">
|
||||
<text class="form-label">性别</text>
|
||||
<view class="flex gap-2">
|
||||
<view class="btn-outline {{gender === 'male' ? 'active' : ''}}" bindtap="setGender" data-g="male">男</view>
|
||||
<view class="btn-outline {{gender === 'female' ? 'active' : ''}}" bindtap="setGender" data-g="female">女</view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<view class="form-item">
|
||||
<text class="form-label">出生日期</text>
|
||||
<picker mode="date" value="{{birthDate}}" bindchange="onDateChange">
|
||||
<view class="picker-input">{{birthDate}}</view>
|
||||
</picker>
|
||||
</view>
|
||||
|
||||
<view class="form-item">
|
||||
<text class="form-label">出生时间</text>
|
||||
<picker mode="time" value="{{birthTime}}" bindchange="onTimeChange">
|
||||
<view class="picker-input">{{birthTime}}</view>
|
||||
</picker>
|
||||
</view>
|
||||
|
||||
<view class="form-item">
|
||||
<text class="form-label">子时流派</text>
|
||||
<view class="flex gap-2">
|
||||
<view class="btn-outline {{ziSect === 'lateZiNextDay' ? 'active' : ''}}" bindtap="setZiSect" data-s="lateZiNextDay">晚子时日柱算次日</view>
|
||||
<view class="btn-outline {{ziSect === 'lateZiSameDay' ? 'active' : ''}}" bindtap="setZiSect" data-s="lateZiSameDay">晚子时日柱算当日</view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<view class="btn-primary mt-2" bindtap="calculate">排盘</view>
|
||||
</view>
|
||||
|
||||
<!-- 八字结果 -->
|
||||
<block wx:if="{{bazi}}">
|
||||
<!-- 四柱 -->
|
||||
<view class="card">
|
||||
<view class="section-title">四柱八字</view>
|
||||
<view class="grid grid-cols-4 gap-2">
|
||||
<view class="pillar" wx:for="{{pillars}}" wx:key="label">
|
||||
<text class="pillar-label">{{item.label}}</text>
|
||||
<text class="pillar-ganzhi">{{item.ganzhi}}</text>
|
||||
<text class="pillar-ten">{{item.tenStar || '日主'}}</text>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- 五行分析 -->
|
||||
<view class="card">
|
||||
<view class="section-title">五行分析</view>
|
||||
<view class="element-bar">
|
||||
<view class="element-item" wx:for="{{elements}}" wx:key="name">
|
||||
<text class="element-name">{{item.name}}</text>
|
||||
<view class="element-track">
|
||||
<view class="element-fill" style="width: {{item.percent}}%"></view>
|
||||
</view>
|
||||
<text class="element-count">{{item.count}}</text>
|
||||
</view>
|
||||
</view>
|
||||
<view class="mt-2 text-sm text-muted">
|
||||
日主:{{bazi.eightChar.dayMaster}} | dominant: {{elementAnalysis.dominant}} | weakest: {{elementAnalysis.weakest}}
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- 大运 -->
|
||||
<view class="card">
|
||||
<view class="section-title">大运</view>
|
||||
<scroll-view scroll-x class="scroll-x">
|
||||
<view class="flex gap-2">
|
||||
<view class="fortune-item" wx:for="{{bazi.decadeFortunes}}" wx:key="index">
|
||||
<text class="text-sm text-muted">{{item.startAge}}-{{item.endAge}}岁</text>
|
||||
<text class="text-base font-medium">{{item.ganzhi}}</text>
|
||||
<text class="text-xs text-muted">{{item.startYear}}-{{item.endYear}}</text>
|
||||
</view>
|
||||
</view>
|
||||
</scroll-view>
|
||||
</view>
|
||||
|
||||
<!-- 流年 -->
|
||||
<view class="card">
|
||||
<view class="section-title">流年</view>
|
||||
<scroll-view scroll-x class="scroll-x">
|
||||
<view class="flex gap-2">
|
||||
<view class="fortune-item" wx:for="{{bazi.annualFortunes}}" wx:key="year">
|
||||
<text class="text-sm text-muted">{{item.age}}岁</text>
|
||||
<text class="text-base font-medium">{{item.ganzhi}}</text>
|
||||
<text class="text-xs text-muted">{{item.year}}</text>
|
||||
</view>
|
||||
</view>
|
||||
</scroll-view>
|
||||
</view>
|
||||
|
||||
<!-- 操作 -->
|
||||
<view class="flex gap-2 mt-2">
|
||||
<view class="btn-outline flex-1 text-center" bindtap="reset">重新排盘</view>
|
||||
<view class="btn-primary flex-1 text-center" bindtap="goFortune">看运势</view>
|
||||
</view>
|
||||
</block>
|
||||
</view>
|
||||
@@ -0,0 +1,107 @@
|
||||
.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;
|
||||
}
|
||||
|
||||
.btn-outline.active {
|
||||
background: #C41E3A;
|
||||
color: #FFFFFF;
|
||||
border-color: #C41E3A;
|
||||
}
|
||||
|
||||
.pillar {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
padding: 20rpx;
|
||||
background: #FFFBF5;
|
||||
border-radius: 12rpx;
|
||||
}
|
||||
|
||||
.pillar-label {
|
||||
font-size: 20rpx;
|
||||
color: #9E8E7E;
|
||||
}
|
||||
|
||||
.pillar-ganzhi {
|
||||
font-size: 36rpx;
|
||||
font-weight: 700;
|
||||
color: #C41E3A;
|
||||
margin: 8rpx 0;
|
||||
}
|
||||
|
||||
.pillar-ten {
|
||||
font-size: 20rpx;
|
||||
color: #6B5E53;
|
||||
}
|
||||
|
||||
.element-bar {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 12rpx;
|
||||
}
|
||||
|
||||
.element-item {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 12rpx;
|
||||
}
|
||||
|
||||
.element-name {
|
||||
width: 60rpx;
|
||||
font-size: 24rpx;
|
||||
}
|
||||
|
||||
.element-track {
|
||||
flex: 1;
|
||||
height: 16rpx;
|
||||
background: #E8D5C4;
|
||||
border-radius: 8rpx;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.element-fill {
|
||||
height: 100%;
|
||||
background: #C41E3A;
|
||||
border-radius: 8rpx;
|
||||
}
|
||||
|
||||
.element-count {
|
||||
width: 60rpx;
|
||||
text-align: right;
|
||||
font-size: 24rpx;
|
||||
}
|
||||
|
||||
.fortune-item {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
padding: 16rpx 24rpx;
|
||||
background: #FFFBF5;
|
||||
border-radius: 12rpx;
|
||||
min-width: 160rpx;
|
||||
}
|
||||
Reference in New Issue
Block a user