feat(i18n): 改造紫微斗数页,替换硬编码中文为 $t() 调用
This commit is contained in:
@@ -0,0 +1,324 @@
|
|||||||
|
<template>
|
||||||
|
<view class="ziwei-page">
|
||||||
|
<view class="section" data-test="birth-form">
|
||||||
|
<text class="section-title">{{ $t('ziwei.birthInfo') }}</text>
|
||||||
|
<view class="form-group">
|
||||||
|
<text class="label">{{ $t('ziwei.birthDate') }}</text>
|
||||||
|
<picker mode="date" :value="birthDate" @change="onBirthDateChange">
|
||||||
|
<text class="picker-value">{{ birthDate || $t('ziwei.pleaseSelect') }}</text>
|
||||||
|
</picker>
|
||||||
|
</view>
|
||||||
|
<view class="form-group">
|
||||||
|
<text class="label">{{ $t('ziwei.birthHour') }}</text>
|
||||||
|
<picker :range="hourOptions" :value="hourIndex" @change="onHourChange">
|
||||||
|
<text class="picker-value">{{ hourOptions[hourIndex] }}</text>
|
||||||
|
</picker>
|
||||||
|
</view>
|
||||||
|
<view class="form-group">
|
||||||
|
<text class="label">{{ $t('ziwei.gender') }}</text>
|
||||||
|
<view class="gender-switch">
|
||||||
|
<text :class="['gender-option', gender === 'male' ? 'active' : '']" @tap="gender = 'male'">{{ $t('common.male') }}</text>
|
||||||
|
<text :class="['gender-option', gender === 'female' ? 'active' : '']" @tap="gender = 'female'">{{ $t('common.female') }}</text>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<view class="action-bar">
|
||||||
|
<button data-test="generate-btn" class="generate-btn" @tap="generateChart" :disabled="isCalculating">
|
||||||
|
{{ isCalculating ? $t('ziwei.generating') : $t('ziwei.generate') }}
|
||||||
|
</button>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<view v-if="chart" class="section chart-result">
|
||||||
|
<text class="section-title">{{ $t('ziwei.chartTitle') }}</text>
|
||||||
|
<view class="chart-grid">
|
||||||
|
<view v-for="palace in chart.palaces" :key="palace.palaceType" class="palace-card">
|
||||||
|
<text class="palace-name">{{ getPalaceName(palace.palaceType) }}</text>
|
||||||
|
<text class="palace-branch">{{ getBranchName(palace.earthlyBranch) }}</text>
|
||||||
|
<text class="palace-score">{{ palace.score }}{{ $t('ziwei.scoreUnit') }}</text>
|
||||||
|
<view class="star-list">
|
||||||
|
<text v-for="star in palace.majorStars" :key="star.star" class="star-item">
|
||||||
|
{{ getStarName(star.star) }}
|
||||||
|
</text>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<view v-if="chart?.sanFangSiZheng" class="section analysis-section">
|
||||||
|
<text class="section-title">{{ $t('ziwei.sanFangAnalysis') }}</text>
|
||||||
|
<view class="analysis-item">
|
||||||
|
<text class="analysis-label">{{ $t('ziwei.sanFangScore') }}</text>
|
||||||
|
<text class="analysis-value">{{ chart.sanFangSiZheng.sanFangScore }}{{ $t('ziwei.scoreUnit') }}</text>
|
||||||
|
</view>
|
||||||
|
<view class="analysis-item">
|
||||||
|
<text class="analysis-label">{{ $t('ziwei.siZhengScore') }}</text>
|
||||||
|
<text class="analysis-value">{{ chart.sanFangSiZheng.siZhengScore }}{{ $t('ziwei.scoreUnit') }}</text>
|
||||||
|
</view>
|
||||||
|
<view class="analysis-item">
|
||||||
|
<text class="analysis-label">{{ $t('ziwei.overallEval') }}</text>
|
||||||
|
<text class="analysis-value">{{ chart.overallLuck }}</text>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<view v-if="chart" class="section summary-section">
|
||||||
|
<text class="section-title">{{ $t('ziwei.summary') }}</text>
|
||||||
|
<text class="summary-text">{{ chart.summary }}</text>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup lang="ts">
|
||||||
|
import { ref } from 'vue'
|
||||||
|
import { useI18n } from 'vue-i18n'
|
||||||
|
import { onShow } from '@dcloudio/uni-app'
|
||||||
|
import { ZiweiService } from '../../services/ziweiService'
|
||||||
|
import { PalaceType, EarthlyBranch, MajorStar } from '../../algorithms/enums'
|
||||||
|
import type { ZiweiChart } from '../../algorithms/types'
|
||||||
|
|
||||||
|
const ziweiService = new ZiweiService()
|
||||||
|
const { t } = useI18n()
|
||||||
|
|
||||||
|
onShow(() => {
|
||||||
|
uni.setNavigationBarTitle({ title: t('ziwei.pageTitle') })
|
||||||
|
})
|
||||||
|
|
||||||
|
const birthDate = ref('')
|
||||||
|
const hourIndex = ref(0)
|
||||||
|
const gender = ref<'male' | 'female'>('male')
|
||||||
|
const isCalculating = ref(false)
|
||||||
|
const chart = ref<ZiweiChart | null>(null)
|
||||||
|
|
||||||
|
const hourOptions = [
|
||||||
|
'子时 (23:00-01:00)', '丑时 (01:00-03:00)', '寅时 (03:00-05:00)',
|
||||||
|
'卯时 (05:00-07:00)', '辰时 (07:00-09:00)', '巳时 (09:00-11:00)',
|
||||||
|
'午时 (11:00-13:00)', '未时 (13:00-15:00)', '申时 (15:00-17:00)',
|
||||||
|
'酉时 (17:00-19:00)', '戌时 (19:00-21:00)', '亥时 (21:00-23:00)',
|
||||||
|
]
|
||||||
|
|
||||||
|
const onBirthDateChange = (e: any) => {
|
||||||
|
birthDate.value = e.detail.value
|
||||||
|
}
|
||||||
|
|
||||||
|
const onHourChange = (e: any) => {
|
||||||
|
hourIndex.value = e.detail.value
|
||||||
|
}
|
||||||
|
|
||||||
|
const getPalaceName = (palaceType: string): string => {
|
||||||
|
try {
|
||||||
|
return PalaceType.name(palaceType as any)
|
||||||
|
} catch {
|
||||||
|
return palaceType
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const getBranchName = (branch: any): string => {
|
||||||
|
try {
|
||||||
|
return EarthlyBranch.name(branch)
|
||||||
|
} catch {
|
||||||
|
return String(branch)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const getStarName = (star: any): string => {
|
||||||
|
try {
|
||||||
|
return MajorStar.name(star)
|
||||||
|
} catch {
|
||||||
|
return String(star)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const generateChart = async () => {
|
||||||
|
if (!birthDate.value) return
|
||||||
|
|
||||||
|
isCalculating.value = true
|
||||||
|
try {
|
||||||
|
const hour = hourIndex.value * 2
|
||||||
|
const birthTime = `${birthDate.value}T${String(hour).padStart(2, '0')}:00:00`
|
||||||
|
chart.value = await ziweiService.generateChart({
|
||||||
|
birthTime,
|
||||||
|
gender: gender.value,
|
||||||
|
timezone: 'Asia/Shanghai',
|
||||||
|
})
|
||||||
|
} catch (e) {
|
||||||
|
console.error('排盘失败:', e)
|
||||||
|
} finally {
|
||||||
|
isCalculating.value = false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped lang="scss">
|
||||||
|
.ziwei-page {
|
||||||
|
min-height: 100vh;
|
||||||
|
background-color: rgba(244, 244, 245, 0.3);
|
||||||
|
padding: 16px;
|
||||||
|
padding-bottom: 40px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.section {
|
||||||
|
background-color: #fff;
|
||||||
|
border-radius: 12px;
|
||||||
|
padding: 16px;
|
||||||
|
margin-bottom: 16px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.section-title {
|
||||||
|
font-size: 18px;
|
||||||
|
font-weight: 700;
|
||||||
|
color: rgba(44, 24, 16, 255);
|
||||||
|
margin-bottom: 12px;
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
|
||||||
|
.form-group {
|
||||||
|
margin-bottom: 12px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.label {
|
||||||
|
font-size: 14px;
|
||||||
|
color: #666;
|
||||||
|
margin-bottom: 6px;
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
|
||||||
|
.picker-value {
|
||||||
|
font-size: 15px;
|
||||||
|
color: #333;
|
||||||
|
padding: 8px 12px;
|
||||||
|
background-color: #f5f5f5;
|
||||||
|
border-radius: 8px;
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
|
||||||
|
.gender-switch {
|
||||||
|
display: flex;
|
||||||
|
gap: 12px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.gender-option {
|
||||||
|
flex: 1;
|
||||||
|
text-align: center;
|
||||||
|
padding: 8px 0;
|
||||||
|
border-radius: 8px;
|
||||||
|
font-size: 15px;
|
||||||
|
color: #666;
|
||||||
|
background-color: #f5f5f5;
|
||||||
|
}
|
||||||
|
|
||||||
|
.gender-option.active {
|
||||||
|
color: #fff;
|
||||||
|
background-color: rgba(44, 24, 16, 255);
|
||||||
|
}
|
||||||
|
|
||||||
|
.action-bar {
|
||||||
|
margin-bottom: 16px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.generate-btn {
|
||||||
|
width: 100%;
|
||||||
|
height: 48px;
|
||||||
|
line-height: 48px;
|
||||||
|
background-color: rgba(44, 24, 16, 255);
|
||||||
|
color: #fff;
|
||||||
|
font-size: 16px;
|
||||||
|
font-weight: 600;
|
||||||
|
border-radius: 12px;
|
||||||
|
border: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.generate-btn[disabled] {
|
||||||
|
opacity: 0.6;
|
||||||
|
}
|
||||||
|
|
||||||
|
.chart-grid {
|
||||||
|
display: grid;
|
||||||
|
grid-template-columns: repeat(4, 1fr);
|
||||||
|
gap: 8px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.palace-card {
|
||||||
|
background-color: #fafafa;
|
||||||
|
border-radius: 8px;
|
||||||
|
padding: 8px;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.palace-name {
|
||||||
|
font-size: 13px;
|
||||||
|
font-weight: 600;
|
||||||
|
color: rgba(44, 24, 16, 255);
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
|
||||||
|
.palace-branch {
|
||||||
|
font-size: 12px;
|
||||||
|
color: #999;
|
||||||
|
display: block;
|
||||||
|
margin-top: 2px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.palace-score {
|
||||||
|
font-size: 14px;
|
||||||
|
font-weight: 700;
|
||||||
|
color: #e74c3c;
|
||||||
|
display: block;
|
||||||
|
margin-top: 4px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.star-list {
|
||||||
|
margin-top: 4px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.star-item {
|
||||||
|
font-size: 11px;
|
||||||
|
color: #666;
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
|
||||||
|
.analysis-section {
|
||||||
|
.analysis-item {
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-between;
|
||||||
|
padding: 8px 0;
|
||||||
|
border-bottom: 1px solid #f0f0f0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.analysis-label {
|
||||||
|
font-size: 14px;
|
||||||
|
color: #666;
|
||||||
|
}
|
||||||
|
|
||||||
|
.analysis-value {
|
||||||
|
font-size: 14px;
|
||||||
|
font-weight: 600;
|
||||||
|
color: rgba(44, 24, 16, 255);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.summary-section {
|
||||||
|
.summary-text {
|
||||||
|
font-size: 14px;
|
||||||
|
line-height: 22px;
|
||||||
|
color: #333;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@media screen and (max-width: 375px) {
|
||||||
|
.chart-grid {
|
||||||
|
grid-template-columns: repeat(3, 1fr);
|
||||||
|
}
|
||||||
|
|
||||||
|
.palace-card {
|
||||||
|
padding: 6px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.palace-name {
|
||||||
|
font-size: 12px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.palace-score {
|
||||||
|
font-size: 12px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
||||||
Reference in New Issue
Block a user