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

Odoo14中如何实现控制器路由内Python函数调用JS函数

Odoo14 异步第三方回调触发前端逻辑方案

服务端无法直接主动调用浏览器端运行的JS函数,所有这类场景都需要通过前后端约定的数据通道传递信号,前端收到信号后自行触发对应逻辑。针对你的第三方支付异步回调场景,有两种可直接落地的成熟方案,根据业务场景选择即可。


方案一:前端短轮询(实现成本最低,无额外配置要求)

适合对实时性要求不高(1~3秒延迟可接受)的场景,不需要调整服务端部署配置,兼容性最好。

  1. 调整原有do_payment_transaction方法逻辑:发起第三方API请求后不要同步等待回调结果,直接将当前交易记录的ID、初始状态(处理中)返回给前端,避免RPC请求超时。
  2. 自定义控制器收到第三方回调时,只需要根据交易标识匹配到对应的atm.transaction记录,更新记录状态、存储回调数据即可,不需要额外处理前端逻辑。
  3. 前端拿到交易ID后启动定时轮询,间隔固定时间查询交易状态,直到状态变为终态(成功/失败)时清除定时器,执行后续业务逻辑。

JS参考代码:

this.rpc({
  model: 'atm.transaction',
  method: 'do_payment_transaction',
  args: [customer_id],
}).then(function (data) {
  const transactionId = data.transaction_id;
  // 启动轮询
  const pollTimer = setInterval(() => {
    this.rpc({
      model: 'atm.transaction',
      method: 'search_read',
      args: [[['id', '=', transactionId]], ['status', 'callback_result']],
    }).then(function (res) {
      const txInfo = res[0];
      // 状态不是处理中说明已经收到第三方回调
      if (txInfo.status !== 'processing') {
        clearInterval(pollTimer);
        console.log("获取到回调结果", txInfo.callback_result);
        // 此处编写你原本需要被触发的JS业务逻辑
      }
    })
  }, 1500); // 轮询间隔建议不小于1秒,避免给服务端造成过大压力
});

方案二:基于Odoo自带Bus长连接实现实时推送(实时性高)

适合对响应速度要求高的场景,Odoo14原生集成了长连接总线服务,不需要额外引入第三方组件。

  1. 模型侧新增通知方法,收到第三方回调更新交易状态后,通过bus向指定频道推送消息。
    Python模型参考代码:
from odoo import models

class AtmTransaction(models.Model):
    _name = 'atm.transaction'

    def push_callback_notify(self, callback_data):
        # 自定义频道规则,绑定交易所属用户和交易ID
        channel = (self.env.user.partner_id.id, 'atm_payment_callback', self.id)
        self.env['bus.bus'].sendone(channel, {
            'tx_id': self.id,
            'status': self.status,
            'result': callback_data
        })
  1. 自定义控制器收到第三方回调、更新完交易记录后,调用上述push_callback_notify方法推送通知即可。
  2. 前端在发起支付请求后订阅对应交易的通知频道,收到匹配的消息后执行后续逻辑,完成后取消订阅避免内存泄漏。

JS参考代码:

// 引入bus服务
const busService = require('bus.bus').bus;

this.rpc({
  model: 'atm.transaction',
  method: 'do_payment_transaction',
  args: [customer_id],
}).then(function (data) {
  const txId = data.transaction_id;
  // 拼接当前交易对应的通知频道
  const targetChannel = [this.session.partner_id.id, 'atm_payment_callback', txId];
  // 订阅频道
  busService.add_channel(targetChannel);
  // 监听通知
  busService.on('notification', this, function (notifications) {
    notifications.forEach(notif => {
      const [channel, payload] = notif;
      if (JSON.stringify(channel) === JSON.stringify(targetChannel)) {
        console.log("实时收到回调结果", payload);
        // 此处编写你原本需要被触发的JS业务逻辑
        // 执行完成后移除订阅
        busService.delete_channel(targetChannel);
        busService.off('notification', this);
      }
    })
  })
});

注意:使用该方案需要确认Odoo配置文件中longpolling_port参数已正确配置,且服务启动时开启了至少1个worker进程,否则长连接服务不会生效。


不推荐方案

不建议自行接入额外WebSocket服务实现推送,会大幅增加部署、鉴权、连接维护的成本,上述两种方案已经可以覆盖绝大多数ATM支付场景的需求。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.30 13:39:17