BOS开发平台功能和基础业务详介
162-BOS开发平台功能和基础业务详介.md
注意
本博文仅供学术研究和交流参考,严禁将其用于商业用途。如因违规使用产生的任何法律问题,使用者需自行负责。
一、前置条件 BOS 环境搭建
二、BOS产品概述
金蝶业务操作系统(Kingdee Business Operating System
)
开放的集成与应用平台
金蝶ERP解决方案
合作伙伴解决方案、客户定制应用的技术平台
金蝶BOS基础原理
金蝶EAS BOS在逻辑结构上将企业级应用的开发分成了三个模型层次
业务模型→业务建模工具
设计模型→设计开发工具
实现模型→JAVA视图
金蝶BOS集成开发环境

金蝶BOS工作原理

三、元数据体简介
元数据是用来描述业务数据模型结构的一种模型。BOS的元数据包括有解决方案、包、实体、关系、查询,数据表、功能、业务功能、枚举、异常等诸多元数据类型
在EAS中,元数据即MDA模型,基于MOF理论建立起来的元数据体系,贯穿EAS建模/设计/开发/实施的全过程。
元数据是EAS的心脏,EAS的质量首先是由元数据决定的。

BOS元数据作用于各个角落,在EAS中任何功能都依赖于元数据,离开元数据,寸步难行
设计期
BIM
工作流设计器
移动BOS
DEP
Web动态扩展平台
运行期
ORM-RPC
BOS J2EE基础框架
各种BOS运行服务组件
业务模块
BOS元数据对架构的侵入非常强,架构上不存在没有元数据支撑的计算模式
元数据介绍
BOS 设计器,编辑/维护元数据,发布Java代码
DEP 动态扩展平台,通过编辑/维护的元数据,对单据进行扩展开发
移动BOS,通过元数据设计移动端业务功能
J2EE框架,访问元数据获取事务属性并缓存
ORMapping,通过元数据生成sql语句
应用框架,通过元数据生成应用逻辑代码框架
权限/同步,通过元数据进行授权/权限通过/同步控制
工作流,通过元数据设计业务流程,流程属性
后台事务,通过元数据定义事务内容
BOTP/DAP,通过元数据定义转换规则
BOS元数据家族

实体(Entity)和关系(Relationship)
实体:实体对象是元数据模型的核心内容,数据对象、查询对象、实体界面对象等其他对象均附属或依赖于他。实体对象是数据存储的一个逻辑视图,它对应于业务系统中的实体类,指的是可永久存储的数据对象。
关系:关系是指实体对象之间的连接关系。关系可以用连接(Link)来描述。关系一般分为以下几种: 继承(Implementation)、关联(Association)、组成(Composition)
从数据库操作的角度看,关联、聚合和组合关系之间的唯一不同是对象相互之间的绑定程度:组合通常需要整体的读取、保存和删除。
数据表(Table)
数据表:数据表(Table)是与关系型数据库中对应的数据实体表。
数据表在元数据模型分为三类:
普通类型:作为实体对象主表的数据表。
交叉类型。当两个业务对象间存在多对多的关系时,映射到E—R关系时,需要有一个单独的表来存储关联关系。
扩展类型:扩展表可以将实体映射到不同的数据表中。当一个业务对象的内容在物理上无法在一张表中完全存储时(数据库的列个数/总宽度的限制,或者当表中有数据时限制对表结构的更改),就需要用扩展表来完成存储。这样不至于在逻辑上人为地将业务对象割裂。
查询(Query)
查询:BOS中的Query对象是实体对象的查询视图,可以在数据访问过程中只获取视图中指定属性的数据,并按照过滤、排序条件进行数据的过滤和排序。
Query对象的数据组织形式是二维模型的,Query对象可以分为连接查询对象(Join Query)和联合查询对象(Union Query)。在一个连接查询对象中可以包含多个子对象:实体(Entity)或者其他的查询对象(Sub Query称为子查询),但是在一个连接查询对象中有且仅有一个主对象。在一个联合查询对象中,包含的子对象都必须是一个(Sub Query 称为子查询),并且联合查询对象默认第一个选中的子对象为主对象。
用户界面(UI)
- 用户界:用户界面是对人机交互界面的抽象性描述,记录了一个界面内有什么控件、控件的各属性值是多少、控件是如何布局、界面的多语言等信息。
枚举(Enumeration)
- 枚举:枚举是一种常用的数据类型,用于定义例如性别、血型、单据状态等。枚举元数据的发布的类名这个属性是生成的枚举类名称,允许与枚举元数据的名称不同。
权限(Permission)
- 权限:权限是用于对使用者使用功能或数据的一种控制手段。通过定义权限,可以对菜单显示、界面功能操作、及后台数据操作进行使用限制。权限元数据是权限项的一个集合,权限项是定义权限的最小单位。
业务功能(Function)和功能(Facade)
业务功能(Function)是对运行系统的Entity对象、UI对象及其方法的一定封装,供其它模块或二次开发使用,目前业务功能的主要使用对象为工作流和后台事务。
功能对象(Facade)是相对与实体对象而言的,它是只包含操作的Interface类或操作多个实体的Business Façade类。
区别:功能(Facade)与业务功能(Function)相似,区别在于功能的操作不绑定到实体,而业务功能的操作需要绑定到某个实体。因此在依赖于某个实体的处理,例如单据的审核操作,使用业务功能(Function),而不依赖于具体实体的处理,例如月末结账,使用功能(Facade)。
四、业务建模工具
业务建模工具工作原理
通过基础原理介绍,对业务建模工具的工作原理需要明确两个基本概念:
金蝶EAS BOS在完成业务单元的定义后,需要通过“发布”和“部署”功能转化后才能在业务场景中使用的
金蝶EAS BOS定义的应用是编译运行的,最终都将会转化成实现模型:Java代码、数据库定义、J2EE部署及BOS所独有的元数据(MetaData)
业务建模工具特点
避免繁复:
BIM有如下特点:
图形化的业务定义,所见即所得
对运行引擎进行了封装
与应用框架、单据转换平台无缝结合
支持绑定业务功能到业务流程
屏蔽了技术细节,用户只需从业务模型的角度来定制和扩展ERP系统,决定其适应面更广,更易用
随需而变:支持用户自定义
业务建模工具用途
基础资料自定义、业务单据自定义
定义资料的查询和过滤功能
设置业务范围
主菜单管理
工具栏和菜单栏的菜单管理
功能自定义
权限管理
集成工作流、单据转换平台、编码规则
业务建模工具-组别新增
设计步骤:
步骤1:选中某个目录,点鼠标右键,选择【新建】【业务组别】
步骤2:定义业务组别


