const fortuneStore = require("../../store/fortuneStore"); const messages = require("../../constants/messages"); const { analyzeFortune } = require("../../services/fortuneService"); const { showRewardedVideoAd } = require("../../utils/adService"); const { getPageSafeTop } = require("../../utils/safeArea"); const { formatRegionDisplay, deriveRegionFromParts, getRegionParts, normalizeRegionArray } = require("../../utils/region"); const LOADING_HINTS = [ "正在推演今日天干地支,请稍候...", "为你梳理六维度能量波动...", "结合命盘与今日日运,编排最佳行动节奏..." ]; function showToast(title) { if (typeof tt === "undefined" || !tt.showToast) { console.warn("Toast:", title); return; } tt.showToast({ title, icon: "none", duration: 2000 }); } Page({ data: { birthDate: "", birthTime: "", selectedCity: "", selectedProvince: "", selectedDistrict: "", regionValue: [], regionDisplay: "", isSubmitting: false, isLoading: false, loadingMessage: "", safeAreaTop: 64, tips: [ "建议每天专注测算一次,深度分析更精准", "填写精确城市,可获得更贴近地域气场的指引", "保持心态稳定,才能更好接住好运" ], tipIndex: 0 }, onLoad() { const { form } = fortuneStore.getState(); const persistedRegion = normalizeRegionArray(form.birthRegion); const regionValue = persistedRegion.length ? persistedRegion : this.getInitialRegionValue(form); const parts = getRegionParts(regionValue, { province: form.birthProvince, city: form.birthCity, district: form.birthDistrict }); this.setData({ birthDate: form.birthDate, birthTime: form.birthTime, selectedProvince: parts.province, selectedCity: parts.city, selectedDistrict: parts.district, regionValue, regionDisplay: formatRegionDisplay(regionValue, [parts.province, parts.city, parts.district]), tipIndex: Math.floor(Math.random() * this.data.tips.length) }); if (!persistedRegion.length && regionValue.length && parts.city) { fortuneStore.setForm({ birthProvince: parts.province, birthCity: parts.city, birthDistrict: parts.district, birthRegion: regionValue }); } this.updateSafeAreaPadding(); }, getInitialRegionValue(form) { return deriveRegionFromParts({ province: form.birthProvince, city: form.birthCity, district: form.birthDistrict }); }, updateSafeAreaPadding() { const padding = getPageSafeTop(); this.setData({ safeAreaTop: padding }); }, resetRegionState() { this.setData({ regionValue: [], selectedProvince: "", selectedCity: "", selectedDistrict: "", regionDisplay: "" }); }, syncRegion(regionValue, fallbackParts = {}, options = {}) { let normalized = normalizeRegionArray(regionValue); if (!normalized.length) { normalized = deriveRegionFromParts(fallbackParts); } const parts = getRegionParts(normalized, fallbackParts); if (!parts.city) { if (options.resetOnEmpty) { this.resetRegionState(); } return false; } this.setData({ regionValue: normalized, selectedProvince: parts.province, selectedCity: parts.city, selectedDistrict: parts.district, regionDisplay: formatRegionDisplay(normalized, [parts.province, parts.city, parts.district]) }); if (options.persist !== false) { fortuneStore.setForm({ birthProvince: parts.province, birthCity: parts.city, birthDistrict: parts.district, birthRegion: normalized }); } return true; }, handleDateChange(event) { const value = event.detail.value; this.setData({ birthDate: value }); fortuneStore.setForm({ birthDate: value }); }, handleTimeChange(event) { const value = event.detail.value; this.setData({ birthTime: value }); fortuneStore.setForm({ birthTime: value }); }, handleRegionChange(event) { const value = event.detail.value || []; this.syncRegion(value, {}, { resetOnEmpty: true }); }, handleLocate() { if (typeof tt === "undefined" || !tt.chooseLocation) { showToast("当前端暂不支持定位"); return; } tt.chooseLocation({ success: (res) => { const city = this.extractCity(res.address || res.name || ""); if (!city) { showToast("未能识别所在城市,请通过选择器选择"); return; } const segments = this.parseAddressSegments(res); const fallback = { province: segments[0] || res.province || "", city, district: segments[2] || res.district || "" }; this.syncRegion(segments, fallback, { resetOnEmpty: true }); }, fail: () => { showToast("定位失败,请检查权限后重试"); } }); }, extractCity(text) { if (!text) { return ""; } const cityMatch = text.match(/([\u4e00-\u9fa5]+?(市|自治州|地区|盟))/); if (cityMatch) { return cityMatch[1]; } const districtMatch = text.match(/([\u4e00-\u9fa5]+?(区|县))/); if (districtMatch) { return districtMatch[1].replace(/(区|县)$/, "市"); } return ""; }, parseAddressSegments(locationResult) { const segments = []; const province = locationResult.province || ""; const city = locationResult.city || ""; const address = locationResult.address || ""; const text = `${province}${city}${address}`; const provinceMatch = text.match(/([\u4e00-\u9fa5]+?(省|自治区|特别行政区))/); const cityMatch = text.match(/([\u4e00-\u9fa5]+?(市|自治州|地区|盟))/); const districtMatch = text.match(/([\u4e00-\u9fa5]+?(区|县|市))/); if (provinceMatch) { segments.push(provinceMatch[1]); } if (cityMatch) { segments.push(cityMatch[1]); } if (districtMatch && (!segments.length || segments[segments.length - 1] !== districtMatch[1])) { segments.push(districtMatch[1]); } return segments; }, handleGoHistory() { if (typeof tt !== "undefined" && tt.navigateTo) { tt.navigateTo({ url: "/pages/history/index" }); } }, validateForm() { const { birthDate, selectedCity } = this.data; if (!birthDate || !selectedCity) { showToast(messages.FORM_INCOMPLETE); return false; } if (selectedCity.length < 2) { showToast(messages.CITY_INVALID); return false; } if (!fortuneStore.canGenerateToday()) { showToast(messages.QUOTA_EXCEEDED); return false; } return true; }, handleGenerate() { if (this.data.isSubmitting) { return; } if (!this.validateForm()) { return; } this.setData({ isSubmitting: true }); showRewardedVideoAd() .then(() => this.requestFortune()) .catch((error) => { if (error && error.code === "ad_not_completed") { showToast(messages.WATCH_AD_TO_CONTINUE); } else { showToast(messages.GENERATION_FAILED); } this.hideLoadingOverlay(); this.setData({ isSubmitting: false }); }); }, requestFortune() { const payload = { birthDate: this.data.birthDate, birthTime: this.data.birthTime || "", birthProvince: this.data.selectedProvince, birthCity: this.data.selectedCity, birthDistrict: this.data.selectedDistrict, birthRegion: Array.isArray(this.data.regionValue) ? this.data.regionValue.slice() : [] }; this.showLoadingOverlay(); return analyzeFortune(payload) .then((response) => { if (!response) { showToast(messages.GENERATION_FAILED); return; } fortuneStore.setCurrentFortune(response); fortuneStore.incrementQuota(); fortuneStore.appendHistory( { birthDate: payload.birthDate, birthTime: payload.birthTime, birthProvince: payload.birthProvince, birthCity: payload.birthCity, birthDistrict: payload.birthDistrict, birthRegion: payload.birthRegion }, response ); if (typeof tt !== "undefined" && tt.navigateTo) { tt.navigateTo({ url: "/pages/result/index" }); } }) .catch((error) => { console.log(error) const message = error && error.data && error.data.message; if (message === "CONTENT_RISK") { showToast(messages.CONTENT_RISK); } else if (message === "BIRTHDATE_INVALID") { showToast("出生日期格式异常,请重新选择"); } else { showToast(messages.GENERATION_FAILED); } }) .finally(() => { this.hideLoadingOverlay(); this.setData({ isSubmitting: false }); }); }, showLoadingOverlay() { const hint = LOADING_HINTS[Math.floor(Math.random() * LOADING_HINTS.length)]; this.setData({ isLoading: true, loadingMessage: hint }); }, hideLoadingOverlay() { if (!this.data.isLoading) { return; } this.setData({ isLoading: false, loadingMessage: "" }); } });