5 odoo 自定义界面

本文以项目模块自定义工作台为例 模块名称:my_project

odoo的自定义界面实现主要的两个工具:Qweb、js

正式开始之前在需要自定义内容的模块中定义几个文件:

  • static/js/project_workspace.js 用于js代码
  • static/scss/project_workspace.scss 模板样式渲染
  • static/scss/workspace_table_style.scss 模板中展示表格样式渲染
  • static/xml/project_workspace.xml 使用Qweb自定义html界面
  • views/project_workspace_views.xml 定义自定义界面的菜单项目入口
  • views/template.xml 加载js以及css模板

views/project_workspace_views.xml文件

  1. <?xml version="1.0" encoding="UTF-8" ?>
  2. <odoo>
  3. <!-- 项目工作台-->
  4. <record id="bw_project_workspace_action" model="ir.actions.client">
  5. <field name="name">工作台</field>
  6. <field name="tag">project_workspace.main</field>
  7. </record>
  8. <menuitem name="工作台"
  9. parent="bw_project.menu_root"
  10. id="bw_project_workspace_menu"
  11. action="bw_project_workspace_action"
  12. sequence="100" groups="base.group_system"/>
  13. </odoo>

首先定义一个工作台的客户端动作
其次定义一个工作台的菜单项目,通过action属性指定触发的客户端动作

views/template.xml 文件:

  1. <?xml version="1.0" encoding="utf-8"?>
  2. <odoo>
  3. <!-- 自定义项目工作台 -->
  4. <template id="bw_project_assets_backend" inherit_id="web.assets_backend" name="bw_project_assets_backend">
  5. <xpath expr="." position="inside">
  6. <link rel="stylesheet" type="text/scss" href="/bw_project/static/src/scss/project_workspace.scss"/>
  7. <link rel="stylesheet" type="text/scss" href="/bw_project/static/src/scss/workspace_table_style.scss"/>
  8. <script type="text/javascript" src="/bw_project/static/src/js/project_workspace.js"/>
  9. </xpath>
  10. </template>
  11. </odoo>

加载scss或js文件 自动渲染html

static/xml/project_workspace.xml文件:

  1. <?xml version="1.0" encoding="UTF-8" ?>
  2. <template xml:space="preserve">
  3. <t t-name="Projectworkspace">
  4. <div class="container-fluid py-2 o_bw_project_workspace">
  5. <div class="form-row">
  6. <div class="col-12 col-lg-6 o_bw_project_workspace_col">
  7. <div class="o_bw_project_workspace_show">
  8. <p>项目工作台 显示1</p>
  9. </div>
  10. </div>
  11. <div class="col-12 col-lg-6 o_bw_project_workspace_col">
  12. <div class="o_web_settings_dashboard_invitations">
  13. <p>项目工作台 显示3</p>
  14. </div>
  15. <div class="o_web_settings_dashboard_company">
  16. <p>项目工作台 显示4</p>
  17. </div>
  18. </div>
  19. </div>
  20. </div>
  21. </t>
  22. <t t-name="BwProjectProject">
  23. <div class="text-center o_bw_project_workspace_show">
  24. <h1 class="my_project">我的项目</h1>
  25. <hr/>
  26. <t t-set="project_objs" t-value="widget.data.project_objs"/>
  27. <table class="mt">
  28. <tr>
  29. <th>项目编码</th>
  30. <th>项目名称</th>
  31. <th>项目状态</th>
  32. </tr>
  33. <t t-foreach="project_objs" t-as="project">
  34. <tr>
  35. <td>
  36. <a href="#" class="badge badge-pill o_bw_project_to_form"
  37. t-att-data-project-id="project.id"> <t t-esc="project.code"/> </a>
  38. </td>
  39. <td>
  40. <a href="#" class="badge badge-pill o_bw_project_to_form"
  41. t-att-data-project-id="project.id"><t t-esc="project.name"/> </a>
  42. </td>
  43. <td>
  44. <a href="#" class="badge badge-pill o_bw_project_to_form"
  45. t-att-data-project-id="project.id"><t t-esc="project.state"/> </a>
  46. </td>
  47. </tr>
  48. </t>
  49. </table>
  50. <t t-if="project_objs.length &lt; widget.data.project_count">
  51. <br/>
  52. <a href="#" class="o_web_settings_dashboard_more o_bw_project_more"><t t-esc="widget.data.project_count - project_objs.length"/> 查看更多 </a>
  53. </t>
  54. </div>
  55. </t>
  56. </template>

模板id为Projectworkspace中定义了整个模板的样式
模板id为BwProjectProject中渲染模板内容