业务建模工具-根据向导定义单据
- 步骤1:业务单元管理视图鼠标右键,选择【新建】【业务单元】

- 步骤2:设置单据基本信息,输入单据的名称和别名

步骤3:业务类别选择业务单据,业务属性(即主业务组织),选择适当的业务类型
步骤4:设置创建方式,选择复制基础模板

- 步骤5:模板选择“多分录单据基础模板”,此模板适用于单分录/多分录等各种情况,比较通用。

- 步骤6:选择模板字段,然后完成。

- 根据向导定义完成的单据初始界面

业务建模工具-新增字段
方式一:逐个新增
点设计界面的单据头或单据体位置
点鼠标右键,选择【新增字段】
在字段定义窗口逐个新增字段

方式二:批量新增
点设计界面的单据头或单据体位置
点鼠标右键,选择【字段管理】
批量新增字段
单据表头字段
分录字段


方式三:复制新增
对于属性接近的字段可以进行【复制新增】

业务建模工具-数据来源
新增字段中字段来源:
手工录入:用户直接录入
基础资料类别:系统中定义的基础资料
已有基础资料相关属性:业务单元上已有基础资料的属性
固定下拉列表:系统中定义的枚举(包括自定义枚举)
其他业务单元:系统中定义的其他的业务单元
业务建模工具-手工录入
字段来源为手工录入的分为以下几种:
文本
日期
小数
整数
数量
金额
单价
备注
布尔
时间

业务建模工具-基础资料及其属性
- 步骤1:数据来源:选择【基础资料类别】

- 步骤2:基础资料:选择【F7】


- 步骤3:设置界面显示字段

业务建模工具-已有基础资料相关属性
数据来源:已有基础资料相关属性
- 选择具体的基础资料

业务建模工具-固定下拉列表
数据来源:固定下拉列表
选择具体得基础资料
点击[F7],选择关联的枚举


业务建模工具-枚举设计
枚举包括
系统默认的枚举
用户自定义枚举
设计步骤:
步骤1:选择菜单上【业务单元】【枚举】
步骤2:新增枚举
步骤3:定义枚举类型
步骤4:定义枚举项
枚举定义



业务建模工具-字段布局调整
为使得业务单据界面美观及符合用户录入习惯,需要对界面字段的位置及录入顺序进行调整
界面字段位置格式快速调整对齐
左对齐
右对齐
居中对齐
顶部对齐
中间对齐
底部对齐
宽度相等
高度相等
规范化控件尺寸
标签等宽

业务建模工具-字段录入顺序调整
调整录入时TAB/回车切换顺序
点鼠标右键,选择【字段管理】菜单
切换到【录入顺序调整】页签
调整字段录入顺序

业务建模工具-字段查询顺序调整
调整序时簿中字段显示顺序是否可见
点鼠标右键,选择【字段管理】菜单
切换到【查询顺序管理】页签
调整顺序跟可见性

业务建模工具-预留字段
系统运行时通过“界面配置”功能使用
点鼠标右键,选择【字段管理】菜单
切换到【预留字段】页签
点击【新增】
编辑字段属性

业务建模工具-常用属性设置
从【大纲】中选择某个字段,并在【属性】窗口设置相关属性
字段标题有关的属性:描述
字段值录入控制有关属性:是否是必录项、自动校验必录项、默认值、可用(锁定)
字段数值合计有关属性:编辑合计、列表合计
字段的可见性有关属性:录入可见、查询可见、在通用过滤中显示、是否在通用过滤中参与排序
字段属性设置

业务建模工具-字段管理—F7过滤
自定义的基础资料可以在F7中以树型结构出现,由系统后台自动实现
F7按主业务组织和用户权限范围过滤 ,
通过新增业务组织关联字段,由系统在后台实现
F7可定义过滤条件

业务建模工具-事件管理—事件触发
- 对某控件,可以在以下情况设置触发事件 (保存、更新、加载)

业务建模工具-事件管理—操作分类
定义指定字段计算公式
设置功能属性
单据合法性校验
携带关联资料属性到指定字段
设置字段属性
根据关联资料属性设置字段精度
业务建模工具-事件管理—事件定义
步骤
1、选中某个字段
2、指定规则事件
3、新增事件操作

