OneCode3.0插件开发指南:注解驱动的UI功能扩展框架

124 阅读10分钟

前言:OneCode插件技术体系与优势

OneCode插件体系是基于Java注解驱动的扩展性框架,允许二次开发用户通过标准化的注解配置与业务逻辑实现,无缝扩展UI设计器功能。该技术体系具备三大核心优势:

在这里插入图片描述

技术功能特点

  • 注解驱动开发:通过@EsbBeanAnnotation@FParams注解完成插件注册与参数声明,无需XML配置
  • 类型安全设计:强类型参数注入与返回值约束,编译期即可捕获类型错误
  • 微内核架构:插件与核心引擎松耦合,支持热部署与独立升级
  • UI组件深度集成:直接操作UI组件属性(可见性、禁用状态、数据权限等)
  • 业务流程嵌入:支持流程条件判断、活动权限控制等业务逻辑扩展 在这里插入图片描述

开发效率优势

  • 零配置集成:注解自动扫描与注册,无需手动配置插件路径
  • 标准化接口:统一的参数注入与结果返回模式,降低学习成本
  • 即插即用:编译打包后放入指定目录即可生效
  • 丰富的基础组件:内置8大类20+常用插件,覆盖大部分UI扩展场景 在这里插入图片描述

一、插件体系结构

在这里插入图片描述

1.1 整体架构

OneCode插件系统采用三层架构设计:

┌─────────────────────────────────────────┐
            UI设计器前端层                 插件功能可视化配置
├─────────────────────────────────────────┤
           插件运行时引擎层                注解解析参数注入生命周期管理
├─────────────────────────────────────────┤
           业务逻辑实现层                  用户开发的插件类(Java实现)
└─────────────────────────────────────────┘

1.2 包结构组织

插件开发包com.ds.esd.fun采用功能模块化组织:

com.ds.esd.fun
├── bar/           # 工具栏相关插件
├── bpm/           # 流程相关插件
├── component/     # 通用组件插件
├── condition/     # 条件判断插件
├── form/          # 表单相关插件
├── grid/          # 表格相关插件
├── item/          # 列表项插件
└── tab/           # 标签页插件

1.3 插件关系结构

┌─────────────────────────────────────────────────────────────┐
│                     核心注解体系                            │
│  ┌──────────────────┐        ┌──────────────────────────┐  │
│  │ @EsbBeanAnnotation │       │       @FParams           │  │
│  └──────────┬───────┘        └──────────────┬───────────┘  │
└─────────────┼───────────────────────────────┼──────────────┘
              │                               │
┌─────────────▼───────────────┐ ┌─────────────▼───────────────┐
│      功能插件分类           │ │        参数类型体系         │
│ ┌─────────┐ ┌─────────────┐ │ │ ┌─────────┐ ┌─────────────┐ │
│ │组件控制  │ │流程条件判断 │ │ │ │ESDCOM   │ │GRIDCOM      │ │
│ ├─────────┤ ├─────────────┤ │ │ ├─────────┤ ├─────────────┤ │
│ │表格操作  │ │权限管理     │ │ │ │CURRFORMCOM│ │CURRBAR     │ │
│ └─────────┘ └─────────────┘ │ │ └─────────┘ └─────────────┘ │
└─────────────────────────────┘ └─────────────────────────────┘

二、核心注解与参数枚举

2.1 核心注解详解

@EsbBeanAnnotation

插件注册核心注解,用于将Java类标记为OneCode插件:

@EsbBeanAnnotation(
    type = FormulaType.ESDCOM,  // 插件类型
    name = "隐藏组件"           // 插件显示名称
)

加粗样式

@FParams

参数注入注解,用于声明插件所需的输入参数:

public HiddenCom(@FParams(type = FormulaParams.ESDCOM) List<Component> comIds) {
    // 构造函数实现
}

加粗样式

2.2 FormulaType枚举完整说明

