服务好的专业建站公司wordpress可视化divi

张小明 2026/1/8 18:33:21
服务好的专业建站公司,wordpress可视化divi,亚马逊雨林视频纪录片,房地产基础知识新手必看文章目录一、Expression 是什么#xff1f;二、Expression 的类型三、Expression 如何被注入#xff1f;四、在 BPMN 文件中配置五、Expression 的常用方法六、支持多种表达式类型#xff08;完整示例#xff09;七、抄送任务监听器中的使用八、完整的改进监听器示例一、Ex…文章目录一、Expression 是什么二、Expression 的类型三、Expression 如何被注入四、在 BPMN 文件中配置五、Expression 的常用方法六、支持多种表达式类型完整示例七、抄送任务监听器中的使用八、完整的改进监听器示例一、Expression 是什么在Activiti或Flowable中Expression是一个表达式对象它可以用来存储流程定义中配置的表达式。这个表达式可以是固定值也可以是动态的比如使用UEL表达式。在流程定义中我们可以在监听器配置中设置表达式的值。二、Expression 的类型Flowable 支持多种表达式类型类型示例说明固定值user1,user2,user3直接指定的值变量表达式${userId}从流程变量中获取方法表达式${bean.method(userId)}调用 Spring Bean 的方法组合表达式${userService.getCcUsers(processId)}复杂表达式三、Expression 如何被注入在你的代码中privateExpressionuserIds;这个字段会被 Flowable 引擎自动注入注入的来源是流程定义文件BPMN中的配置。四、在 BPMN 文件中配置!-- 方式1直接指定用户ID固定值 --userTaskidapproveTaskname审批任务flowable:assigneezhangsanextensionElementsflowable:taskListenereventcreateclasscom.ruoyi.flowable.listener.FlowCopyTaskListenerflowable:fieldnameuserIdsflowable:string![CDATA[1001,1002,1003]]/flowable:string/flowable:field/flowable:taskListener/extensionElements/userTask!-- 方式2使用变量动态值 --userTaskidapproveTaskname审批任务extensionElementsflowable:taskListenereventcreateclasscom.ruoyi.flowable.listener.FlowCopyTaskListenerflowable:fieldnameuserIdsflowable:expression![CDATA[${ccUserIds}]]/flowable:expression/flowable:field/flowable:taskListener/extensionElements/userTask!-- 方式3调用Spring Bean方法 --userTaskidapproveTaskname审批任务extensionElementsflowable:taskListenereventcreateclasscom.ruoyi.flowable.listener.FlowCopyTaskListenerflowable:fieldnameuserIdsflowable:expression![CDATA[${userService.getCcUsers(execution.getVariable(deptId))}]]/flowable:expression/flowable:field/flowable:taskListener/extensionElements/userTask五、Expression 的常用方法publicinterfaceExpression{// 获取表达式原文StringgetExpressionText();// 获取解析后的值ObjectgetValue(VariableScopevariableScope);// 设置值voidsetValue(Objectvalue,VariableScopevariableScope);// 检查是否为文字文本booleanisLiteralText();}六、支持多种表达式类型完整示例Slf4jComponentpublicclassFlowCopyTaskListenerimplementsTaskListener{privateExpressionuserIds;Overridepublicvoidnotify(DelegateTaskdelegateTask){log.info(抄送任务监听器被触发, 任务ID: {},delegateTask.getId());// 方法1直接获取表达式文本适用于固定值StringexpressionTextuserIds.getExpressionText();log.info(表达式原文: {},expressionText);// 方法2获取解析后的值适用于变量表达式ObjectvalueuserIds.getValue(delegateTask.getExecution());log.info(解析后的值: {},value);// 解析抄送人员IDListStringuserIdListparseUserIds(value,expressionText,delegateTask);if(!CollectionUtils.isEmpty(userIdList)){processCopyTask(delegateTask,userIdList);}}/** * 解析用户ID列表 */privateListStringparseUserIds(Objectvalue,StringexpressionText,DelegateTaskdelegateTask){ListStringuserIdListnewArrayList();// 情况1如果值是List类型if(valueinstanceofList){List?list(List?)value;for(Objectitem:list){if(item!null){userIdList.add(item.toString());}}}// 情况2如果值是字符串逗号分隔elseif(valueinstanceofString){StringstrValue(String)value;if(StringUtils.isNotBlank(strValue)){userIdListArrays.asList(strValue.split(,));}}// 情况3直接使用表达式文本固定值elseif(StringUtils.isNotBlank(expressionText)){// 检查是否为变量表达式以${开头}结尾if(expressionText.startsWith(${)expressionText.endsWith(})){// 尝试从流程变量中获取StringvariableNameexpressionText.substring(2,expressionText.length()-1);ObjectvariableValuedelegateTask.getExecution().getVariable(variableName);if(variableValueinstanceofString){userIdListArrays.asList(((String)variableValue).split(,));}}else{// 直接按逗号分隔userIdListArrays.asList(expressionText.split(,));}}// 去除空白字符returnuserIdList.stream().map(String::trim).filter(StringUtils::isNotBlank).collect(Collectors.toList());}/** * 处理抄送任务 */privatevoidprocessCopyTask(DelegateTaskdelegateTask,ListStringuserIdList){// ... 原有处理逻辑RepositoryServicerepositoryServiceSpringUtils.getBean(RepositoryService.class);ISysCopyServicesysCopyServiceSpringUtils.getBean(ISysCopyService.class);// ... 其他代码}}七、抄送任务监听器中的使用在抄送任务监听器中userIds是一个Expression类型的属性它会在流程引擎运行到该任务节点时根据流程定义中配置的表达式进行解析。在流程定义XML中配置监听器如下flowable为例userTaskidmyTasknameMy TaskextensionElementsflowable:taskListenereventcreateclasscom.ruoyi.flowable.listener.FlowCopyTaskListenerflowable:fieldnameuserIdsflowable:string![CDATA[${抄送人员表达式}]]/flowable:string/flowable:field/flowable:taskListener/extensionElements/userTask其中${抄送人员表达式}可以是一个变量也可以是多个用户ID的拼接字符串如1,2,3或者是一个返回用户ID列表的表达式。在监听器类中我们使用private Expression userIds;来接收这个表达式。当监听器被触发时userIds已经被流程引擎注入我们可以通过userIds.getExpressionText()来获取表达式字符串或者通过userIds.getValue(delegateTask)来获取表达式的值如果表达式是变量则会解析为变量值。但是注意在上面的代码中监听器直接使用了userIds.getExpressionText()这意味着它获取的是表达式原文而不是解析后的值。如果表达式是变量比如c c U s e r I d s 那么这里得到的就是 {ccUserIds}那么这里得到的就是ccUserIds那么这里得到的就是{ccUserIds}字符串而不是变量值。因此这种方式只适用于表达式是固定字符串的情况比如直接写死用户ID列表。如果要支持表达式动态解析应该使用userIds.getValue(delegateTask)来获取解析后的值。例如如果我们在流程变量中设置了ccUserIds为1,2,3那么userIds.getValue(delegateTask)将返回一个字符串1,2,3。然后我们可以按照逗号分割得到用户ID列表。注意userIds.getValue(delegateTask)返回的类型是Object我们需要根据实际情况进行类型转换。如果表达式是多个用户ID的列表也可以配置为集合类型但通常我们使用逗号分隔的字符串。因此修改后的代码可以这样写如果表达式是固定字符串比如1,2,3那么使用getExpressionText()即可。如果表达式是变量那么应该使用getValue(delegateTask)。但是为了同时支持两种情况我们可以这样做先尝试用getValue(delegateTask)获取值如果返回值为空则使用getExpressionText()。或者我们可以在流程定义中明确配置是固定值还是变量。然而在大多数情况下我们更希望支持动态变量。所以我们可以这样修改Slf4jComponentpublicclassFlowCopyTaskListenerimplementsTaskListener{/** * 抄送人员id集合 */privateExpressionuserIds;Overridepublicvoidnotify(DelegateTaskdelegateTask){log.info(抄送任务监听器, 任务ID:{},delegateTask.getId());// 获取抄送人员ID字符串StringuserIdsStrnull;if(userIds!null){// 尝试获取表达式的值如果是变量则解析变量ObjectvalueuserIds.getValue(delegateTask);if(value!null){userIdsStrvalue.toString();}else{// 如果解析变量后为空则使用表达式原文可能是固定值userIdsStruserIds.getExpressionText();}}if(StringUtils.isNotBlank(userIdsStr)){// 从 Spring 容器中获取相关服务RepositoryServicerepositoryServiceSpringUtils.getBean(RepositoryService.class);ISysCopyServicesysCopyServiceSpringUtils.getBean(ISysCopyService.class);ISysUserServicesysUserServiceSpringUtils.getBean(ISysUserService.class);// 获取流程定义信息ProcessDefinitionpdrepositoryService.createProcessDefinitionQuery().processDefinitionId(delegateTask.getProcessDefinitionId()).singleResult();// 获取任务发起人信息注意这里delegateTask.getAssignee()是当前任务的办理人不一定是流程发起人// 如果需要流程发起人可以通过流程实例的启动人获取// 例如String startUserId delegateTask.getProcessInstance().getStartUserId();// 这里根据业务需求调整StringassigneedelegateTask.getAssignee();SysUserstartUsernull;if(assignee!null){startUsersysUserService.selectUserById(Long.parseLong(assignee));}// 构造 SysCopy 对象SysCopysysCopynewSysCopy();sysCopy.setProcInsId(delegateTask.getProcessInstanceId());sysCopy.setDeployId(pd.getDeploymentId());sysCopy.setProcName(pd.getName());sysCopy.setTaskId(delegateTask.getId());sysCopy.setTaskName(delegateTask.getName());if(startUser!null){sysCopy.setSendUserId(startUser.getUserId());sysCopy.setSendUserName(startUser.getNickName());}sysCopy.setStatus(0);sysCopy.setCreateTime(newDate());// 分割用户ID字符串注意处理可能的分隔符逗号、分号等ListStringuserIdListArrays.asList(userIdsStr.split([,;]));userIdList.forEach(userId-{// 去除空白userIduserId.trim();if(StringUtils.isNotBlank(userId)){sysCopy.setReceiveUserId(Long.parseLong(userId));// 插入抄送记录sysCopyService.insertSysCopy(sysCopy);}});}}}注意上面的代码中我修改了获取流程发起人的方式。因为delegateTask.getAssignee()是当前任务的办理人而抄送可能是由当前办理人发起的所以这样设置。但是如果抄送是要发送给其他人而发起人应该是流程的启动人那么就需要通过delegateTask.getProcessInstance().getStartUserId()来获取流程启动人。另外增加了sysCopy.setCreateTime(new Date());因为通常插入记录需要创建时间。还有分割用户ID时我支持了逗号和分号两种分隔符并去除了空白。这样修改后监听器就可以支持表达式动态获取抄送人员列表了。在流程定义中我们可以这样配置固定值1,2,3 变量${ccUserIds}其中ccUserIds是流程变量值为1,2,3这样监听器就可以灵活地获取抄送人员了。八、完整的改进监听器示例下面是一个灵活的监听器类的示例Slf4jComponentpublicclassEnhancedFlowCopyTaskListenerimplementsTaskListener{AutowiredprivateRepositoryServicerepositoryService;AutowiredprivateISysCopyServicesysCopyService;AutowiredprivateISysUserServicesysUserService;AutowiredprivateApplicationContextapplicationContext;privateExpressionuserIds;privateExpressioncopyType;// 抄送类型固定、变量、方法privateExpressioncopyRule;// 抄送规则Overridepublicvoidnotify(DelegateTaskdelegateTask){try{// 1. 获取流程信息ProcessDefinitionpdrepositoryService.createProcessDefinitionQuery().processDefinitionId(delegateTask.getProcessDefinitionId()).singleResult();// 2. 解析抄送人员支持多种方式ListLonguserIdsresolveUserIds(delegateTask);// 3. 获取发起人改进从流程实例启动人获取StringstartUserIddelegateTask.getProcessInstance().getStartUserId();SysUserstartUsersysUserService.selectUserById(Long.parseLong(startUserId));// 4. 创建抄送记录createCopyRecords(delegateTask,pd,startUser,userIds);}catch(Exceptione){log.error(抄送任务处理失败,e);}}/** * 解析用户ID支持多种表达式类型 */privateListLongresolveUserIds(DelegateTaskdelegateTask){// 获取表达式值ObjectvalueuserIds.getValue(delegateTask.getExecution());if(valuenull){returnCollections.emptyList();}// 根据类型处理if(valueinstanceofString){StringstrValue(String)value;returnArrays.stream(strValue.split(,)).map(String::trim).filter(StringUtils::isNotBlank).map(Long::parseLong).collect(Collectors.toList());}elseif(valueinstanceofCollection){Collection?collection(Collection?)value;returncollection.stream().filter(Objects::nonNull).map(obj-Long.parseLong(obj.toString())).collect(Collectors.toList());}returnCollections.emptyList();}}在具体的代码中直接使用 userIds.getExpressionText() 只适用于固定字符串的场景。如果要支持更复杂的场景如从变量获取应该使用 userIds.getValue(execution) 方法。“人的一生会经历很多痛苦但回头想想都是传奇”。
版权声明:本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!

