版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
14:15:10 文Activiti学习资料14(组件介绍Activiti组件activiti项目由三种类型的组件组成,分别是:工具(DedicatedTools)、内容(St具oredContent)、协作工(CollaborationTool)。工具( 工具(Dedicated Tools)组件 plugin具组件。Alfresco—为Alfresco公司的企业级内容管理产品Alfresco是Alfresco公司的内容管理产品的名称(同时也是公司名称)Web内容管理等功能。infoWorld被了2010年的最佳开源应用程序。现在Alfresco公司作为Activiti项目的主要赞Activiti包括流程本身,都是被内容管理产品所管理的资源。ActivitiModeler—建模器Activiti建模器是基于开源的Signavio流程编辑器的一个定制版本,它提供了对BPMN2.0图形化规范的支持,建模后的流程以文件格式进行文件格式进行。在后端提供导入导出BPMN2.0流程定义文件的功能。文件格式进行此建模器的优点是,它是基于web浏览器的。其设计器界面如下图所示ActivitiDesigner—EclipseEclipse的插件,可以使得开EclipseSignavioActivitiprobe—管理及组件它是一个对流程引擎运行期实例提供管理及的web应用程间、失败多次的工作等功能。其示意界面如下:这是一个对于数据库表记录的查看界面,基本上是一个demo级别的,没有多大意义。ActivitiExplorer—任务管理组件它是一个web的应用程序,提供任务管理功能和对基于历史数据的统计分析及流程实例的检查而产生的报表功能。如下图所示:内容(内容(StoredContent)组件文档仓库(sRepository)模型仓库、(ModelRepository)SVN仓库(SVNRepository)MVN仓库(MVNRepository)、Activiti引擎(ActivitiEngine)。其中文档仓库、SVN仓库、MVN仓库三个组件是为协作工具(ActivitiCycle)提供底层的支撑。例如BPM开发过程中的文档,采用Alfresco文档仓库进行,采用SVN进行版本管理,采用MVN(maven)作为项目构建和管理工具。模型仓库(ModelRepository)实际上就是Activiti建模器的后端组件,它负责对Activiti建模器建模后的流程定义文件进行管理。ActivitiEngine—ActivitiBPM的引擎运行时组件,解析流程定义文件(.bpmn20.xml文件),将其转化为纯粹的内存Java对象,以供运行时各个功能使用;Activiti引擎,基于流程虚拟机(PVM)进行构建(关于PVM的详细介绍,参见8.1.2章节),是Activiti项目的底层组件。它可以直接运行原生的BPMN2.0规范格式的流程定义。是业内目前第一个,也是唯一的一个从建模到执行,完全按照BPMN2.0规范进行实现的BPM项目。这也是笔者选择它作为BPM开源产品介绍的最直接原因。Activiti引擎具备三个重要的特性。首先就是器器。这个特性允许引擎可以直接器执行一个动作(即为流程图中的某个特定的,定义的一段java代码或)。这意味着,开发人员可以利用特定问题。第二个特性是定制活动定制活动。Activiti引擎实现了对BPMN的要一些与这些已定义的活动不匹配的活动类型。在这种情景下,开发人员可以采用java代码编写一个定制的活动,用来实现业务人员所描述的复杂行是定义好的。是一个封装的黑盒子,是不可能提供定制功能的。另一个创新的特性是,它提供了对某些冗长的BPMN规范进行实现的快捷方式或捷提供BPMNXMLXML描述格式。而这种XML格式不是Activiti径。BPMNXMLActivitiBPMNXML((CollaborationTool))ActivitiCycleBPMIT操webBPM产品都关注于怎样将业务人员创建BPMIT文档来需求和visio格式的流程图,开发人员管理可执行的流程和大量的java源文件,IT人员管理部署在tomcat中的.war文件和在Activiti数据库中的流程。ActivitiCycle首先分为左右两个区域,左侧区域是所有交付物的浏览器,这些交付物在仓库中。·一个网络驱动器,例如Vision图,,word文档,excel图表等;·一个业务模型仓库,例如Signavio建模器中包含的BPMN流程模型;·一个SVN仓库,包含java源文件和可执行的BPMN流程;·一个包含业务文档的maven仓库;·Activiti实例,包含一系列被部署的各个版本的交付组件;右侧区域,则分为上中下三个部分,分别是左侧选付物的具体明(包含查看、设定所有人、增加关联)、工作区域和讨论区。现在业务分析员、开发人员和人员,可以在为他们自己提供的区域内,利用相关工具进行工作,而ActivitiCycle则负责组织他们的协作。 ProcessEngineProcessEngineprocessEngine=ProcessEngines.getDefaultProcessERuntimeServiceruntimeService=processEngine.getRuntimeServiceRepositoryServicerepositoryService=processEngine.getReposito TaskServiceTaskServicetaskService=ManagementServiceManagementServicemanagementService=processEngine.getManageme IdentityServiceIdentityServiceidentityService=processEngine.getIdentityServHistoryServicehistoryService=processEngine.getHistoryServiceFormServiceformService=通过ProcessEngineBuilderactiviti的配置文件,就可以生成流程引擎processEngine,getXXXService()取得各种包含workflow/BPM方法的service。RepositoryService提供方法获取各种流程和部署文件的信息TaskService:提供对任务相关的identityService:管理用户和用户组。FormService:获取或者绑定数据到流程实例上RuntimeService:ManagementService:提供管理员对流程引擎的,和流程引擎服务应用无HistoryService:Activiti.cfg.xml文件内必须包含一个Id为’processEngineConfiguration’bean。的processEngineConfiguration对象可以通过解析xml文件得到也可以通过java代码得ProcessEngineConfigurationProcessEngineConfigurationprocessEngineConfiguration=Processr");processEngineConfiguration.setJdbcUrl("jdbc:mysql://localhost:3306/activitiautoReconnect=true");processEngineConfiguration.setJdbcUsername("root");processEngineConfiguration.setJdbcPassword("0000");processEngineConfiguration.setDatabaseSchemaUpdate("true");processEngineConfiguration.setJobExecutorActivate(false);ProcessEngineprocessEngine=processEngineConfigura要根据你在build.*.properties文件指定的属性来创建数据的配置文件,在setup文件内运行antcfg.create,可以在setup/build/activiti.cfg内找到生成的配置文件。 以及那些服务对象都是线程安全的。ProcessEngines.getDefaultProcessEngine()会在第一次被调用时初始并构建processengine,接下来对该方法的调用返回的都是同一个流程引擎。利用ProcessEngines.init()、ProcessEngines.destroy()可以正确创建、关闭流程引擎。流程初始化:xml文件中流程定义的id属性(这个id接下来可以通过RuntimeService的startProcessInstanceByKey方法来启动该流程定义的一个新流程实例这个方法总是选取流程定义的部署版本)作为流程定义的key属性;xml文件中流程定义的name属性作为流程定义的name属性,如果不指定name属性,那么id属性作为name;带有特定key的流程第一次被部署时,被分配的版本号为1,同一key值的流程定义的后续部署,版本号会被设置为比当前最大的部署版本号大1的值,key属性用来区分流程定义;流程定义的id属性被设置为{processDefinitionKey}processDefinitionVersiongenerated-idgenerated-id是唯一性的数字,用来确保缓存在集群环境程定义id的唯一性。部署流程:流程定义将到为Activiti引擎配置好了的持久化数据仓库中。因此通过BPMN2.0流程定义文件会被解析到一个内存对象模型,可以通过ActivitiAPI1.activitiProbe2.StringbarFileNamepath/to/process-one.barZipInputStreaminputStreamnewZipInputStream(newFileInputStream(barFileName));repositoryService.createDeployment().name("process-one.bar").addZipInputStream(inputStream).deploy();使用ant部署<taskdefname="deploy-bar"classname="org.activiti.engine.impl.ant.DeployBarTask"><classpath><filesetdir="..."><includename="activiti-cfg.jar"/><includename="your-db-driver.jar"/></fileset><filesetdir="${activiti.home}/lib"><includename="activiti-engine-${activiti.version}.jar"/><includename="ibatis-sqlmap-*.jar"/></fileset></classpath></taskdef><deploy-barfile=".../yourprocess.bar"/>ProcessInstanceprocessInstance=将创建一个流程实例,并首先通过start。通过start后,流程会沿着start的所有输出流执行,执行到第一个任务。此时activiti引擎会向 一个任务。此时,关联在该任务上的用户或组的分配得以解析,并且也被 到数据库中。Activiti引擎会继续流程的执行步骤直到流程进入一种等待状态,比如用户任务。在这样的一种状态,流程实例的当前状态被到数据库中。流程会保持该状态直到所有用户决定完成其任务。那时,流程引擎会继续执行流程直到流程进入一个新的等待状态或流程总是被形象成一个圆圈。存在两种主要的类型:捕获和抛出事件。捕获:流程执行到该时,会等待触发。触发类型由内部图标或xml中的类型 来定义。捕获视觉上可以通过白色的图标区分抛 xml中的类型 标区分。Start 会一直等待直到触发发生。Activiti特有属性:formKey和initiatorActiviti:formKey指向一个用户必须在启动新流程实例时填写的表单模板。可以包含任何可以包含任何文本,用于标示你的表单。但对于内置的表单渲染,Activiti:formKey的值最好是所在的文本同一个流程归档文件内的资源的。<startEventid="request"activiti:formKey="org/activiti/request.form"/>NoneStart:没有为启动流程实例指定触发器,这意味着流程引擎不能预期什么时候流程实例要被启动。Nonestart使用在通过调用startProcessInstanceByXXX方法启动流程实例ProcessInstanceprocessInstance= 。子流程总是使用nonestart。由不带内图标的圆表示表示: :Xml表示:不带子元素的普通start:<startEventid="start"name="mystartevent"/>它可以用在只启动一次的流程中,Timerstart用于在给定的时间点创建流程实例。也可以用你在特定时间间隔下启动的流程。子流程不能用timerstart。子流程不能用。<startEventid="theStart"><timerEventDefinition><timeDate>2011-03-</timerEventDefinition></startEvent>总是抛出型的。这意味着当流程执行到结束时,有一个结果会End :结束总是抛出型总是抛出型被 标来表示的。NoneEnd:意味着没有指定在进入 时抛出的结果。这样,流程引擎除了结束当前的执路径不会在执行任何其他操作。Xml表示为没有子元素的普通的end<endEventid="end"name="myend/>当流程执行到errorend时,会结束当前的执行路径,并抛出error。ErrorEnd:Error可以被与之匹配的中间边界error 获。如果没有找到匹配的边界error事件,默认会使用none Xml表示为带有errorEventDefinition子元素的end。图标为内有end<endEventid="myErrorEndEvent"><errorEventDefinitionerrorRef="myError"</endEvent>定时器:Timer是被定义的定时器触发的可以作为start、定时器executorinternediate或boundary来使用。只有开启jobexecutor时定时器只有开启才能被触发(即需要在activiti.cfg.xml中将jobExecutorActivat设置为true,默才能被触发认为false)。定时器只能有一个下面的元素:定时器只能有一个下面的元素:定时器只能有一个下面的元素1.timeDateimeDate:该格式以ISO8601格式指定了触发的确定时间imeDate<timerEventDefinition><timeDate>2011-03-11T12:13:14</timeDate></timerEventDefinition>2.timeDurationtimeDuration:指定定时器在触发前运行多长时间, <timeDuration>P10D</timeDuration></timerEventDefinition>3.timeCycletimeCycle:指定循环的时间间 <timerEventDefinition> <timeDuration>${duration}</timeDuration></timerEventDefinition></boundaryEvent>顺序流<sequenceFlowid="flow1"sourceRef="theStart"targetRef="theTask"/>带条件的顺序流:可以在顺序流上定义条件。当顺序流左侧是BPMN2.0的活动时,就会带条件的顺xml中含有conditionExpression子元素的普通流来表示。目前仅支持tFormalExpression,目前conditionExpression只能使用UELUEL,在此使用的表达式的解析的结果必须是布尔类型的值。<sequenceFlowid="flow"sourceRef="theStart" <![CDATA[${order.price>100&&order.price<</conditionExpression></sequenceFlow>默认顺序流:只有当没默认顺序流所有的BPMN2.0任务以及getways都可以有一个默认的顺序流。有其他顺序流被选取的情况下,才选取该顺序流。<exclusiveGatewayid="exclusiveGw"name="ExclusiveGateway" <sequenceFlowid="flow2sourceRef="exclusiveGw"targetRef="task2sequenceFlowid="flow3"sourceRef="exclusiveGw"targetRef="task3"><conditionExpressionxsi:type="tFormalExpression">${conditionB}</conditionExpressionsequenceFlow>单xml异常。<exclusiveGatewayid="exclusiveGw"name="ExclusiveGateway"/><sequenceFlowid="flow2"sourceRef="exclusiveGw" targetRef="theTask2"><conditionExpressionxsi:type="tFormalExpression">${input== xsi:type="tFormalExpression">${input==3}</conditionExpression></sequenceFlow>并行分支(gateway)并行分支(parallelgateway)如果parallelgateway有多个输入流forkJoin行为。那样,gateway会在拆分出多个并发的执行路径前,首先合并所有的输入流。parallelgateway不会计算条件,如果在连接parallelparallelgateway<startEventid="theStart"/><sequenceFlowid="flow1"sourceRef="theStart" <userTaskid="shipOrder"name="ShipOrder"/><sequenceFlowsourceRef="shipOrder" <endEventid=""/>用户任务:行当流程执到这样的用户任务用户任务用来对那些需要人参与完成的工作进行建模。时,会在分配任务的用户或用户组的任务列表中创建新的任务。<userTaskid="theTask"name="Schedulemeeting"><ation>Scheduleanengineeringmeetingfornextweekwiththenewhire.</ation>ation用来定义描述,可以在Java中获得:task.getDescription()1.到期时间:1.activityjava.util.Datenull。<userTaskid="theTask"name="Importanttask"activiti:dueDate="${dateVariable2.过humanPerformer子元素来完成的,需要resourceAssignmentExpression元素<userTaskid='theTask'name='importanttask'><humanPerformerhumanPerformer> </humanPerformer></userTask>执行者分配到任务上人,只能有一个用户作为执 人只能有一个用作为执行者分配到任务上人的任务列表中是不可见的,这些任务存在于所谓的人个人任务列表中。直接分配给用户的任务可以通过TaskService来获取。taskService.createTaskQuery().taskAssignee("kermit").list();List<Task>tasks=taskService.createTaskQuery().taskAssignee("kermit").list();也可以把任务放进所谓的人员候选任务列表候选任务列表中。需要用到potentialOwner。候选任务列表<userTask </resourceAssignmentExpression></potentialOwner></userTask>获取:List<Task>tasks=taskService.createTaskQuery().taskCandidateUser("kermit");如果不给文本字符串指定是用户还是用户组,流程引擎默认认为是用户组。因此下面这与声明为group(accountancy)效果是一样的。<formalExpression>accountancy</formalExpression>Activiti对于任务分配的扩展1.assignee属性属性这个自定义扩展允许将用户任务直接分配给用户<userTaskid="theTask"name="mytask"activiti:assignee="kermit"/>2.candidateUsers属性属性:这个自定义扩展可以使用户成为任务的候选者<userTaskid="theTask"name="mytask"activiti:candidateUsers="kermit,gonzo"/>3.candidateGroups属性属性:这个自定义扩展允许为任务定义一组候选者。<userTaskid="theTask"name="mytask"activiti:candidateGroups="management,accountancy"/>如果以上方案仍然不够,那么可以委托给使用了create上的任务器的自定义分配逻辑:<userTaskid="task1"name="Mytask"><extensionElements><activiti:taskListenerevent="create"class="org.activiti.MyAssignmentHandler/>MyAssignmentHandler" publicclassMyAssignmentHandlerimplementsTaskListener{publicvoidnotify(DelegateTaskdelegateTask){//在此执行自定义的查找 接下来,例如调用以下方法 delegateTask.addCandidateGroup("management");...}}下面的例子中,人是通过调用SpringbeanldapService中的方法findManagerOfEmployee来设置的。<userTask activiti:assignee="${ldapService.findManagerForEmployee(emp)}"/>只有当被调用的方法返回类型是String或Collection<String>对于候选用户和候选组)(对于候选用户和候选组)才能生效。才能生效。任务是自动的活动,当流程执行到任务时,执行相应的。任务通过指定script和scriptFormat来定义任务<scriptTaskid="theScriptTask"name="Executescript"scriptFormat="groovy"><script>sum=0for(iininputArray){sum+=i}</script></scriptTask>服务任务用来调用外部java类,要实现在流程执行期间调用类,该类需要实现 服务任务org.activiti.engine.delegate.javaDelegate接口,在excute方法中提供必要的逻辑,当流程执行到此步时,会执行定义在该方法中的逻辑。1.指定实现了javaDelegate或 的类 activiti:class="org.activiti.MyJavaDelegate"/>activiti:class2.delegateExpression是一个定义在SpringjavaDelegate接口的beanactiviti:delegateExpression3.调用方法表达式,UEL方法表达式<serviceTask activiti:expression="#{printer.printMessage()}"/>activiti:expression activiti:expression="#{split.ready}"/>activiti:expressio5.只会创建定义在serviceTask上的java类的一个实例类的一个实例。所有流程实例共享同一个用于调用execute(DelegateExecution)的类的实例,这意味着,该类中一定不要使用成员变量,并且必须是线程安全的,因为可能会在不同的线程中同时执行该方法。6.流程定义中的类在部署时不会被实例化部署时不会被实例化。只有当流程第一次执行到该类的时候,才部署时不会被实例化创建该类的实例。如果找不到该类,会抛出ActivitiException。处理异常:在执行自定义的逻辑时,常常需要捕获某种异常。一个常见的用例是一旦某处理异常条路径上发生异常将流程导向另一条路径<serviceTaskid="javaService"name="Java <sequenceFlowid="exception"sourceRef="javaService"targetRef="fixException" publicvoidexecute(ActivityExecutionexecution)throwsException{Stringvar=(String) execution.getActivity().findOutgoingTransition("no-exception");}catch(Exception }webWebService同步执行一个或规则集或规则。Activiti使用DroolsExpert业务规则任务和Drool规则引擎来执行业务规则。为此,包含着业务规则的.drl文件必须与定义了业务规则任务的流程定义一同部署才能执行这些规则。这意味着流程中使用的所有.drl文BAR果没有指定结果的变量名,默认使用org.activiti.engine.rules.OUTPUT<process<startEventid="theStart"/><sequenceFlowsourceRef="theStart" <businessRuleTaskid="businessRuleTask"activiti:ruleVariablesInput="${order}" id=" </process>只执行部署的.drl文件中定义的一组规则,由逗号分开<businessRuleTaskid="businessRuleTask"activiti:ruleVariablesInput="${order}"activiti:rules="rule1rule2"/>rule1和rule2 activiti:rules="rule1,rule2"exclude="true"/>任务:其不是BPMN2.0规范中的“办公”任务。因此,activiti中mail任务是任务作为特有服务任务来实现的。Activiti引擎使用外部的SMTP邮件服务器来发送e-mails,需要在文件activiti.cfg.xml中配置:属性mailServerHostMailServerPortmailServerDefaultFrom是否必须?否是否描述邮件服务器主机名默认是localhostSMTP通信端口默认是25在不提供发件人e-mail时,默认是activiti@mailServerUsernamemailServerPassword如果适合你的服务 如果适合你的服务器 默认不设置 默认不设置任务是作为特有的服务任务来实现的 <serviceTaskid="sendMail" EL表达式。<serviceTaskid="sendMail"activiti:type="mail"><<activiti:fieldname="from "/>from"<activiti:fieldname="toexpression="${recipient}"/>to"to<activiti:fieldname="subjectexpression="Yourorder${orderId}hasbeensubject"subjectshipped"/><activiti:field Asof${now},yourorderhasbeen<b>processedandshipped</b>.<br/><br/> </extensionElements>serviceTask>BPM引擎之外的任务。用来对那UI接口。对<manualTaskid="myManualTask"name="Callformoreinformation"/>javaJava接程通过接收任务继续执行。<receiveTaskid="waitState"name="wait"/>执行(execution)器:允许在流程执行期间发生某些时执行外部java代码或执行(execution)器(execution)器计算表达式。可捕获的:流程实例的启动或结束迁移活动的开始和结束<processid="executionListenersProcess"> class="org.activiti.examples.bpmn.executionlistener.ExampleExecutionListenerOne" <userTaskid="secondTask"><extensionElements><activiti:executionListener event="end"/></extensionElements></userTask><sequenceFlowsourceRef="secondTask"targetRef="thirdTask"/><userTaskid="thirdTask"<sequenceFlowsourceRef="thirdTask"targetRef=""/><endEventid=""器是个外部类需要实现org.activiti.engine.delegate.ExecutionListener接口,当发生时,调用方法notify(ExecutionListenerExecutionexecution)。publicclass execution.setVariable("eventReceived",execution.getEventName());}迁移(第二个器)上的器的event属性值会被忽略掉。任务器:用来执行自定义的java逻辑或事件相关的表达式。任务器只能作为任务器用户任务的子元素添加到流程定义中<userTaskid="myTask"name="MyTask"><extensionElements><activiti:taskListener </extensionElements></userTask>属性触发调用任务器的任务的类型可能的类型有Event属性Create:在创建任务、并且任务的所有属性被设置后发生。reateAssignment:在任务分配给后发生。userTask,当流程执行到userTask,首先触发assignment,。,然后触发create。Complete:在任务完成,并且任务从运行时的数据中被删除之前发生。omplete属性被调用的类需实现Class属性org.activiti.engine.impl.pvm.delegate.TaskListener接口。属性:指定发生时执行的表达式。不能与class属性一块使用Expression属性<activiti:taskListenerevent="create"expression="${myObject.callMethod(task,task.eventName)}"/>属性:允许指定一个结果是实现了TaskListener接口对象的表达式。delegateExpression<activiti:taskListenerevent="create"delegateExpression="${myTaskListenerBean}"/>多实例:为流程中某个步骤定义重复的式。Gateway和不能是多实例的。按多实例照规范要求,每个被创建出来的执行路径实例的父执行路径都有如下的变量:个数。顺序的多实例,该值总是1. loopConter:for-each33 </multiInstanceLoopCharacteristics>isSequential表示是否按顺序执行。一旦进入该活动,就计算实例的个数。一旦进入该活动就计算实例的个数。其一是使用loopCardinality子元素直接指定个数 <multiInstanceLoopCharacteristicsisSequential="false|true"><loopCardinality>5</loopCardinality></multiInstanceLoopCharacteristics>也可以用结果是正数的表达 <multiInstanceLoopCharacteristics</multiInstanceLoopCharacteristics>另一种定义实例个数的方式是指定变量名,另一种定义实例个数的方式是指定变量名,它是一个利用loopDataInputRef子元素的集合。会为集合中的每一项创建一个实例。作为一个选择,可以使用inputDataItem子元素会为集展示的:将集合中某项设置给相应的执行实例。如下面的XML例子展示的:<userTaskid="miT
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 2026广东深圳市龙岗区宝龙街道第一幼教集团招聘4人备考题库及参考答案详解(黄金题型)
- 现浇梁施工安全、质量控制要点
- 2026广东广州市白云区石门第一实验幼儿园招聘3人备考题库附参考答案详解(考试直接用)
- 2026湖南湘潭医卫职业技术学院招聘5人备考题库带答案详解(a卷)
- 2026陕西西安临潼博仁医院招聘11人备考题库及完整答案详解1套
- 2026南方科技大学生物医学工程系诚聘海内外高层次人才备考题库附答案详解(夺分金卷)
- 2026浙江温州医科大学附属第一医院泌尿外科(男性科)康复技师招聘1人备考题库有完整答案详解
- 2026上半年安徽黄山市休宁城乡建设投资集团有限公司及权属子公司招聘18人备考题库完整参考答案详解
- 2026山东济南市妇幼保健院招聘卫生高级人才和博士(控制总量)26人备考题库附答案详解ab卷
- 2026湖南益阳市市直医疗卫生单位招聘及引进紧缺(急需)专业人才39人备考题库及答案详解(各地真题)
- DL∕T 1987-2019 六氟化硫气体泄漏在线监测报警装置技术条件
- 南京市指导服务企业安全生产工作指引-加油站现场安全重点检查指引分册
- 小学生心理健康测评报告总结
- 兰州彤辉商贸有限公司肃南县博怀沟一带铜铁矿矿产资源开发与恢复治理方案
- 光伏并网前单位工程验收报告-2023
- 商业插画讲课用课件
- 钢结构施工安全培训
- JCT698-2010 石膏砌块标准
- DB5331T 39-2023 德昂酸茶(干茶)感官审评方法
- GB/T 33187.1-2016地理信息简单要素访问第1部分:通用架构
- 水电站工程安全验收定性定量评价
评论
0/150
提交评论