本文讨论了如何在苍穹系统中实现一个自定义的F7选择框功能,以允许用户选择不仅限于基础资料的数据,包括单据数据或计算得出的数据。通过构建树形结构和单据体数据,并利用插件代码实现这一功能。文中详细描述了插件的开发过程,包括数据源构建、单据体数据加载、事件监听等,最后提供了开发环境的版本要求和注意事项。
关键词:F7已选字段
一、需求
众所周知苍穹的f7是基础资料字段独有的一种展示形式,用于选择数据
但是有的时候我们不止想要选择基础资料,也想选择单据数据
或者有些数据不是结构化的需要拆分构建不好展示
甚至,有些数据根本不是存在数据表中的是凭空出现或者计算出来的
这时候我们还想弹出f7并且让用户选择,返回一些数据,那么我们就可以利用苍穹自己实现这个功能
二、思路与方案
首先我们可以看下页面如何设计
参考标准f7即可
三、实现过程
页面:标识:kdec_testf7andentry
数据因为存在不确定性,这里面我们可以用单据体承载数据,将锁定并且将选择模式改为列表,添加一些必要的控件
将页面设计一下既可开始实现逻辑,插件代码实现
插件:
先构建树 可以参考https://club.kdcloud.com/article/246958760772928000
1、通过数据源构建左树
@Override public void afterCreateNewData(EventObject e) { super.afterCreateNewData(e); TreeView tv1 = this.getView().getControl("kdec_treeview"); this.constructorData(tv1); this.loadEntryData(new QFilter("1", "=", "1")); } /** * 构造数据 */ private void constructorData(TreeView tv1) { final String rootId = "0"; // 根节点id TreeNode rootNode = new TreeNode(null, rootId, "根节点", true); rootNode.setIsOpened(true); // 设置默认展开 // 查出分组数据 DynamicObjectCollection types = QueryServiceHelper.query("kdec_channel_type", "Id,name", null); // 查出渠道数据 DynamicObjectCollection channels = QueryServiceHelper.query("kdec_channel", "Id,name,group.Id", null); // 按照分类分组 Map<String, List<DynamicObject>> datatypeMap = channels.stream() .collect(Collectors.groupingBy(it -> it.getString("group.Id"))); for (DynamicObject type : types) {// 构建树节点 // 构造一级子节点 String typeId = type.getString("Id"); TreeNode tn1 = new TreeNode(rootId, typeId, type.getString("name"), true); tn1.setIsOpened(true); tn1.setColor("red"); // 设置节点文字颜色 List<DynamicObject> channelsByType = datatypeMap.get(type.getString("Id")); for (DynamicObject channel : channelsByType) { // 构造二级子节点 String channelId = channel.getString("Id"); TreeNode tn2 = new TreeNode(typeId, channelId, channel.getString("name"), false); tn1.addChild(tn2); } rootNode.addChild(tn1); } tv1.addNode(rootNode); }
2、构建单据体数据,我这里呢用的是单据的数据构建的,大家可以自己搞各类数据源渲染到字段上就行,这里可扩展性很广,可以加很多字段,只要能对应渲染好即可
/** * 加载单据体数据 */ private void loadEntryData(QFilter qFilter) { DynamicObjectCollection entrys = this.getModel().getEntryEntity("kdec_entryentity"); entrys.clear(); DynamicObject[] datas = BusinessDataServiceHelper.load("kdec_demo1111tree", "Id,billno,kdec_channel.name", qFilter.toArray()); for (DynamicObject data : datas) { DynamicObject entry = new DynamicObject(entrys.getDynamicObjectType()); entry.set("kdec_zj", data.getPkValue()); entry.set("kdec_number", data.getString("billno")); entry.set("kdec_name", data.getString("kdec_channel.name")); entrys.add(entry); } this.getModel().updateCache(); this.getModel().updateEntryCache(entrys); this.getView().updateView("kdec_entryentity"); }
3、监听f7控件的事件为了联动勾选功能,并且监听单据体行点击,定义一个全局集合为的是记录f7数据,这里我只是找了简单方式实现,推荐大家使用页面缓存,或者redis记录集合,亦或者在页面加个隐藏的单据体记录,这样就不用考虑清理机制,还有就是数据隔离的问题
public class EntryTreeF7CusPlugin extends AbstractFormPlugin implements TreeNodeClickListener, F7SelectedListRemoveListener, F7SelectedListSortListener, RowClickEventListener { private static List<ValueTextItem> valueTextItems = new ArrayList<>(); @Override public void registerListener(EventObject e) { super.registerListener(e); TreeView tv1 = this.getView().getControl("kdec_treeview"); tv1.addTreeNodeClickListener(this); F7SelectedList f7SelectedList = this.getControl("kdec_f7selectedlistap"); f7SelectedList.addF7SelectedListRemoveListener(this); f7SelectedList.addF7SelectedListRemoveAllListener(this); f7SelectedList.addF7SelectedListSortListener(this); EntryGrid entryGrid = this.getControl("kdec_entryentity"); entryGrid.addRowClickListener(this); } @Override public void afterCreateNewData(EventObject e) { super.afterCreateNewData(e); TreeView tv1 = this.getView().getControl("kdec_treeview"); this.constructorData(tv1); this.loadEntryData(new QFilter("1", "=", "1")); }
4、treeNodeClick 树点击实现数据的重新加载,还有一些默认勾选的数据,由f7控件带过来
@Override public void treeNodeClick(TreeNodeEvent e) { if (e.getNodeId().equals("0")) { this.loadEntryData(new QFilter("1", "=", "1")); } else { this.loadEntryData(new QFilter("kdec_channel.id", QCP.equals, e.getNodeId()) .or(new QFilter("kdec_channel.group.id", QCP.equals, e.getNodeId()))); } if (valueTextItems.size()>0) { selectDefaultRows(); } }
private void selectDefaultRows() { EntryGrid entryGrid = this.getControl("kdec_entryentity"); List<String> pks = (valueTextItems.stream().map(ValueTextItem::getValue)).collect(Collectors.toList()); DynamicObjectCollection entrys = this.getModel().getEntryEntity("kdec_entryentity"); List<Integer>selectRows = new ArrayList<>(); for (DynamicObject entry : entrys) { if (pks.contains(entry.getString("kdec_zj"))) { selectRows.add(entry.getInt("seq")-1); } } entryGrid.selectRows(selectRows.stream().mapToInt(Integer::valueOf).toArray(), 0); }
5、行点击里面实现赋值f7的功能
@Override public void entryRowClick(RowClickEvent evt) { RowClickEventListener.super.entryRowClick(evt); DynamicObjectCollection entrys = this.getModel().getEntryEntity("kdec_entryentity"); EntryGrid entryGrid = this.getControl("kdec_entryentity"); F7SelectedList f7SelectedList = this.getControl("kdec_f7selectedlistap"); int[] rows = entryGrid.getSelectRows(); valueTextItems.clear(); for (int i : rows) { ValueTextItem item = new ValueTextItem(entrys.get(i).getString("kdec_zj"), entrys.get(i).getString("kdec_number")); valueTextItems.add(item); } f7SelectedList.addItems(valueTextItems); }
6、移除f7数据实现单据体联动
@Override public void RemoveClick(F7SelectedListRemoveEvent arg0) { EntryGrid entryGrid = this.getControl("kdec_entryentity"); if (arg0.getParam() == null) {// 清空 entryGrid.clearEntryState(); } else { String pk = (String) arg0.getParam(); DynamicObjectCollection entrys = this.getModel().getEntryEntity("kdec_entryentity"); for (DynamicObject entry : entrys) { if (entry.getString("kdec_zj").equals(pk)) { List<Integer> rows = Arrays.stream(entryGrid.getSelectRows()).boxed().collect(Collectors.toList()); rows = rows.stream().filter(e -> (entry.getInt("seq") - 1) != e).collect(Collectors.toList()); entryGrid.selectRows(rows.stream().mapToInt(Integer::valueOf).toArray(), 0); break; } } } }
7、清除变量集合
@Override public void beforeClosed(BeforeClosedEvent e) { super.beforeClosed(e); valueTextItems.clear(); }
四、效果图
五、开发环境版本
4.0及以上
六、注意事项
主要是数据联动的功能,因为f7不具备get数据集的功能,所以要自己记录
通过主键等字段确定唯一性
七、参考资料
kdec_case-kdec_grid-2022030817 …(8.46KB)