You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Odoo前端JS函数重写疑问:如何覆盖payment_transaction_poll_status?

你的判断完全正确!website_sale.validate模块确实没有导出任何可供include方法使用的对象,这就是你调用website_sale_validate.include({...})时出现TypeError: Cannot read property 'include' of undefined的原因。原模块的代码完全封装在odoo.define的回调函数中,所有内部函数(包括payment_transaction_poll_status)都是局部变量,外部模块无法直接通过常规的Odoo模块继承机制访问或修改它们。

可行的重写方法

1. 覆盖原模块定义(直接但需同步原代码)

你可以重新定义website_sale.validate模块,将原模块的代码完整复制过来,然后修改payment_transaction_poll_status函数的逻辑。这种方法需要确保你的模块在原模块之后加载(通过在__openerp__.py中声明依赖website_sale),这样你的模块会覆盖原模块的定义。

示例代码(/test/static/src/js/test.js):

odoo.define('website_sale.validate', function(require) {
    "use strict";

    // 复制原website_sale.validate模块的所有代码
    // ... 原模块中的其他逻辑(比如依赖引入、DOM元素获取等)

    $(document).ready(function () {
        // ... 原模块中的其他局部函数和逻辑

        // 重写目标函数
        function payment_transaction_poll_status() {
            // 你的自定义轮询逻辑
            console.log("Custom payment poll running...");
            
            // 如果需要保留原逻辑,可以复制原函数的代码并修改
            // 原逻辑示例:检查支付状态、更新UI、设置下一次轮询等
            
            // 继续轮询(根据需求调整延迟时间)
            setTimeout(payment_transaction_poll_status, 3000);
        }

        // 启动自定义轮询
        payment_transaction_poll_status();
    });
});

注意:这种方法的缺点是原模块更新后,你需要同步复制最新的代码,否则会丢失原模块的新功能。

2. 拦截定时器替换轮询逻辑

如果原payment_transaction_poll_status函数使用setTimeout或setInterval实现循环轮询,你可以通过重写全局的定时器函数,记录原轮询的定时器ID,然后清除它并启动自己的自定义轮询。

示例代码:

odoo.define('test.test', function(require) {
    "use strict";

    // 保存原生setTimeout
    const originalSetTimeout = window.setTimeout;
    let originalPollTimerId = null;

    // 重写setTimeout,捕获原轮询的定时器ID
    window.setTimeout = function(callback, delay) {
        const timerId = originalSetTimeout(callback, delay);
        // 通过函数名判断是否是目标轮询函数
        if (callback.name === 'payment_transaction_poll_status') {
            originalPollTimerId = timerId;
        }
        return timerId;
    };

    $(document).ready(function() {
        // 等待原轮询执行一次后,替换为自定义逻辑
        setTimeout(() => {
            if (originalPollTimerId) {
                // 清除原定时器
                clearTimeout(originalPollTimerId);
                // 启动自定义轮询
                customPaymentPoll();
            }
        }, 1000);
    });

    // 自定义轮询函数
    function customPaymentPoll() {
        // 你的自定义逻辑:比如调用API检查支付状态、更新页面UI等
        console.log("Custom payment poll is running");

        // 继续循环轮询(延迟时间和原函数保持一致或调整)
        originalSetTimeout(customPaymentPoll, 3000);
    }
});

注意:这种方法依赖原函数的名称,如果原函数名被修改会失效,同时可能会影响其他使用setTimeout的代码,建议在调试确认后使用。

3. 通过DOM监听实现逻辑替代(无侵入式)

如果原轮询函数的主要作用是更新页面上的支付状态元素,你可以使用MutationObserver监听这些元素的变化,在状态更新时执行自定义逻辑,无需修改原函数。

示例代码:

odoo.define('test.test', function(require) {
    "use strict";

    $(document).ready(function() {
        // 找到支付状态对应的DOM元素(根据原模块的实际选择器调整)
        const paymentStatusElement = $('#payment-transaction-status');
        
        if (paymentStatusElement.length) {
            // 创建观察者对象
            const statusObserver = new MutationObserver(function(mutations) {
                mutations.forEach(function(mutation) {
                    // 当状态元素内容变化时,执行自定义逻辑
                    const currentStatus = paymentStatusElement.text().trim();
                    handlePaymentStatusUpdate(currentStatus);
                });
            });

            // 配置观察选项:监听子节点变化和文本内容变化
            statusObserver.observe(paymentStatusElement[0], {
                childList: true,
                subtree: true,
                characterData: true
            });
        }
    });

    // 自定义状态处理逻辑
    function handlePaymentStatusUpdate(status) {
        console.log("Payment status updated to:", status);
        // 根据状态执行不同操作:比如显示自定义提示、跳转页面等
        if (status === 'paid') {
            alert("Payment successful! Redirecting...");
            window.location.href = '/thank-you';
        }
    }
});

这种方法完全无侵入,不会影响原模块的逻辑,适合只需要根据状态变化执行额外操作的场景。

内容的提问来源于stack exchange,提问作者Pascal

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.28 04:07:11