Files
workspace/code/g3soft-libs/.changeset/table-number-precision.md
T
2026-10-15 22:47:42 +08:00

4.4 KiB
Raw Blame History

@g3soft/ui
@g3soft/ui
minor

G3Table:新增 editor.precision(数值精度)与列级 format(展示格式化),并导出 checkPrecision / formatNumber。

  • editor.precision:数值精度(小数位数),可传函数按行给。它同时驱动两件事,是一处真源:
    • 展示:非编辑态按精度格式化(1200.5 → 1200.50);
    • 校验:超出精度即 error(红底 + 左侧竖条),悬停浮层显示「最多 N 位小数」—— 这是组件内置的规则,业务不需要写任何与精度有关的 validate。
    • ⚠️ 不静默四舍五入:用户输了 123.456 而精度是 2,值仍然是 123.456,只是这一格被标红,由用户自己改。悄悄改成 123.46 会让「屏幕上的」与「落库的」不是一回事 —— 财务对账时就是「我输的不是这个」。
    • ⚠️ 超精度时不做格式化展示(原样裸露真实值):按精度格式化成 123.46 会让屏幕完全合规、数据却不合规,用户永远发现不了自己错了。
    • 录入时不做实时拦截:实时的精度过滤要与光标位置、输入法组合态、半输入态(12. / -)搏斗,是公认的坑;「输完再判」既确定又可预测。
    • 判定用字符串数小数位而不是数值运算:Math.round(v * 100) / 100 在 1.005 上给出的是 1(1.005 * 100 = 100.49999999999999),而金额最容易撞上这种「看着是两位小数、二进制里不是」的值。
  • checkPrecision(value, precision) 对外导出:业务在保存前做提交拦截时必须复用同一个函数,否则会出现「格子红了但存档能过」这类两边不一致、又极难排查的问题。
  • 列级 format:展示态格式化(只影响显示,落库值不变)。传选项对象走底座的 formatNumber(千分位 / ¥ 前后缀 / 万-亿缩写 / 百分比);传函数则完全自定义(Intl.NumberFormat 的正解 —— 多语言的小数点与千分位符号、会计的括号负数这些 locale 规则,重写一遍必然缺选项)。小数位取 format.decimals ?? editor.precision。
  • 顺带解决一个缺口:底座的 createNumberCell 是纯展示单元格,用法是 customCell: NumberCell(),而我们的 resolveCustomCell 对显式 customCell 是直接放行的 —— 业务一旦用它就绕过了整条编辑链路(编辑、校验、灰底、Tab 跳格、Enter/Esc 语义、草稿与失焦提交全没了)。也就是说「可编辑的金额列」此前没有任何合法方式做格式化展示。现在 format 与 editor 正交,两者可同时存在。
  • 门控(性能):resolveCustomCell 新增两条常驻判据 —— 配了 precision 的 number 列、以及配了 format 的纯展示列(后者走一个只做格式化的轻量 cell)。代价只落在显式配了这两样的列上,普通列照旧走库的原生 td 渲染、零组件开销。
  • 单测覆盖边界(utils/precision.test.ts,13 条):空值/非数字/展示文本/科学计数法一律放行、负数符号不参与位数、1.005 这类浮点陷阱、非法精度配置当作没配、格式化与自定义函数的优先级。
  • 修复:右对齐列一点进编辑,文字就跳到左边。 text-align 本是继承属性,但表单控件的 UA 样式表把它覆盖成 start —— 实测点进金额格后 input 拿到的是 start(LTR 下即左对齐),于是文字与光标从右跳到左,进出编辑有明显位移(与「编辑器无缝嵌入、进出零位移」的目标正好相反)。现在表格侧按库的列对齐类(.text-r / .text-c)把 input / textarea 接回来。
    • 没有给 G3Input 加 prop:右对齐是列的属性(align),只有表格知道该不该右对齐;加在公共组件上只会多一个当前没人用的 API。将来表单里出现真实诉求再加不迟。
    • 判据依赖库的 .text-r / .text-c 类名(实测打在 td 上);库若改名这层会静默失效(表现只是「编辑时又变回左对齐」),代码注释里写明了排查方式。
    • 只管 input / textarea:右对齐的 select 极少见,且它的对齐由触发器内部的 flex 布局决定,不是一条 text-align 能解决的。
  • 文档新增「数值精度与金额」一节(含保存前拦截的完整示例)。