首页 > 其他分享 >插件开发

插件开发

时间:2023-06-29 14:25:30浏览次数:38  
标签:getView 插件 getModel 标识 开发 单据 DynamicObject kded

苍穹开发知识总结

  1. 获取简单字段的值
    1. 数据模型IDataModel中存储了当前页面的数据包,对于文本类型、整数、时间字段等简单类型字段,可以直接通过IDataModel的get方法直接获取字段值,值的返回类型有String、Date、BigDecimal等。
    2. IDataModel model = this.getModel();
    3. String remark = (String)model .getValue("文本字段标识");
    4. BigDecimal qty=this.getModel().getValue("数量字段标识",0)
  2. 获取基础资料的属性值
    1. 方式1:在表单设计器中引用人员的“生日”属性,然后再通过以下代码可以取到基础资料某个属性。
      1. DynamicObject creatorDObj = (DynamicObject) this.getModel().getValue("creator");
      2. String birthday = creatorDObj.getString("birthday");
    2. 方式2:先拿到基础资料的id,再通过orm接口去查基础资料的某个属性值。
      1. //获取当前页面创建人字段的数据对象
      2. DynamicObject creatorDObj = (DynamicObject) this.getModel().getValue("creator");
      3. Object pkValue = creatorDObj.getPkValue();//拿主键即id
      4. QFilter idQFilter = new QFilter("id", QCP.equals, pkValue);//构造过滤条件
      5. DynamicObject queryRuselt =
      6. QueryServiceHelper.queryOne("bos_user", "birthday",new QFilter[] {idQFilter} );//查 询数据库
      7. String birthday = queryRuselt.getString("birthday");//拿属性的值
  3. 获取单据体某个字段或行对象
    1. 获取单据体某行某个字段的值 this.getModel().getValue("kded_textfield", 0);//0代表第一行
    2. 获取单据体中各行的数据
      1. 方式1:
        1. //获取当前页面的数据包
        2. DynamicObject dataEntity = this.getModel().getDataEntity(true);
        3. //获取单据体数据的集合
        4. DynamicObjectCollection goodsEntities=dataEntity.getDynamicObjectCollection(" 单据体标识");
        5. for (DynamicObject entryObj : goodsEntities) {
        6. //获取某行数据的id
        7. Object pk=entryObj.getPkValue();
        8. //获取某行的某个字段的值
        9. Object object = entryObj.get("字段标识");
        10. }
      2. 方式2:
        1. DynamicObjectCollection entryRows = this.getModel().getEntryEntity("单据体标识");
  4. 获取子单据体某个字段或行
    1. 取子单据体某行某个字段 this.getModel().getValue("kded_textfield", 0,0);

//第一个整数代表子单据体行号,第二个整数代表父单据体行号

    1. 获取子单据体中各行的数据

//获取当前页面的数据包

DynamicObject dataEntity = this.getModel().getDataEntity(true);

//先获取单据体数据的集合

DynamicObjectCollection goodsEntities=dataEntity.getDynamicObjectCollection(" 单据体标识");

for (DynamicObject entryObj : goodsEntities) {

//再获取子单据体行某行数据的id

DynamicObjectCollection cols=entryObj .getDynamicObjectCollection("子单据体 标识");

for (DynamicObject col: cols) {

col.get("字段标识");//获取子单据体字段的值

}

}

  1. 获取富文本控件的值

富文本是通用控件,通用控件不能存储数据,所以不能通过model来取值,富文本的控件模型提供了相应的接口。

RichTextEditor edit = this.getView().getControl("富文本控件标识");

String text = edit.getText();

  1. 获取多选基础资料的值

多选基础资料字段配置的时候是要写表名的,通过model拿到的就是该表某些数据的集合,遍历集合才能拿到实际选择的基础资料数据对象。

DynamicObjectCollection multiCols = (DynamicObjectCollection) this.getModel().getValue("kded_mulbasedatafield");

for(DynamicObject col:multiCols){

//获取选择的基础资料数据对象

DynamicObject baseData = (DynamicObject) col.get("fbasedataid");

}

  1. 给简单字段赋值

简单字段的赋值,直接通过当前页面的数据模型IDataModel 赋值给字段赋值。

@Override

public void afterCreateNewData(EventObject e) {

IDataModel model = this.getModel();

model.setValue("kded_remark", "我的备注数据");

}

  1. 给基础资料字段赋值

给基础资料赋值必须用基础资料的id或者基础资料的DynamicObject。

@Override

public void afterCreateNewData(EventObject e) {

long currentUserId = UserServiceHelper.getCurrentUserId();

//方式1:通过id赋值-推荐

this.getModel().setValue("kded_registrant", currentUserId );

//方式2:通过对象赋值

DynamicObject user = BusinessDataServiceHelper.loadSingle(currentUserId, "bos_user");

this.getModel().setValue("kded_registrant", user);

}

注意:不能使用QueryServiceHelper.queryOne查到的平铺对象赋值给基础资料字段。

  1. 给单据体的字段赋值

方式1:如果是知道行号index,且只需要给这行的字段赋值,则参考:

this.getModel().setValue("字段标识","字段值",index);