芮城做网站的机构公司网站改版需要怎么做

Wan2.2-T2V-A14B能否生成舞蹈视频?舞种适配测试 你有没有想过,有一天只要写一句话——比如“一个穿孔雀裙的傣族少女在月光下起舞”——就能立刻看到一段栩栩如生的舞蹈视频自动生成出来?这听起来像是科幻电影里的桥段,但今天&…

张小明 2025/12/29 7:57:03 网站建设

宠物网站建设报告展芒设计网页

快速体验 打开 InsCode(快马)平台 https://www.inscode.net输入框内输入如下内容: 创建一个分步式的EVE-NG新手教程项目,包含:1) 图文并茂的安装指南 2) 基础网络拓扑构建演示 3) 典型CCNA实验案例(如VLAN配置、OSPF路由&#xf…

张小明 2025/12/29 7:56:38 网站建设

统计局网站建设情况wordpress添加版权链接

你是否曾因为“不会处理数据”而放弃一个好选题?是否在导师说“这里要有实证分析”时瞬间慌了神?又或者,明明手握客户反馈、销售记录或问卷结果,却因缺乏技术能力而无法挖掘价值?别再让工具门槛限制你的潜力&#xff0…

张小明 2025/12/29 7:56:41 网站建设

四川大良网站建设公司logo背景墙实景图

