fix(web): 参数表单收束 + 一句话说明改多行(按截图实测修两处失调)

用户给了真实截图,指出两处肉眼可见的不协调,逐项定位后修复:

1. 「一句话说明」是单行 input 被塞进 ~360px 的格子,placeholder
   「例:全市场股息率最高的 2」直接截断 —— 内容太多、框太小。
   → 改为整宽多行 <textarea>(rows=2、min-height 64px、可纵向拉伸),
     与定宽 340px 的策略名并排(.params-meta flex),窄屏自动上下堆叠;
     实时字数 (N/300) 已在提示里。

2. 「太多地方没有对齐」的根因:表单铺满 ~1900px 内容区,5 列各 ~360px,
   控件拉得太开;因子下拉用 1fr 撑到 ~1500px 而权重框才 118px,比例失调;
   数字输入还有 max-width:180px 上限,比同行下拉窄一截。
   → .params-form 约束到 ~1100px(每列 ~210px,所有控件按 1fr 等宽,
     左右边缘严格对齐);移除已多余的 max-width:180px(限宽后它反而
     制造新的不等宽),数值/日期改为填满单元格;因子行首列封顶 460px、
     整行限宽 720px,条件行同理(首列 ≤360px、限宽 760px);
     复权口径选项去掉括号里的「股息策略推荐」(已在 hint 说明),不再截断。

验证方式也升级了:这次是**截图后用 read_image 看渲染像素**确认,而不只量几何。
对齐自检同步把 textarea(高度随行数变、本就该比单行高)排除出「同排等高 /
高度归一」比较,并把数字过宽阈值调到 240px(限宽后 ~210px 属正常)。

门禁:tsc 0 错误、图表单测 7/7、next build 成功、页面 200、
对齐自检 140/140、契约自检 59/59;/backtest 与 /strategies 截图复核通过。
This commit is contained in:
Simon
2026-09-30 19:56:40 +08:00
parent d1287799f7
commit 50a1030afa
4 changed files with 91 additions and 21 deletions
+8 -3
View File
@@ -213,6 +213,9 @@ PROBE = r"""
aria: !!(e.getAttribute("aria-label") || e.getAttribute("title")),
iconOnlyBtn: e.tagName === "BUTTON" && !txt(e.innerText) && !e.getAttribute("data-label"),
nestedIcon: nested && e.classList.contains("icon-btn"),
// 多行文本域:高度随行数变化,是「内容决定高度」的控件,
// 不参与「同排等高」(它本来就该比单行输入高)与「高度取值归一」比较
isTextarea: e.tagName === "TEXTAREA",
x: r.x, y: r.y, w: r.w, h: r.h, fs: parseFloat(s.fontSize),
radius: s.borderRadius, padL: parseFloat(s.paddingLeft), padR: parseFloat(s.paddingRight),
placeholder: txt(e.getAttribute("placeholder")).slice(0, 30),
@@ -317,7 +320,7 @@ def check_geometry(g: dict) -> list[tuple[bool, str, str]]:
# 1 同排等高
mixed = []
for row in rows:
heights = [c["hitH"] for c in row if not c["nestedIcon"]]
heights = [c["hitH"] for c in row if not c["nestedIcon"] and not c["isTextarea"]]
if len(heights) < 2:
continue
if max(heights) - min(heights) > 1.5:
@@ -329,7 +332,7 @@ def check_geometry(g: dict) -> list[tuple[bool, str, str]]:
out.append((not mixed, "同排控件等高", detail or f"{len(rows)} 行全部等高"))
# 2 高度取值归一
uniq = sorted({round(c["hitH"], 1) for c in ctrls if not c["optionRow"]})
uniq = sorted({round(c["hitH"], 1) for c in ctrls if not c["optionRow"] and not c["isTextarea"]})
out.append((len(uniq) <= 3, "控件高度取值归一(≤3 种)", f"实际 {len(uniq)} 种:{uniq}"))
# 3 点击目标
@@ -364,7 +367,9 @@ def check_geometry(g: dict) -> list[tuple[bool, str, str]]:
out.append((len(radii) <= 2, "控件圆角 ≤2 种", f"{radii}"))
# 7 尺寸匹配内容
wide_num = [c for c in ctrls if c["tag"] == "input" and c["type"] in ("number", "date") and c["w"] > 220]
# 阈值 240:参数表单约束到 ~1100px 后每列约 210px,数字输入填满单元格属正常;
# 真正失调的是早先 flex:1 拉到 359px 那种(截图实测)。
wide_num = [c for c in ctrls if c["tag"] == "input" and c["type"] in ("number", "date") and c["w"] > 240]
narrow = [c for c in ctrls if c["tag"] == "input" and c["type"] in ("text", "search", "")
and c["w"] < 120 and not c["nestedIcon"]]
det = []