Merge pull request !12690 from 李鹏宇/dev
This commit is contained in:
李鹏宇
2026-08-20 10:23:03 +00:00
committed by Gitee
@@ -3,16 +3,24 @@
import { patch } from "@web/core/utils/patch";
import { DateTimePicker } from "@web/core/datetime/datetime_picker";
// yuthon_datetime_rounding v2(Odoo 16 / 17 通用)
// yuthon_datetime_rounding(Odoo 16 / 17 通用)
// ---------------------------------------------------------------------------
// 目的:Odoo 时间选择器(DateTimePicker)默认 rounding=5(分钟只能选 0/5/10/.../55),
// 导致"选05变04 / 选00变59"这类分钟精度困惑。
// 本补丁把"未显式配置 rounding 的字段"默认改为分钟精确(rounding=1):
// Odoo 时间选择器(DateTimePicker)默认 rounding=5(分钟只能选 0/5/10/.../55)。
// 本补丁把"未显式配置 rounding 的字段"默认改为系统参数 yuthon_datetime.rounding
// 指定的精度(默认 1 = 分钟精确):
// - 全局默认值来自系统参数 yuthon_datetime.rounding(1=分钟精确,5=每5分钟,15=每15分钟...),
// 修改后重新登录或刷新页面(session_info 刷新)生效;
// - 视图里字段显式配置 options="{'rounding': N}" 且 N 非 5 时,尊重视图设置(不覆盖)。
// 实现双保险:① 基类 setup 前修正 props.rounding,让基类初始计算即用新值;
// ② setup 后按需重算 availableMinutes,兼容基类内部实现差异。
//
// 为何这样实现(踩坑记录):
// 旧实现试图在 setup() 内执行 `this.props.rounding = getForcedRounding()`,
// 但 OWL 的 props 在组件内是只读/冻结的,赋值不会真正生效;
// super.setup() -> onPropsUpdated 仍按原生 rounding=5 过滤 availableMinutes,
// 分钟下拉里只有 5 的倍数,而字段原始分钟(如 04)不在选项中,浏览器原生的
// <select> 行为与预期冲突,表现为"选05变04 / 选00变59"。
// 改为在 onPropsUpdated 内、super 之后直接覆盖 availableMinutes,绕开 props 写
// 限制,稳定生效;取值层(getTimeValues/selectTime)本就只读 state.timeValues,
// 不依赖 rounding,无需改动。
// ---------------------------------------------------------------------------
function getForcedRounding() {
@@ -27,25 +35,14 @@ function buildMinutes(step) {
}
patch(DateTimePicker.prototype, {
setup() {
const wasDefault =
this.props.rounding === undefined || this.props.rounding === 5;
if (wasDefault) {
this.props.rounding = getForcedRounding();
}
super.setup();
if (wasDefault && this.props.rounding > 0) {
this.availableMinutes = buildMinutes(this.props.rounding);
}
},
onPropsUpdated(props) {
if (typeof super.onPropsUpdated === "function") {
super.onPropsUpdated(props);
}
const isDefault =
props.rounding === undefined || props.rounding === 5;
if (isDefault && this.props.rounding > 0) {
this.availableMinutes = buildMinutes(this.props.rounding);
super.onPropsUpdated(props);
// 仅对"未显式配置 rounding"的字段生效(Odoo 默认 rounding=5):
// 字段显式配置 options={'rounding': N} 且 N 非 5 时不覆盖,尊重视图设置。
const isDefault = props.rounding === undefined || props.rounding === 5;
const forced = getForcedRounding();
if (isDefault && forced > 0) {
this.availableMinutes = buildMinutes(forced);
}
},
});