- 4、定义事件操作类型和逻辑

业务建模工具-事件管理—操作分类
系统预定义的事件操作类型I
定义指定字段计算公式:为需要重新计算的字段指定一个计算公式
比如:金额=数量x建议采购单价
则“金额”的值随着“数量”和“建议采购单价”的值的改变而改变。由此可判断事件应该定义在公式右侧的字段“数量”和“建议采购单价”上;事件的触发时机在“更新”事件上。
系统预定义的事件操作类型II
单据合法性校验:对字段的录入值进行校验,判断是否符合需求描述
根据关联资料属性设置字段精度:选择关联资料,将其属性设置另一数值型字段的精度。
比如金额的精度是由币别的属性——精度决定的。当币别发生变化时,币别的精度随之发生变化,同时此精度影响到金额的精度一并发生变化.因此此事件触发在“更新”事件上,事件的触发位置在“币别”字段上
系统预定义的事件操作类型III
设置字段属性:设置字段的可见性或可用性
携带关联资料属性到指定字段:选择基础资料,将其属性设置另一字段的值
- 此事件触发位置在被引用的基础资料上,触发在更新事件上;当该基础的值发生变化时,它的一个相关属性的值同时也在变化,并赋值给被设置的字段。
业务建模工具-菜单管理
菜单管理
菜单栏
工具栏


业务建模工具-主菜单管理
设计业务单元与界面菜单的绑定
通过BIM设计EAS主控台界面的菜单,包括菜单组和菜单项,在业务单元发布后,将直接写入对应的数据库中去
菜单【方案】-->【主菜单管理】


业务建模工具-主菜单管理-设置菜单组
- 建立菜单分组

业务建模工具-主菜单管理-设置菜单项
在菜单组下增加菜单项
1:点【新增菜单项】按钮
2:设置菜单项名称
3:选择关联的业务单元
4:设置状态
5:设置权限
在菜单组下增加菜单项



业务建模工具-发布
定义完的元数据可以即时发布
- “业务单元管理”-->选中单据并右键--->“发布业务单元” 注:发布时要把它引用的业务单元先发布
发布过程包含的功能:
发布之前计算、装载业务单元相关元数据
发布相关元数据,包括校验、发布生成代码
生成部署文件,生成相关的属性文件
编译代码
生成数据库升级脚本(根据目标数据库的内容)
执行数据库脚本生成、更新表结构
还包括做发布记录等相关内容
定义完的元数据可以即时发布

业务建模工具-测试
两种测试方式:
界面测试,不登陆BOS主框架,不需加主菜单
启动测试,需登陆BOS主框架,需要加主菜单

3种测试方式:
本地部署,服务器和BOS在同一机器,服务器不需要启动BIM服务
远程部署,服务器和BOS在不同机器,服务器需启动BIM服务
构建补丁部署,使用方式和标准补丁相同