方式2:需要给每行赋值,则需遍历单据体进行赋值:

DynamicObjectCollection entryRows = this.getModel().getEntryEntity("单据体标识");

for (DynamicObject entryObj : entryRows) {

//修改某行的某个字段的值

entryObj.set("kded_textfield", "测试");}

this.getView().updateView("entryentity");

}

注意点:方式2如果在afterCreateNewData事件则不需要updateView,否则需要代码刷新前台才会显示。

  1. 给单据体新建行
    1. 方式1:单据体虽然是集合,但是数据模型IModel提供了直接增加行的接口,需要知道要增加的行数row。
      1. int[] newEntryRow = this.getModel().batchCreateNewEntryRow("单据体标识", row);
      2. for (int index : newEntryRow) {
      3. this.getModel().setValue("单据体某个字段标识", 值, index);
      4. }
    2. 方式2:给单据体创建行对象,再调用IModel增加行的接口。
      1. DynamicObject entry = ORM.create().newDynamicObject(this.getModel().getEntryEntity("单据体标 识 ").getDynamicObjectType());
      2. entry.set("kded_textfield1","44");
      3. entry.set("kded_amountfield","10");
      4. int rowindex = this.getModel().createNewEntryRow("单据体标识", entry);
      5. 注意:如果单据体字段有设置默认值,此方式默认值会覆盖代码设置的值。
    3. 方式3:通过数据包给单据体直接新增行对象。
      1. DynamicObjectCollection entryentityCols = this.getModel().getDataEntity(true).getDynamicObjectCollection("entryentity");
      2. DynamicObject entryCol = entryentityCols.addNew();
      3. entryCol.set("kded_textfield", "方式4");
      4. this.getView().updateView("entryentity");
      5. 获取单据体数据包,在数据包新增行对象,是需要代码调用updateView才会将新内容显示到界面上。
  2. 给子单据体新建一行

//先设置父单据体选中行

this.getModel().setEntryCurrentRowIndex("entryentity",0);

//创建子单据体行-方式1

int[] ints = this.getModel().batchCreateNewEntryRow("kded_subentryentity", 1);

for (int index : ints) {

this.getModel().setValue("kded_textfield2", "文本值", index);

}

//创建子单据体行-方式2

DynamicObject subEntry = ORM.create().newDynamicObject(this.getModel().getEntryEntity("kded_subentryentit y").getDynamicObjectType());

subEntry.set("kded_textfield2","行对象");

int rowindex = this.getModel().createNewEntryRow("kded_subentryentity", subEntry);

  1. 给富文本控件赋值

富文本是通用控件,不能像实体字段一样直接用数据模型this.getmodel赋值,需要通过富文本控件模型RichTextEditor 提供的方法setText设置值。

RichTextEditor edit = this.getView().getControl("richtexteditorap");

edit.setText("要设置的内容");

  1. 给多选基础资料赋值

https://vip.kingdee.com/article/198799132897594368?productLineId=29

  1. 列表页面赋值

https://vip.kingdee.com/article/306390194805169920?productLineId=29

  1. 如何复制单据数据

public class SrSubmitOpPlugin extends AbstractOperationServicePlugIn {

@Override

public void onPreparePropertys(PreparePropertysEventArgs e) {

super.onPreparePropertys(e);

e.getFieldKeys().add("kded_srstatus");

}

@Override

public void beginOperationTransaction(BeginOperationTransactionArgs e) {

super.beginOperationTransaction(e);

DynamicObject[] dataEntities = e.getDataEntities();

for(DynamicObject data : dataEntities) {

//单据标识

String entityNumber = data.getDataEntityType().getName();

//data是保存前且校验通过的数据包,此处备份数据

Object pkValue = obj.getPkValue()

boolean exists = QueryServiceHelper.exists(entityNumber , pkValue);

if(exists){

//如下复制数据方案1或者方案2

)else{

}

}

}

}

数据复制有两种方案:

方案1:创建空数据包,并逐一赋值-不推荐,后续表单增加字段,需要不断迭代代码。

//创建空的数据包

DynamicObject newDynamicObject = BusinessDataServiceHelper.newDynamicObject(entityNumber);

newDynamicObject.set("单据头字段标识a", data.get("单据头字段标识a"));

newDynamicObject.set("备注字段标识", "备份数据");

//单据体数据行

DynamicObjectCollection newCol = newDynamicObject.getDynamicObjectCollection("单据体标识");

DynamicObjectCollection oldCol = data.getDynamicObjectCollection("单据体标 识 ");

//复制当前分录数据到新增数据包的新增分录行上

for (DynamicObject oldEntry : oldCol) {

//创建一个空的分录行

DynamicObject newEntry = new DynamicObject(newCol.getDynamicObjectType());

newEntry.set("单据体字段标识x", oldEntry.get("单据体字段标识x"));

//新增数据行添加到单据体上

newCol.add(newEntry);

}

//保存数据

SaveServiceHelper.saveOperate(entityNumber, new DynamicObject[] {newDynamicObject})

方案2:直接克隆整个数据包-增加字段无需迭代代码,推荐。

DynamicObject newData = (DynamicObject) new CloneUtils(false,true).clone(data );

