feat: 实现生辰信息存储与真太阳时计算
- 新增 ADR 文档记录生辰信息存储设计决策 - 新增真太阳时计算模块 (solarTime.ts),基于 Spencer 1971 时差方程 - 新增城市经纬度内置数据库,覆盖全国主要区县,系统自动匹配坐标 - 更新紫微页面:移除手动经纬度输入,改为 500ms 防抖自动定位 - 更新所有 9 个语言文件,替换经纬度提示为定位提示
This commit is contained in:
@@ -24,16 +24,9 @@
|
||||
<view class="form-group">
|
||||
<text class="label">{{ $t('ziwei.birthPlace') }}</text>
|
||||
<input class="text-input" :value="birthPlace" @input="onBirthPlaceChange" :placeholder="$t('ziwei.birthPlaceHint')" />
|
||||
</view>
|
||||
<view class="form-row">
|
||||
<view class="form-group form-half">
|
||||
<text class="label">{{ $t('ziwei.longitude') }}</text>
|
||||
<input class="text-input" type="digit" :value="longitude" @input="onLongitudeChange" :placeholder="$t('ziwei.longitudeHint')" />
|
||||
</view>
|
||||
<view class="form-group form-half">
|
||||
<text class="label">{{ $t('ziwei.latitude') }}</text>
|
||||
<input class="text-input" type="digit" :value="latitude" @input="onLatitudeChange" :placeholder="$t('ziwei.latitudeHint')" />
|
||||
</view>
|
||||
<text v-if="detectedLocation" class="location-hint detected">{{ detectedLocation }}</text>
|
||||
<text v-else-if="birthPlace && birthPlace.trim().length > 2 && !isLookingUp" class="location-hint not-found">{{ $t('ziwei.locationNotFound') }}</text>
|
||||
<text v-if="isLookingUp" class="location-hint looking-up">{{ $t('ziwei.lookingUp') }}</text>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
@@ -89,6 +82,7 @@ import { onShow } from '@dcloudio/uni-app'
|
||||
import { ZiweiService } from '../../services/ziweiService'
|
||||
import { PalaceType, EarthlyBranch, MajorStar } from '../../algorithms/enums'
|
||||
import type { ZiweiChart } from '../../algorithms/types'
|
||||
import { lookupCityCoordinates } from '../../data/cityCoordinates'
|
||||
|
||||
const ziweiService = new ZiweiService()
|
||||
const { t } = useI18n()
|
||||
@@ -101,11 +95,13 @@ const birthDate = ref('')
|
||||
const hourIndex = ref(0)
|
||||
const gender = ref<'male' | 'female'>('male')
|
||||
const birthPlace = ref('')
|
||||
const longitude = ref('')
|
||||
const latitude = ref('')
|
||||
const isCalculating = ref(false)
|
||||
const isLookingUp = ref(false)
|
||||
const detectedLocation = ref('')
|
||||
const chart = ref<ZiweiChart | null>(null)
|
||||
|
||||
let lookupTimer: ReturnType<typeof setTimeout> | 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)',
|
||||
@@ -123,14 +119,28 @@ const onHourChange = (e: any) => {
|
||||
|
||||
const onBirthPlaceChange = (e: any) => {
|
||||
birthPlace.value = e.detail.value
|
||||
detectedLocation.value = ''
|
||||
autoLookupCoordinates(birthPlace.value)
|
||||
}
|
||||
|
||||
const onLongitudeChange = (e: any) => {
|
||||
longitude.value = e.detail.value
|
||||
}
|
||||
|
||||
const onLatitudeChange = (e: any) => {
|
||||
latitude.value = e.detail.value
|
||||
/** 自动查找出生地坐标 */
|
||||
function autoLookupCoordinates(place: string): void {
|
||||
if (lookupTimer) {
|
||||
clearTimeout(lookupTimer)
|
||||
}
|
||||
if (!place || place.trim().length < 2) {
|
||||
isLookingUp.value = false
|
||||
return
|
||||
}
|
||||
isLookingUp.value = true
|
||||
lookupTimer = setTimeout(() => {
|
||||
const result = lookupCityCoordinates(place)
|
||||
isLookingUp.value = false
|
||||
if (result) {
|
||||
detectedLocation.value = `${result.displayName}(${result.longitude}°E, ${result.latitude}°N)`
|
||||
}
|
||||
lookupTimer = null
|
||||
}, 500)
|
||||
}
|
||||
|
||||
const getPalaceName = (palaceType: string): string => {
|
||||
@@ -164,15 +174,25 @@ const generateChart = async () => {
|
||||
try {
|
||||
const hour = hourIndex.value * 2
|
||||
const birthTime = `${birthDate.value}T${String(hour).padStart(2, '0')}:00:00`
|
||||
const lng = longitude.value ? parseFloat(longitude.value) : undefined
|
||||
const lat = latitude.value ? parseFloat(latitude.value) : undefined
|
||||
|
||||
// 从检测结果中解析经纬度
|
||||
let longitude: number | undefined
|
||||
let latitude: number | undefined
|
||||
if (detectedLocation.value) {
|
||||
const coordResult = lookupCityCoordinates(birthPlace.value)
|
||||
if (coordResult) {
|
||||
longitude = coordResult.longitude
|
||||
latitude = coordResult.latitude
|
||||
}
|
||||
}
|
||||
|
||||
chart.value = await ziweiService.generateChart({
|
||||
birthTime,
|
||||
gender: gender.value,
|
||||
timezone: 'Asia/Shanghai',
|
||||
birthPlace: birthPlace.value || undefined,
|
||||
longitude: lng,
|
||||
latitude: lat,
|
||||
longitude,
|
||||
latitude,
|
||||
})
|
||||
} catch (e) {
|
||||
console.error('排盘失败:', e)
|
||||
@@ -245,15 +265,6 @@ const generateChart = async () => {
|
||||
background-color: rgba(44, 24, 16, 255);
|
||||
}
|
||||
|
||||
.form-row {
|
||||
display: flex;
|
||||
gap: 12px;
|
||||
}
|
||||
|
||||
.form-half {
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
.text-input {
|
||||
font-size: 15px;
|
||||
color: #333;
|
||||
@@ -265,6 +276,24 @@ const generateChart = async () => {
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
.location-hint {
|
||||
font-size: 12px;
|
||||
margin-top: 4px;
|
||||
display: block;
|
||||
}
|
||||
|
||||
.location-hint.detected {
|
||||
color: #52c41a;
|
||||
}
|
||||
|
||||
.location-hint.not-found {
|
||||
color: #faad14;
|
||||
}
|
||||
|
||||
.location-hint.looking-up {
|
||||
color: #999;
|
||||
}
|
||||
|
||||
.action-bar {
|
||||
margin-bottom: 16px;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user