枚举值说明应用场景
ESDCOM组件操作类型UI组件显示/隐藏/禁用等控制
GridRight表格权限类型表格行/列权限控制
BarRight工具栏权限类型工具栏按钮控制
ItemRight列表项权限类型下拉列表/单选框选项控制
TabRight标签页权限类型标签页显示/隐藏控制
FormRight表单权限类型表单组件权限控制
ExpressionCon表达式条件类型条件判断逻辑
WorkFlowCon工作流条件类型流程节点权限控制
UIRightUI组件权限类型UI组件高级控制
PageCon页面条件类型页面级条件判断

2.3 FormulaParams枚举完整说明

枚举值说明对应参数类型
ESDCOMUI组件参数List
GRIDCOM表格组件参数List
CURRBAR当前工具栏参数List
CURRFORMCOM当前表单组件参数List
CURRITEM当前列表项参数List
CURRTAB当前标签页参数List/List
EXPRESSION表达式字符串参数String/Object
ACTIVITYDEF流程活动定义参数List
CURRUICOM当前UI组件参数List

加粗样式

三、插件分类与功能详解

3.1 组件控制类插件

用于控制UI组件的可见性、禁用状态等基础属性。

3.1.1 隐藏组件 (HiddenCom)

@EsbBeanAnnotation(type = FormulaType.ESDCOM, name = "隐藏组件")
public class HiddenCom {
    public HiddenCom(@FParams(type = FormulaParams.ESDCOM) List<Component> comIds) {
        for (Component component : comIds) {
            if (component.getProperties() instanceof AbsUIProperties) {
                AbsUIProperties absUIProperties = (AbsUIProperties) component.getProperties();
                absUIProperties.setDisplay("none");  // 设置组件不可见
            }
        }
    }
}

功能:通过设置组件样式display:none隐藏指定UI组件 适用场景:根据业务条件动态隐藏不需要的表单元素

3.1.2 隐藏UI组件 (HiddenUICom)

@EsbBeanAnnotation(type = FormulaType.UIRight, name = "隐藏组件")
public class HiddenUICom {
    public HiddenUICom(@FParams(type = FormulaParams.CURRUICOM) List<Component> comIds) {
        for (Component component : comIds) {
            if (component.getProperties() instanceof AbsUIProperties) {
                AbsUIProperties absUIProperties = (AbsUIProperties) component.getProperties();
                absUIProperties.setDisplay("none");
            }
        }
    }
}

功能:隐藏当前上下文的UI组件 区别:与HiddenCom相比,参数类型为CURRUICOM,专注于当前上下文组件

3.2 表格操作类插件

专注于表格组件的权限控制与交互限制。

3.2.1 隐藏操作按钮 (HiddenRowBar)

@EsbBeanAnnotation(type = FormulaType.GridRight, name = "隐藏操作按钮")
public class HiddenRowBar {
    public HiddenRowBar(@FParams(type = FormulaParams.GRIDCOM) List<UIItem> tabids) {
        for (UIItem tabListItem : tabids) {
            tabListItem.setHidden(true);  // 隐藏表格操作按钮
        }
    }
}

功能:隐藏表格行操作按钮 适用场景:根据数据状态控制操作权限(如已审核数据隐藏编辑按钮)

3.2.2 隐藏列选项 (HiddenHeader)

@EsbBeanAnnotation(type = FormulaType.GridRight, name = "隐藏列选项")
public class HiddenHeader {
    public HiddenHeader(@FParams(type = FormulaParams.GRIDCOM) List<UIItem> tabids) {
        for (UIItem tabListItem : tabids) {
            tabListItem.setHidden(true);
        }
    }
}

功能:隐藏表格列头选项 适用场景:根据用户权限隐藏敏感列(如身份证号、联系方式等)

3.3 工具栏控制插件

控制工具栏按钮的显示与禁用状态。

3.3.1 禁用按钮 (DisabledBarItem)

@EsbBeanAnnotation(type = FormulaType.BarRight, name = "禁用按钮")
public class DisabledBarItem {
    public DisabledBarItem(@FParams(type = FormulaParams.CURRBAR) List<UIItem> barItems) {
        for (UIItem barItem : barItems) {
            barItem.setDisabled(true);  // 禁用工具栏按钮
        }
    }
}