newData.set("备注字段标识", "备份数据");

//保存数据

SaveServiceHelper.saveOperate(entityNumber, new DynamicObject[] {newData })

  1. 如何判断界面是否新增界面

①首先确认要重写的事件,要在“新增”和“编辑”状态下都会执行。而弹出提示是view的行为,所以一般建议在afterBindData事件中处理。

②每个界面视图中,都保存了相关界面的参数,包括但不局限于:页面pageid,表单标识、表单运行插件、父页面传过来的自定义参数等,例如当前页面是新增状态还是编辑状态,可以根据单据页面的界面参数FormShowParameter中的getStatus方法获取到。

BillShowParameter bsp=(BillShowParameter)this.getView().getFormShowParameter();

if(bsp.getStatus()==OperationStatus.ADDNEW ){

this.getView().showTipNotification("您正在新增办公用品登记单");

}

if(bsp.getStatus()==OperationStatus.EDIT){

this.getView().showTipNotification("您正在编辑一个办公用品登记单");

}

  1. 取消打开页面

@Override

public void preOpenForm(PreOpenFormEventArgs e) {

e.setCancel(true);

e.setCancelMessage("对不起,周日不能制单!");

}

  1. 锁定单据头字段

方式1:表单设计器上设置”新增锁定、修改锁定、提交锁定、审核锁定"。

方式2:通过如下代码设置锁定性。

@Override

public void afterBindData(EventObject e) {

super.afterBindData(e);

this.getView().setEnable(false, "字段标识");

}

说明:其他场景下,影响锁定性的因素还有单据类型、界面规则、布局等。

  1. 锁定单据体或单据体字段

问题1:如何锁定单据体某几行?

参考答案:

//锁定单据体某几行,所有字段都锁定

EntryGrid entryGrid = this.getView().getControl("entryentity");

entryGrid.setRowLock(true,new int[]{0,1});

问题2:如何锁定单据体某一行某一列?

参考答案:

//锁定单据体某行某列

this.getView().setEnable(false,2,"kded_dealdesc");

问题3:如何锁定某一列?

参考答案:没有锁定整列的接口,需遍历单据体行锁定

int rowCount = this.getModel().getEntryRowCount("entryentity");

for(int i = 0,i<rowCount ,i++){

this.getView().setEnable(false,i,"kded_dealdesc");

}

问题4:如何锁定整个单据体?

参考答案:

this.getView().setEnable(false,"entryentity");

  1. 设置控件可见性

在afterBindData事件中先判断单据状态是审核状态时,再设置审核人字段可见:this.getView().setVisible(true, "字段标识");

  1. 设置字段必录性

问题1:如何通过代码设置单据头字段必录?

参考答案:

TextEdit textField = (TextEdit)this.getView().getControl("kded_textfield1");

textField.setMustInput(true);

问题2:如何通过代码设置单据体字段必录?

参考答案:

//设置单据体字段必录,kded_dealdesc是单据体一个文本字段的标识

TextEdit textField1 = (TextEdit)this.getView().getControl("kded_dealdesc");

textField1.setMustInput(true);

TextProp it2 =(TextProp) textField1.getProperty();

it2.setMustInput(true);

  1. 设置单据体选中行

//数据模型中获取单据体的数据行数

int entryRowCount = this.getModel().getEntryRowCount("sunp_entryentity");

if (entryRowCount!=0) {

//获取单据体控件模型

EntryGrid eg = this.getView().getControl("sunp_entryentity");

//通过单据体控件模型的方法实现选中行功能

eg.selectRows(0);

}

  1. 执行页面的按钮点击事件

//tbmain是工具栏标识,bar_save是工具栏项标识,save是工具栏绑定的操作

Toolbar toolbar = this.getView().getControl("tbmain");

toolbar.itemClick("bar_save", "save");

//触发按钮,kded_btsave是按钮标识

Button button = this.getView().getControl("kded_btsave");

button.click();

  1. 执行操作

问题:如何通过代码触发某个操作?

参考答案:界面模型提供了相关接口。

this.getView().invokeOperation("save");//save是操作标识

  1. 刷新数据

问题1:通过插件给单据头的字段赋值,发现值没显示出来时,应该如何刷新字段的值?

参考答案:

this.getView().updateView("字段标识");

//或者

this.getView().updateView();

问题2:通过插件给单据体的字段赋值,发现值没显示出来时,应该如何刷新单据体字段的值?

参考答案:

this.getView().updateView("单据体字段", 所在行号);

//如果刷新很多单据体字段,可以选择刷新整个单据体

this.getView().updateView("单据体标识");

//或者

this.getView().updateView();

问题3:在用户打开查看单据的某条数据时,并在插件中通过BusinessDataServiceHelper.loadSingle查数据库中对应的数据进行修改,并通过SaveServiceHelper.update更新数据到数据库,那么用户此时该如何刷新修改的数据到当前页面

参考答案:

//或者调用表单的“刷新”操作

this.getView().invokeOperation("refresh");

推荐:由于刷新是有性能消耗的,updateView建议指定刷新字段或刷新单据体的标识,尽量不要进行全局刷新-this.getView().updateView()

  1. 页面关闭