建模工具-动手实践
新建物料:
类型:基础资料
字段:编码、名称、物料产地、物料规格
新建币别:
类型:基础资料
字段:编码、名称、ISO编码、计量单位、精度
采购申请单:
类型:业务单据
字段:申请编码、申请人( base\permission\user.bizunit )、供应商(supplier.bizunit)、新建币别、申请时间、申请状态
分录:物料编码(新建物料F7)、物料名称、物料规则、申请数量、建议采购单价、总金额
采购订单:
类型:业务单据
字段:订单编码、采购员( base\permission\user.bizunit )、供应商(supplier.bizunit)、新建币别、业务日期、付款方式(固定下拉框)
分录:物料编码(新建物料F7) 、物料名称、物料规则、采购数量、单价、总金额
五、设计开发工具
业务建模工具与设计开发工具关注同一元数据,只是处于不视图
为什么需要设计开发工具:
元数据是BOS的核心,元数据的设计与管理需通过设计开发进行。
BIM虽可生成相应元数据,但其功能也是有限的,对于繁杂的元数据应功能的定义需通过设计开发工具进行,如特殊用户界面、Query及其他元数据的定义。
设计开发工具能做什么:
进行各项元数据的定义,主要包括:实体、实体关系、数据表、查询、用户界面、功能对象、业务功能、枚举、异常、权限、多语言资源、规则、业务数据类型日志等
各项元数据的导入、导出
元数据的校验及发布
复制标准产品单据元数据,进行修改
设计开发工具-动手实践
采购申请单:
列表显示”申请人”的”组织范围、”供应商”的编码。
更改列表界面和编辑界面的标题。
采购订单:
列表显示”采购员”的”组织范围、”供应商”的编码。
更改列表界面和编辑界面的标题。
六、代码结构
常用类说明
第一个:IPurOrder
- 作为创建,更新及其他操作‘采购订单’实体对象的接口。获得IPurOrder的实例:
Java IPurOrder i PurOrder = PurOrderFactory.getRemoteInstance();
第二个:PurOrderInfo
- 对于值对象,都从 BillBaseInfo 继承,其中 BillBaseInfo 包含单据基本信息所需要的属性,PurOrderInfo 类添加了对于特定的实体对象的属性 。
第三个:PurOrderFactory
- 作为辅助工具类(helper)屏蔽后台屏蔽后台操作,提供静态方法,方便用户创建 IPurOrder 接口,该类继承自Object:
常用创建方法:
PurOrderFactory.getRemoteInstance();
PurOrderFactory.getLocalInstance();
以上方法均返回接口 IPurOrder,通过该接口可以创建、更新、删除、查询‘采购订单’实体对象的值对象‘PurOrderInfo’。
第四个:PurOrderControllerBean
- 作为‘采购订单’实现类:专注于业务逻辑的实现。
第五个:PurOrderEditUI、PurOrderListUI用户界面类,包含客户端的业务逻辑控制代码
其它: Abstract*
- 对应同格式类名的抽象类,在每次发布的时候会重新生成。
开发修改java代码一般只需要修改这三个java文件的代码:*EditUI.java、*ListUI.java、ControllerBean.java。确切的说我们需要修改的java类主要包括ControllerBean,*EidteUI,*ListUI 结尾的非抽象类。
代码调用过程
在采购订单例子中,例如新增一条‘采购订单’信息,
Step1:用户打开‘采购订单编辑界面’(系统调用 PurOrderEditUI.class)
Step2:录入相关信息
Step3:保存,PurOrderEditUI先进行合法性校验
Step4:调用 PurOrderEditUI的storeFields方法将值填入 editData
Step5:应用框架调用 PurOrderFactory类创建 IPurOrder 接口
Step6:应用框架调用 IPurOrder接口以editData 值对象为参数调用addNew远程方法
Step7:应用框架调用PurOrderControllerBean的addNew方法,完成新增操作
代码结构-常用扩展点
服务端常用扩扩展点:
addnew:新增数据时调用
delete:删除数据时调用
save:保存数据时调用
submit:设置业务数据生效,并保存时调用
getValue:获取业务数据时调用
passAudit:审核通过时调用
客户端常见扩扩展点:
loadFields:将业务数据装载到控件
delete:删除数据时调用
submit:提交业务数据时调用
afterActionPerformed:在每个Action动作之后调用
beforeActionPerformed:在每个Action动作之前调用
storeFields:从控件中获得最新的业务数据
applyDefaultValue:设置默认值到数据对象
afterSelectLine:在选中分录行后调用
checkSelected:判断是否选中行
getSelectedKeyValue:获取选中行的ID
initDefaultFilter:设置默认条件
refresh:刷新表格数据
refreshList:序事薄刷新
代码结构-常用代码
- 设置是否在调入列表界面之前先出过滤框
protected boolean initDefaultFilter()
{
return true;
}
- 客户端环境工具类
com.kingdee.eas.common.client.SysContext ;
静态存储用户当前登录信息,登录的当前组织信息(ContextUtil在服务端使用)
- 获得当前用户的环境变量
Context ctx = SysContext.getSysContext();
- 获得当前财务组织,其他组织如:销售等也可从环境变量中取得
SysContext.getSysContext().getCurrentFIUnit();
- 取得用户信息:
SysContext.getSysContext().getCurrentUserInfo() ;
- SysUtil.abort()
停止当前UI的所有操作,或终止服务端方法。
4.接口方法的访问方式
- 客户端访问
CurrencyInfo cur = new CurrencyInfo();
ICurrency c = CurrencyFactory.getRemoteInstance();//建立实体对象
c. getCurrencyCollection();
- 服务端访问
CurrencyInfo cur = new CurrencyInfo();
ICurrency c = CurrencyFactory. getLocalInstance (ctx);//建立实体对象
c. getCurrencyCollection();
- 监听
this.promtF7.addChangeListener(new javax.swing.event.ChangeListener() {
public void stateChanged(javax.swing.event.ChangeEvent e) {
try {
myStateChanged(e);
} catch (Exception exc) {
handUIException(exc);
} finally {
}
}
});
- 消息提示框
com.kingdee.eas.util.client.MsgBox
该工具类拥有多个方法,根据不同的需要调用方法,只能在客户端使用。
- 消息提示框例子:




BOS Studio-动手实践
采购申请单:
通过代码实现新增申请单“申请状态”的默认值设为制表。
添加审核功能,为列表界面添加审核功能按钮,将申请单的“申请状态”设为“下达”。

七、基础业务服务
编码
- 业务单据都需要一个具有数字含义,同时参杂着重要信息的编号,作为单据的唯一的、有意义的标识,这个标识符,就是编码。
编码规则
- 如何在应用系统中,有效的管理、控制和应用这些编码?我们需要统一的编码生成策略并进行管理,这个编码生成策略,称作编码规则。
编码规则-主要属性
固定值:
标识编码业务对象的含义,可以由用户按自己的设计要求,定义固定值的具体内容:
通常为英文缩写或中文缩写,
例如:借款单-20051115-001
LRB-20051115-001
属性值:
- 用户可以将当前业务对象的属性参与编码。
系统日期:
- 用户可以将当前的时间加入到编码中,而且我们可以提供各种不同的时间格式供用户选择。
系统属性:
- 用户可以将当前系统属性加入到编码中,例如创建时间,修改时间。
顺序号:
- 由数字组成,如001,002,003等,顺序号不会重复。
初始值:
- 顺序号起始的数值
步长:
- 业务对象递增编码的顺序号之差
例如:对于客户编码,初始值为100,步长为10,对于第一个客户编码为Coding00000100,那么第二个客户编码为Coding00000110。
注意:一般用于编码规则的尾段,目的是为了对应用规则的对象进行计数和相关排序。
校验码:
- 检查编码是否存在分隔符以及编码长度是否符合要求。分9+1和EAN13两种验证码,主要是用来验证长度,而且检验码必须放在分录的最后一行。
集团优先:
- 集团内任何一个组织设定的编码规则均可以被集团内所有组织应用。
多组织优先:
- 指定的组织(可以指派多个)均可以使用当前规则。
组织优先:
- 指定的组织均可以使用当前规则。
编码规则-断号与新增显示
新增显示、不允许断号、新增显示且不允许断号
新增显示: 即单据新增时即产生编码,这样的方式不能用在不允许断号的场景,因为新增一个单据时就取了号,用户很可能不会保存这么一个单据,那这个取到号就会丢失,就会产生断号。
不允许断号: 不允许断号的应用场景就是要求断号约束的编码规则,要满足这种需求,必须在单据保存的时候才去取编码,这样才能保证的不丢失编码,另外,在单据删除时,发现当前启用的编码规则是不允许断号的时候,必须显式的调用编码规则的回收接口来回收当前的这个编码,以备下一次取编码的时候使用。
新增显示且不允许断号:
编码规则-流程图

