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

Odoo14 POS开发无需RPC获取记录及RPC返回Promise问题处理

Odoo 14 POS未支付订单列表展示解决方案

问题核心

RPC网络请求属于异步操作,默认返回Promise对象,无法直接同步获取返回值,你当前的写法赋值给this.orders的是Promise实例而非后端返回的订单数据,另外还有两处代码冗余、变量不匹配的问题也需要同步修正。


修正步骤

1. 后端Python代码调整

Odoo的RPC接口会自动序列化返回的Python列表/字典,不需要手动用json.dumps转成字符串,否则前端拿到还要额外解析,修改后代码如下:

from odoo import api, fields, models, _
from odoo.exceptions import AccessError, UserError, ValidationError

class PosSession(models.Model):
    _inherit = 'pos.session'

    @api.model
    def get_unpaid_orders(self, session_id=None):
        res = []
        orders = self.env['pos.order'].search([('session_id', '=', session_id), ('state', '=', 'draft')])
        for order in orders:
            res.append({
                'id': order.id,
                'name': order.name,
                'price': order.amount_total,
            })
        # 直接返回列表即可,RPC会自动处理序列化
        return res

2. 前端JS代码调整

异步请求的结果只能在回调里获取,拿到数据后赋值给this.orders,Odoo POS使用的Owl框架会自动监听状态变化触发视图重渲染,建议把请求逻辑放到willStart生命周期钩子(组件渲染前触发)中,搭配async/await语法简化异步逻辑,修改后代码如下:

odoo.define('opens_pos_order.UnpaidOrdersScreen', function(require) { 
   'use strict'; 
    const PosComponent = require('point_of_sale.PosComponent'); 
    const Registries = require('point_of_sale.Registries'); 
    const rpc = require('web.rpc')

    class UnpaidOrdersScreen extends PosComponent { 
        constructor() { 
            super(...arguments);
            // 初始化空数组,避免渲染时报变量未定义错误
            this.orders = [];
        };

        // 组件渲染前的生命周期钩子,适合放置初始化数据请求
        async willStart() {
            await super.willStart(...arguments);
            try {
                // await等待异步请求返回结果
                const orderData = await rpc.query({
                    model: 'pos.session',
                    method: 'get_unpaid_orders',
                    args: [this.env.pos.pos_session.id]
                });
                // 拿到结果后赋值给this.orders
                this.orders = orderData;
            } catch (e) {
                console.error('获取未支付订单失败', e);
            }
        }

        back() { 
               this.trigger('close-temp-screen'); 
        }

    } 
    UnpaidOrdersScreen.template = 'UnpaidOrdersScreen'; 
    Registries.Component.add(UnpaidOrdersScreen); 
    return UnpaidOrdersScreen; 
});

3. XML模板调整

当前模板里遍历的变量是categories,和JS里定义的this.orders不匹配,且表头有两列仅渲染了一列,修正后代码如下:

<?xml version="1.0" encoding="UTF-8"?> 
<templates id="template" xml:space="preserve"> 
    <t t-name="UnpaidOrdersScreen" owl="1"> 
        <div class="clientlist-screen screen"> 
            <div class="screen-content"> 
                <div class="top-content"> 
                    <div class="button back" t-on-click="back"> 
                        Back 
                    </div> 
                </div> 
                <section class="full-content"> 
                    <div class="client-window"> 
                        <section class="subwindow list">
                            <div class="subwindow-container">
                                <div class="subwindow-container-fix scrollable-y"> 
                                    <table class="client-list"> 
                                        <thead> 
                                            <tr> 
                                                <th> 订单名称 </th> 
                                                <th> 订单金额 </th> 
                                            </tr> 
                                        </thead> 
                                        <tbody>
                                            <!-- 遍历JS里的orders变量 -->
                                            <t t-foreach="orders" t-as="order" t-key="order.id"> 
                                                <tr> 
                                                    <td> <t t-esc="order.name"/> </td> 
                                                    <td> <t t-esc="order.price"/> </td>
                                                </tr> 
                                            </t>
                                        </tbody> 
                                    </table> 
                                </div> 
                            </div> 
                        </section> 
                    </div> 
                </section> 
            </div> 
        </div> 
    </t> 
</templates>

补充说明

浏览器端网络请求默认都是异步的,没有办法直接同步返回非Promise类型的结果,强制使用同步请求会阻塞页面渲染,属于不推荐的写法,上述async/await的写法已经可以做到逻辑上的同步书写,完全满足业务需求。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.06 05:09:04