STUDIO生成主子孙单据开发说明

更新时间:2024-05-01 08:06:01 阅读量: 综合文库 文档下载

说明:文章内容仅供预览,部分内容可能不全。下载后的文档,内容与下面显示的完全一致。下载之前请确认下面内容是否您想要的,是否完整无缺。

主子孙单据开发说明

一.元数据设计

主子孙单据需要设计如上图的元数据模型,现在以上图元数据模型为例,叙述开发主子孙单据过程 设计主子孙元数据,实体之间的对应关系都为组合关系,这和设计主子表单据类似。只是有几点需要注意:

1. 点击主表实体(任务) 设计如下

访问策略设置为bodyOfAggVOAccess

2.点击子表实体(分摊任务接收方) 设计如下,

访问策略需要设计为PojoAccessor

2. 点击孙表实体(接收方子表)设计如下

3. 只有主表实体的类型为AggVO,子表实体和孙表实体都为NCVO

二.生成VO

点击生成Java代码,会生成如图

几个VO类,需要注意的几点,

必须在子表VO类中加上:如图的孙

表的属性,属性名字必须和单据模板对应的页签名字一样(这个是SendVO中加的,RecieveVO也是同样的加上),加上这个属性时为了在保存的时候,能够把孙表的信息一块存入表中.

同时还需要再孙表的VO类中加上

个是SendChildVO中加的,RecieveChildVO也同样)。