编码规则-编码生成

编码规则-相关的扩展属性:
codingRuleEnable:实体类是否使用编码规则生成编码。
CRNumberEdit:实体类使用编码规则生成编码后是否允许修改。
CRDHMaintain:实体类是否使用编码规则断号维护功能。
CRNumberAddView:实体类使用编码规则生成编码后是否在界面显示。
CRDHRefuse:实体类使用编码规则生成编码是否不允许断号。
CRAddNoBreak:实体类使用编码规则既在界面显示且不允许断号。
isInCode:属性是否可用于编码规则中参与编码。
isBindingProperty:属性是否编码规则过滤条件。
编码规则相关开发接口






编码规则接口调用
//获取编号
ICodingRuleManager iCodingRuleManager = null;
iCodingRuleManager = CodingRuleManagerFactory.getRemoteInstance();
//判断规则是否存在
iCodingRuleManager.isExist(billInfo, companyID);
//是否启用断号支持
iCodingRuleManager.isUseIntermitNumber(billInfo, companyID);
//读取当前最新编码
String sysNumber = iCodingRuleManager.readNumber(billInfo, companyID);
//没有启用断号支持功能,则获取编码规则产生的编码
String sysNumber = iCodingRuleManager.getNumber(billInfo, companyID);
BOTP概述
BOTP名称
- BOTP(Business Object Translate Platform),业务对象转换平台。是为了解决单据和单据之间的数据转换的问题,通过参数配置的方式,让这种转换规则不再是一种固化的规则,而是可以灵活调配的
BOTP原理
- 基于元数据模型的对象转换引擎,提供单据间的自动转换
BOTP职责
通过统一的平台处理多种转换关系
实现企业应用中的单据转换的可配置
BOTP:属性映射(3种方式)

直接映射:目标对象属性对应源对象属性
缺省值:目标对象属性对应默认值
公式计算:目标对象属性对应运算结果
BOTP:分组与合并

BOTP:反写

BOTP:核销反写

功能讲解
单据的转换方式
推式生成
由源单据生成成目标单据
分为两种方式:推式生成和关联生成
在单据编辑界面叫做推式生成,列表界面叫做关联生成
关联生成时可选择一条单据,也可选择多条
拉式生成
在目标单据上从源单据“拉”数据生成目标单据
必须是新建的空目标单据才能拉式生成
功能详解—单据转换方式

