odoo现代版本都是基于B/S架构,H5浏览器做前端虽然很强大,但是天然欠缺一些传统基于C/S客户端原生控件的基础能力,比如Excel常用的Freeze Panes与Data Filter功能,其铁粉用户的呼声就非常高。
完全开源的社区版odoo,就如同开发商标配的开放式简装房,通过万能的二次开发与交互设计,可以满足我们随心所欲的各种改善型需求。
odoo现代版本都是基于B/S架构,H5浏览器做前端虽然很强大,但是天然欠缺一些传统基于C/S客户端原生控件的基础能力,比如Excel常用的Freeze Panes与Data Filter功能,其铁粉用户的呼声就非常高。
完全开源的社区版odoo,就如同开发商标配的开放式简装房,通过万能的二次开发与交互设计,可以满足我们随心所欲的各种改善型需求。
odooapp的外链能力,可以在应用内打开第三方非odoo网站,且每个子页链接都可以使用app或小程序的原生分享、群发、收藏等功能,极大丰富了传统h5网页在移动端上的分发效果。
html5纯页面角度,通过外套app层混合打包成全网通应用发布至所有平台,并获得相关系统的开放能力,可以最低成本最快速度一劳永逸的抢占各种自然流量入口,以实现其全网存在的最大化价值。
odooapp还提供web sdk开发库,可以让外链的页面嵌入sdk续而调用所提供的javascript api接口返回或跳转到指定的原生页面,这机制也完善了内外链之间的生态闭环切换流程。
ODOO一对多对多混合字段模型
原生的One2many和Many2many已经可以解决大部分模型之间的关系映射,但在一些特殊场景下还是需要混合两者优点形成一个新的关系模型
如生产制造相关的部件与工序:一个部件是由多个工序所组成,而其工序之间还有调整顺序等要求;一个工序可以在多个部件里的不同位置所引用,也可以在同一个部件里不同顺序多次引用
标准的一对多模型桥接做映射可以自定义明细行顺序、独立参数。缺点是只能一个个添加,无法直接打开被桥接的模型进行操作
标准的多对多模型直接做映射可以批量选择、直接编辑。缺点是不可重复且没有顺序及独立参数,后续基本没有可扩展的灵活性
混合的一对多对多模型则是结合上述两者各自优势进行互补以达到可用性层面的最佳用户体验
ODOO12新起点
终于迎来了12,也是传说中期待的双数版本号
去年这个时候是11,虽也惊喜,但毕竟是python2到3的过渡期,有历史责任包袱的产品还是需要双兼容,于是那个版本是从7持续以来第一个被忽视的版本
所以我们现在的感觉就如同当年还在Windows Mobile的odoo78910,因为专注取舍错过了整个Symbian过渡时期,然后一口气飞奔进入iOS/Android双雄争霸时代
这比喻也许有些夸张,但对定位为开源企业级应用操作系统的我们来说,还是比较合适的:)
随着新产品线开始全面拥抱odoo12已经一个月有余,目前各种感觉都很顺畅,真不愧是一个全新的高起点定制系统:
框架模式方面基本成型,落后的能淘汰的都淘汰了,缺陷的能优化的也都优化了,结构上开始趋向稳定,预计未来大版本升级会容易很多
数据库方面过去成熟稳定的PostgreSQL9低版本已经无法胜任,久违的ORM开始慢慢的启用了一些新特性,长远发展看pg10+要成为标配
XML视图方面更新了更为严谨的rng约束,各种元素及属性将不可随意添加或缺失,有效的规范了页面结构的整体质量
CSS样式方面预处理器由Less改成了与整体框架更为融洽的Scss,核心的Bootstrap库大版本也从经典的3升级到了最新的4,感觉表现层这系列折腾起码要稳定几年了
Python方面彻底进入3时代,以后可能还有一些3.7前后版本的对应兼容库问题,但总算是完全告别2时代了
JavaScript方面基本已经将odoo9以来奠定的框架基础改造至极限,虽不能说很完美,但这一路优化过来已属不易,二次可开发的地方也越多越完善,将来Hack代码的机会不多了
其他应用层面的变化太多就不一一列举了,这里就重点说一个原来的document模块要废弃了,其在表单顶部工具栏的文档附件管理已被底部的mail消息日志功能所整合替代。长远看这也是一个很好的改进,只是可惜了原来依赖该基础模块的一大波第三方模块要被迫转型升级。考虑到要适应多年以来形成的附件操作习惯突然改变,同时我们自己也有直接间接依赖的几十号各类模块需要以空间换时间的兼容使用,特此立项从12版本开始上架维护用于替代的Document Sidebar模块,该应用市场链接https://apps.odoo.com/apps/modules/12.0/document_sidebar/
ODOO集成Excel xls和xlsx文件读写库
开源物以类聚角度LibreOffice Calc的ods格式是整合电子表格的最佳选择,但由于Excel尾大不掉还有着2003及之前xls格式和2007及之后xlsx格式的历史问题
存储:原生Binary字段是最合适的,但不管最终是文件存储还是数据库存储,程序上都是以base64库的encodestring编码和decodestring解码进行出入
前端:SheetJS库可以用来做附件和报表的预览应用及所见即所得数据的快速结构化导出
后端:xlrd+xlwt、XlsxWriter、OpenPyXL三大Python库各有所长又相互制衡反垄断,根据场景自由组合起来可以做各种类型复杂应用。StringIO和BytesIO可用于中转处理过程中的内存临时存储,避免了要生成和清理文件的麻烦
ODOO列表视图动态行选择字段
由于框架模型限定了选择字段是需要事先定义的,也就是选择下拉内容是确定且固定的,对应成列表视图则是每一行都是相同有限的选择
比如以上这种每一个物料都有自己的颜色和规格明细组合,这与odoo原生的产品变体刚好相反,后者是由产品属性及值自动生成所有排列组合的变体,前者则根据实际有限的明细反推出其属性集合
最后体现在一些行业应用中,比如鞋服箱包产品款式的BOM配色配码,其颜色尺码的表头是由产品基础属性组成动态列,而颜色规格的配置行则是根据所选物料的不同集合来动态限定范围选择列,间接实现每一行的Many2one和Selection字段都是独立定义
ODOO搜索视图触屏设备禁用自动聚焦
标准搜索视图都是配合其他数据视图组合呈现的,其有个特性就是会自动获取焦点到搜索输入框方便用户快速进行数据筛选
如今大部分的移动设备如手机、平板等都是使用软键盘进行触控输入,当系统检测到焦点被可输入元素获取到时会自动弹出占用将近一半屏幕大小的虚拟键盘。如此搜索视图那原本人性化的设计在移动设备下日常使用动不动就被弹出键盘的行为反而变的更不友好
经过源码分析若不覆盖原设计方法冗余重构的情况下还有自动失焦的对冲方案,同时这个效果也是Web浏览器经典的UI线程和JS线程互斥表现演示:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
/** * author: i@renjie.me */ var config = require('web.config'); var SearchView = require('web.SearchView'); SearchView.include({ renderFacets: function() { var self = this; self._super.apply(self, arguments); if (config.device.touch) { var input_view = _.last(self.input_subviews); if(input_view){ input_view.$el.blur(); } } } }); |
ODOO富文本字段Summernote编辑器自定义
Summernote是一个非常简单灵活所见即所得的HTML在线编辑器,基于jQuery和Bootstrap构建,支持快捷键操作,提供大量可定制的选项
不同版本的ODOO在不同阶段都尝试过各种自定义,比如字体选择、全屏功能以及开发者模式下的源码视图,以下将根据代码odoo/addons/web_editor/static/src/js/backend.js里的默认配置为基础进行自定义调整:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 |
/** * author: i@renjie.me */ var FieldTextHtmlSimple = core.form_widget_registry.get("html"); FieldTextHtmlSimple.include({ _config: function() { var self = this; var config = self._super.apply(self, arguments); // 初始高度 config["height"] = 200; // 删除线功能 config.toolbar[1][1].splice(3, 0, 'strikethrough'); // 普通模式源码视图 if(!session.debug){ config.toolbar.splice(7, 0, ['view', ['codeview']]); } // 全屏功能 config.toolbar[7][1].unshift('fullscreen'); return config; }, initialize_content: function() { var self = this; self._super.apply(self, arguments); // 关闭拼写检查 if(!self.get("effective_readonly")){ self.$content.attr("spellcheck", false); } } }); |
ODOO集成Raphaël可视化销控视图
Raphaël 是一个用于在网页中绘制矢量图形的 Javascript 库。它使用 SVG W3C 推荐标准和 VML 作为创建图形的基础,你可以通过 JavaScript 操作 DOM 来轻松创建出各种复杂的柱状图、饼图、曲线图等各种图表,还可以绘制任意形状的图形,可以进行图表或图像的裁剪和旋转等复杂操作
虽然 D3.js 已经非常优秀,但多一个选择也不是坏事,何况理论上各种优秀的前端图形库都可以按照 ODOO 视图规范兼容共处一起飞:)
ODOO阿里钉钉桌面和移动客户端免登认证通用模板
钉钉的免登接口是先要通过基于前端H5的JSAPI获取到code后才能进行后台服务端校验,但其PC端和手机端开发很可能是两个不同风格的小团队耦合而成,所以调用接口需要整合一下才能对外透明,也难怪后台应用针对两端的首页都可以分别进行配置:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 |
<template id="entry" name="renjie_dingtalk entry"> <t t-call="web.layout"> <t t-set="head"> <script t-if="type == 'mobile'" type="text/javascript" src="//g.alicdn.com/dingding/open-develop/1.9.0/dingtalk.js"></script> <script t-if="type == 'pc'" type="text/javascript" src="//g.alicdn.com/dingding/dingtalk-pc-api/2.7.0/index.js"></script> </t> <script type="text/javascript"> /** * author: i@renjie.me */ var auth = { corpId: "<t t-raw="corp_id"/>", onSuccess: function(ret){ location.href = "/auth_dingtalk/sso" + location.search + "\u0026code=" + ret.code + "\u0026state=<t t-raw="state"/>"; }, onFail: function(err){} }; <t t-if="type == 'mobile'"> dd.ready(function(){ dd.runtime.permission.requestAuthCode(auth); }); </t> <t t-if="type == 'pc'"> DingTalkPC.runtime.permission.requestAuthCode(auth); </t> </script> </t> </template> |