static/scss/project_workspace.scss 文件:

  1. .o_bw_project_workspace {
  2. $bg-dashboard-col: #FFF;
  3. @mixin o-web-settings-dashboard-card {
  4. box-shadow: 0 1px 2px 0 rgba(0,0,0,.14);
  5. background: $bg-dashboard-col;
  6. border-radius: 2px;
  7. }
  8. background: #F7F7F7;
  9. height: 100%;
  10. .o_bw_project_workspace_col {
  11. > div > hr {
  12. margin: 12px -18px 15px -18px;
  13. border-color: #CBCBCB;
  14. }
  15. > div {
  16. @include o-web-settings-dashboard-card;
  17. padding: 25px 18px 18px 18px;
  18. .o_web_settings_dashboard_header {
  19. font-size: 22px;
  20. margin-bottom: 8px;
  21. }
  22. }
  23. .o_bw_project_to_form {
  24. font-size: 14px;
  25. }
  26. .btn.o_browse_apps, .btn.o_web_settings_dashboard_invitations {
  27. margin-top: 12px;
  28. }
  29. .o_web_settings_dashboard_compact_subtitle {
  30. line-height: 12px;
  31. display: block;
  32. }
  33. .o_web_settings_dashboard_invitations {
  34. .o_web_settings_dashboard_invitation_form {
  35. text-align: left;
  36. > textarea {
  37. resize: vertical;
  38. width: 100%;
  39. }
  40. }
  41. }
  42. .o_web_settings_dashboard_planner {
  43. .progress {
  44. height: 10px;
  45. background-color: darken($bg-dashboard-col, 15%);
  46. cursor: pointer;
  47. margin-bottom: 30px;
  48. }
  49. .o_web_settings_dashboard_planner_progress_text {
  50. font-size: 18px;
  51. padding-right: 0px;
  52. padding-top: 3px;
  53. }
  54. .o_web_settings_dashboard_planner_progress_bar {
  55. padding-left: 10px;
  56. }
  57. .o_web_settings_dashboard_progress_title {
  58. font-weight: bold;
  59. cursor: pointer;
  60. color: $o-brand-primary;
  61. }
  62. }
  63. }
  64. }

static/js/project_workspace.js 文件:

  1. odoo.define('bw_project', function(require){
  2. "use strict";
  3. //自定义项目工作台
  4. var AbstractAction = require('web.AbstractAction');
  5. var config = require('web.config');
  6. var core = require('web.core');
  7. var framework = require('web.framework');
  8. var session = require('web.session');
  9. var Widget = require('web.Widget');
  10. var QWeb = core.qweb;
  11. var _t = core._t;
  12. var Projectworkspace = AbstractAction.extend({
  13. template: 'Projectworkspace',
  14. init: function(){
  15. this.load_workspace = ['bw_project']
  16. return this._super.apply(this, arguments);
  17. },
  18. start: function(){
  19. return this.load(this.load_workspace);
  20. },
  21. load: function(workspaces){
  22. var self = this;
  23. var loading_done = new $.Deferred();
  24. this._rpc({route: '/bw_project_workspace/data'})
  25. .then(function (data) {
  26. // Load each workspace
  27. var all_workspaces_defs = [];
  28. _.each(workspaces, function(workspace) {
  29. console.log(workspace)
  30. var workspace_def = self['load_' + workspace](data);
  31. if (workspace_def) {
  32. all_workspaces_defs.push(workspace_def);
  33. }
  34. });
  35. $.when.apply($, all_workspaces_defs).then(function() {
  36. loading_done.resolve();
  37. });
  38. });
  39. return loading_done;
  40. },
  41. load_bw_project: function(data){
  42. return new ShowProject(this, data.projects_info).replace(this.$('.o_bw_project_workspace_show'));
  43. },
  44. });
  45. var ShowProject = Widget.extend({
  46. template: 'BwProjectProject',
  47. events: {
  48. 'click .o_bw_project_to_form': 'to_form_clicked',
  49. 'click .o_bw_project_more': 'on_more',
  50. },
  51. init: function(parent, data) {
  52. this.data = data;
  53. this.parent = parent;
  54. this.emails = [];
  55. return this._super.apply(this, arguments);
  56. },
  57. to_form_clicked: function (e) {
  58. var self = this;
  59. e.preventDefault();
  60. var project_id = $(e.currentTarget).data('project-id');
  61. var action = {
  62. type: 'ir.actions.act_window',
  63. view_type: 'form',
  64. view_mode: 'form',
  65. res_model: 'project.project',
  66. views: [[this.data.project_form_view_id, 'form']],
  67. res_id: project_id,
  68. };
  69. this.do_action(action,{
  70. on_reverse_breadcrumb: function(){ return self.reload();}
  71. });
  72. },
  73. on_more: function(e) {
  74. var self = this;
  75. e.preventDefault();
  76. var action = {
  77. name: _t('项目'),
  78. type: 'ir.actions.act_window',
  79. view_type: 'form',
  80. view_mode: 'tree,form',
  81. res_model: 'project.project',
  82. domain: [['is_user_read', '=', true]],
  83. views: [[false, 'list'], [false, 'form']],
  84. };
  85. this.do_action(action,{
  86. on_reverse_breadcrumb: function(){ return self.reload();}
  87. });
  88. },
  89. reload:function(){
  90. return this.parent.load(['bw_project']);
  91. },
  92. });
  93. core.action_registry.add('project_workspace.main', Projectworkspace);
  94. return {
  95. Projectworkspace: Projectworkspace,
  96. };
  97. });

异步访问路由 /bw_project_workspace/data,获取后台项目信息。并实现 记录的点击跳转

core.action_registry.add(‘project_workspace.main’, Projectworkspace);中为客户端动作定义的tag内容。

template: ‘Projectworkspace’, template关键字指定模板id则自动渲染html界面,未知的这需手动渲染html界面

其中static/xml/project_workspace.xml文件引入manifest.py的qweb关键字下

结果展示(程序员审美请见谅。工作台区域美化可自定义)

posted @   CrossPython  阅读(415)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 分享4款.NET开源、免费、实用的商城系统
· 全程不用写代码,我用AI程序员写了一个飞机大战
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了
· 记一次.NET内存居高不下排查解决与启示
点击右上角即可分享
微信分享提示