BOTP扩展点
实体中与BOTP相关的扩展属性:
isForMapping:是否映射属性,单据/单据分录实体中需要参与BOTP映射的属性(作为目标单据)
isForMatching:是否核销属性,单据/单据分录实体中需要参与BOTP核销的属性(作为目标单据)
IsBOTPMustInput:用来做BOTP必录项设置
ISACCTCUSSENT:(是否往来户ID)单据/单据分录实体中作为往来帐id的属性(作为源单据)
isForGrouping:是否分组属性,单据/单据分录实体中需要参与BOTP分组合并的属性(作为目标单据)
isForWrittenBack:是否反写属性,单据/单据分录实体中需要参与BOTP反写的属性(作为源单据)
判断是否已生成凭证
- EAS 6.1及以后版本还可以通过以下接口方法判断,IDAPTransformer类中提供了以下接口方法查询单据是否已生成凭证:
public boolean isHaveVoucher(String srcBillId, String companyOrgId) throws BOSException;
其中参数srcBillId为单据单据; 参数companyOrgId用于指定组织ID, 为空表示单账簿;返回值为boolean型, true表示已生成凭证, false表示未生成;
转换前回调接口:
- BOTP单据转换开始前会调用CoreBillListUI类的以下接口,业务开发可根据需要重载:
//在下推生成时,要求在转换前业务单据能够加上适当的校验,内容有具体单据单据填//充,框架不做处理;
public void beforeTransform(IObjectCollection srcObjCols, String destBillBosType)
{
}
转换后回调接口:
- BOTP在单据转换完成,单据保存、提交、显示前都会调用CoreBillBaseControllerBean类的以下接口, 业务开发可根据需要重载:
//单据转换后回调接口,业务开发可根据需要重载
protected void _handleAfterTransform(Context ctx, String action, IObjectCollection collection) throws BOSException, EASBizException
{
}
权限系统
BOS权限系统是基于用户、角色、组织、权限的思维权限模型,能够控制系统的功能、数据、属性各个维度,包括以下一些方面:
1.权限项元数据: 是所需要控制的功能的元数据模型,由开发人员在开发期间创建,元数据中可绑定界面操作功能、服务端方法、查询(query),部署时系统会将元数据信息同步到数据库中。
2.功能权限: 功能权限控制用户能做什么操作,BOS权限系统的权限和组织相关。
3.普通数据权限: 数据权限可以控制用户可以操作哪些数据记录,可以通过定义授权规则,限制用户拥有操作哪些数据的权限,这是一种纵向的数据控制。
4.字段权限: 字段权限控制用户可以操作哪些字段。
5.特殊数据权限: 业务操作中经常有这样的需求:用户只能对自己创建的单据进行操作,或用户只能对自己主管的部门的单据进行操作,这种规则是动态的,不能用普通的数据权限进行配置,由此产生了特殊数据权限
八、二次开发案例
案例-扩展类开发
业务场景: 很多业务场景下,需要我们对标准产品的单据进行二次开发。这时候我们就需要使用扩展类开发,
服务端扩展相关步骤:
- 1、用文本编辑器打开实体元数据PayRequestBill.entity,增加一扩展属性
<rs key="entityObject[com.kingdee.eas.fi.ap.app.PayRequestBill].extendedProperty.controllerBeanEx">
<lang locale="zh_CN" value="com.kingdee.eas.fi.ap.app.PayRequestBillControllerBeanEx" />
<lang locale="zh_TW" value="com.kingdee.eas.fi.ap.app.PayRequestBillControllerBeanEx" />
<lang locale="en_US" value="com.kingdee.eas.fi.ap.app.PayRequestBillControllerBeanEx" />
</rs>
2、切换到java视图,创建XXXControllerBeanEx类继承XXXControllerBean类。
3、在XXXControllerBeanEx中覆盖对应的方法即可。
客户端扩展相关步骤:
对于客户端的UI类,无论是listUI,还是EditUI,都可以在通过追加后缀名CTEx的方式来扩展。
如要重写标准产品采购订单的保存方法:
com.kingdee.eas.fi.ap.client.PayRequestBillEditUI,在实际二次开发中,发布之后只会生成 com.kingdee.eas.fi.ap.client.AbstractPayRequestBillEditUI ,
如果要重写保存的方法,则可以在com.kingdee.eas.fi.ap.client包下新建PayRequestBillEditUICTEx,此类继PayRequestBillEditUI类即可,然后在PayRequestBillEditUICTEx重写保存方法

