fix(miniapp): 小程序界面全量中文化,消除英文/非中文枚举码上屏
- 新增 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;已做负向注入验证判别力
This commit is contained in:
@@ -8,6 +8,8 @@
|
||||
* 不变量(AGENTS.md 第 2 条):用户已勾选"必须符合"的字段不可被前端自动放宽为
|
||||
* "最好符合",UI 必须显式提示用户此操作将影响匹配精度。
|
||||
*/
|
||||
const { ACCEPT_CHILDREN_OPTIONS } = require('../../constants')
|
||||
|
||||
Component({
|
||||
options: { addGlobalClass: true },
|
||||
properties: {
|
||||
@@ -19,6 +21,24 @@ Component({
|
||||
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
|
||||
@@ -54,9 +74,13 @@ Component({
|
||||
},
|
||||
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: e.detail.value,
|
||||
value: opt.value,
|
||||
});
|
||||
},
|
||||
},
|
||||
|
||||
@@ -111,13 +111,13 @@
|
||||
<view class="ui-pref__label">子女</view>
|
||||
<picker
|
||||
class="ui-pref__picker"
|
||||
value="{{preference.acceptChildren}}"
|
||||
range="{{['any', 'accept', 'reject']}}"
|
||||
range-key=""
|
||||
value="{{childrenIndex < 0 ? 0 : childrenIndex}}"
|
||||
range="{{childrenOptions}}"
|
||||
range-key="label"
|
||||
bindchange="onAcceptChildrenChange"
|
||||
>
|
||||
<view class="ui-pref__picker-value">
|
||||
{{preference.acceptChildren === 'any' ? '不限' : preference.acceptChildren === 'accept' ? '可接受' : '不接受'}}
|
||||
{{childrenLabelMap[preference.acceptChildren] || '不限'}}
|
||||
</view>
|
||||
</picker>
|
||||
</view>
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
* 不暴露"放宽了 X 条件才得到这个推荐"的字样,前端只显示后端返回的 reasons。
|
||||
* - 第 5 条:红娘不可替用户操作——本卡片仅由当前用户操作,不接受 matchmakerId 参数。
|
||||
*/
|
||||
const { STATUS_BADGE } = require('../../constants');
|
||||
const { STATUS_BADGE, profileLabelOf } = require('../../constants');
|
||||
|
||||
Component({
|
||||
options: { addGlobalClass: true },
|
||||
@@ -29,6 +29,21 @@ Component({
|
||||
medium: 'info',
|
||||
normal: 'warning',
|
||||
},
|
||||
// 由后端枚举码派生的中文展示值(界面不得出现英文码)
|
||||
educationLabel: '',
|
||||
occupationLabel: '',
|
||||
},
|
||||
observers: {
|
||||
recommendation(rec) {
|
||||
if (!rec) {
|
||||
this.setData({ educationLabel: '', occupationLabel: '' })
|
||||
return
|
||||
}
|
||||
this.setData({
|
||||
educationLabel: profileLabelOf('educationCode', rec.educationCode),
|
||||
occupationLabel: profileLabelOf('occupationCode', rec.occupationCode),
|
||||
})
|
||||
},
|
||||
},
|
||||
methods: {
|
||||
onViewDetail() {
|
||||
|
||||
@@ -2,8 +2,8 @@
|
||||
<ui-avatar src="{{recommendation.avatarUrl || '/assets/brand/default-avatar.png'}}" size="lg" verified="{{recommendation.verified}}" reviewed="{{recommendation.reviewed}}" default-text="{{recommendation.displayName}}" />
|
||||
<view class="ui-rec__info">
|
||||
<view class="ui-rec__name-row"><text class="ui-rec__name">{{recommendation.displayName || '善缘用户'}}</text><text wx:if="{{recommendation.age}}" class="ui-rec__age">{{recommendation.age}}岁</text><text wx:if="{{recommendation.online}}" class="ui-rec__online">在线</text></view>
|
||||
<view class="ui-rec__meta"><text wx:if="{{recommendation.regionName}}">{{recommendation.regionName}}</text><text wx:if="{{recommendation.heightCm}}"> · {{recommendation.heightCm}}cm</text><text wx:if="{{recommendation.educationCode}}"> · {{recommendation.educationCode}}</text></view>
|
||||
<view wx:if="{{recommendation.occupationCode}}" class="ui-rec__meta">{{recommendation.occupationCode}}</view>
|
||||
<view class="ui-rec__meta"><text wx:if="{{recommendation.regionName}}">{{recommendation.regionName}}</text><text wx:if="{{recommendation.heightCm}}"> · {{recommendation.heightCm}}cm</text><text wx:if="{{educationLabel}}"> · {{educationLabel}}</text></view>
|
||||
<view wx:if="{{occupationLabel}}" class="ui-rec__meta">{{occupationLabel}}</view>
|
||||
<view wx:if="{{recommendation.recommendationReasons && recommendation.recommendationReasons.length}}" class="ui-rec__reasons"><text wx:for="{{recommendation.recommendationReasons}}" wx:key="*this" class="ui-rec__reason">{{item}}</text></view>
|
||||
</view>
|
||||
<view wx:if="{{showActions}}" class="ui-rec__actions">
|
||||
|
||||
@@ -7,6 +7,8 @@
|
||||
* <view slot="actions">…自定义按钮…</view>
|
||||
* </ui-user-card>
|
||||
*/
|
||||
const { profileLabelOf } = require('../../constants')
|
||||
|
||||
Component({
|
||||
options: { addGlobalClass: true, multipleSlots: true },
|
||||
properties: {
|
||||
@@ -15,6 +17,25 @@ Component({
|
||||
selectable: { type: Boolean, value: false }, // 是否显示选择框
|
||||
selected: { type: Boolean, value: false },
|
||||
},
|
||||
data: {
|
||||
// 由后端枚举码派生的中文展示值(界面不得出现英文码)
|
||||
educationLabel: '',
|
||||
occupationLabel: '',
|
||||
maritalLabel: '',
|
||||
},
|
||||
observers: {
|
||||
user(u) {
|
||||
if (!u) {
|
||||
this.setData({ educationLabel: '', occupationLabel: '', maritalLabel: '' })
|
||||
return
|
||||
}
|
||||
this.setData({
|
||||
educationLabel: profileLabelOf('educationCode', u.educationCode),
|
||||
occupationLabel: profileLabelOf('occupationCode', u.occupationCode),
|
||||
maritalLabel: profileLabelOf('maritalStatus', u.maritalStatus),
|
||||
})
|
||||
},
|
||||
},
|
||||
methods: {
|
||||
onTap() {
|
||||
if (!this.data.user) return;
|
||||
|
||||
@@ -19,16 +19,16 @@
|
||||
<view class="ui-user-card__meta">
|
||||
<text wx:if="{{user.heightCm}}">{{user.heightCm}}cm · </text>
|
||||
<text>{{user.regionName}}</text>
|
||||
<text wx:if="{{user.educationCode}}"> · {{user.educationCode}}</text>
|
||||
<text wx:if="{{educationLabel}}"> · {{educationLabel}}</text>
|
||||
</view>
|
||||
<view wx:if="{{user.occupationCode}}" class="ui-user-card__meta">
|
||||
{{user.occupationCode}}
|
||||
<view wx:if="{{occupationLabel}}" class="ui-user-card__meta">
|
||||
{{occupationLabel}}
|
||||
</view>
|
||||
<view wx:if="{{user.recommendationReasons && user.recommendationReasons.length}}" class="ui-user-card__tags">
|
||||
<text wx:for="{{user.recommendationReasons}}" wx:key="*this" class="ui-user-card__tag">{{item}}</text>
|
||||
</view>
|
||||
<view wx:if="{{user.maritalStatus || user.hasChildren !== undefined}}" class="ui-user-card__meta">
|
||||
<text wx:if="{{user.maritalStatus}}">{{user.maritalStatus}}</text>
|
||||
<view wx:if="{{maritalLabel || user.hasChildren !== undefined}}" class="ui-user-card__meta">
|
||||
<text wx:if="{{maritalLabel}}">{{maritalLabel}}</text>
|
||||
<text wx:if="{{user.hasChildren}}"> · 有孩</text>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
Reference in New Issue
Block a user