/** @odoo-module */ import { KanbanController } from "@web/views/kanban/kanban_controller"; import { KanbanRenderer } from "@web/views/kanban/kanban_renderer"; import { kanbanView } from "@web/views/kanban/kanban_view"; import { registry } from "@web/core/registry"; import { useService } from "@web/core/utils/hooks"; import { useState, onWillStart, onWillUnmount, onMounted } from "@odoo/owl"; // 自定义看板渲染器 class CustomKanbanRenderer extends KanbanRenderer { } // 自定义看板控制器 class CustomKanbanController extends KanbanController { setup() { super.setup(); this.orm = useService("orm"); this.searchModel = this.model.env.searchModel; this.defaultPagerLimit = this.getSystemDefaultLimit(); this._onUpdate = (payload) => { this._handleSearchUpdate(payload); }; this.env.services.user.updateContext({ isBaseStyle: true }); let self = this; onWillStart(async () => { try { this.preproductionShelfIds = await this.orm.call( 'sf.shelf.location', 'get_preproduction_shelf_ids', [] ); } catch (error) { this.preproductionShelfIds = []; } this.searchModel.on('update', self, self._onUpdate); await this.loadShelfLayersData(); }); // 组件销毁时移除监听 onWillUnmount(() => { this.searchModel.off('update', self, self._onUpdate); }); // 监听视图切换事件以监控面包屑 onMounted(() => { this.handleRouteChange() }); } handleRouteChange() { this.render(true); let domain = this.searchModel.domain; if (domain.length > 0) { let shelfDomain = domain.find(item => item[0] === 'shelf_id'); if (shelfDomain && shelfDomain[2] && this.preproductionShelfIds && this.preproductionShelfIds.includes(shelfDomain[2])) { this.onShelfChange(shelfDomain[2]); } else { this.setKanbanStyle('sf_kanban_location_style'); } } else { this.setKanbanStyle('sf_kanban_location_style'); } } _handleSearchUpdate() { try { let domain = this.searchModel.domain; if (domain.length > 0) { let shelfDomain = domain.find(item => item[0] === 'shelf_id'); if (shelfDomain) { let shelfId = shelfDomain[2]; if (shelfId && this.preproductionShelfIds.includes(shelfId)) { this.onShelfChange(shelfId); return; } } } //设置默认样式 this.updatePagerLimit(this.defaultPagerLimit); this.setKanbanStyle('sf_kanban_location_style'); } catch (error) { } } // 加载所有货架的层数数据 async loadShelfLayersData() { this.shelfLayersMap = {}; const shelfIds = await this.orm.search('sf.shelf', []); const shelves = await this.orm.read('sf.shelf', shelfIds, ['id', 'layer_capacity']); shelves.forEach(shelf => { this.shelfLayersMap[shelf.id] = shelf.layer_capacity; }); } setKanbanStyle(style) { this.env.services.user.updateContext({ isBaseStyle: style === 'sf_kanban_location_style' }); const kanbanViewEl = document.querySelector('.o_kanban_renderer'); if (kanbanViewEl) { let isHave = false; // 移除所有现有的 sf_kanban_* 类 Array.from(kanbanViewEl.classList).forEach(cls => { if (cls.startsWith('sf_kanban_location_style')) { kanbanViewEl.classList.remove(cls); isHave = true; } }); // 添加新类 if (isHave) kanbanViewEl.classList.add(style); } // 获取当前的搜索域 let domain = this.searchModel.domain; let shelfDomain = domain.find(item => item[0] === 'shelf_id'); // 只有当shelf_id在preproductionShelfIds中时才删除幽灵看板 if (shelfDomain && this.preproductionShelfIds && this.preproductionShelfIds.includes(shelfDomain[2])) { const ghostCards = document.querySelectorAll('.o_kanban_ghost'); ghostCards.forEach(card => { card.remove(); }); } } updatePagerLimit(limit) { if (this.model.root.limit !== limit) { this.model.root.limit = limit; this.render(true); } } // 处理货架变更事件 async onShelfChange(shelfId) { let style = 'sf_kanban_location_style'; let isBaseStyle = true; if (shelfId) { // 如果没有缓存,从服务器加载数据 if (!(shelfId in this.shelfLayersMap)) { const [shelf] = await this.orm.read('sf.shelf', [shelfId], ['layer_capacity']); this.shelfLayersMap[shelfId] = shelf.layer_capacity; } // 获取该货架的层数 const layerCapacity = this.shelfLayersMap[shelfId]; // 根据层数设置不同的样式 if (layerCapacity >= 1) { style = `sf_kanban_location_style${layerCapacity}`; isBaseStyle = false; } } if (isBaseStyle) { this.updatePagerLimit(this.defaultPagerLimit); } else { this.updatePagerLimit(500); } this.setKanbanStyle(style); } /** * 获取系统默认分页记录数 */ getSystemDefaultLimit() { // 方法1:从用户服务获取默认值 const userService = this.env.services.user; // 获取用户配置的默认分页大小 if (userService && userService.user_context && userService.user_context.limit) { return userService.user_context.limit; } // 方法3:使用Odoo核心默认值(通常为80) return 80; } } // 设置自定义模板 CustomKanbanController.template = "sf_warehouse.CustomKanbanView"; export const customKanbanView = { ...kanbanView, Controller: CustomKanbanController, Renderer: CustomKanbanRenderer, }; registry.category("views").add("custom_kanban", customKanbanView);