案例-修改F7 字段所关联的对象
业务场景:
在一般情况下,在BIM 视图对单据新增F7 字段时,就可以关联到想要的基础档案或其它视图。但是,当需要关联一些不存在业务单元(即*.bizunit 文件)的基础档案时(如:自定义核算项目), BIM 视图无法直接完成其新增,这时可通过修改F7 字段所关联对象的方法实现。
相关操作步骤:
在BIM 里加一个F7 字段,关联物料或其他可以选到的基础资料。保存后先别发布;
切换到BOS 透视图,打到对应的.relation 文件,修改supplierEntity,原来是指定物料的实体,改成自定义核算项目的实体;
打开XXXEditUI.ui,修改F7 字段的queryInfo,fieldType,[displayFormat],原来是指向物料的query、Info、字段,改成自定义核算项目的query、Info、字段 。
案例-通过BOSTYPE生成对象ID
业务场景:
某些场景下需要后台代码构建一个完整的info对象,或者想通过SQL语句把数据导入到数据库中。 ID为info对象中非常重要的属性,需严格根据EAS的规则构建,随意定义可能会造成各种错误,ID需要通过EAS提供的方法生成。
相关生成方法:
1.使用数据库中的newbosid(BOSTYPE)方法。
2.使用后台BOSUui的create(BOSTYPE)方法。
对象对应的BOSTYPE可打开其*.entity实体文件找到其中<BOSTYPE>标签,或者在数据库中的T_SYS_EntityRef表中找到对应的BOSTYPE。
案例-不同类型的id相互转化
业务场景:
EAS系统中的id有String,BOSUuid和IObjectPK这些类型,大多数业务场景下,开发人员获取到的id类型是有限的,需要进行对其进行类型转化。
相关转换方法:
(1) BOSUuid –> IObjectPK:IObjectPK pk = new ObjectUuidPK(uuid);
(2) IObjectPK –> BOSUuid:BOSUuid.read(pk.toString());
(3) BOSUuid和IObjectPK –> String:uuid.toString()和pk.toString();
(4) String –> BOSUuid和IObjectPK: BOSUuid.read(id); IObjectPK pk = new ObjectUuidPK(BOSUuid.read(id));
BOSUuid 与ObjectUuidPK 的区别: BOSUuid表示数据库分录ID,可以理解为数据库行ID, 数据库行对应一个java对象,所以就用ObjectUuidPK表示java对象的ID. 本质上,两者是一致的。只是在理解的角度不一样,一个从数据库的角度,一个从java对象的角度
案例-数据库工具用法
业务场景:
某些业务场景下我们需要对数据库进行直接的增、删、改、查操作,这时我们就需要用到相关的数据库工具。
- DbUtil用法:
com.kingdee.eas.util.app.DbUtil
(1)查询操作
StringBuffer sql = new StringBuffer();
sql.append("select fid from t_cas_ztdemo");
//返回结果集,结果集的取值和JAVA ResultSet 相同
IRowSet rowSet = DbUtil.executeQuery(ctx, sql.toString());
(2)增加、删除、修改操作调用
DbUtil. Execute().
2. IFMIsqlFacade用法:
com.kingdee.eas.fm.common.IFMIsqlFacade;
//客户端
IFMIsqlFacade fMIsqlFacade = FMIsqlFacadeFactory.getRemoteInstance();
//服务端
IFMIsqlFacade fMIsqlFacade = FMIsqlFacadeFactory.getLocalInstance(ctx);
StringBuffer sql = new StringBuffer();
sb.append(" select a.fid from T_BD_Acct_Contorl a");
sb.append(" inner join t_org_company c on a.FDestCompanyID = c.fid");
sb.append(" where a.FAccountTableID = ? ");
//其中 new Object[] {传递的参数,可以是多个用逗号分开}
IRowSet rs = fMIsqlFacade.executeQuery(sb.toString(),
new Object[] {accountTableId});
案例-显示BOTP规则选择界面
业务场景:
不同的业务场景的需求也各不相同, 当符合条件的已启用规则有多个时,某些场景下需要弹出转换规则选择界面, 而某些场景则希望不弹出此界面; BOTP引擎提供了选项允许业务开发根据需要自行决定是否弹出界面。
在BOS基类中 CoreBillListUI 和 CoreBillEditUI 提供了以下接口:
public boolean isNeedShowBOTPRule()
{
return false;
}
BOTP引擎会根据此方法的返回值来决定是否弹出规则选择界面, 默认值为 false , 表示不弹出界面; 而如果业务开发希望弹出界面的话, 需要重载此方法并修改返回值为 true;
如果转换规则只有一条时, 默认不弹出规则选择界面;
如果转换规则有多条且设置为不弹出界面时, 默认选择第一条转换规则;
如果转换规则有多条且设置为弹出界面时, 系统弹出规则选择界面, 并根据用户选择的规则进行转换;
案例-判断当前UI是否为BOTP打开
业务场景:
某些场景下业务开发需要根据当前UI是否为BOTP打开来做不同的逻辑处理。
具体可以通过定义在基类的以下接口来判断:
protected final int getBOTPViewStatus()
{
}
返回值为0表示正常打开UI, 值为1表示当前UI为BOTP打开。
案例- BOTP自定义公式
业务场景:
运行时BOTP的公式平台提供的函数较少,如果要实现比较复杂的逻辑,譬如通过物料编码从其他单据取出对应数量,运行时的公式平台就显得捉襟见肘了。对于客户开发的单据,可以通过写代码实现。但是对于标准产品的单据,如果反编译代码,则升级时相当麻烦。而自定义公式方案正是为了解决此难题而生。它可以通过写代码在BOTP公式平台挂上自定义的公式,公式内容由程序员自由决定,而不会受升级影响。
相关步骤:
1.在BOS自定义一个公式类,实现 com.kingdee.bos.service.formula.api.IFormulaFunctions 接口。
2.在BOTP目标单据的实体(entity)上加扩展属性“billFormulaClass”,属性值设为第1步创建的类的全名(含包名)。
几个要实现的方法:
//返回所有公式的名称的
public String[] getAllFuncNames()
//返回公式的所在分类,参数为公式名称
public String getFuncCategory(String name)
//返回公式描述,参数为公式名称
public String getFuncDesc(String name)
//返回公式是否存在,参数为公式名称
public boolean existFunction(String name)
//返回公式运行结果,参数为公式名称、参数list
public Object evalFunction(String func, List paramList)
相关自定义公式的定义,也可以参见BotpFormulaFunctions类
案例-编码规则运用到其它字段
业务场景:
编码规则默认支持的字段为编码(number),某些场景下业务开发我们需要编码之外的字段使用编码规则,例如名称字段、批号批次字段、出货号等等字段都可能需要采用一定的规则产生编码。这时我们可以通过相关配置,将编码规则运用到对应字段。
相关步骤:
- 1.修改配置文件 codingruleadape.prperties 。此配置文件路径:
bs_codingrule-client.jar \com \kingdee\eas\base\ codingrule\util以及bs_codingrule- server.jar \com\kingdee\eas\ base\ codingrule\util中。
- 2.配置文件中需要配置对应的业务单据实体元数据的bostype,以及对应的实现类全路径,如:
FF66566A =com.kingdee.eas.base.codingrule.util.testBotp;
- 实现ICodingRuleAdapt接口类的getAdaptItemList方法
实现类参考:
public class TestBotp implements ICodingRuleAdapt {
public List getAdaptItemList() {
AdaptItem item = new AdaptItem();
item.setNumber(“name");
item.setName_l2(“简体名称");
item.setName_l3(“繁体名称");
List list = new ArrayList();
list.add(item);
return list;
}
}
业务组建在getNumber和readNumber时需要传入ParmCodingRule参数对象,获取自定义字段编码。 可参考以下代码
ParmCodingRule pcr = new ParmCodingRule();
pcr.setCustomProperty("name"); this.kDLabel5.setText(CodingRuleManagerFactory.getRemoteInstance().getNumber(info,org,pcr));
案例-界面之间传递参数
业务场景:
某些场景下业务开发我们需要将某个界面的信息传递到下一个界面,如根据当前界面申请人的信息传递到下个界面,初始化下一个界面上申请人的字段信息。这就涉及到界面之间的参数传递。
相关步骤:
- 1.父界面定义传递的参数
HashMap map = new HashMap();
map.put(String key, Object object);
IUIFactory uiFactory= UIFactory.createUIFactory(String path);
IUIWindow uiWindow = uiFactory.create(String UI,map);
uiWindow.show();
- 2.子界面接收参数
this.getUIContext().get(String key)
参考代码:
- 1.父界面要传递给子界面的信息定义
HashMap map = new HashMap();
String note=“我的传递信息”;
map.put(“Owner”, this);//必须,被启动UI的父UI对象
map.put(“myNote”, note);
IUIFactory uiFactory= UIFactory. createUIFactory("com.kingdee.eas.base.uiframe.client.UIModelDialogFactory");
IUIWindow uiWindow = uiFactory.create(com.kingdee.eas.basedata.master.auxacct.client.AccountSelectUI“,map);
uiWindow.show();
- 2.子界面获取传递数据
private void loadContext()
{
String getnote=this.getUIContext().get(“myNote ")).StringValue();
AuxAccountEditUI ui = (AuxAccountEditUI) this.getUIContext().get("Owner");
}
案例-后台发送消息的代码
业务场景:
某些场景下业务开发我们需要在进行某些操作之后能给用户发送相应的消息。例如某用户创建的单据被修改或者被删除后,给该用户发送相应的消息。这时我们就可以通过后台代码实现发送消息的功能。
相关代码:
SenderAgent sender = SenderAgent.getSenderAgent(); //发送类
Message message = MessageFactory.newMessage(String type); //生成消息对象message.setLocaleStringHeader(“title”, “标题”, locale) //设置消息标题
message.setLocaleStringHeader(“sender”, “发送人”, locale) //设置发送人String
message.setLocaleStringHeader(“body”, “消息内容”, locale)//设置消息内容
message.setIntHeader("type", MsgType.NOTICE_VALUE);//设置消息类型为通知
message.setIntHeader(“bizType”, MsgBizType.FORWARN_VALUE);//业务类型message.setIntHeader(“sourceStatus”, MsgSourceStatus.EMPTY_VALUE);//任务状态
message.setIntHeader("priority", MsgPriority.MIDDLE_VALUE);//设置消息优先级message.setStringHeader("databaseCenter", ctx.getAIS());//得到数据中心
message.setStringHeader("solution", ctx.getSolution());//设置解决方案
message.setStringHeader("receiver",remindPersonId);//设置接收用户ID
sender.sendMessage(message);//发送消息
案例- webservice接口开发
**接口开发相关步骤 : **
一.建立Facade以及相应的方法
二.在BOS Studio中选择Façade发布WebService
发布成功以后,在临时目录里会生成一个wsdd文件和一个目录,例如:
文件拷贝到解决方案src目录中,注意包名和路径一致;MyFacade.wsdd处理方法如下:
- 找到解决方案的runtime\server\deploy\eas.ear目录,用解压缩软件打开web.war,进入WEB-INF目录
把MyFacade.wsdd添加进去;
- 把MyFacade.wsdd文件里的service节点内容添加到server-config.wsdd文件。操作方法建议:提取server-config.wsdd文件到临时目录,用UltraEdit打开,再打开MyFacade.wsdd,拷贝service节点内容粘贴到server-config.wsdd文件,注意XML格式一致;保存server-config.wsdd文件并拷回到web.war压缩包里。
三.部署到正式服务器
1、在BIM中部署代码和元数据;
2、把解决方案下改好的runtime\server\deploy\eas.ear\web.war文件拷贝到EAS服务器的server\deploy\eas.ear目录中,
3.将生成的Web Service的java代码编译为class,放在EAS服务器的eas\server\deploy\eas.ear\web.war\WEB-INF\class下,把发布的wsdd文件中服务部分拷贝到server-config.wsdd中。
4.重启 EAS服务器
四.验证
打开浏览器,输入地址:http://server-ip:port/ormrpc/services,应该可以看到新建的Webservice,右键点击相应的wsdl,选择另存为…,扩展名改为wsdl,就可以下载客户端开发使用的wsdl文件。
客户端调用相关步骤:
新建java项目,
把下载的wsdl文件拷贝到项目中
右键点击,选择:Web Services—>Generate Client,产生客户端代理类。
使用EAS的WebService之前,必须先通过EASLogin Web服务登录(运行EAS登录接口),否则会产生认证错误。EASLogin里有两个login方法,只调用参数如下的login:
String userName //EAS登录用户名,可以是user或其他有效的用户名
String password //EAS用户登录密码
String slnName //eas
String dcName //注册的数据中心名称
String language //登录的语言
Int32 dbType //数据类型,0:MSSQL,1:ORACLE
客户端代码示例:
public class wstest {
public static void main(String[] args){
try {
//通过WebService登录EAS
EASLoginProxyServiceLocator loginLocator = new EASLoginProxyServiceLocator();
EASLoginProxy loginProxy = loginLocator.getEASLogin();
WSContext context = loginProxy.login(“user”, “”, “eas", "001", "L2", 0);
//调用getBasedata接口
WSMyFacadeSrvProxyServiceLocator accountLocator = new WSMyFacadeSrvProxyServiceLocator();
WSMyFacadeSrvProxy accountProxy = accountLocator.getWSMyFacade();
String result = accountProxy.getBasedata(null);
System.out.println(result);
} catch (ServiceException e) {
e.printStackTrace();
} catch (RemoteException e) {}
分割线
相关信息
以上就是我关于 BOS开发平台功能和基础业务详介 知识点整理与总结的全部内容,希望对你有帮助。。。。。。。