From 371ff7a2c8e2722dc68b670314c64c649d26dc08 Mon Sep 17 00:00:00 2001 From: qitangbo Date: Fri, 16 Oct 2026 17:42:52 +0800 Subject: [PATCH] =?UTF-8?q?=E6=A8=A1=E5=9D=97=E5=88=97=E8=A1=A8=E5=88=86?= =?UTF-8?q?=E9=A1=B5=E5=99=A8=E9=9A=90=E8=97=8F"/=E6=80=BB=E6=95=B0"?= =?UTF-8?q?=EF=BC=8C=E5=8F=AA=E6=98=BE=E7=A4=BA1-50?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 实训模块/应用主页的 ir.module.module 看板: - KanbanController.setup 在 env.config 打隐藏标记(仅 kanban,list 不受影响) - Pager.setup 读到标记后挂载时加 class o_pager_hide_total - JS 注入 CSS 隐藏分页器的" / "分隔 span 和总数 span - 真实总数照常统计,只是不显示;翻页/锁50行为不变 - 本地已用 ir.qweb._get_asset_content 真实编译 bundle 验证补丁在位 --- college/static/src/js/module_list_cap.js | 63 ++++++++++++++++++++++-- 1 file changed, 60 insertions(+), 3 deletions(-) diff --git a/college/static/src/js/module_list_cap.js b/college/static/src/js/module_list_cap.js index 2d15994..fcc6efd 100644 --- a/college/static/src/js/module_list_cap.js +++ b/college/static/src/js/module_list_cap.js @@ -1,11 +1,11 @@ /** - * 模块列表(ir.module.module)每页数量锁定为 50。 + * 模块列表(ir.module.module)每页数量锁定为 50,并隐藏分页器里的 "/ 总数"。 * * 覆盖两个入口(同一模型、同款 kanban,一起受益): * 1. 应用主页(Odoo 自带「应用」菜单) * 2. 实训模块页(college 自定义 action) * - * 原理(两个 patch,全在数据链路上,不碰 Odoo 源码、不删任何模块): + * 原理(四个 patch,全在数据链路上,不碰 Odoo 源码、不删任何模块): * Patch 1 KanbanController.prototype.modelParams(getter): * 模型为 ir.module.module 时,把初始每页数 limit 钉为 50, * 并在 modelConfig 上打一个标记(__yuthon_module_list_cap)。 @@ -15,8 +15,19 @@ * 这是翻页/手输每页数的唯一数据出口(Pager.onUpdate 最终就是调到 * model.root.load({offset, limit}))。带标记且调用方传了 limit 时, * 强制压回 offset=0 / limit=50 —— 第 2 页进不去、每页数改了也白改。 + * Patch 3 KanbanController.prototype.setup: + * 同样是 ir.module.module 看板时,在 env.config 上打一个标记 + * (__yuthon_hide_pager_total)。usePager() 在 setup 里通过 + * useSubEnv 把 pagerProps 挂到 env.config,control panel 的 + * 渲染时 env 一路继承到这里, + * 所以 Pager 侧能读到该标记(list 视图不经过这里,不受影响)。 + * Patch 4 Pager.prototype.setup: + * 读到标记后,挂载时给根节点 nav.o_pager 加 class + * o_pager_hide_total,由本文件注入的 CSS 把 + * " / " 分隔 span 和总数 span(o_pager_limit)隐藏掉, + * 分页器只剩 "1-50"(真实总数照常统计,只是不显示)。 * - * 效果:页面永远只显示前 50 个模块,总数仍正常显示(如 1-50 / 56); + * 效果:页面永远只显示前 50 个模块,分页器只显示 "1-50"(不显示 "/ 56"); * 搜索照常能用,结果同样只取前 50;其他所有页面零影响。 * * 注意:本文件必须注册进 __manifest__.py 的 web.assets_backend 才会生效; @@ -24,13 +35,32 @@ * 仅 git pull + 重启不会重建前端资源包。 */ /** @odoo-module **/ +import { onMounted } from "@odoo/owl"; import { patch } from "@web/core/utils/patch"; import { KanbanController } from "@web/views/kanban/kanban_controller"; import { DynamicList } from "@web/model/relational_model/dynamic_list"; +import { Pager } from "@web/core/pager/pager"; const MODULE_MODEL = "ir.module.module"; const PAGE_LIMIT = 50; const CAP_FLAG = "__yuthon_module_list_cap"; +const HIDE_TOTAL_FLAG = "__yuthon_hide_pager_total"; +const HIDE_TOTAL_STYLE_ID = "yuthon-pager-hide-total-style"; + +// 隐藏分页器 " / 总数" 的样式(只对带 o_pager_hide_total 的分页器生效)。 +// .o_pager_value 后面紧跟的裸 span 就是模板里的 " / ", +// 配合 .o_pager_limit(总数)一起隐藏;编辑态(input)时同样只剩输入框。 +if (!document.getElementById(HIDE_TOTAL_STYLE_ID)) { + const style = document.createElement("style"); + style.id = HIDE_TOTAL_STYLE_ID; + style.textContent = [ + ".o_pager.o_pager_hide_total .o_pager_value + span,", + ".o_pager.o_pager_hide_total .o_pager_limit {", + " display: none !important;", + "}", + ].join("\n"); + document.head.appendChild(style); +} // Patch 1:kanban 初始每页数锁 50,并给数据链路打标记(仅 kanban,list 不打) patch(KanbanController.prototype, { @@ -46,6 +76,18 @@ patch(KanbanController.prototype, { }, }); +// Patch 3:给分页器链路打隐藏标记(usePager 的 useSubEnv 在 setup 内完成, +// super.setup() 之后 env.config.pagerProps 已就位;此处只动 env.config, +// 不碰 pagerProps 对象本身,避免给 Pager 传未声明的 prop) +patch(KanbanController.prototype, { + setup() { + super.setup(); + if (this.props.resModel === MODULE_MODEL) { + this.env.config[HIDE_TOTAL_FLAG] = true; + } + }, +}); + // Patch 2:翻页/手输的唯一数据出口,强制压回第 1 页、每页 50 条 patch(DynamicList.prototype, { load(params) { @@ -56,3 +98,18 @@ patch(DynamicList.prototype, { return super.load(params); }, }); + +// Patch 4:带标记的 Pager 挂载后加 class,由上面的 CSS 隐藏 "/ 总数" +patch(Pager.prototype, { + setup() { + super.setup(); + const config = this.env && this.env.config; + if (config && config[HIDE_TOTAL_FLAG]) { + onMounted(() => { + if (this.root.el) { + this.root.el.classList.add("o_pager_hide_total"); + } + }); + } + }, +});