功能:禁用指定的工具栏按钮 适用场景:权限控制、业务状态限制(如未保存时禁用提交按钮)

3.3.2 隐藏按钮 (HiddenBarItem)

@EsbBeanAnnotation(type = FormulaType.BarRight, name = "隐藏按钮")
public class HiddenBarItem {
    public HiddenBarItem(@FParams(type = FormulaParams.CURRBAR) List<UIItem> barItems) {
        for (UIItem barItem : barItems) {
            barItem.setHidden(true);
        }
    }
}

功能:隐藏工具栏按钮 区别:与禁用按钮的区别在于完全隐藏而非仅置灰,适用于基于角色的功能显示控制

3.4 列表项控制插件

控制列表选项的可用性。

3.4.1 禁用选择项 (DisabledItem)

@EsbBeanAnnotation(type = FormulaType.ItemRight, name = "禁用选择项")
public class DisabledItem {
    public DisabledItem(@FParams(type = FormulaParams.CURRITEM) List<UIItem> tabids) {
        for (UIItem tabListItem : tabids) {
            tabListItem.setDisabled(true);  // 禁用列表项
        }
    }
}

功能:禁用下拉列表或单选框中的指定选项 适用场景:动态选项过滤、权限控制

3.5 标签页控制插件

控制标签页的显示与禁用状态。

3.5.1 隐藏标签页 (HiddenTab)

@EsbBeanAnnotation(type = FormulaType.TabRight)
public class HiddenTab {
    public HiddenTab(@FParams(type = FormulaParams.CURRTAB) List<UIItem> tabItems) {
        for (UIItem uiItem : tabItems) {
            uiItem.setHidden(true);  // 隐藏标签页
        }
    }
}

功能:隐藏指定的标签页 适用场景:根据用户角色或业务场景显示不同标签页内容

3.5.2 禁用TAB菜单 (DisabledTab)

@EsbBeanAnnotation(type = FormulaType.TabRight, name = "禁用TAB菜单")
public class DisabledTab {
    public DisabledTab(@FParams(type = FormulaParams.CURRTAB) List<TabListItem> tabids) {
        for (TabListItem tabListItem : tabids) {
            tabListItem.setDisabled(true);
        }
    }
}

功能:禁用标签页切换 区别:与隐藏标签页的区别在于标签仍可见但不可点击,适用于需要提示用户存在但无权限访问的场景

3.6 表单控制插件

专注于表单组件的特殊属性控制。

3.6.1 设置只读 (ReadOnlyCom)

@EsbBeanAnnotation(type = FormulaType.FormRight, name = "设置只读")
public class ReadOnlyCom {
    public ReadOnlyCom(@FParams(type = FormulaParams.CURRFORMCOM) List<Component> formComs) {
        for (Component component : formComs) {
            if (component.getProperties() instanceof DataProperties) {
                DataProperties dataProperties = (DataProperties) component.getProperties();
                dataProperties.setReadonly(true);  // 设置为只读
            }
        }
    }
}

功能:将表单组件设置为只读状态 适用场景:查看详情页面、已提交数据的编辑限制

3.7 条件判断插件

提供业务逻辑条件判断能力。

3.7.1 条件表达式 (FunConditionCon)

@EsbBeanAnnotation(type = FormulaType.ExpressionCon, name = "条件表达式")
public class FunConditionCon extends AbstractFunction {
    public Boolean perform(@FParams(type = FormulaParams.EXPRESSION) Object obj, ModuleComponent module) {
        if (obj == null || !Boolean.valueOf(obj.toString())) {
            return false;
        }
        return true;  // 返回表达式计算结果
    }
}

功能:计算表达式结果并返回布尔值 适用场景:复杂条件判断、权限控制逻辑

3.7.2 页面条件 (PageConditionCon)