如图的属性(这

三.设计模板

设计完元数据和生成VO后,开始进行手工配置,这个节点没法使用向导生成,需要自行进行功能节点注册,菜单注册,单据模板初始化等等操作。这里需要说明是在设计单据模板。 根据元数据,首先设计一个如下图样的主子表的模板

接着再设计一个孙表模板:因为这里孙表实体是两个,所以还需要再设计一个孙表模板

最后进行功能节点默认模板设置: 如下图:

这里需要注意,节点标示一定要写,这里会在之后的xml配置中用到这个节点标识。

四.Xml配置

1.设计model,主子孙界面需要设计如下图的model

2.元数据转换工厂:

一个是主表和子表用,一个是孙表用

3.数据模型和模板容器,如下图,其中nodekeies和之前配置的节点标识对应上

4. 界面元素xml:

class=\ init-method=\>

class=\>

class=\>

class=\ init-method=\>

class=\ init-method=\>

class=\ init-method=\>

class=\ init-method=\>

class=\ineAction\>

class=\ />

class=\ />

class=\ />

class=\anelValueAdapter\ />

class=\ init-method=\>

class=\ineAction\>

class=\ />

class=\ />

class=\ />

class=\ />

class=\ />

class=\ />

class=\ndAction\>

class=\diator\>

以下这个是孙表空行过滤,对应的页签code,一定要和你单据模板初始化中的页签code一样

class=\p\>

5. 单据操作代理

这里的页签code和上面的一样,必须和单据模板里面设置的页签code一样

class=\>

以上XML是比较重要的部分,全部的XML有附件,这里就不全部给出了。

五.开发中需要注意的问题:

XML配置完之后,就能够出现如图的主子孙界面了。

不过主子孙单据开发和平常的单据会有些区别,这里一一说明:

1. 界面初始化数据:

界面初始化会用到ModelDataManager类,这个类又会调用代理类,来执行查询的数据,返回的数据才通过ModelDataManager来初始化到界面上:

首先代理类必须继承AbstractGrandQueryService类

然后开始远程调用查询。

后台查询方法如下:

需要注意的是:这里会专门用到查询孙表的方法,不然查询出来的数据没有孙表数据。

如果不用这个封装好的类,那可以自己定义一个查询出封装好vo的方法,使其是主子孙VO:

@Override

public AggMgsSchoolVO[] queryAllData(String whereSql)throws

AggMgsSchoolVO[] aggVOs = null;

//EfficientBillQuery是根据sql条件(以and开始)进行单据VO高效查询的工具EfficientBillQuery efq = new try { }

if(aggVOs.length < 1){ }

StringBuffer pk_c_a_list = new StringBuffer(); pk_c_a_list.append(\

for (int i = 0; i < aggVOs.length; i++) { }

pk_c_a_list.append(\

AggMgsSchoolVO aggMgsSchoolVO = aggVOs[i]; MgsClassaVO[] acvo = (MgsClassaVO[]) if(acvo.length > 0){ }

for (int j = 0; j < acvo.length; j++) { }

MgsClassaVO mgsClassaVO = acvo[j];

pk_c_a_list.append(mgsClassaVO.getPk_c_a()+\

//如果查询出的aggVOs数据没有数据,那么直接返回null

return null;

aggVOs = efq.query(whereSql);

throw new BusinessException(e.getMessage()); } catch (Exception e) {

BusinessException {

EfficientBillQuery(AggMgsSchoolVO.class);

aggMgsSchoolVO.getChildren(MgsClassaVO.class);

//构造出孙表外键的数组

String pk_c_a_lists = pk_c_a_list.delete(pk_c_a_list.length()-4,

StringBuffer pk_c_b_list = new StringBuffer(); pk_c_b_list.append(\

for (int i = 0; i < aggVOs.length; i++) {

AggMgsSchoolVO aggMgsSchoolVO = aggVOs[i]; MgsClassbVO[] bcvo = (MgsClassbVO[])

pk_c_a_list.length()-2).toString();

aggMgsSchoolVO.getChildren(MgsClassbVO.class);

}

if(bcvo.length > 0){ }

for (int j = 0; j < bcvo.length; j++) {

MgsClassbVO mgsClassaVO = bcvo[j];

pk_c_b_list.append(mgsClassaVO.getPk_c_b()+\

}

pk_c_b_list.append(\

//构造出孙表外键的数组

String pk_c_b_lists = pk_c_b_list.delete(pk_c_b_list.length()-4,

BaseDAO bd = new BaseDAO();

//查询出MgsTeacheraVO数据

List tas = (List)

pk_c_b_list.length()-2).toString();

bd.retrieveByClause(MgsTeacheraVO.class, \in\

//查询出MgsTeacherbVO数据

List tbs = (List)

bd.retrieveByClause(MgsTeacherbVO.class, \in\

//封装为主子孙的VO

for(int k = 0; k < aggVOs.length; k++){

MgsClassaVO[] mgsca = (MgsClassaVO[]) for (int i = 0; i < mgsca.length; i++) {

Set lavos = new HashSet(); String pk_c_a = mgsca[i].getPk_c_a(); for(int j = 0 ; j < tas.size() ; j++){ }

((MgsClassaVO[])

MgsTeacheraVO tavo = tas.get(j); if(tavo.getPk_c_a().equals(pk_c_a)){ }

lavos.add(tavo); tas.remove(tavo);

aggVOs[k].getChildren(MgsClassaVO.class);

aggVOs[k].getChildren(MgsClassaVO.class))[i].setPk_t_a(lavos.toArray(new MgsTeacheraVO[0]));

}

for(int k = 0; k < aggVOs.length; k++){

MgsClassbVO[] mgscb = (MgsClassbVO[]) for (int i = 0; i < mgscb.length; i++) {

Set lbvos = new HashSet(); }

aggVOs[k].getChildren(MgsClassbVO.class);

String pk_c_b = mgscb[i].getPk_c_b(); for(int j = 0 ; j < tbs.size() ; j++){ }

((MgsClassbVO[])

MgsTeacherbVO tbvo = tbs.get(j); if(tbvo.getPk_c_b().equals(pk_c_b)){ }

lbvos.add(tbvo); tbs.remove(tbvo);

aggVOs[k].getChildren(MgsClassbVO.class))[i].setPk_t_b(lbvos.toArray(new MgsTeacherbVO[0]));

}

} }

return aggVOs;

在这里面需要先查询出主子VO,再遍历子VO找到其主键,将其加到一个StringBuffer数组当中,再这些根据条件查询出孙的VO,最后在组装一次主子孙全VO,这样只是对数据库执行查询操作3次,而且条件也比较精确,而上一种方法需要遍历整个主子aggVO,没遍历一次就执行一次查询,这样对数据库就会产生频繁的操作,影响性能(没有很大的数据量测试过,只是根据需要对数据库的相互次数得到的结论,不完全保证正确)。

选中的代码就是根据子VO再去查出孙VO,并且组合出一个完整的主子孙VO的代码。

2. 新增保存动作:

和上面一样,使用代理类,调新增,后台代码如下:

这里的新增需要用到GCInsertBPTemplate 类来进行主子孙的保存. nc.util.mmf.framework.gc.GCBillTransferTool这是一个主子孙单据单据简化工具.在保存前,打断点看看孙表数据是否传到后台,如下图:

前台代码需要新增:

在保存按钮里面,注入主子孙管理的model,再保存方法里面再调用如图红线标注的方法

保存数据以后,界面依然是卡片界面,如果此时不做特殊处理,那么返回到列表界面的时候,当前选中的数据就是增加前选中的数据,所以我们需要在返回按钮当中做特殊的处理。重写返回按钮,强制发一个事件即可。

nc.ui.xgh_study.maingrand.action.UEReturnActionEx

同样修改,删除和新增类似这里不一一说明。

3. 第一次打开界面问题

主子孙界面第一次在打开界面时,可能孙表模板被隐藏,第二次打开才能显示,这里的解决办法是: 列表界面: 重写这个类,

nc.ui.pubapp.uif2app.components.grand.ListGrandPanelComposite

将readListCacheInfo()方法重写

卡片界面类似

如果孙表的数据不能显示,在数据初始化的时候代码如下:

4. 卡片界面保存问题 需要重写这个类

nc.ui.pubapp.uif2app.components.grand.CardGrandPanelComposite

在初始化界面的时候调用如下方法:

/**

* 重写下初始化方法 平台代码没有考虑多页签的问题 需要给每个子页签都添加上伪列 *

* @param mainBillForm

* void TODO(参数说明) */

private void constructPreColumBillItem(BillForm mainBillForm) { String[] bodyTableCodes =

mainBillForm.getBillCardPanel().getBillData() .getBodyTableCodes();

for (int i = 0; i < bodyTableCodes.length; i++) { BillModel billModel =

mainBillForm.getBillCardPanel().getBillModel( bodyTableCodes[i]);

if (billModel.getBodyColByKey(\) > 0) continue; // 添加伪列操作

BillItem[] bodyItems = billModel.getBodyItems(); BillItem newItem = new BillItem(); BillItem[] newItems = Arrays

.copyOf(bodyItems, bodyItems.length + 1); newItem.setKey(\); newItem.setShow(false);

newItem.setNull(false);

newItem.setShowOrder(bodyItems.length + 1); newItems[bodyItems.length] = newItem; billModel.setBodyItems(newItems);

mainBillForm.getBillCardPanel().getBodyPanel(bodyTableCodes[i]) .setTableModel(billModel); } }

在保存按钮的doAction方法中需要修改为如下代码,这样自己手动增加伪列,否则在保存的时候就会显示错误数据。

5. 在主子孙单据中,由于是将一个主子表和一个孙表糅合在一起,所以在操作列表界面或者是卡片界面时都是通过

nc.ui.pubapp.uif2app.components.grand.ListGrandPanelComposite 需要重写的方法:

private void tabChangeProcess() {

// 获得当前选中行

int currentRow = ((BillListView)

.getBodyTable().getSelectedRow();

.getBillListPanel().getChildListPanel().getTableCode();

this.mainPanel).getBillListPanel()

String currentbodyTabCode = ((BillListView) this.getMainPanel()) // 根据当前子页签获取孙表view

BillListView grandListView = (BillListView) this

.get(currentbodyTabCode);

.getMaingrandrelationship().getBodyTabTOGrandListComposite()

// 加载孙模板

this.getMainGrandAssist().updateGrandListByBodyTab(this); if (grandListView != null && currentRow != -1 ){

// 加载孙面板数据

AbstractBill aggVO = (AbstractBill) ((BillListView) this

.getMainPanel()).getModel().getSelectedData();

ShowUpableBillListViewEx billListViewEx =

.getMainPanel();

(ShowUpableBillListViewEx) this

// 获取类路径

String bodyClassName = billListViewEx.getBillListPanel()

List grandVOList = this.getMainGrandAssist() }

//如果子表没有数据,则先清空孙表数据,再强制发送一次数据选择改变事件 this.clearGrandData(); ((BillListView)

.getGrandListDataByMainRow((BillListView)

currentRow, grandListView, bodyClassName, this.getMaingrandrelationship());

.getBodyBillModel(currentbodyTabCode).getTabvo()

.getBillMetaDataBusinessEntity().getFullClassName();

this.mainPanel,

if (grandVOList != null) {

// 孙面板加载数据并显示

grandListView.getBillListPanel().getBodyBillModel()

.setBodyDataVO(grandVOList.toArray(new

SuperVO[0]));

grandListView.getBillListPanel().getBodyBillModel()

.loadLoadRelationItemValue(); .execLoadFormula();

grandListView.getBillListPanel().getBodyBillModel()

} else {

grandListView.getBillListPanel().getBodyBillModel()

.clearBodyData();

}else{

this.getMainPanel()).getModel().fireEvent(new AppEvent(AppEventConst.SELECTION_CHANGED));

}

}

@Override

public void handleEvent(AppEvent event) { } /**

if (event instanceof ListBodyTabChangedEvent) { }

super.handleEvent(event);

//页签改变时的处理

this.tabChangeProcess(); return;

MainGrandEventTypeEnum.loadcardgranddata.toString())) {

} else if (event.getType().equals(

CardPanelEventUtil.grandListModelInit(this);

* 清除孙表数据 */

private void clearGrandData() {

String currentbodyTabCode = ((BillListView)

this.getMainPanel()).getBillListPanel().getChildListPanel().getTableCode();

// 根据当前子页签获取孙表view BillListView grandListView = (BillListView)

this.getMaingrandrelationship().getBodyTabTOGrandListComposite().get(currentbodyTabCode);

if (grandListView != null) { String[] grandTabCodes =

grandListView.getBillListPanel().getBillListData().getBodyTableCodes();

for (String grandTabcode : grandTabCodes) {

grandListView.getBillListPanel().getBillListData().getBodyBillModel(grandTabcode).clearBodyData(); } } }

nc.ui.pubapp.uif2app.components.grand.CardGrandPanelComposite

来进行操作的,例如事件的处理,给孙表设值等等。

6 点击查询按钮,需要根据查询面板得到语句,再进行查询,重写查询Action:

附件:红色部分需要小心配置 主子孙单据完整xml :

xsi:schemaLocation=\http://www.springframework.org/schema/beans/spring-beans.xsd\>

class=\>

class=\ />

class=\ry\ />

class=\ />

class=\>

class=\>

class=\>

class=\

class=\>

pm01 pm0101 pm0102

class=\ init-method=\>

class=\>

class=\>

class=\ init-method=\>

class=\ init-method=\>

class=\ init-method=\>

class=\ init-method=\>

class=\ineAction\>

class=\ />

class=\ />

class=\ />

class=\anelValueAdapter\ />

class=\ init-method=\>

class=\ineAction\>

class=\ />

class=\ />

class=\ />

class=\ />

class=\ />

class=\ />

class=\ndAction\>

class=\diator\>

class=\\>

recieve

send

class=\p\>

class=\ />

class=\>

class=\>

class=\>

class=\>

class=\>

class=\>

class=\>

class=\ id=\>

class=\ id=\>

class=\>

nc.vo.pram.practice.TaskVO

nc.vo.pram.practice.SendVO nc.vo.pram.practice.RecieveVO

class=\>

class=\>

value=\ />

class=\>

class=\>

value=\ />

class=\>

class=\>

value=\ />

class=\ />

class=\>

value=\ />

class=\>

class=\>

nc.vo.pram.practice.SendChildVO

class=\>

class=\>

value=\ />

class=\>

class=\>

value=\ />

class=\ />

class=\>

nc.vo.pram.practice.RecieveChildVO

class=\>

class=\>

value=\ />

class=\>

class=\>

value=\ />

class=\ />

class=\ />

class=\>

class=\>

class=\>

class=\>

class=\>

class=\>

class=\ >

class=\>

class=\>

class=\>

class=\leAction\>

class=\>

class=\ />

class=\>

class=\>

class=\>

class=\

init-method=\>

class=\>

class=\>

class=\>

class=\>

本文来源:https://www.bwwdw.com/article/qfqg.html

Top