feat(i18n): 改造紫微斗数页,替换硬编码中文为 $t() 调用

This commit is contained in:
张翔
2026-04-29 18:29:52 +08:00
parent 0dee22f5c3
commit ad92d00e68
@@ -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>