在页面关闭时的校验,那么可以在页面关闭前事件beforeClosed中,通过修改事件参数取消校验。

@Override

    public void beforeClosed(BeforeClosedEvent e) {

         super.beforeClosed(e);

         e.setCheckDataChange(false);

    }

问题2:如何通过代码关闭页面。

参考答案:

this.getView().close();

//或者

this.getView().invokeOperation("close");

  1. 页面弹出提示信息

this.getView.showMessage("提示信息");

https://vip.kingdee.com/school/238714716992919296?topicId=239383452913417728&stageId=239383671570873856&pathId=239410657773565696&productLineId=29

  1. 修改控件名称

问题1:如何通过代码修改字段控件的名称?

参考答案:TextEdit的父类FieldEdit提供setCaption接口修改控件名称。如:

TextEdit textField = (TextEdit)this.getView().getControl("kded_textfield1");

textField.setCaption(new LocaleString("sss"));

注意:当通过该方式修改字段标题后,修改该字段退出界面会提示已有XXX字段修改,是否继续退出,这里还是显示修改前的字段名称,需要通过以下代码修改主数据模型对应属性的标题:

//对应修改元数据对应属性的标题

Map<String, IDataEntityProperty> allFields

=this.getModel().getDataEntityType().getAllFields();

IDataEntityProperty kded_textfield1 = allFields.get("kded_textfield1");

kded_textfield1.getDisplayName().setLocaleValue("sss");

问题2:如何通过代码修改非字段类型的控件名称,比如按钮、高级面板等?

参考答案:使用动态更新元数据属性的接口updateControlMetadata。

Map<String, Object> text = new HashMap<>(); 

 Map<String, Object> text1 = new HashMap<>(); 

 text.put("zh_CN", "test"); 

 text1.put("text", text); 

 this.getView().updateControlMetadata("控件标识", text1);

  1. 页面缓存

问题:如何使用页面缓存?

参考答案:

this.getView().getPageCache().put("isLeaf","true");

String isLeaf = this.getView().getPageCache().get("isLeaf");

  1. 获取当前页面的元数据信息

问题:如何获取运行期表单及表单所有控件信息?

参考答案:

元数据相关的servicehelper:MetadataServiceHelper、AppMetaServiceHelper、ConvertMetaServiceHelper、LocaleMetadataServiceHelper等,优先使用这些。(注意不要用到非平台的)

//根据表单编码获取表单id

String id = MetadataDao.getIdByNumber("kdec_cehsi", MetaCategory.Form);

//获取表单元数据

FormMetadata formMeta = (FormMetadata) MetadataDao.readRuntimeMeta(id, Meta Category.Form);

//遍历获取所有控件集合

for (ControlAp<?> item : formMeta.getItems()) {

//可见性

String visible = item.getVisible();

//控件名称

String name = item.getName().getLocaleValue();

 //控件编码

 String key = item.getKey();

}

  1. 数据联动

问题:办公用品登记单选择物品后,如何自动给物品分类赋值?

参考答案:

方式1:使用基础资料属性字段,然后绑定物品字段,显示属性选择物品分类名称。

方式2:通过业务规则配置【计算定义公式的值并填写到指定列 】服务实现。

方式3:在值更新事件propertyChanged中获取变更的物品值,并给“物品分类”字段赋值。

@Override

public void propertyChanged(PropertyChangedArgs e) {

if (e.getProperty().getName().equals("物品字段标识")) {

ChangeData changeData = e.getChangeSet()[0];

//变更后的数据

DynamicObject newValue = (DynamicObject) changeData.getNewValue();

DynamicObject

goodObj=BusinessDataServiceHelper.loadSingle(newValue.getPkValue(), "物 品的标识", "物品里分类字段标识");

DynamicObject groupObj = goodObj.getDynamicObject("物品里分类字段标 识");

this.getModel().setValue("物品分类字段标识", groupObj);

}

}

  1. 通过代码赋值后不想触发值更新事件

方式1:在afterCreatedNewData事件赋值,是不会触发值更新事件的。

方式2:在其他事件赋值时,使用以下方式赋值。

this.getModel().beginInit();

this.getModel().setValue("字段标识","字段值");

this.getModel().endInit();

  1. 用户点击

苍穹平台表单页面的点击及触发原理也是基于Java委托事件处理机制,关键对象包括如下:

Event Source(事件源):事件发生的场所,通常就是各个组件,例如按钮、窗口、菜单、工具栏(在苍穹上对应Toolbar控件)等。

Event(事件):事件封装了GUI组件上发生的特定事情(用户动作、行为)。

Event Listener(事件监听器):注册于某个事件源上,用于响应特定的事件。

在苍穹平台中,所有标准控件的事件源(Button.class,Toolbal.class,EntryGrid.class等)已经定义好了,用户点击苍穹表单页面某个地方时,是否会触发特定的响应方法(click、itemClick、billListHyperLinkClick等),需要满足以下两个条件。

①事件的产生:以用户点击工具栏新增按钮为例,表单微服务根据前端发送的指令最终调用事件源(Toolbar控件模型)创建了两个事件(BeforeItemClickEvent、ItemClickEvent)。

