本文档描述了两种数据展示的技术方案,包括数据库分页查询和内存分页实现。内存分页实现部分通过扩展特定框架的类并复写方法来实现自定义分页控件`CustEntryGrid`。表单插件`DemoLinkFormPlugin`被用于初始化这个自定义控件,并处理数据绑定、控件获取、超链接点击等事件。自定义控件`CustEntryGrid`采用Builder模式构建,支持设置查询元数据标识、查询字段、字段映射、排序和过滤条件等。通过该插件和控件,实现了对第三方数据列表的分页展示以及其他单据数据的组合列表展示。
场景:
1.第三方数据列表分页展示
2.其他单据数据,组合列表展示
技术方案:
1.数据库分页查询
2.内存分页
实现:
1.扩展kd.bos.form.control.EntryGrid类,并复写onFetchPageData取数方法,getRowCount总行数方法。
2.扩展kd.bos.form.plugin.AbstractFormPlugin类,并复写onGetControl获取控件方法,initialize方法里声明为自定义控件,afterBindData方法里调用自定义控件方法进行初始化列表。
实现代码:
表单插件:
public class DemoLinkFormPlugin extends AbstractFormPlugin implements HyperLinkClickListener {
private final String KEY_ENTRYENTITY = "entryentity"; // 动态表单上分录或单据体标识
private final String KEY_SELECTFIELDS = "id,查询的字段";
private final String KEY_ORDERBY = "排序";
private String KEY_QUERYENTITY = ""; // 查询的元数据标识
@Override
public void initialize() {
super.initialize();
this.getView().addCustomControls(KEY_ENTRYENTITY);
}
@Override
public void afterBindData(EventObject e) {
super.afterBindData(e);
EntryGrid entry = this.getView().getControl(KEY_ENTRYENTITY);
entry.setPageRows(entry.getPageRow());
}
@Override
public void onGetControl(OnGetControlArgs e) {
super.onGetControl(e);
if (KEY_ENTRYENTITY.equalsIgnoreCase(e.getKey())) {
Control oldGrid = e.getControl();
if (oldGrid == null){
return ;
}
CustEntryGrid custGrid = null ;
if (oldGrid instanceof CustEntryGrid) {
custGrid = (CustEntryGrid) oldGrid;
} else {
custGrid = onGetControl();
}
if (Objects.isNull(custGrid)) {
return ;
}
custGrid.setView(this.getView());
custGrid.setKey(KEY_ENTRYENTITY);
custGrid.setEntryKey(KEY_ENTRYENTITY);
custGrid.setSplitPage(true);
if (oldGrid instanceof EntryGrid) {
//将设计器设置的字段赋值到新的控件上
custGrid.getItems().addAll(((EntryGrid) oldGrid).getItems());
//将设计器设置的分页条数赋值到新的控件上
custGrid.setPageRow(((EntryGrid) oldGrid).getPageRow());
}
e.setControl(custGrid);
}
}
protected CustEntryGrid onGetControl() {
if (条件1) {
KEY_QUERYENTITY = "元数据标识1" ;
} else if (条件2) {
KEY_QUERYENTITY = "元数据标识2" ;
}
if (StringUtils.isBlank(KEY_QUERYENTITY)) {
return null ;
}
// 可以从当前页面获取参数
Map<String, Object> values = this.getView().getFormShowParameter().getCustomParams();
QFilter qFilter = 构造过滤条件;
return CustEntryGrid.getInstance().setQueryEntityId(KEY_QUERYENTITY)
.setSelectFields(KEY_SELECTFIELDS)
.addQFilter(qFilter)
.addFieldMapping(new Tuple<>("查询列字段标识", "展示列字段标识"))
... ....
.setOrderBy(KEY_ORDERBY)
.setThird(false)
.builder();
}
@Override
public void registerListener(EventObject e) {
super.registerListener(e);
EntryGrid entry = this.getView().getControl(KEY_ENTRYENTITY);
if (Objects.nonNull(entry)) {
entry.addHyperClickListener(this);
}
}
@Override
public void hyperLinkClick(HyperLinkClickEvent event) {
CustEntryGrid source = (CustEntryGrid) event.getSource();
int[] selectRows = source.getSelectRows();
Object id = this.getModel().getValue("id", selectRows[0]);
BillShowParameter showParameter = new BillShowParameter();
showParameter.setFormId(KEY_QUERYENTITY);
showParameter.setPkId(id);
showParameter.setCustomParam("mykey", "hello world"); // 自定义参数,随开发者喜欢,想传什么就传什么
showParameter.getOpenStyle().setShowType(ShowType.NewWindow); //打开方式
if (showParameter.getFormConfig() == null) {
showParameter.setFormConfig(FormMetadataCache.getFormConfig(KEY_QUERYENTITY));
}
showParameter.setHasRight(true);
showParameter.setBillStatus(BillOperationStatus.VIEW);
showParameter.setStatus(OperationStatus.VIEW);
this.getView().showForm(showParameter);
}
}
自定义控件:
public class CustEntryGrid extends EntryGrid {
private CustEntryGridBuilder builder;
/**
* 用Builder模式构建
*/
private CustEntryGrid(CustEntryGridBuilder custEntryGridBuilder) {
this.builder = custEntryGridBuilder;
}
public static class CustEntryGridBuilder {
/**
* 查询的单据标识
*/
private String queryEntityId;
/**
* 查询的字段
*/
private String selectFields;
/**
* 构建字段映射
* 查询的表字段 to 分录的字段
* 如果为空则默认使用字段名一致
*/
private List<Tuple<String, String>> fieldMapping;
/**
* 排序
*/
private String orderBy;
/**
* 是否第三方接口数据
*/
private boolean isThird;
/**
* 过滤条件
*/
private List<QFilter> qFilters;
public CustEntryGridBuilder setQueryEntityId(String queryEntityId) {
this.queryEntityId = queryEntityId;
return this;
}
public CustEntryGridBuilder setSelectFields(String selectFields) {
this.selectFields = selectFields;
return this;
}
public CustEntryGridBuilder setThird(boolean third) {
isThird = third;
return this ;
}
public CustEntryGridBuilder addSelectFields(String selectField) {
if (StringUtils.isNotBlank(selectField)) {
if (StringUtils.isBlank(this.selectFields)) {
this.selectFields = selectField;
} else {
this.selectFields = this.selectFields.concat(",").concat(selectField);
}
}
return this;
}
public CustEntryGridBuilder setFieldMapping(List<Tuple<String, String>> fieldMapping) {
this.fieldMapping = fieldMapping;
return this;
}
public CustEntryGridBuilder addFieldMapping(Tuple<String, String> fieldMappingTuple) {
if (CollectionUtils.isEmpty(this.fieldMapping)) {
this.fieldMapping = new ArrayList<>();
}
if (fieldMappingTuple != null) {
this.fieldMapping.add(fieldMappingTuple);
}
return this;
}
public CustEntryGridBuilder setOrderBy(String orderBy) {
this.orderBy = orderBy;
return this;
}
public CustEntryGridBuilder setQFilters(List<QFilter> qFilters) {
this.qFilters = qFilters;
return this;
}
public CustEntryGridBuilder addQFilter(QFilter qFilter) {
if (CollectionUtils.isEmpty(this.qFilters)) {
this.qFilters = new ArrayList<>();
}
if (qFilter != null) {
this.qFilters.add(qFilter);
}
return this;
}
public String getQueryEntityId() {
return queryEntityId;
}
public String getSelectFields() {
if (StringUtils.isBlank(selectFields)) {
if (CollectionUtils.isEmpty(fieldMapping)) {
DynamicObject queryEntity = BusinessDataServiceHelper.newDynamicObject(queryEntityId);
IDataEntityType queryEntityType = queryEntity.getDataEntityType();
selectFields = queryEntityType.getProperties().stream().map(p -> p.getName()).collect(Collectors.joining(","));
} else {
selectFields = fieldMapping.stream().map(t -> t.item1).collect(Collectors.joining(","));
}
}
return selectFields;
}
public List<Tuple<String, String>> getFieldMapping() {
return fieldMapping;
}
public String getOrderBy() {
return orderBy;
}
public boolean isThird() {
return isThird;
}
public List<QFilter> getQFilters() {
return qFilters;
}
public CustEntryGrid builder() {
if (StringUtils.isBlank(queryEntityId)) {
throw new KDBizException("queryEntityId is empty.");
}
if (CollectionUtils.isEmpty(qFilters)) {
throw new KDBizException("qFilters is empty.");
}
if (CollectionUtils.isEmpty(fieldMapping)) {
throw new KDBizException("fieldMapping is empty.");
}
return new CustEntryGrid(this);
}
}
public static CustEntryGridBuilder getInstance() {
return new CustEntryGridBuilder();
}
@Override
protected boolean onFetchPageData(int pageIndex, int pageRows) {
//1、先清空单据体控件的数据
DynamicObject dataEntity = this.getModel().getDataEntity(true);
DynamicObjectCollection entryEntities = dataEntity.getDynamicObjectCollection(this.getKey());
entryEntities.clear();
//2、查询并设置分录数据
if (builder.isThird) {
setThirdEntryEntities(entryEntities, pageIndex, pageRows);
} else {
setEntryEntities(entryEntities, pageIndex, pageRows);
}
//数据起始行索引更新:
//① 单据体序号显示
//② setValue赋值时,序号要一致,比如:5行/页,展示第二页数据时,第一行显示序号是6(RowIndex是5)
//赋值示例:this.getModel.setValue("key","value",5); 是对第二页第一行字段赋值
//③ 如果你想第二页第一行序号页从1开始,则设置起始序号从0开始即可:setEntryStartRowIndex(this.getKey(), 0);
int startRowIndex = (pageIndex - 1) * pageRows;
dataEntity.getDataEntityState().setEntryStartRowIndex(this.getKey(), startRowIndex);
dataEntity.getDataEntityState().setEntryPageSize(this.getKey(), pageRows);
//设置分录记录总行数
dataEntity.getDataEntityState().setEntryRowCount(this.getKey(), this.getRowCount());
return true;
}
@Override
protected int getRowCount() {
ORM orm = ORM.create();
String algoKey = this.getKey() + "_" + builder.getQueryEntityId();
String entityName = builder.getQueryEntityId();
String selectFields = "id" ;
List<QFilter> qFilters = builder.getQFilters();
Distinctable distinct = null ;
int count = orm.count(algoKey, entityName, selectFields, qFilters.toArray(new QFilter[0]), distinct);
return count ;
}
/**
* 基础服务云自定义api调用
* @param entryEntities
* @param pageIndex
* @param pageRows
*/
protected void setThirdEntryEntities(DynamicObjectCollection entryEntities, int pageIndex, int pageRows) {
Map<String, String> requestData = null ; // context.getThirdRequestParam();
String authorization = null ; // context.getTransparentToken();
String empNo = ""; // requestData.get(HtmHdmBaseHelper.EMP_NO);
DynamicObject[] eDatas = IscCallUtils.callScriptApi("IscCallUrl", new Object[]{requestData, empNo, authorization}, null);
if (eDatas != null && eDatas.length > 0) {
Arrays.stream(eDatas).forEach(dy -> {
DynamicObject entryRow = entryEntities.addNew();
if (CollectionUtils.isNotEmpty(builder.getFieldMapping())) {
builder.getFieldMapping().forEach(t -> {
entryRow.set(t.item2, dy.get(t.item1));
});
} else {
Arrays.stream(builder.getSelectFields().split(",")).forEach(f -> {
entryRow.set(f, dy.get(f));
});
}
});
}
}
private void setEntryEntities(DynamicObjectCollection entryEntities, int pageIndex, int pageRows) {
//2、调用第三方API接口获取当前页数据
DynamicObject[] eDatas = BusinessDataServiceHelper.load(builder.getQueryEntityId(), builder.getSelectFields(), builder.getQFilters().toArray(new QFilter[0]), builder.getOrderBy(), pageIndex - 1, pageRows);
if (eDatas != null && eDatas.length > 0) {
Arrays.stream(eDatas).forEach(dy -> {
DynamicObject entryRow = entryEntities.addNew();
if (CollectionUtils.isNotEmpty(builder.getFieldMapping())) {
builder.getFieldMapping().forEach(t -> {
entryRow.set(t.item2, dy.get(t.item1));
});
} else {
Arrays.stream(builder.getSelectFields().split(",")).forEach(f -> {
entryRow.set(f, dy.get(f));
});
}
});
}
}
}
~END~
推荐阅读