- 新增 miniapp/constants/profileLabels.js 作为「枚举码→中文简体」唯一字典 (婚姻/子女/学历/职业/吸烟饮酒/择偶子女/红娘状态),覆盖表单值与种子 实际值两套并集,保证详情页无论后端返回哪种码都显示中文 - 修复「择偶条件-子女」下拉英文选项(any/accept/reject→不限/可接受/不接受), 改用 value/label 数组 + range-key="label" - 修复 recommend-card / user-card / profile-detail / profile-confirm 直接渲染 后端枚举码(educationCode/maritalStatus/occupationCode…)的问题,改由 observers 派生中文 label 上屏 - 清理残留英文文案:Required 条件→必须符合的条件、喜欢TA/向Ta→喜欢对方/向对方、 U51 服务预约→服务预约、U64 公益服务记录→公益服务记录 - 修复 7 个英文窗口标题与 3 个英文占位页正文 - matchmaker 历史服务状态消除原始码兜底,统一走字典 - 加固 scripts/audit-miniapp-language.mjs(A 整行先剥离 mustache、B 排除 bind:action 处理器、F 窗口标题、JPG/PNG 入白名单) - 新增 ui-tests/miniapp-language-contracts.mjs 语种守卫(复用审计脚本,断言 0 命中), UI 契约门禁 MIN_GUARDS 21→22;已做负向注入验证判别力
88 lines
2.7 KiB
JavaScript
88 lines
2.7 KiB
JavaScript
/**
|
||
* PreferenceEditor 择偶条件编辑器(规范 §30)
|
||
*
|
||
* 每条条件有两个 importance 等级:
|
||
* - required:必须符合(AGENTS 第 2 条硬约束)
|
||
* - preferred:最好符合(软约束,后端可适度放宽匹配)
|
||
*
|
||
* 不变量(AGENTS.md 第 2 条):用户已勾选"必须符合"的字段不可被前端自动放宽为
|
||
* "最好符合",UI 必须显式提示用户此操作将影响匹配精度。
|
||
*/
|
||
const { ACCEPT_CHILDREN_OPTIONS } = require('../../constants')
|
||
|
||
Component({
|
||
options: { addGlobalClass: true },
|
||
properties: {
|
||
preference: { type: Object, value: null },
|
||
readonly: { type: Boolean, value: false },
|
||
},
|
||
data: {
|
||
importanceLabelMap: {
|
||
required: '必须符合',
|
||
preferred: '最好符合',
|
||
},
|
||
// 子女(是否接受有孩)下拉:选项均为中文,value 为后端枚举码
|
||
childrenOptions: ACCEPT_CHILDREN_OPTIONS,
|
||
childrenLabelMap: {
|
||
any: '不限',
|
||
accept: '可接受',
|
||
reject: '不接受',
|
||
},
|
||
childrenIndex: -1,
|
||
},
|
||
observers: {
|
||
preference(pref) {
|
||
if (!pref) {
|
||
this.setData({ childrenIndex: -1 })
|
||
return
|
||
}
|
||
const idx = this.data.childrenOptions.findIndex((o) => o.value === pref.acceptChildren)
|
||
this.setData({ childrenIndex: idx })
|
||
},
|
||
},
|
||
methods: {
|
||
// 切换某字段的 importance:required ↔ preferred
|
||
onToggleImportance(e) {
|
||
if (this.data.readonly) return;
|
||
const { field } = e.currentTarget.dataset;
|
||
const pref = this.data.preference || {};
|
||
const current = pref[field];
|
||
if (!current) return;
|
||
const next = current === 'required' ? 'preferred' : 'required';
|
||
this.triggerEvent('change', {
|
||
field,
|
||
importance: next,
|
||
// 必须符合 → 最好符合,需用户二次确认(AGENTS 第 2 条)
|
||
needConfirmRelax: current === 'required',
|
||
});
|
||
},
|
||
onAgeChange(e) {
|
||
if (this.data.readonly) return;
|
||
const { bound } = e.currentTarget.dataset;
|
||
this.triggerEvent('change', {
|
||
field: bound === 'min' ? 'ageMin' : 'ageMax',
|
||
value: Number(e.detail.value),
|
||
});
|
||
},
|
||
onHeightChange(e) {
|
||
if (this.data.readonly) return;
|
||
const { bound } = e.currentTarget.dataset;
|
||
this.triggerEvent('change', {
|
||
field: bound === 'min' ? 'heightMin' : 'heightMax',
|
||
value: Number(e.detail.value) || null,
|
||
});
|
||
},
|
||
onAcceptChildrenChange(e) {
|
||
if (this.data.readonly) return;
|
||
const idx = Number(e.detail.value)
|
||
const opt = this.data.childrenOptions[idx]
|
||
if (!opt) return
|
||
this.setData({ childrenIndex: idx })
|
||
this.triggerEvent('change', {
|
||
field: 'acceptChildren',
|
||
value: opt.value,
|
||
});
|
||
},
|
||
},
|
||
});
|