2025-11-06 19:23:37 +08:00
|
|
|
|
const namingStore = require("../../store/namingStore");
|
2025-11-05 00:22:09 +08:00
|
|
|
|
const messages = require("../../constants/messages");
|
|
|
|
|
|
const { validateSurname, generateName } = require("../../services/namingService");
|
|
|
|
|
|
const { showRewardedVideoAd } = require("../../utils/adService");
|
|
|
|
|
|
const config = require("../../config/index");
|
|
|
|
|
|
|
2025-11-06 19:23:37 +08:00
|
|
|
|
const LOADING_MESSAGES = [
|
|
|
|
|
|
"AI 正在推演八字,请稍候...",
|
|
|
|
|
|
"结合天干地支,为您筛选契合佳名...",
|
|
|
|
|
|
"耐心等待,吉名正在汇聚灵感..."
|
|
|
|
|
|
];
|
|
|
|
|
|
|
2025-11-05 00:22:09 +08:00
|
|
|
|
function showToast(title) {
|
|
|
|
|
|
if (typeof tt === "undefined" || !tt.showToast) {
|
|
|
|
|
|
console.warn("Toast:", title);
|
|
|
|
|
|
return;
|
|
|
|
|
|
}
|
|
|
|
|
|
tt.showToast({
|
|
|
|
|
|
title,
|
|
|
|
|
|
icon: "none",
|
|
|
|
|
|
duration: 2000
|
|
|
|
|
|
});
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
Page({
|
|
|
|
|
|
data: {
|
|
|
|
|
|
surname: "",
|
|
|
|
|
|
surnameError: "",
|
|
|
|
|
|
gender: "male",
|
|
|
|
|
|
birthDate: "",
|
|
|
|
|
|
birthTime: "",
|
|
|
|
|
|
nameLength: "double",
|
|
|
|
|
|
isSubmitting: false,
|
2025-11-06 19:23:37 +08:00
|
|
|
|
quotaRemaining: null,
|
|
|
|
|
|
isLoading: false,
|
|
|
|
|
|
loadingMessage: ""
|
2025-11-05 00:22:09 +08:00
|
|
|
|
},
|
|
|
|
|
|
onLoad() {
|
|
|
|
|
|
const { form, quota } = namingStore.getState();
|
|
|
|
|
|
this.setData({
|
|
|
|
|
|
surname: form.surname,
|
|
|
|
|
|
gender: form.gender,
|
|
|
|
|
|
birthDate: form.birthDate,
|
|
|
|
|
|
birthTime: form.birthTime,
|
|
|
|
|
|
nameLength: form.nameLength,
|
|
|
|
|
|
quotaRemaining: config.maxDailyQuota - quota.count
|
|
|
|
|
|
});
|
|
|
|
|
|
},
|
|
|
|
|
|
handleSurnameInput(event) {
|
|
|
|
|
|
const value = (event.detail.value || "").trim();
|
|
|
|
|
|
this.setData({
|
|
|
|
|
|
surname: value,
|
|
|
|
|
|
surnameError: ""
|
|
|
|
|
|
});
|
|
|
|
|
|
namingStore.setForm({ surname: value });
|
|
|
|
|
|
},
|
|
|
|
|
|
handleSurnameBlur() {
|
|
|
|
|
|
const surname = this.data.surname;
|
|
|
|
|
|
if (!surname) {
|
|
|
|
|
|
return;
|
|
|
|
|
|
}
|
|
|
|
|
|
validateSurname(surname)
|
|
|
|
|
|
.then((response) => {
|
2025-11-06 19:23:37 +08:00
|
|
|
|
const isValid = response ? response.isValid !== false : true;
|
|
|
|
|
|
const message = response && response.message ? response.message : messages.INVALID_SURNAME;
|
|
|
|
|
|
if (!isValid) {
|
|
|
|
|
|
showToast(message);
|
2025-11-05 00:22:09 +08:00
|
|
|
|
this.setData({
|
|
|
|
|
|
surname: "",
|
2025-11-06 19:23:37 +08:00
|
|
|
|
surnameError: message
|
2025-11-05 00:22:09 +08:00
|
|
|
|
});
|
|
|
|
|
|
namingStore.setForm({ surname: "" });
|
|
|
|
|
|
} else {
|
|
|
|
|
|
this.setData({ surnameError: "" });
|
|
|
|
|
|
}
|
|
|
|
|
|
})
|
|
|
|
|
|
.catch(() => {
|
|
|
|
|
|
showToast(messages.INVALID_SURNAME);
|
|
|
|
|
|
this.setData({
|
|
|
|
|
|
surname: "",
|
|
|
|
|
|
surnameError: messages.INVALID_SURNAME
|
|
|
|
|
|
});
|
|
|
|
|
|
namingStore.setForm({ surname: "" });
|
|
|
|
|
|
});
|
|
|
|
|
|
},
|
|
|
|
|
|
handleGenderChange(event) {
|
|
|
|
|
|
const value = event.detail.value;
|
|
|
|
|
|
this.setData({ gender: value });
|
|
|
|
|
|
namingStore.setForm({ gender: value });
|
|
|
|
|
|
},
|
|
|
|
|
|
handleBirthDateChange(event) {
|
|
|
|
|
|
const value = event.detail.value;
|
|
|
|
|
|
this.setData({ birthDate: value });
|
|
|
|
|
|
namingStore.setForm({ birthDate: value });
|
|
|
|
|
|
},
|
|
|
|
|
|
handleBirthTimeChange(event) {
|
|
|
|
|
|
const value = event.detail.value;
|
|
|
|
|
|
this.setData({ birthTime: value });
|
|
|
|
|
|
namingStore.setForm({ birthTime: value });
|
|
|
|
|
|
},
|
|
|
|
|
|
handleNameLengthChange(event) {
|
|
|
|
|
|
const value = event.detail.value;
|
|
|
|
|
|
this.setData({ nameLength: value });
|
|
|
|
|
|
namingStore.setForm({ nameLength: value });
|
|
|
|
|
|
},
|
|
|
|
|
|
handleGoFavorites() {
|
|
|
|
|
|
if (typeof tt !== "undefined" && tt.navigateTo) {
|
|
|
|
|
|
tt.navigateTo({ url: "/pages/favorites/index" });
|
|
|
|
|
|
}
|
|
|
|
|
|
},
|
|
|
|
|
|
validateForm() {
|
|
|
|
|
|
const { surname, gender, birthDate, nameLength } = this.data;
|
|
|
|
|
|
if (!surname || !gender || !birthDate || !nameLength) {
|
|
|
|
|
|
showToast(messages.FORM_INCOMPLETE);
|
|
|
|
|
|
return false;
|
|
|
|
|
|
}
|
|
|
|
|
|
if (!namingStore.canGenerateToday()) {
|
|
|
|
|
|
showToast(messages.QUOTA_EXCEEDED);
|
|
|
|
|
|
return false;
|
|
|
|
|
|
}
|
|
|
|
|
|
return true;
|
|
|
|
|
|
},
|
|
|
|
|
|
updateQuotaState() {
|
|
|
|
|
|
const { quota } = namingStore.getState();
|
|
|
|
|
|
this.setData({
|
|
|
|
|
|
quotaRemaining: Math.max(config.maxDailyQuota - quota.count, 0)
|
|
|
|
|
|
});
|
|
|
|
|
|
},
|
|
|
|
|
|
handleGenerate() {
|
|
|
|
|
|
if (this.data.isSubmitting) {
|
|
|
|
|
|
return;
|
|
|
|
|
|
}
|
|
|
|
|
|
if (!this.validateForm()) {
|
|
|
|
|
|
return;
|
|
|
|
|
|
}
|
|
|
|
|
|
this.setData({ isSubmitting: true });
|
|
|
|
|
|
showRewardedVideoAd()
|
|
|
|
|
|
.then(() => this.generateName())
|
|
|
|
|
|
.catch((error) => {
|
|
|
|
|
|
if (error && error.code === "ad_not_completed") {
|
|
|
|
|
|
showToast(messages.WATCH_AD_TO_CONTINUE);
|
|
|
|
|
|
} else {
|
|
|
|
|
|
showToast("广告加载失败,请稍后重试");
|
|
|
|
|
|
}
|
2025-11-06 19:23:37 +08:00
|
|
|
|
this.hideLoadingOverlay();
|
2025-11-05 00:22:09 +08:00
|
|
|
|
this.setData({ isSubmitting: false });
|
|
|
|
|
|
});
|
|
|
|
|
|
},
|
|
|
|
|
|
generateName() {
|
|
|
|
|
|
const payload = {
|
|
|
|
|
|
surname: this.data.surname,
|
|
|
|
|
|
gender: this.data.gender,
|
|
|
|
|
|
birthDate: this.data.birthDate,
|
|
|
|
|
|
birthTime: this.data.birthTime || "",
|
|
|
|
|
|
nameLength: this.data.nameLength
|
|
|
|
|
|
};
|
2025-11-06 19:23:37 +08:00
|
|
|
|
this.showLoadingOverlay();
|
|
|
|
|
|
return generateName(payload)
|
2025-11-05 00:22:09 +08:00
|
|
|
|
.then((response) => {
|
|
|
|
|
|
const results = response && Array.isArray(response.results) ? response.results : [];
|
2025-11-05 17:26:52 +08:00
|
|
|
|
const analysis = response && response.analysis ? response.analysis : null;
|
2025-11-05 00:22:09 +08:00
|
|
|
|
if (!results.length) {
|
|
|
|
|
|
showToast(messages.GENERATION_FAILED);
|
|
|
|
|
|
return;
|
|
|
|
|
|
}
|
|
|
|
|
|
const normalizedResults = results.reduce((accumulator, item) => {
|
|
|
|
|
|
const name = item.name || item.Name || "";
|
|
|
|
|
|
if (!name) {
|
|
|
|
|
|
return accumulator;
|
|
|
|
|
|
}
|
|
|
|
|
|
accumulator.push({
|
|
|
|
|
|
name,
|
2025-11-05 17:26:52 +08:00
|
|
|
|
meaning: item.meaning || item.Meaning || "",
|
|
|
|
|
|
elementReason: item.elementReason || item.ElementReason || ""
|
2025-11-05 00:22:09 +08:00
|
|
|
|
});
|
|
|
|
|
|
return accumulator;
|
|
|
|
|
|
}, []);
|
|
|
|
|
|
if (!normalizedResults.length) {
|
|
|
|
|
|
showToast(messages.GENERATION_FAILED);
|
|
|
|
|
|
return;
|
|
|
|
|
|
}
|
2025-11-05 17:26:52 +08:00
|
|
|
|
namingStore.setResults({
|
|
|
|
|
|
results: normalizedResults,
|
|
|
|
|
|
analysis
|
|
|
|
|
|
});
|
2025-11-05 00:22:09 +08:00
|
|
|
|
namingStore.incrementQuota();
|
|
|
|
|
|
this.updateQuotaState();
|
|
|
|
|
|
if (typeof tt !== "undefined" && tt.navigateTo) {
|
|
|
|
|
|
tt.navigateTo({ url: "/pages/result/index" });
|
|
|
|
|
|
}
|
|
|
|
|
|
})
|
2025-11-06 19:23:37 +08:00
|
|
|
|
.catch((error) => {
|
|
|
|
|
|
const message = error && error.data && error.data.message;
|
|
|
|
|
|
if (message === "CONTENT_RISK") {
|
|
|
|
|
|
showToast(messages.CONTENT_RISK);
|
|
|
|
|
|
} else if (message === "INVALID_SURNAME") {
|
|
|
|
|
|
showToast(messages.INVALID_SURNAME);
|
|
|
|
|
|
} else {
|
|
|
|
|
|
showToast(messages.GENERATION_FAILED);
|
|
|
|
|
|
}
|
2025-11-05 00:22:09 +08:00
|
|
|
|
})
|
|
|
|
|
|
.finally(() => {
|
2025-11-06 19:23:37 +08:00
|
|
|
|
this.hideLoadingOverlay();
|
2025-11-05 00:22:09 +08:00
|
|
|
|
this.setData({ isSubmitting: false });
|
|
|
|
|
|
});
|
2025-11-06 19:23:37 +08:00
|
|
|
|
},
|
|
|
|
|
|
showLoadingOverlay() {
|
|
|
|
|
|
const hint = LOADING_MESSAGES[Math.floor(Math.random() * LOADING_MESSAGES.length)];
|
|
|
|
|
|
this.setData({
|
|
|
|
|
|
isLoading: true,
|
|
|
|
|
|
loadingMessage: hint
|
|
|
|
|
|
});
|
|
|
|
|
|
},
|
|
|
|
|
|
hideLoadingOverlay() {
|
|
|
|
|
|
if (!this.data.isLoading) {
|
|
|
|
|
|
return;
|
|
|
|
|
|
}
|
|
|
|
|
|
this.setData({
|
|
|
|
|
|
isLoading: false,
|
|
|
|
|
|
loadingMessage: ""
|
|
|
|
|
|
});
|
2025-11-05 00:22:09 +08:00
|
|
|
|
}
|
|
|
|
|
|
});
|