Ubuntu系统下数字设备与多媒体文件的使用指南 1. 安卓设备的弹出操作 要弹出安卓设备,可通过以下两种方式: - 右键点击桌面上该设备的图标,然后选择“弹出”。 - 在Nautilus窗口中,点击窗口侧边栏中设备图标的旁边的弹出按钮。之后在手机上,拖动打开通知栏,点击“关闭…

张小明 2025/12/29 2:27:12 网站建设

神农架网站建设棉桃剥壳机做网站

gRPC-web完整入门教程:从零开始构建现代Web应用 【免费下载链接】grpc-web gRPC for Web Clients 项目地址: https://gitcode.com/gh_mirrors/gr/grpc-web gRPC-web是现代Web开发中革命性的通信技术,它让浏览器能够直接与gRPC服务进行高效通信。&…

张小明 2025/12/29 7:56:43 网站建设

滨海县城乡建设局网站东莞公司注册地址查询

大模型内存优化技术:从碎片化到高效管理,性能提升45%的实战指南 【免费下载链接】llama.cpp Port of Facebooks LLaMA model in C/C 项目地址: https://gitcode.com/GitHub_Trending/ll/llama.cpp 你是否在本地部署大模型时经常遇到内存占用飙升、…

张小明 2025/12/29 7:56:43 网站建设