@EsbBeanAnnotation(type = FormulaType.PageCon, name = "页面条件")
public class PageConditionCon extends AbstractFunction {
    public Boolean perform(@FParams(type = FormulaParams.EXPRESSION)String expression, ModuleComponent module) {
        return EsbFactory.par(expression, JDSActionContext.getActionContext().getContext(), module, Boolean.class);
    }
}

功能:计算页面级表达式结果 区别:专注于页面级别的条件判断,可访问页面上下文数据

3.8 流程控制插件

与工作流引擎集成,控制流程节点权限。

3.8.1 指定活动条件 (BPMConditionCon)

@EsbBeanAnnotation(type = FormulaType.WorkFlowCon, name = "指定活动条件")
public class BPMConditionCon extends AbstractFunction {
    public Boolean perform(@FParams(type = FormulaParams.ACTIVITYDEF) List<ActivityDef> activityDefs, ModuleComponent module) {
        ActivityInst activityInst = EsbFactory.par("$currActivityInst", ActivityInst.class);
        if (activityInst != null && activityDefs != null) {
            try {
                return activityDefs.contains(activityInst.getActivityDef());
            } catch (BPMException e) {
                e.printStackTrace();
            }
        }
        return true;  // 判断当前活动是否在指定列表中
    }
}

功能:判断当前流程活动是否在指定活动列表中 适用场景:流程节点权限控制、动态流程路由

3.8.2 流程条件 (WorkFlowCondition)

@EsbBeanAnnotation(type = FormulaType.WorkFlowCon, name = "流程条件")
public class WorkFlowCondition extends AbstractFunction {
    public Boolean perform(@FParams(type = FormulaParams.EXPRESSION) String expression, ModuleComponent module) {
        return EsbFactory.par(expression, JDSActionContext.getActionContext().getContext(), module, Boolean.class);
    }
}

功能:计算流程表达式并返回结果 适用场景:复杂流程条件判断、动态分支

四、插件开发指南

4.1 开发环境准备

  • JDK 1.8+ 开发环境
  • OneCode SDK 3.0+ 依赖包
  • Maven/Gradle 构建工具
  • IDE (IntelliJ IDEA 推荐)

4.2 开发步骤详解

步骤1:创建Maven项目

<!-- pom.xml 核心依赖 -->
<dependencies>
    <dependency>
        <groupId>com.onecode</groupId>
        <artifactId>onecode-esd</artifactId>
        <version>1.0-SNAPSHOT</version>
    </dependency>
    <dependency>
        <groupId>com.ds.esb</groupId>
        <artifactId>esb-core</artifactId>
        <version>1.0.0</version>
    </dependency>
</dependencies>

步骤2:创建插件类并添加注解

package com.ds.esd.fun.custom;

import com.ds.esb.config.EsbBeanAnnotation;
import com.ds.esb.config.formula.FormulaType;

@EsbBeanAnnotation(type = FormulaType.ESDCOM, name = "自定义显示控制")
public class CustomDisplayControl {
    // 实现代码
}

步骤3:定义构造函数与参数注入

import com.ds.esb.config.formula.FParams;
import com.ds.esb.config.formula.FormulaParams;
import com.ds.esd.tool.ui.component.Component;
import java.util.List;

public class CustomDisplayControl {
    // 注入UI组件参数
    public CustomDisplayControl(@FParams(type = FormulaParams.ESDCOM) List<Component> components) {
        // 业务逻辑实现
    }
}

步骤4:实现业务逻辑

public class CustomDisplayControl {
    public CustomDisplayControl(@FParams(type = FormulaParams.ESDCOM) List<Component> components) {
        for (Component component : components) {
            // 根据组件名称设置不同样式
            if ("statusField".equals(component.getName())) {
                setStatusStyle(component);
            }
        }
    }
    
    private void setStatusStyle(Component component) {
        // 设置组件样式逻辑
        String status = component.getValue().toString();
        if ("approved".equals(status)) {
            component.getProperties().setStyle("color: green;");
        } else if ("rejected".equals(status)) {
            component.getProperties().setStyle("color: red;");
        } else {
            component.getProperties().setStyle("color: black;");
        }
    }
}

