Files
danyang-match/miniapp/pages/profile-preference/profile-preference.js
T

258 lines
8.6 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
/**
* 择偶条件页 U12-U14(Phase 04 P04-T27)
*
* 重构要点(遵循 AGENTS.md 不变量):
* - 数据:userStore.fetchPreferences + updatePreferences(第 9 条)
* - Required/Preferred:preference-editor 的 needConfirmRelax 触发二次确认(第 2 条:
* "必须符合"不可自动放宽为"最好符合",UI 必须显式提示)
* - 草稿恢复:onLoad 读 ONBOARDING_DRAFT.preference,保存前写回
* - 下一步:跳 profile-confirm
*/
const { userStore, appStore } = require('../../stores');
const { ROUTE, STORAGE_KEYS } = require('../../constants');
const REGION_OPTIONS = ['丹阳', '镇江市区', '镇江其他辖区', '不限'];
const MARITAL_ACCEPT_OPTIONS = ['未婚', '离异', '丧偶'];
const EDUCATION_OPTIONS = ['不限', '高中/中专以上', '大专以上', '本科以上', '研究生以上'];
const CHILDREN_OPTIONS = [
{ value: 'any', label: '不限' },
{ value: 'accept', label: '可接受' },
{ value: 'reject', label: '不接受' },
];
const MORE_PREF_OPTIONS = {
occupation: ['不限', '机关事业单位', '教育', '医疗', '企业职员', '技术人员', '其他'],
smoking: ['不限', '不吸烟', '偶尔', '经常'],
drinking: ['不限', '不饮酒', '偶尔', '经常'],
settlement: ['不限', '长期定居丹阳', '愿意来丹阳', '不限地区'],
marriagePlan: ['不限', '半年内', '1年内', '1~2年', '顺其自然'],
};
function buildDefaultPreference() {
return {
ageMin: null,
ageMax: null,
ageImportance: 'preferred',
heightMin: null,
heightMax: null,
heightImportance: 'preferred',
region: [],
regionImportance: 'preferred',
maritalStatusAccepted: [],
maritalImportance: 'preferred',
educationAccepted: [],
educationImportance: 'preferred',
acceptChildren: 'any',
// 更多条件(U14,均默认不限)
occupationPreference: '',
smokingPreference: '',
drinkingPreference: '',
settlementPreference: '',
marriagePlanPreference: '',
};
}
Page({
data: {
statusBarHeight: 20,
navBarHeight: 44,
loading: false,
saving: false,
preference: buildDefaultPreference(),
// 选项
regionOptions: REGION_OPTIONS,
maritalAcceptOptions: MARITAL_ACCEPT_OPTIONS,
educationOptions: EDUCATION_OPTIONS,
childrenOptions: CHILDREN_OPTIONS,
morePrefOptions: MORE_PREF_OPTIONS,
educationIndex: 0,
occupationIndex: 0,
smokingIndex: 0,
drinkingIndex: 0,
settlementIndex: 0,
marriagePlanIndex: 0,
},
onLoad() {
this._initSystemInfo();
this._applyDraft();
this.loadPreferences();
},
_initSystemInfo() {
try {
const sysInfo = wx.getSystemInfoSync();
this.setData({
statusBarHeight: sysInfo.statusBarHeight || 20,
navBarHeight: 44,
});
} catch (e) { /* 使用默认值 */ }
},
async loadPreferences() {
this.setData({ loading: true });
try {
const preferences = await userStore.fetchPreferences();
this._mergePreferences(preferences);
} catch (err) { /* 首次填写 */ } finally {
this.setData({ loading: false });
}
},
_mergePreferences(prefs) {
if (!prefs) return;
const d = this._readDraft();
const preference = { ...buildDefaultPreference(), ...prefs, ...(d.preference || {}) };
// 同步更多条件的 picker index
this.setData({
preference,
educationIndex: Math.max(0, EDUCATION_OPTIONS.indexOf((preference.educationAccepted && preference.educationAccepted[0]) || '不限')),
occupationIndex: Math.max(0, MORE_PREF_OPTIONS.occupation.indexOf(preference.occupationPreference || '不限')),
smokingIndex: Math.max(0, MORE_PREF_OPTIONS.smoking.indexOf(preference.smokingPreference || '不限')),
drinkingIndex: Math.max(0, MORE_PREF_OPTIONS.drinking.indexOf(preference.drinkingPreference || '不限')),
settlementIndex: Math.max(0, MORE_PREF_OPTIONS.settlement.indexOf(preference.settlementPreference || '不限')),
marriagePlanIndex: Math.max(0, MORE_PREF_OPTIONS.marriagePlan.indexOf(preference.marriagePlanPreference || '不限')),
});
},
// ============ 草稿 ============
_readDraft() {
try {
const draft = wx.getStorageSync(STORAGE_KEYS.ONBOARDING_DRAFT) || {};
return draft.preference || {};
} catch (e) {
return {};
}
},
_applyDraft() {
const d = this._readDraft();
if (!d || !d.preference) return;
this._mergePreferences(d.preference);
},
_writeDraft() {
try {
const draft = wx.getStorageSync(STORAGE_KEYS.ONBOARDING_DRAFT) || {};
draft.preference = { preference: this.data.preference };
draft.currentStep = 'preference';
wx.setStorageSync(STORAGE_KEYS.ONBOARDING_DRAFT, draft);
} catch (e) { /* ignore */ }
},
// ============ preference-editor 变更 ============
/**
* 处理 preference-editor 的 change 事件
* AGENTS 第 2 条:Required → Preferred 需二次确认(needConfirmRelax=true)
*/
async onPrefChange(e) {
const { field, importance, value, needConfirmRelax } = e.detail;
if (needConfirmRelax) {
// 必须符合 → 最好符合,需用户二次确认
const ok = await appStore.confirm({
title: '确认放宽此条件?',
content: '"必须符合"的条件不会被系统放宽。改为"最好符合"后,可能匹配到略不满足此条件的对象。',
});
if (!ok) return; // 用户取消,不修改
}
const preference = { ...this.data.preference };
if (importance !== undefined) {
preference[field] = importance;
} else if (value !== undefined) {
preference[field] = value;
}
this.setData({ preference });
},
// ============ 地区/婚姻多选 ============
onRegionTap(e) {
const region = e.currentTarget.dataset.region;
const preference = { ...this.data.preference };
const list = [...(preference.region || [])];
const idx = list.indexOf(region);
if (idx >= 0) list.splice(idx, 1);
else list.push(region);
preference.region = list;
this.setData({ preference });
},
onMaritalTap(e) {
const status = e.currentTarget.dataset.status;
const preference = { ...this.data.preference };
const list = [...(preference.maritalStatusAccepted || [])];
const idx = list.indexOf(status);
if (idx >= 0) list.splice(idx, 1);
else list.push(status);
preference.maritalStatusAccepted = list;
this.setData({ preference });
},
// ============ 学历单选 ============
onEducationChange(e) {
const idx = Number(e.detail.value);
const preference = { ...this.data.preference };
preference.educationAccepted = [EDUCATION_OPTIONS[idx]];
this.setData({ preference, educationIndex: idx });
},
// ============ 更多条件(U14) ============
onOccupationChange(e) {
const idx = Number(e.detail.value);
const preference = { ...this.data.preference };
preference.occupationPreference = MORE_PREF_OPTIONS.occupation[idx];
this.setData({ preference, occupationIndex: idx });
},
onSmokingPrefChange(e) {
const idx = Number(e.detail.value);
const preference = { ...this.data.preference };
preference.smokingPreference = MORE_PREF_OPTIONS.smoking[idx];
this.setData({ preference, smokingIndex: idx });
},
onDrinkingPrefChange(e) {
const idx = Number(e.detail.value);
const preference = { ...this.data.preference };
preference.drinkingPreference = MORE_PREF_OPTIONS.drinking[idx];
this.setData({ preference, drinkingIndex: idx });
},
onSettlementChange(e) {
const idx = Number(e.detail.value);
const preference = { ...this.data.preference };
preference.settlementPreference = MORE_PREF_OPTIONS.settlement[idx];
this.setData({ preference, settlementIndex: idx });
},
onMarriagePlanPrefChange(e) {
const idx = Number(e.detail.value);
const preference = { ...this.data.preference };
preference.marriagePlanPreference = MORE_PREF_OPTIONS.marriagePlan[idx];
this.setData({ preference, marriagePlanIndex: idx });
},
// ============ 导航 ============
onBack() {
this._writeDraft();
wx.navigateBack();
},
async onNext() {
if (this.data.saving) return;
const { preference } = this.data;
if (!preference.ageMin || !preference.ageMax) {
return appStore.toast('请填写年龄范围');
}
this.setData({ saving: true });
this._writeDraft();
try {
await userStore.updatePreferences(preference);
this.setData({ saving: false });
wx.navigateTo({ url: ROUTE.ONBOARDING.PROFILE_CONFIRM });
} catch (err) {
this.setData({ saving: false });
appStore.toastError(err, '保存失败');
}
},
});