You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

如何在Odoo POS界面弹窗显示客户列表并恢复后台产品界面?

解决Odoo POS弹窗显示客户列表时产品屏幕被隐藏的问题

我来帮你搞定这个问题~ 你之前尝试的直接移除oe_hidden或者调用show()方法无效,核心原因是Odoo POS的show_screen方法内部自带了屏幕切换的强制隐藏逻辑——每次调用它显示新屏幕时,框架会自动给当前活跃屏幕加上oe_hidden类,同时移除目标屏幕的该类,你的手动操作会被这个内置逻辑覆盖掉。

下面给你两个可行的解决方案,按需选择:


方案1:改用弹窗组件(推荐)

不要把客户列表做成独立screen,而是自定义一个弹窗组件,这样完全不会影响产品屏幕的显示状态:

  1. 先定义客户列表弹窗的Widget:
odoo.define('your_module.customer_popup', function(require) {
    "use strict";

    var core = require('web.core');
    var PopupWidget = require('point_of_sale.popup');
    var gui = require('point_of_sale.gui');
    var _t = core._t;

    // 自定义弹窗组件
    var CustomerPopup = PopupWidget.extend({
        template: 'CustomerPopupTemplate', // 需自己创建对应XML模板
        init: function(parent, options) {
            this._super(parent, options);
            this.customers = options.customers; // 传入客户数据
        },
        renderElement: function() {
            this._super();
            // 绑定客户选择事件
            this.$('.customer-item').on('click', function() {
                var customerId = $(this).data('id');
                // 将选中客户绑定到当前订单
                const order = this.pos.get_order();
                order.set_client(this.pos.db.get_partner_by_id(customerId));
                this.close(); // 关闭弹窗
            }.bind(this));
        },
    });

    // 注册弹窗
    gui.define_popup({name:'customer_popup', widget: CustomerPopup});
    return CustomerPopup;
});
  1. 在XML里添加弹窗模板(示例):
<t t-name="CustomerPopupTemplate">
    <div class="popup">
        <div class="title">选择客户</div>
        <div class="body">
            <div class="customer-list">
                <t t-foreach="widget.customers" t-as="customer">
                    <div class="customer-item" t-att-data-id="customer.id">
                        <span t-esc="customer.name"/>
                    </div>
                </t>
            </div>
        </div>
        <div class="footer">
            <button class="button cancel" t-on-click="widget.close()">取消</button>
        </div>
    </div>
</t>
  1. 修改ActionpadWidget的点击事件:
// 替换原来的show_screen逻辑
this.gui.show_popup('customer_popup', {
    title: _t('选择客户'),
    customers: this.pos.db.get_partners_sorted(), // 取排序后的客户列表
});

方案2:修改屏幕切换逻辑(保留screen模式)

如果你坚持要用clientlist-screen作为弹窗,需要重写Odoo的屏幕切换方法,让它支持不隐藏当前屏幕:

  1. 重写Gui的show_screen方法:
odoo.define('your_module.custom_gui', function(require) {
    "use strict";

    var gui = require('point_of_sale.gui');

    // 保存原方法
    const originalShowScreen = gui.Gui.prototype.show_screen;
    // 扩展方法,添加hide_current参数
    gui.Gui.prototype.show_screen = function(screenName, options) {
        options = options || {};
        if (!options.hide_current) {
            // 不隐藏当前屏幕,直接显示目标屏幕
            const targetScreen = this.screens[screenName];
            if (targetScreen) {
                targetScreen.$el.removeClass('oe_hidden');
                targetScreen.show();
                if (options.params) {
                    targetScreen.render_element(options.params);
                }
            }
            return;
        }
        // 原逻辑:隐藏当前屏幕,显示目标屏幕
        originalShowScreen.call(this, screenName, options);
    };
});
  1. clientlist-screen添加弹窗样式(确保它悬浮在产品屏幕上方):
.clientlist-screen {
    position: fixed;
    top: 50%;
    left: 50%;
    transform: translate(-50%, -50%);
    width: 80%;
    max-width: 650px;
    height: 75%;
    background-color: white;
    z-index: 9999;
    border-radius: 8px;
    box-shadow: 0 4px 12px rgba(0,0,0,0.2);
    overflow-y: auto;
}
  1. 在ActionpadWidget的点击事件里调用:
// 传入hide_current参数,阻止隐藏产品屏幕
self.gui.show_screen('clientlist', {hide_current: false});

内容的提问来源于stack exchange,提问作者Gopakumar N G

火山引擎 最新活动