②在表单插件的registerListener方法中注册ToolBar事件源的事件监听器(ClickListener、ItemClickListener)并重写监听器对应的响应事件方法click、itemClick。

由于只产生了BeforeItemClickEvent、ItemClickEvent这两个事件,没有ClickEvent事件,所以只会响应itemClick方法。

  1. 父子页面交互

代码弹出表单页面

第一步:办公用品登记单插件的itemClick方法中弹出物品新增申请单。

@Override

public void itemClick(ItemClickEvent evt) {

FormShowParameter fsp = new FormShowParameter();

fsp.setFormId("物品新增申请单");

fsp.getOpenStyle().setShowType(ShowType.Modal);

fsp.setCloseCallBack(new CloseCallBack(this, "show-kded_supaddnew"));//

this.getView().showForm(fsp);

super.itemClick(evt);

}

修改父页面的数据

方案1:直接在子页面的表单插件中拿到父页面的数据模型model进行赋值。

@Override

public void click(EventObject evt) {

if (evt.getSource() instanceof Button) {

Button bt=(Button) evt.getSource();

String key = bt.getKey();

if (key.equals("btnok")) {

Object goodName = this.getModel().getValue("物品名称字段标识");

IFormView parentView = this.getView().getParentView();//父页面

IDataModel parentModel = parentView.getModel();

parentModel.setValue("sunp_textfield",goodName ) );//修改父页面数据

parentView .updateView();//刷新

//调用了其他表单的控制方法时,需调用以下方法将目标表单的控制 指 //令发给前端

this.getView().sendFormAction(this.getView().getParentView()); this.getView().close();

}

}

super.click(evt);

}

方案2:将子页面的字段值传给父页面,然后在父页面的表单插件的closedCallBack方法中修改备注字段值。

新增物品申请单表单插件:

@Override

public void click(EventObject evt) {

if (evt.getSource() instanceof Button) {

Button bt=(Button) evt.getSource();

String key = bt.getKey();

if (key.equals("btnok")) {//确定按钮或者是邮件通知按钮

Object goodName = this.getModel().getValue("物品名称字段标识");/

this.getView().returnDataToParent(goodName);//返回数据给父页面

this.getView().close();

}

}

}

办公用品登记单插件:

@Override

public void closedCallBack(ClosedCallBackEvent closedCallBackEvent) {

if (closedCallBackEvent.getActionId().equals("show-kded_supaddnew")) {

Object returnData = closedCallBackEvent.getReturnData();

this.getModel().setValue("sunp_textfield",returnData);

}

super.closedCallBack(closedCallBackEvent);

}

方案3:将子页面的值放到父页面缓存,由父页面插件进行赋值处理。

新增物品申请单表单插件:

@Override

public void click(EventObject evt) {

if (evt.getSource() instanceof Button) {

Button bt=(Button) evt.getSource();

String key = bt.getKey();

if (key.equals("btnok")) {//确定按钮或者是邮件通知按钮

Object goodName = this.getModel().getValue("物品名称字段标识");/

//通过界面缓存传递值

this.getView().getParentView().getPageCache().put("name", goodName );

this.getView().close();

}

}

}

}

办公用品登记单插件:

@Override

public void closedCallBack(ClosedCallBackEvent closedCallBackEvent) {

if (closedCallBackEvent.getActionId().equals("show-kded_supaddnew")) {

this.getModel().setValue("sunp_textfield",this.getView().getPageCache(). get("name"));

}

super.closedCallBack(closedCallBackEvent);

}

  1. 基础资料选择界面(F7)

F7选择界面显示哪些字段

基本上F7选择界面都是统一的界面,普通基础资料用的是bos_listf7,分组基础资料和树形基础资料用的是bos_templatetreelistf7界面,部分基础资料,比如人员、组织、客户、供应商等基础资料有自己的f7界面。

F7选择界面的字段由基础资料列表的字段决定,给列表增加字段,并且【可见性】选上F7界面可见。

F7选择界面显示未审核的数据

@Override

