From ebff252913115f481c085f5df49c7ce08a2212f5 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=E6=9D=8E=E9=B9=8F=E5=AE=87?=
Date: Fri, 31 Jul 2026 15:11:36 +0800
Subject: [PATCH] =?UTF-8?q?=E5=88=9B=E5=BB=BA=E6=8F=90=E9=86=92=E5=BC=B9?=
=?UTF-8?q?=E7=AA=97?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
yuthon_issue/__manifest__.py | 1 +
.../static/src/js/issue_m2o_confirm.js | 100 ++++++++++++++++++
yuthon_issue/static/xml/issue_approval.xml | 15 +++
yuthon_issue/views/inherit_room_booking.xml | 2 +-
yuthon_issue/views/issue_library_views.xml | 4 +-
5 files changed, 119 insertions(+), 3 deletions(-)
create mode 100644 yuthon_issue/static/src/js/issue_m2o_confirm.js
diff --git a/yuthon_issue/__manifest__.py b/yuthon_issue/__manifest__.py
index 514faea02..ef834e826 100644
--- a/yuthon_issue/__manifest__.py
+++ b/yuthon_issue/__manifest__.py
@@ -34,6 +34,7 @@
],
'assets': {
'web.assets_backend': [
+ 'yuthon_issue/static/src/js/issue_m2o_confirm.js',
'yuthon_issue/static/xml/issue_approval.xml',
'yuthon_issue/static/scss/issue_library_scss.scss',
],
diff --git a/yuthon_issue/static/src/js/issue_m2o_confirm.js b/yuthon_issue/static/src/js/issue_m2o_confirm.js
new file mode 100644
index 000000000..212caedf3
--- /dev/null
+++ b/yuthon_issue/static/src/js/issue_m2o_confirm.js
@@ -0,0 +1,100 @@
+/* @odoo-module */
+/**
+ * 议题 Many2one 字段创建前确认弹窗
+ * - 继承 Odoo 17 原生 Many2OneField,包裹 quickCreate(拦截"创建 xxx")
+ * - 自定义 Many2XAutocomplete,包裹 openMany2X(拦截"创建并编辑...")
+ */
+import { Component } from "@odoo/owl";
+import { registry } from "@web/core/registry";
+import { _t } from "@web/core/l10n/translation";
+import { Dialog } from "@web/core/dialog/dialog";
+import { Many2OneField } from "@web/views/fields/many2one/many2one_field";
+import { Many2XAutocomplete } from "@web/views/fields/relational_utils";
+
+// ============================================================
+// 自定义确认弹窗组件
+// ============================================================
+class IssueM2OConfirmDialog extends Component {
+ static template = "yuthon_issue.IssueM2OConfirmDialog";
+ static components = { Dialog };
+}
+
+// ============================================================
+// 通用:显示确认弹窗,返回 Promise
+// ============================================================
+function showCreateConfirm(env, value) {
+ const displayName = value || "";
+ return new Promise((resolve) => {
+ // 注意:dialog.add() 返回值本身就是一个 close 函数(非 dialog 对象)
+ const closeDialog = env.services.dialog.add(
+ IssueM2OConfirmDialog,
+ {
+ title: _t("创建新选项"),
+ body: _t("请您确认要创建一个新的选项") + (displayName ? `: "${displayName}"` : ""),
+ confirmLabel: _t("确认创建"),
+ cancelLabel: _t("取消"),
+ // 确认创建:resolve(true) 并关闭弹窗
+ onConfirm: () => { resolve(true); closeDialog(); },
+ // 取消:resolve(false) 并关闭弹窗
+ onCancel: () => { resolve(false); closeDialog(); },
+ },
+ // 点 X 或 ESC 关闭时视为取消
+ { onClose: () => resolve(false) }
+ );
+ });
+}
+
+// ============================================================
+// 自定义 Many2XAutocomplete:拦截"创建并编辑..."
+// ============================================================
+class IssueM2OConfirmAutocomplete extends Many2XAutocomplete {
+ setup() {
+ super.setup();
+ if (this.openMany2X) {
+ const originalOpenMany2X = this.openMany2X;
+ this.openMany2X = async (params) => {
+ const request =
+ (params &&
+ params.context &&
+ (params.context.default_name ||
+ params.context[`default_${this.props.nameCreateField}`])) ||
+ "";
+ const confirmed = await showCreateConfirm(this.env, request);
+ if (!confirmed) return;
+ return originalOpenMany2X(params);
+ };
+ }
+ }
+}
+
+// ============================================================
+// 自定义 Many2OneField:拦截"创建 xxx"(quickCreate)
+// ============================================================
+export class IssueM2OConfirmCreate extends Many2OneField {
+ setup() {
+ super.setup();
+ // 包裹 quickCreate("创建 xxx" 快速创建)
+ if (this.quickCreate) {
+ const originalQuickCreate = this.quickCreate;
+ this.quickCreate = async (name, params) => {
+ const confirmed = await showCreateConfirm(this.env, name);
+ if (!confirmed) return;
+ return originalQuickCreate(name, params);
+ };
+ }
+ }
+}
+
+IssueM2OConfirmCreate.template = "web.Many2OneField";
+// 让模板里的 使用我们的自定义版本(拦截"创建并编辑...")
+IssueM2OConfirmCreate.components = {
+ Many2XAutocomplete: IssueM2OConfirmAutocomplete,
+};
+IssueM2OConfirmCreate.componentName = "issue_m2o_confirm_create";
+
+// 注册自定义字段组件
+registry.category("fields").add("issue_m2o_confirm_create", {
+ component: IssueM2OConfirmCreate,
+ displayName: _t("议题 Many2one 创建确认"),
+ supportedTypes: ["many2one"],
+});
diff --git a/yuthon_issue/static/xml/issue_approval.xml b/yuthon_issue/static/xml/issue_approval.xml
index 46ab2a6d2..442fb32b8 100644
--- a/yuthon_issue/static/xml/issue_approval.xml
+++ b/yuthon_issue/static/xml/issue_approval.xml
@@ -23,4 +23,19 @@
+
+
+
+
+
\ No newline at end of file
diff --git a/yuthon_issue/views/inherit_room_booking.xml b/yuthon_issue/views/inherit_room_booking.xml
index 277f84339..111cfa89f 100644
--- a/yuthon_issue/views/inherit_room_booking.xml
+++ b/yuthon_issue/views/inherit_room_booking.xml
@@ -29,7 +29,7 @@
-
+
diff --git a/yuthon_issue/views/issue_library_views.xml b/yuthon_issue/views/issue_library_views.xml
index 547a35f8d..b26a3e8c3 100644
--- a/yuthon_issue/views/issue_library_views.xml
+++ b/yuthon_issue/views/issue_library_views.xml
@@ -63,7 +63,7 @@
decoration-muted="issue_state == 'cancel'">
@@ -732,7 +732,7 @@