步骤5:打包部署

  1. 使用Maven打包:mvn clean package
  2. 将生成的JAR文件复制到OneCode插件目录:{onecode_home}/plugins/
  3. 重启OneCode设计器,插件自动加载

4.3 开发示例:自定义状态标签插件

完整代码实现

package com.ds.esd.fun.custom;

import com.ds.esb.config.EsbBeanAnnotation;
import com.ds.esb.config.formula.FParams;
import com.ds.esb.config.formula.FormulaParams;
import com.ds.esb.config.formula.FormulaType;
import com.ds.esd.tool.ui.component.Component;
import com.ds.esd.tool.ui.component.container.AbsUIProperties;
import java.util.List;

@EsbBeanAnnotation(type = FormulaType.ESDCOM, name = "状态标签样式控制")
public class StatusLabelControl {
    // 注入需要控制的组件列表
    public StatusLabelControl(@FParams(type = FormulaParams.ESDCOM) List<Component> components) {
        for (Component component : components) {
            applyStatusStyle(component);
        }
    }
    
    /**
     * 根据状态值应用不同样式
     */
    private void applyStatusStyle(Component component) {
        if (!(component.getProperties() instanceof AbsUIProperties)) {
            return;
        }
        
        AbsUIProperties properties = (AbsUIProperties) component.getProperties();
        String status = String.valueOf(component.getValue()).toLowerCase();
        String style = getStyleByStatus(status);
        
        // 设置组件样式
        properties.setStyle(style);
        // 设置提示信息
        properties.setTooltip("状态: " + status);
    }
    
    /**
     * 根据状态获取样式
     */
    private String getStyleByStatus(String status) {
        switch (status) {
            case "draft":
                return "background-color: #f0f0f0; color: #666; padding: 2px 8px; border-radius: 12px;";
            case "pending":
                return "background-color: #fff3cd; color: #856404; padding: 2px 8px; border-radius: 12px;";
            case "approved":
                return "background-color: #d4edda; color: #155724; padding: 2px 8px; border-radius: 12px;";
            case "rejected":
                return "background-color: #f8d7da; color: #721c24; padding: 2px 8px; border-radius: 12px;";
            default:
                return "background-color: #e9ecef; color: #383d41; padding: 2px 8px; border-radius: 12px;";
        }
    }
}

使用说明

  1. 插件类型:FormulaType.ESDCOM(组件操作类型)
  2. 参数类型:FormulaParams.ESDCOM(UI组件列表)
  3. 功能描述:根据组件值(状态)自动应用不同样式,实现标签化展示
  4. 应用场景:流程状态、审批状态等需要视觉区分的场景

五、插件应用最佳实践

5.1 权限控制组合

// 组合使用禁用和隐藏插件实现复杂权限控制
HiddenBarItem("editBtn") + DisabledBarItem("viewBtn")

5.2 动态表单控制

// 根据角色显示不同表单元素
if (currentUser.hasRole("admin")) {
    ReadOnlyCom("normalField")
} else {
    HiddenCom("adminField")
}

5.3 流程节点控制

// 流程条件与组件控制结合
if (BPMConditionCon("activity1,activity2")) {
    HiddenCom("approveBtn")
} else {
    ReadOnlyCom("commentField")
}

六、总结

OneCode自定义扩展函数采用注解驱动开发模式,通过简单的Java类定义即可实现丰富的业务功能。本文详细介绍了com.ds.esd.fun包下的全部20个插件,涵盖组件控制、表格操作、工具栏控制、标签页控制、表单控制、条件判断和流程控制七大类别。

开发者可根据实际需求,参考现有插件结构快速开发新的扩展函数,实现UI控制、权限管理、流程判断等多样化需求。插件体系的设计遵循开闭原则,既提供了丰富的内置功能,又保留了灵活的扩展能力,是OneCode平台低代码开发理念的重要体现。