public void beforeF7Select(BeforeF7SelectEvent beforeF7SelectEvent) {

if("kded_basedatafield".equals(beforeF7SelectEvent.getProperty().getName())){

ListShowParameter listShowParameter = (ListShowParameter) beforeF7SelectEvent.getFormShowParameter();

listShowParameter.setShowApproved(false);

}

F7选择界面展示已选择的数据,开启多选等

public void beforeF7Select(BeforeF7SelectEvent beforeF7SelectEvent) {

if("kded_basedatafield".equals(beforeF7SelectEvent.getProperty().getName())){

ListShowParameter listShowParameter = (ListShowParameter)

beforeF7SelectEvent.getFormShowParameter();

listShowParameter.setShowApproved(false);

DynamicObject baseData = (DynamicObject) this.getModel().getValue("kded_basedatafield");

if(baseData != null) {

//设置单个已选

listShowParameter.setSelectedRow(baseData.getPkValue()); listShowParameter.setSelectedRows(new Object[]{baseData.getPkValue()});//设置多个已选

listShowParameter.setMultiSelect(true);//开启多选

}

  1. 新建数据对象并赋值

新建空数据对象

可以使用DynamicObject的构造函数,也可以使用BusinessDataServiceHelper或ORM提供的接口。

方式1:

DynamicObject data

=BusinessDataServiceHelper.newDynamicObject("kded_simplebill");

方式2:

DynamicObject kded_simplebill =

ORM.create().newDynamicObject("kded_simplebill");

方式3

MainEntityType type =

EntityMetadataCache.getDataEntityType("kded_simplebill");

DynamicObject data1 = new DynamicObject((DynamicObjectType) type);

给对象赋简单字段的值

data.set("billno","测试0002");

data.set("billstatus","A");

给对象新增单据体并赋值

DynamicObjectCollection entryentity =

data.getDynamicObjectCollection("entryentity");

//新增单据体方式一:

DynamicObject dynamicObject = entryentity.addNew();

dynamicObject.set("kded_textfield","代码新增单据体方式1");

//新增单据体方式二:

DynamicObject dynamicObject1 =

new DynamicObject(entryentity.getDynamicObjectType());

dynamicObject1.set("kded_textfield","代码新增单据体方式2");

entryentity.add(dynamicObject1);

给对象新增子单据体并赋值

DynamicObjectCollection entryentity = data.getDynamicObjectCollection("entryentity");

DynamicObject entry = new DynamicObject(entryentity.getDynamicObjectType()); entry.set("kdec_textfield","hello1");

entry.set("kdec_integerfield", 95271);

entryentity.add(entry);

//单据体数据

DynamicObjectCollection subentryentity = entry.getDynamicObjectCollection("subentryentity");

//单据体的子单据体

DynamicObject subentry = new DynamicObject(subentryentity.getDynamicObjectType());

subentry.set("kdec_textfield1","world");

subentry.set("kdec_integerfield1", 12138); subentryentity.add(subentry);

  1. 保存数据对象

SaveServiceHelper

//方式1-走保存操作的校验

OperationResult operationResult1 =

SaveServiceHelper.saveOperate("kded_simplebill", new DynamicObject[]{data},

OperateOption.create());

//方式2-直接存库

SaveServiceHelper.save(new DynamicObject[]{data});

OperationServiceHelper

该接口可以执行单据的操作,如执行提交操作:

OperationResult operationResult =

OperationServiceHelper.executeOperate("submit","kded_simplebill",new DynamicObject[]{data},OperateOption.create());

if(!operationResult.getSuccessPkIds().isEmpty()){

//执行成功

}

  1. 查询数据对象

查询简单字段&使用简单字段做过滤条件

//方式1-根据单据id查询-可以查询所有字段

Object billId = "1515996182680175616";

DynamicObject simpleBill = BusinessDataServiceHelper.loadSingle(billId,

"kded_simplebill");

//方式2-根据单据id查询-查询指定字段,查询结果是平铺的

QFilter filter = new QFilter("id", QCP.equals, billId);

DynamicObject simpleBillObject =

QueryServiceHelper.queryOne("kded_simplebill", "id,billno,createtime", new QFilter[]{filter});

查询复杂字段&使用复杂字段做过滤条件

//方式1-根据创建人的名称构造过滤条件-BusinessDataServiceHelper

QFilter filter2 = new QFilter("creator.name", QCP.equals, "XXX");

DynamicObject simpleBill2 =

BusinessDataServiceHelper.loadSingle("kded_simplebill","id,billno,creator,creato r.id,createtime",new QFilter[]{filter2});

DynamicObject creator = simpleBill2.getDynamicObject("creator");

long creatorId = simpleBill2.getLong("creator.id");

//方式2-根据创建人的名称构造过滤条件-QueryServiceHelper

DynamicObject simpleBillObject3 =

QueryServiceHelper.queryOne("kded_simplebill",

"id,billno,creator,creator.id,createtime", new QFilter[]{filter2});

DynamicObject creator1 = simpleBill2.getDynamicObject("creator");

查询单据体字段&使用单据体字段做过滤条件

①使用BusinessDataServiceHelper

//根据单据体的字段构造过滤条件

QFilter filter3 = new QFilter("entryentity.kded_dealuser.name", QCP.equals, "金小

蝶");

DynamicObject simpleBill3 =

BusinessDataServiceHelper.loadSingle("kded_simplebill","id,billno,kded_dealuse r,kded_dealdesc",new QFilter[]{filter3});

DynamicObjectCollection cols =

simpleBill3.getDynamicObjectCollection("entryentity");

for(DynamicObject col:cols){

DynamicObject user = col.getDynamicObject("kded_dealuser");

String name = user.getString("name");

String dec = col.getString("kded_dealdesc");

}

注意点:

1.过滤条件使用单据体字段做过滤条件需要加上单据体标识,如entryentity.kded_dealuser.name;

2.查询字段selectfields查询单据体字段可不用加单据体标识,如

DynamicObject user = col.getDynamicObject("kded_dealuser");

3.user默认有id,number、name字段,如需其他字段,需要单据给该基础资料字段配置引用属性。

②使用BusinessDataServiceHelper

QFilter filter5 = new QFilter("entryentity.kded_dealuser.name", QCP.equals, "金小

蝶");

DynamicObjectCollection simpleBills =

QueryServiceHelper.query("kded_simplebill","id,billno,entryentity.kded_dealuser. name,entryentity.kded_dealdesc",new QFilter[]{filter5});

for (DynamicObject dynamicObject : simpleBills) {

dynamicObject.get("entryentity.kded_dealuser.name");

}

注意点:过滤条件和查询字段使用单据体字段都需要用单据体标识entryentity, 指定什么字段则查出什么字段。

查询子单据体字段&使用单据体字段做过滤条件

//根据单据体的字段构造过滤条件查询子单据体字段

QFilter filter4 = new QFilter("entryentity.kded_dealuser.name", QCP.equals, "金小蝶 ");

DynamicObject simpleBill4 =

BusinessDataServiceHelper.loadSingle("kded_simplebill","id,billno,kded_dealuser, kded_dealdesc,kded_subdealuser,kded_subdec",new QFilter[]{filter4});

DynamicObjectCollection cols1 =

simpleBill4.getDynamicObjectCollection("entryentity");

for(DynamicObject col:cols1){

//获取单据体字段

DynamicObject user = col.getDynamicObject("kded_dealuser");

String name = user.getString("name");

String dec = col.getString("kded_dealdesc");

DynamicObjectCollection subCols =

col.getDynamicObjectCollection("kded_subentryentity");

for (DynamicObject subCol:subCols) {

//获取子单据体字段

DynamicObject subDealUser =

subCol.getDynamicObject("kded_subdealuser");

String subDec = subCol.getString("kded_subdec");

}

}

  1. 删除数据对象

(1)直接从数据库删除数据,不触发数据校验

DynamicObject dObj = null;

//IDataEntityType 为实体类型基类

IDataEntityType dataEntityType = dObj.getDataEntityType();

//pks为数据主键值

DeleteServiceHelper.delete(IDataEntityType type, Object[] pks)

(2)删除数据时,触发数据校验

DeleteServiceHelper deleteServiceHelper = new DeleteServiceHelper();

deleteServiceHelper.deleteOperate("删除的操作代码", "单据标识", pks,

OperateOption.create());

//或者直接调用通用操作接口

OperationServiceHelper.executeOperate("删除的操作代码", "单据标识", pks,

OperateOption.create())

  1. 界面插件触发操作

界面模型View提供了触发操作的接口。

this.getView().invokeOperation("submit");

  1. 非界面插件触发操作

非界面插件没有界面模型View,需要通过操作服务工具类触发(也可以界面插件使用)。

OperationResult operationResult =

OperationServiceHelper.executeOperate("submit","kded_simplebill",new DynamicObject[]{data},OperateOption.create());

if(!operationResult.getSuccessPkIds().isEmpty()){

//todo;

}

  1. 代码触发操作如何忽略验权

通过OperateOption传递对应参数,可以绕过权限校验。

OperateOption option = OperateOption.create();

option.setVariableValue(OperateOptionConst.ISHASRIGHT, "true");OperationResult

  1. 操作后如何刷新字段

配置实现

单据状态、日期这两种类型的字段可以在操作配置刷新字段实现。

代码实现

@Override

public void afterDoOperation(AfterDoOperationEventArgs

afterDoOperationEventArgs) {

super.afterDoOperation(afterDoOperationEventArgs);

FormOperate formoperate = (FormOperate)

afterDoOperationEventArgs.getSource();

if("操作代码".equals(formoperate.getOperateKey())) {

if(!afterDoOperationEventArgs.getOperationResult().getSuccessPkIds().

isEmpty()) {

this.getView().updateView("字段标识");

}

}

  1. 操作后如何提示

配置提示

固定的提示语可以直接在操作进行配置,如图:

代码修改操作后的提示

首先得在操作配置操作成功后提示,通过代码修改提示内容才会弹出显示。

方式1:在操作插件实现。

@Override

public void afterExecuteOperationTransaction(AfterOperationArgs e) {

if("save".equals(e.getOperationKey())&&!this.getOperationResult().getSuccessPkI ds().isEmpty()) {

this.getOperationResult().setMessage("保存成功啦-操作插件");

}

}

方式2:在界面插件实现。

@Override

public void afterDoOperation(AfterDoOperationEventArgs

afterDoOperationEventArgs) {

super.afterDoOperation(afterDoOperationEventArgs);

FormOperate formoperate = (FormOperate)

afterDoOperationEventArgs.getSource();

if("save".equals(formoperate.getOperateKey())&&!afterDoOperationEventA rgs.getOperationResult().getSuccessPkIds().isEmpty()) {

afterDoOperationEventArgs.getOperationResult().setMessage("保存成

功!-界面插件");

}

}

  1. 操作插件跟界面插件如何传递参数

从界面传递参数给操作插件

首先在界面插件给操作塞参数

@Override

public void beforeDoOperation(BeforeDoOperationEventArgs args) {

super.beforeDoOperation(args);

FormOperate formoperate = (FormOperate) args.getSource();

if("save".equals(formoperate.getOperateKey())) {

formoperate.getOption().setVariableValue("customItem",this.getView().

getPageCache().get("customItem"));

}

}

然后在操作插件取参数:

@Override

public void beginOperationTransaction(BeginOperationTransactionArgs e) {

super.beginOperationTransaction(e);

if ("save".equals(e.getOperationKey())) {

//取出界面传过来的参数

String customItem = this.getOption().getVariableValue("customItem");

}

}

从操作插件传递参数给界面

首先在操作插件给操作Option塞参数

@Override

public void afterExecuteOperationTransaction(AfterOperationArgs e) {

if("save".equals(e.getOperationKey())&&!this.getOperationResult().getSuccessPkI ds(). isEmpty()) {

this.getOption().setVariableValue("allBillNo","");

}

}

然后在界面插件取参数

@Override

public void afterDoOperation(AfterDoOperationEventArgs

afterDoOperationEventArgs) {

super.afterDoOperation(afterDoOperationEventArgs);

FormOperate formoperate = (FormOperate)

afterDoOperationEventArgs.getSource();

if("save".equals(formoperate.getOperateKey())&&!afterDoOperationEventArgs.g etOperationResult().getSuccessPkIds().isEmpty()) {

String allBillNo = formoperate.getOption().getVariableValue("allBillNo");

}

}

标签:getView,插件,getModel,标识,开发,单据,DynamicObject,kded
From: https://www.cnblogs.com/lcyyds/p/17514085.html

相关文章

  • 急速报表开发步骤
    新建字段库根据中台报表模板在该应用下创建报表页面导出页面到想要的位置设置过滤条件添加需要查询的字段到字段库创建字段映射创建数据源编写报表页面插件extendsAbstractReportFormPlugin给查询条件加默认值afterCreateNewData{}验证查询verifyQuery(ReportQueryParamquer......
  • 解决方案|基于TQA40I开发板的智慧教育投屏方案
    解决方案|基于TQA40I开发板的智慧教育投屏方案该解决方案采用了流媒体、组播、硬件解码等技术,实现了对电脑画面的采集、编码、组播传输、TQA40I硬件解码、显示流程。支持主屏广播模式及分组投屏模式两种投屏模式,支持文件内容显示、视频播放等功能,支持点对点方式,也支持一对多方式。......
  • Ruby web开发实战(3)-Ruby疑难点(3)
    目录运算符方法调用正则表达式命令行参数读文件运算符方法调用irb(main):001:0>10-9*33=>-287irb(main):002:0>irb(main):003:0>a=11=>11irb(main):004:0>b=12=>12irb(main):005:0>c=3=>3irb(main):006:0>a-b*c=>-25irb(main):007:0>在Ruby中......
  • 制作有延迟插件的rabbitmq镜像
    插件Git官方地址:https://github.com/rabbitmq/rabbitmq-delayed-message-exchangeDockerfileFROMrabbitmq:3.8.2-managementADD./rabbitmq_delayed_message_exchange-3.8.0.ez/pluginsRUNchown-Rrabbitmq./plugins/rabbitmq_delayed_message_exchange-3.8.0.ezRUNrabb......
  • C# HttpClient、API访问插件、接口访问
    关于使用插件访问接口.Net版本:NETFramework4.7.2 RestSharp版本:105.2.3.0Post访问 staticstringPostAction(){//公共apiconststringurl="https://api.uomg.com/api/rand.qinghua";//添加api访问......
  • Apifox:在线调试 OpenAI 接口,提供便捷的开发体验
    OpenAI 的API不仅可以通过编程语言(如Python、node.js)进行调用,还可以借助 Apifox 来在线调试。Apifox提供了直观且功能强大的方式来调试OpenAI接口,帮助开发者高效地发现和解决潜在问题。通过利用Apifox,开发者能够更快速地对项目进行迭代优化,确保OpenAI接口的稳定性和可......
  • Java or Python?测试开发工程师如何选择合适的编程语言?
    很多测试开发工程师尤其是刚入行的同学对编程语言和技术栈选择问题特别关注,毕竟掌握一门编程语言要花不少时间成本,也直接关系到未来的面试和就业(不同企业/项目对技术栈要求也不一样),根据自身情况做一个相对正确的选择确实要比盲目投入更明智也更高效。目前最常见的情况是纠结选择Jav......
  • 揭秘开心农场开发团队:初期仅15万元创业基金
     本文发表于2009-10-2709:1911/5/200911:29:21AM10月27日早间消息,据台湾媒体报道,《开心农场》游戏开发团队五分钟的三位创办人日前在接受台湾媒体《今周刊》的专访时透露,创业初期囊中羞涩,只能以15万元人民币的大学生创业奖金当成第一笔资金。以下为《今周刊》专访全文:你今天偷......
  • 如何做好网站开发项目需求分析
    作者:网络收集时间:2008-11-2511/5/200911:45:27AM一个网站项目的确立是建立在各种各样的需求上面的,这种需求往往来自于客户的实际需求或者是出于公司自身发展的需要,其中客户的实际需求也就是说这种交易性质的需求占了绝大部分。面对对网站开发拥有不同知识层面的客户,项目的负......
  • 明德扬FPGA核心板Xilnx开发Lattice光纤7K325T410T光纤PCIE口DDR3
                   ......