258 lines
8.6 KiB
JavaScript
258 lines
8.6 KiB
JavaScript
/**
|
||||
|
|
* 择偶条件页 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, '保存失败');
|
|||
|
|
}
|
|||
|
|
},
|
|||
|
|
});
|