NC二次开发概述.docx
《NC二次开发概述.docx》由会员分享,可在线阅读,更多相关《NC二次开发概述.docx(248页珍藏版)》请在冰豆网上搜索。
NC二次开发概述
导论
我和你一样曾经对NC一无所知,因为选择了这个工作,所以我决心要做好它。
学习一个新的东西总要走不少弯路,学习有时候会很枯燥,让你对它的热情降低,你要不时的看看别的东西来调节下自己的口味。
要学的东西很多,如何才能印象深刻呢,你要去理解,抓住事物的本质,在一个更高的层次上去看待。
理解就像一个压缩工具可以将知识压缩占用更少的大脑空间,这样你就会长期保持一种愉悦的心情。
本文将带您进入NC的世界,你不要害怕,你完全有能力掌握它。
首先我要提以下几个问题:
1、如何搭建NC开发环境
2、NC的UI的核心是什么?
3、如何在NC中开发应用
读完本文你将会对你的工作更有信心。
综述
本文以ncv55版本讲述nc-uap平台二次开发全过程,包括以下内容:
开发环境搭建、功能节点注册、权限分配、单据开发以及单据UI架构
知识必备
NC-UAP平台是架构在J2EE平台上,UI界面均为Swing组件,采用oracle、sqlserver、db2(oracle数据库在应用中非常常用)这3种数据库作为后台存储。
因此在学习NC之前应该具备以下知识。
1、java编程语言基础
2、了解Swing组件构建界面
3、了解oracle的安装,创建用户,表空间,以及基本的sql语法。
4、学习eclipse集成开发平台的使用
开发环境搭建
Eclipse3.2,v55的nchome,v55的eclipse插件,oracle10g数据库
MDE配置
将v55的eclipse插件放入plugins目录下,启动eclipse
查看【首选项】,如下图,左边会出现我们需要的MDE选项,右边需要配置nchome和数据库的相关信息
Java运行环境配置
配置成nchome自带的,位于nchome的ufjdk目录
需要导入tools.jar和plugin.jar两个包
数据库安装
请参看《UFIDANC5.5安装指南.htm》
新建项目
这些都配置完后,新建MDE项目,会出现如下的目录结构
client目录存放前台类;private目录里存放后台类;public里存放公共的类,供前后台使用
启动项目
第一次启动项目,右键选择项目,以调试的方式启动NCMiddleware(NC中间件),中间件启动完成后再启动NCClient。
以后启动直接可以从快捷菜单,如下图
平台配置及升级
项目启动后,登录界面如下
以root用户登录,密码为空
新建帐套
新建一个帐套,关联一个数据源,并设置管理员。
一个帐套只能对应一个数据源,我们可以建多个帐套,以不同的帐套登录系统相当于对应了不同的数据库。
帐套升级
如下图,选择待安装的产品,进行数据库安装,【客户化】是必须安装的,里面带有二次开发需要的节点。
登录系统
选择新建的帐套,以管理员身份登录系统
新建用户
建立一个新用户,以后以此用户登录系统。
如下图
注册新模块
注册一个新的模块需要在表sm_codetocode插入一条记录
dispcode
dr
funccode
isleaf
moduletype
pk_codetocode
subfunccode
ts
HL
0
HL
N
1
ET
HLH1,HLH3
在新建公司账的时候,系统会读取此处的数据
新建公司
定义集团本位币
新建公司账
配置模块名显示为中文
Nchome/langlib下增加一个et_sim_langres.jar文件,采用ZIP压缩
et_sim_langres.jar文件目录结构为\lang\simpchn\funcode,位于funcode的目录下
有一个属性文件HL.properties(HL为功能节点),内容如下:
DHL=进出口管理
对于V502的nchome,
该属性文件放置的位置为nchome\resources\lang\simpchn\funcode\
注册功能节点
权限分配
NC的权限管理是基于角色的,首先建立角色,对角色分配权限,然后将角色再分配给用户,那么用户就拥有了角色对应的权限,详细内容请参看红皮书。
单据开发
概述
NC-UAP平台UI的核心内容是单据,单据泛指所有能表示为主子表关系的数据模型对应为关系数据库的主子表关系,在NC系统里每个单据都有一个单据类型来标识单据的唯一性。
最终系统通过该单据类型加载定义的单据模板来实现加载界面。
从业务上来看,NC中有两类单据,一类称作基本档案,一类称作业务单据(通常也叫单据),这两类单据的动作在系统中的实现是不一样的,注意后续介绍。
以下内容将简单的介绍如何开发单据界面。
功能注册
注册所有的可功能节点,包括虚功能节点,可执行功能节点。
【对应文件名或控件名】:
可执行功能节点时需注册,对应于单据的ui类名
系统类型定义
【模块名】:
对应nchome/modules下面的一个目录名
【相关节点编码】:
对应于【功能注册】的节点编码
【是否发送会计平台】:
系统里存在单据需要生成凭证,此字段需打钩
单据类型定义
【单据类型编码】:
4位字符(varchar(4))
【参照查询对应的后台类】:
在开发流程时使用
【审批流检查类】:
有审批时需要。
可设置为HYSuperDMO,需加包名
单据模板定义
可以手工的一个个字段增加到单据模板,也可以通过powerdesigner工具先设计表再导入表,然后生成单据模板。
PDM设计
字段命名规范
描述
命名
数据库类型
NC数据对象
备注
主键字段
pk开头或者c开头
char(20)
String
日期类型
d开头
char(10)
UFDate
逻辑类型
b开头
char
(1)
UFBoolean
整数/下拉
i开头
Integer/smallint
Integer
数值型
n开头
decimal(20,8)
UFDouble
一般字符
v开头
varchar(100)
String
编码字段
v开头
varchar(30)
String
名称字段
v开头
varchar(100)
String
备注字段
v开头
varchar(256)
String
常用字段命名参看类:
BillField
该类里面的常用字段并没有按照上述规范命名,如果基于标准的UAP开发,我们只好遵循历史的字段命名,如果基于BUAP开发,我们可以按照新的命名规范,查看HLBillField类
描述
命名
数据库类型
NC数据对象
备注
公司
pk_corp
Char(4)
String
一般单据
单据号
vbillno
Varchar(30)
String
一般单据
单据类型
pk_billtype
Varchar(4)
String
一般单据
单据日期
dbilldate
Char(10)
UFDate
一般单据
制单日期
dmakedate
Char(10)
UFDate
一般单据
制单人
voperatorid
Char(20)
String
一般单据
审批人
vapproveid
Varchar(30)
String
审批流需要
审批日期
dapprovedate
Char(10)
UFDate
审批流需要
审批批语
vapprovenote
Varchar(256)
String
审批流需要
单据状态
vbillstatus
smallint
Integer
审批流需要
业务类型
pk_busitype
Char(20)
String
流程需要
上层单据类型
vlastbilltype
Varchar(4)
String
流程需要
上层单据号
vlastbillcode
Varchar(30)
String
流程需要
上层单据行ID
vlastbillrowid
Varchar(30)
String
流程需要
上层单据ID
vlastbillid
Varchar(30)
String
流程需要
上层单据行号
vlastbillrowno
Varchar(30)
String
流程需要
源头单据类型
vsourcebilltype
Varchar(4)
String
流程需要
源头单据号
vsourcebillcode
Varchar(30)
String
流程需要
源头单据行ID
vsourcebillrowid
Varchar(30)
String
流程需要
源头单据ID
vsourcebillid
Varchar(30)
String
流程需要
源头单据行号
vsourcebillrowno
Varchar(30)
String
流程需要
PDM使用
按照powerdesigner软件后打开,新建一个physicaldatamodel
选择面板上的表格,然后点击在空白的地方
双击打开,录入数据库表名称、编码和字段
General页签
Columns页签,录入表的列,表的主键需要打上后面的勾
Preview页签,查看建表脚本
PDM插件自动生成TS、DR字段
ts、dr字段是NC表结构里必须的字段。
ts标识数据的产生时间,由数据库自动生成(ts在数据的一致性校验起着至关重要的作用),dr字段标识数据是否逻辑删除,当dr=1时表明数据是删除状态的,当dr=0或者为空时,表示数据是有效的。
在做数据库设计时,我们不需要在Columns页签里设计ts,dr字段,我们只需要给powerdesigner打上自动生成ts,dr的补丁即可。
导入PDM
Pdm设计好了后,我们需要将它导入到NC平台,v5系列的平台只支持sqlserver7.x类型的pdm的导入。
所有我们需要切换下pdm的数据库
选择sqlserver7.x确定,然后保存pdm即可
增加单据模板
增加后
增加查询模板
可以在单据模板初始化界面,模板操作菜单下生成查询模板,然后去查询模板初始化节点找出来进行相关修改,也可以直接在查询模板初始化节点增加。
查询模板是通过节点号来对应到具体的功能节点的。
NC默认的查询,查询条件只支持表头条件。
在查询模板初始化节点可查询到生成的查询模板
查询条件的取值可以使用系统函数,带有#value#的为系统函数,列表如下:
系统函数名称 描述
Sys_Account 会计期间
Sys_Year 当前年份
Sys_Month 当前月份
Sys_Date 当前日期
Sys_Operator 当前操作员
Sys_department 当前部门
Sys_CurrCorp 当前公司
Sys_daysBefore_i 当前日期前i天
Sys_monthsBefore_i 当前月前i月
Sys_DeptWithChild 当前部门及其下级门
设置默认模板
对于单据模板,查询版,报表模板,打印模板,需要在此节点进行相应的分配
点击分配按钮
选择查询模板
点击添加
选择相应的节点,选择【默认模板】,选择【模板】然后确认。
最后保存
管理型单据开发示例
开发一个单据,除了单据模板,查询模板的基本配置,需要开发的最基本的类只需要3个,分别是,控制类,事件处理类,界面UI类。
但是实际的业务中可能还需要有相关的数据校验,所以就有了前台校验类、后台校验类。
以下是开发主子(非多子表)管理型单据,包含了实际的业务处理
管理型单据列表界面
管理型单据卡片界面
UI端的类:
前台校验类:
CheckUI,需要在单据类型节点的自定义项3上配置类全名
控制类:
ClientCtrl
事件处理类:
ClientEH
界面UI类:
ClientUI
这4个类UAP平台都给我们提供了相应的基类去继承,具体查看《UI工厂》
ClientCtrl类配置
卡片界面按钮
默认的系统按钮都是定义在IBillButton接口
列表界面按钮
单据类型
这里的单据类型是定义在常量接口里的,统一管理
单据VO类数组
如果是业务单据(单据是用来录入日常业务数据的)需要配置业务动作类型
业务动作类型定义在接口IBusinessActionType
PLATFORM:
平台类型,需要动作脚本(需要另外的java类,针对保存、删除、查询、审批、弃审等按钮的动作)
BD:
基本档案类型,不需要动作脚本
如果当前单据需要审批(即单据走审批流),则就存在一个单据状态。
存在单据状态返回true,不存在返回false
ClientEH类配置
如果没有自定义事件处理,暂时不需要做任何配置,只需继承父类即可
ClientUI类配置
关联事件处理类
关联控制类
BS端的类
如果单据动作是平台类型的,一些基本的事件东西需要动作脚本
单据动作配置
保存:
WRITE
删除:
DELETE
修改:
EDIT
提交:
SAVE
审批:
APPROVE
弃审:
UNAPPROVE
动作执行脚本
单据动作脚本通过平台编译,生成的类在模块下的META-INF目录里子目录可以找到,把生成的类Copy放置在eclipse环境下的private的nc.bs.pub.action包中
保存:
WRITE
ObjectretObj=null;
//####重要说明:
生成的业务组件方法尽量不要进行修改####
//方法说明:
公共保存方法
retObj=runClassCom@"save.BillSave","saveBill","nc.vo.pub.AggregatedValueObject:
01"@;
//##################################################
returnretObj;
删除:
DELETE
//####本脚本必须含有返回值,返回DLG和PNL的组件不允许有返回值####
ObjectretObj=null;
//方法说明:
行业公共删除
retObj=runClassCom@"delete.BillDelete","deleteBill","nc.vo.pub.AggregatedValueObject:
01"@;
//##################################################
returnretObj;
修改:
EDIT
//####本脚本必须含有返回值,返回DLG和PNL的组件不允许有返回值####
ObjectretObj=null;
returnnull;
提交:
SAVE
ObjectretObj=null;
//####重要说明:
生成的业务组件方法尽量不要进行修改####
//方法说明:
公共提交方法
retObj=runClassCom@"status.BillCommit","commitBill","nc.vo.pub.AggregatedValueObject:
01"@;
//##################################################
returnretObj;
审批:
APPROVE
//####该组件为单动作工作流处理开始...不能进行修改####
procActionFlow@@;
//####该组件为单动作工作流处理结束...不能进行修改####
ObjectretObj=runClassCom@"status.BillApprove","approveBill","nc.vo.pub.AggregatedValueObject:
01"@;
returnretObj;
弃审:
UNAPPROVE
//####本脚本必须含有返回值,返回DLG和PNL的组件不允许有返回值####
procUnApproveFlow(vo);
ObjectretObj=runClassCom@"status.BillUnApprove","unApproveBill","nc.vo.pub.AggregatedValueObject:
01"@;
returnretObj;
结束:
END
//####本脚本必须含有返回值,返回DLG和PNL的组件不允许有返回值####
ObjectretObj=runClassCom@"status.BillEnd","endBill","nc.vo.pub.AggregatedValueObject:
01"@;
returnretObj;
取消结束:
UNEND
//####本脚本必须含有返回值,返回DLG和PNL的组件不允许有返回值####
ObjectretObj=runClassCom@"status.BillUnEnd","unEndBill","nc.vo.pub.AggregatedValueObject:
01"@;
returnretObj;
PUB端的类
编写代码
要熟悉管理型单据的开发,管理型单据是最基础最常用的单据。
详细内容见《UI工厂.pdf》介绍。
自定义按钮
将系统按钮加入卡片界面,我们只需实现控制类的方法
publicint[]getCardButtonAry(){
returnnewint[]{
IBillButton.Save,//保存
IBillButton.Edit,//修改
IBillButton.Cancel,//取消
IBillButton.Delete//删除
}
}
事实上,每一个按钮对应这一个int型的编码,系统预置按钮的编码在100以内,它们都定义在IBillButton接口里。
那么我们自定按钮的话,按钮的编码必需大于100,并且同一个单据的自定义按钮的编码不能重复。
下面我们来实现一个自定义按钮“导入”
自定义按钮实现步骤:
步骤1、定义按钮编码接口:
publicinterfaceIDefButton{
intImport=101;
}
步骤2、定义按钮VO,可以参照系统预置按钮的VO定义做
publicclassImprotBtnVOimplementsIBillButtonVO
{
publicfinalstaticStringbtnChinaName="导入";//按钮中文名字
publicImprotBtnVO()
{
super();
}
publicnc.vo.trade.button.ButtonVOgetButtonVO()
{
ButtonVObtnVo=newButtonVO();
btnVo.setBtnNo(IDefButton.Import);//设置按钮编号
btnVo.setBtnChinaName(btnChinaName);//设置按钮中文名字(按钮权限控//制时用到)
btnVo.setBtnName(“导入”);//设置按钮的名字
btnVo.setHintStr(“导入数据”);//设置按钮提示文字
btnVo.setOperateStatus(newint[]{IBillOperate.OP_NOTEDIT,
IBillOperate.OP_INIT});//设置按钮的可操作状态,系统会根据它//来设置按钮的可用状态
btnVo.setBusinessStatus(null);//设置按钮的业务状态
btnVo.setHotKey("I");//设置快捷健
btnVo.setDisplayHotKey("(Ctrl+I)");
btnVo.setModifiers(Event.CTRL_MASK);
returnbtnVo;
}
}
步骤3、将按钮加到控制类
publicint[]getCardButtonAry(){returnnewint[]{IDefButton.Import};}
步骤4、在UI类里初始化按钮,需要覆盖下面方法
protectedvoidinitPrivateButton(){
ButtonVOimprotBtnVO=(newImprotBtnVO()).getButtonVO();
addPrivateButton(improtBtnVO);//加入私有按钮
}
上面定义的按钮只有操作状态,没有业务状态。
系统中像增加,保存等按钮都没有业务状态,这些都属于普通按钮,另外的属于业务按钮,业务按钮要定义按钮的业务状态,这个状态也就是单据的默认的8种状态。
和自定义普通按钮基本一样,只需加入私有按钮时,将addPrivateButton换成addPrivateBusinessButton即可,业务按钮是需要调用动作脚本的,单据是要走平台的,是存在单据状态的。
所以要实现按钮事件还要生成动作脚本,后两项都是在控制类里设置的。
界面数据获得与设置
对于NC系统的单据而言,数据分为两部分,一是界面数据,二是缓存数据。
界面数据和缓存数据只有在非编辑状态下才是一样的,在修改状态下,界面数据和缓存数据是脱钩的。
所以说修改状态下要获得单据数据的话,一定要从界面获
得,这样保证了数据的同步。
NC单据界面分为两种,一种是卡片界面,一种是列表界面。
这两个界面是分开的。
但是数据都是缓存在一个地方。
界面上的数据则是放在不同组件上。
所以从两种不同的界面上获得数据的方式也不一样。
如果你想了解这两种界面的布局的话,可以参看文章《加载单据模板》,该文里面画出了单据卡片、列表界面的结构图。
了解了结构图,有助于开发人员深入了解单据界面的实现。
卡片、列表界面的判断:
在UI端有方法isListPanelSelected()返回true时,说明当前界面为列表界面,返回false时,说明当前界面为卡片界面。
(1)卡片界面取值(一下都是从UI端取值,如果在事件处理端取值,首先获得UI对象):
获得表头某字段的值:
getBillCardPanel().getHeadItem(strKey).getValueObject()
//strKey为字段编码表头取值不分页签
获得表体某字段的值:
getBillCardPanel().getBodyValueAt(rowIndex,strKey)
//rowIndex为表体行索引strKey为字段编码默认为第一个页签
getBillCardPanel().getBillModel(tableCode).getValueAt(row