v39 第 39 批:观影弹框(antd 中文化 + 影院搜索 + 简介备注各占一行 + 海报照片对齐)
用户原话(四条):
①「观影模块的时间控件,比如说时间呀,还有下面的确定按钮啊。现在显示的都是英文,
应该给它设置成中文。」
②「影院那个地方应该有一个搜索的功能,下拉的地方上面有一个搜索筛选的功能。」
③「简介和备注不要放在一行,也就是说一个字段它就占一行。所以简介后面是一行,
备注后面是一行。」
④「海报和观影照片为什么和上面的标题不一样呢?海报的字体和简介是一样的,也带一个冒号。
然后把后面点击或拖动进行上传往后放,和简介后面的输入框保持一样大小。观影照片也是
类似的,观影照片也是加粗。和简介的字体保持一致,不带冒号,后面放上点击或拖动进行上传。」
① antd 中文化 —— 三个条件缺一不可(缺任一条按钮就还是英文)
· 🔴 **英文的真根因**:`antd.min.js` 这个产物**不含 locale 包**
(实测 `window.antd.locales` 是 undefined)⇒ 只能用它内置的英文默认值。
**换文件**才解决,不是加参数 ⇒ 改用 `antd-with-locales.min.js`
(多带各语言包,全局多挂 `antd.locales`,`antd.locales.zh_CN` 即简体中文包)。
· 🔴 dayjs 的中文 locale 是**单独一个文件**(核心包只有 en)⇒ 引 `dayjs-zh-cn.js`
并调 `dayjs.locale('zh-cn')`(星期/月份由 dayjs 出)。
· 🔴 必须用 `<ConfigProvider locale={zh_CN}>` 包住控件 —— antd 读的是**上下文里的**
locale,不包的话**日历文字会变中文、按钮却仍是英文**(最容易误判成"已经中文化了")。
· 独立探针 `_tooling/_antd_probe/{zh.html,zh_probe.py}` 9/0 把这三条钉死。
· 删除不再引用的 `assets/vendor/antd/antd.min.js`(1.5MB 冗余,留着会让
"两个 antd 哪个是真的"变成下一个坑);部署断言改为钉四资源 + ConfigProvider + zh-cn。
② 影院下拉加搜索筛选
· 搜索框放在弹出列表**内部**(`.cs-search` 吸顶),打开下拉**即聚焦**;回车选第一项。
· 🔴 `.cs-item[hidden] { display: none; }` **必须显式写** —— `.cs-item` 自己声明了
`display:flex`,会盖过浏览器默认的 `[hidden]{display:none}` ⇒ 过滤"看着完全没生效"
(项目第 11 批选人组件踩过同一个坑)。
· 三个事件都 stopPropagation,否则冒到 document 的"点外面关"⇒ 一点搜索框下拉就没了。
· 「不记录影院」恒保留(清空选择的出口);收起时清空搜索词(否则下次带着旧过滤)。
③ 简介 / 备注各占一行
· 撤销 v38 的 `.mv-pair` 并排(半宽的多行文本框每行都换行,更难读);
CSS 与模板里的并排容器**全部清干净**。
④ 海报 / 观影照片与简介对齐 —— 它们本来就不需要特殊规则
· 用户看到的"更窄/不一样"有两个原因:① 海报那块被误包进 `.mv-grid.mv-pair`
且**里面只有一个孩子** ⇒ grid 两列让它只占**半宽**;② 标签被一条
"宽度自适应、左对齐"的规则覆盖掉了固定 62px 右对齐 + 冒号。
· ⇒ 两块都改成普通 `.mv-row.mv-row-media`,标签用 `.mv-lb`(**继承**简介那套),
内容包 `.mv-media-body`(占满剩余);观影照片标签加 `.no-colon`。
实测:所有控件左缘 **424**、宽度 **624**,与简介**完全一致**。
· 🔴🔴 **通识**:v38 的 `.mv-media`(手填 margin-left:72px)是**被一个取错元素的
探针误导出来的** —— 它按文档序取"第一个非标签子元素",而 `_stage_drop.php` 吐的
`.sr-only` 文件框是 `position:absolute`(**脱离文档流、不参与 flex**),却被算成
"控件",于是得出"1px 隐框把上传框推走 130px"的**假结论**。
⇒ "对齐"类断言必须取直接子元素、且只取真正参与布局的那个;量到反常数字先怀疑探针。
验证(全部真机 + 反向验证):
· _fb_b39_movie.py **39/0**(中文化三条 + 搜索框打开即聚焦/输入即过滤/无匹配空态/
点搜索框不关下拉/回车选中/重开已清词 + 简介备注各占一行且占整行宽 +
海报照片标签字重字号同简介/海报带冒号/照片不带/上传框左缘与宽度同简介);
· _fb_b39_narrow.py **21/0**(宽 1440 / 平板 768 / 窄屏 390:不横向溢出、
标签与控件仍同行、影院下拉不出视口、搜索框可用);
· _fb_b39_falsify.py **14/0**(四处各自证伪成功:拿掉 ConfigProvider→按钮变英文、
藏起搜索框→②红、塞回两列并排→③红、标签退回普通 span→④红;复原回全绿);
· v38 两套按 v39 更新后 **36/0**(新增"已无 mv-pair / 主列 6 行");
v38 的旧窄屏套件(断言"简介备注并排")已作废删除,由 v39 窄屏完全覆盖;
· 全路由 e2e **1503/0**、日期控件真机 **53/0** + 反向 **7/0**、v37 两套、
观影照片两套、b30 三件套、各批真机与 DAV 三套、部署静态断言空跑 —— 全绿;
· 线上四个 antd 资源 HTTP **200 可达**;app.js / app.css / form.php / layout.php
的 SHA256 与本地**逐字节一致**。
⚠️ 顺带修的探针/夹具问题(都不是页面 bug):
· 夹具库重铺后 `cinemas` 是**空的** ⇒ v39 探针**自带播种**(造两家影院),
不再依赖别的套件先跑过(与 v38 的"名册只有 1 人"同类:页面没问题,是夹具没数据);
· 部署断言第一版按裸词 grep `mv-pair`,把注释里那句"已撤销 .mv-pair"当成回归
⇒ 改为只认 `class="...mv-pair..."` 这种**真的类名用法**;
· v39 探针第一版判"简介/备注各占一行"看的是"是不是同一个 DOM 节点"——
那个在**并排**时也是 false(并排仍是两个 .mv-row),连并排都抓不住
(反向验证当场抓到 13/1)⇒ 改为按**垂直位置**判(top 相差 ≥20px)。
This commit is contained in:
+38
-2
@@ -1547,6 +1547,17 @@
|
||||
③ `onChange` 只在**两端都齐了**才触发,单端改动走 `onCalendarChange`。
|
||||
⇒ 回写必须同时挂 `onCalendarChange`(实时)**和** `onChange`(确认),
|
||||
否则"只填了开始时间就提交"会丢值。
|
||||
|
||||
🔴🔴 v39(用户 2026-10-10):「时间控件…还有下面的确定按钮,现在显示的都是英文,
|
||||
应该给它设置成中文。」
|
||||
· 英文的**根因**:普通 `antd.min.js` 产物**不含** locale 包(`antd.locales` 是
|
||||
undefined),所以面板只能用它内置的英文默认值 ⇒ 改载 **antd-with-locales**;
|
||||
· 另外 dayjs 核心包只有 en,星期/月份是 dayjs 出的 ⇒ 必须**另加载**
|
||||
`dayjs-zh-cn.js` 并调 `dayjs.locale('zh-cn')`;
|
||||
· 最后用 `<ConfigProvider locale={zh_CN}>` 包住控件 —— antd 读的是**上下文里的**
|
||||
locale,不包的话即使资源在、面板照样是英文(但**日历文字**会变中文,容易误判)。
|
||||
⚠️ 三个条件缺一不可;这也是为什么单独写了 `_antd_probe/zh.html` 把它钉死(9/0)。
|
||||
|
||||
⚠️ 这个适配层**不认识的页面不受影响**:没有 `[data-dt-antd]` 就直接返回。
|
||||
============================================================================ */
|
||||
function bootAntd(hosts) {
|
||||
@@ -1572,12 +1583,20 @@
|
||||
if (!window.ReactDOM) { chain = chain.then(function () { return loadJs(conf.dom || ''); }); }
|
||||
loading = chain
|
||||
.then(function () { return window.dayjs ? null : loadJs(conf.dayjs); })
|
||||
// 🔴 v39:dayjs 的中文 locale 是**单独一个文件**(核心包只有 en)。
|
||||
// 它必须在 dayjs 之后、antd 之前加载 —— 加载完是挂一个
|
||||
// `window.dayjs_locale_zh_cn` 函数(见文件头的说明)。
|
||||
.then(function () {
|
||||
if (!conf.dayjsZh || window.dayjs_locale_zh_cn) { return null; }
|
||||
return loadJs(conf.dayjsZh).catch(function () { return null; });
|
||||
})
|
||||
.then(function () { return window.antd ? null : loadJs(conf.antd); });
|
||||
return loading;
|
||||
}
|
||||
|
||||
var done = 0;
|
||||
ensure().then(function () {
|
||||
applyDayjsZh();
|
||||
Array.prototype.forEach.call(hosts, function (box) {
|
||||
if (mountAntd(box)) { done++; }
|
||||
});
|
||||
@@ -1588,6 +1607,14 @@
|
||||
});
|
||||
}
|
||||
|
||||
/** 把 dayjs 切到简体中文(星期/月份/相对时间都由它出)。
|
||||
* ⚠️ 拿不到就静默跳过 —— 那只会让星期显示成英文,不该拦住整个控件。 */
|
||||
function applyDayjsZh() {
|
||||
try {
|
||||
if (window.dayjs && window.dayjs.locale) { window.dayjs.locale('zh-cn'); }
|
||||
} catch (e) { /* 忽略:dayjs locale 未注册时不做任何事 */ }
|
||||
}
|
||||
|
||||
/** 把**一对**端点升级成 antd RangePicker;成功返回 true。 */
|
||||
function mountAntd(box) {
|
||||
var group = box.closest ? box.closest('.dt-range') : null;
|
||||
@@ -1625,7 +1652,7 @@
|
||||
}
|
||||
|
||||
try {
|
||||
ReactDOM.createRoot(host).render(React.createElement(antd.DatePicker.RangePicker, {
|
||||
var picker = React.createElement(antd.DatePicker.RangePicker, {
|
||||
showTime: { format: 'HH:mm' },
|
||||
format: 'YYYY-MM-DD HH:mm',
|
||||
allowClear: true,
|
||||
@@ -1635,7 +1662,16 @@
|
||||
// onChange 只在两端齐了才响。两个都挂才不会丢值。
|
||||
onCalendarChange: function (vals, strs) { writeBack(strs); },
|
||||
onChange: function (vals, strs) { writeBack(strs); }
|
||||
}));
|
||||
});
|
||||
/* 🔴 v39:**必须用 ConfigProvider 包住**,否则面板上的「确定 / 取消 / 此刻」
|
||||
和星期格式还是英文 —— antd 读的是**上下文里的** locale,不是全局变量。
|
||||
(实测过:资源挂了但没包,日历标题/日期会变中文,**按钮却仍是英文**,
|
||||
最容易误判成"已经中文化了"。) */
|
||||
var loc = (window.antd.locales && window.antd.locales.zh_CN) || undefined;
|
||||
if (loc) {
|
||||
picker = React.createElement(antd.ConfigProvider, { locale: loc }, picker);
|
||||
}
|
||||
ReactDOM.createRoot(host).render(picker);
|
||||
} catch (e) {
|
||||
if (window.console) { console.warn('antd RangePicker 挂载失败,留在自建下拉:', e && e.message); }
|
||||
host.parentNode.removeChild(host);
|
||||
|
||||
Reference in New Issue
Block a user