`
chenyanjiang
  • 浏览: 2705 次
  • 性别: Icon_minigender_1
  • 来自: 广州
社区版块
存档分类
最新评论

ESTBPM3 --- Activiti 5 在线流程设计器开发

阅读更多

   jbpm4的开发成员tom离开了jboss后,加入afresco公司,并且才有activiti5的项目,这开源项目继承了jbpm4的所有优点,同时将其发扬光大,相对jbpm4,activiti5改进了储多我们国内开发人员关心的问题,如:

  • 流程代办
  • 在线流程设计器
  • 流程嵌入式部署
  • 流程独立部署
  • 动流程节点
  • 自由流程
  • 支持了bpmn2的标准
  • 支持规则引擎


     activiti 5 底层上的api跟jbpm4的api相似程序也达60%以上,特别是service提供的接口,都是在jbpm4上提供扩展,大大方便了jbpm4的开发人员,这也是tom的先明之处,毕竟jbpm原来打的品牌效应不可否认的,把原来的jbpm4积累的人气再次带至activiti5上,这也将是该项目能够断续前进的重要保障。


     尽管activiti5目前发展趋势前途光明,但其也有不足的地方,其前端的的表现总是存在不足,如在线流程设计器,目前eclipse插件生成的bpmn20.xml文件则不行,而官方提供的activiti-modler设计器,扩展及实现均面临困难,并且对浏览器的要求让它在国内的项目实施总会面临技术难度。

 

       宏天estbpm3则又是一个基于activiti5的产品,并且公司也有打算断续原来的产品销售模式,对企业开放源代码,而原来的设计器通过改进后,则可以直接支持activiti5的流程设计的需要,如:

 

 

设计器按设计器生成一份文档格式,通过系统中提供的xslt转化文档,完成转化后,生成bpmn20的格式文档,该文档可被activiti5直接识别。



 

其设计器及转化效果如下所示:



 

 

发布后,通过activiti5的api生成的流程图如下所示:

 



 

 

 

设计器原生成的文档格式:

<diagram xmlns:bg="bpm.graphic" xmlns:ciied="com.hotent.bpm.editor"
	xmlns:fg="flash.geom">
	<bg:Task id="task1" height="50" user="true" width="90" x="230"
		y="110">
		<label>用户任务1</label>
		<ports>
			<ciied:Port id="port1" clipOnShape="true" movable="false" />
			<ciied:Port id="port2" x="0" />
			<ciied:Port id="port3" y="1" />
			<ciied:Port id="port4" clipOnShape="true" movable="false">
				<id>CENTER</id>
			</ciied:Port>
		</ports>
	</bg:Task>
	<bg:StartEvent id="startEvent1" height="46" width="31" x="60"
		y="119.5">
		<label>开始</label>
		<ports>
			<ciied:Port id="port5" clipOnShape="true" movable="false" />
			<ciied:Port id="port6" x="1" />
			<ciied:Port id="port7" clipOnShape="true" movable="false">
				<id>CENTER</id>
			</ciied:Port>
		</ports>
	</bg:StartEvent>
	<bg:SubProcess id="subProcess1" automaticGraphLayout="false"
		expandedHeight="210" expandedWidth="570" height="210" width="570" x="360"
		y="230">
		<label>子流程</label>
		<ports>
			<ciied:Port id="port8" clipOnShape="true" movable="false" />
			<ciied:Port id="port9" x="0" />
			<ciied:Port id="port10" y="0" />
			<ciied:Port id="port11" clipOnShape="true" movable="false">
				<id>CENTER</id>
			</ciied:Port>
			<ciied:Port id="port12" horizontalOffset="-5" y="1">
				<id>BOTTOM</id>
			</ciied:Port>
			<ciied:Port id="port13" horizontalOffset="5" y="1">
				<id>BOTTOM</id>
			</ciied:Port>
		</ports>
		<bg:Task id="task2" height="50" user="true" width="90" x="180"
			y="53">
			<label>用户任务2</label>
			<ports>
				<ciied:Port id="port14" clipOnShape="true" movable="false" />
				<ciied:Port id="port15" x="0" />
				<ciied:Port id="port16" x="1" />
				<ciied:Port id="port17" clipOnShape="true" movable="false">
					<id>CENTER</id>
				</ciied:Port>
			</ports>
		</bg:Task>
		<bg:StartEvent id="startEvent2" height="46" width="32"
			x="29" y="62.5">
			<label>开始2</label>
			<ports>
				<ciied:Port id="port18" clipOnShape="true" movable="false" />
				<ciied:Port id="port19" x="1" />
				<ciied:Port id="port20" clipOnShape="true" movable="false">
					<id>CENTER</id>
				</ciied:Port>
			</ports>
		</bg:StartEvent>
		<bg:SequenceFlow id="sequenceFlow1" endPort="port15"
			startPort="port19">
			<fallbackEndPoint>
				<fg:Point id="point1" x="198" y="58" />
			</fallbackEndPoint>
			<fallbackStartPoint>
				<fg:Point id="point2" />
			</fallbackStartPoint>
			<label></label>
		</bg:SequenceFlow>
		<bg:EndEvent id="endEvent1" height="49" width="34" x="380"
			y="61">
			<label>结束2</label>
			<ports>
				<ciied:Port id="port21" clipOnShape="true" movable="false" />
				<ciied:Port id="port22" x="0" />
				<ciied:Port id="port23" clipOnShape="true" movable="false">
					<id>CENTER</id>
				</ciied:Port>
			</ports>
		</bg:EndEvent>
		<bg:SequenceFlow id="sequenceFlow2" endPort="port22"
			startPort="port16">
			<fallbackEndPoint>
				<fg:Point id="point3" x="364" y="68" />
			</fallbackEndPoint>
			<fallbackStartPoint>
				<fg:Point id="point4" />
			</fallbackStartPoint>
			<label></label>
		</bg:SequenceFlow>
	</bg:SubProcess>
	<bg:EndEvent id="endEvent2" height="49" width="34" x="740"
		y="120">
		<label>结束1</label>
		<ports>
			<ciied:Port id="port24" clipOnShape="true" movable="false" />
			<ciied:Port id="port25" x="0" />
			<ciied:Port id="port26" clipOnShape="true" movable="false">
				<id>CENTER</id>
			</ciied:Port>
		</ports>
	</bg:EndEvent>
	<bg:SequenceFlow id="sequenceFlow3" endPort="port2"
		startPort="port6">
		<fallbackEndPoint>
			<fg:Point id="point5" x="237" y="125" />
		</fallbackEndPoint>
		<fallbackStartPoint>
			<fg:Point id="point6" />
		</fallbackStartPoint>
		<label></label>
	</bg:SequenceFlow>
	<bg:SequenceFlow id="sequenceFlow4" endPort="port9"
		startPort="port3">
		<fallbackEndPoint>
			<fg:Point id="point7" x="396" y="461" />
		</fallbackEndPoint>
		<fallbackStartPoint>
			<fg:Point id="point8" />
		</fallbackStartPoint>
		<label></label>
	</bg:SequenceFlow>
	<bg:SequenceFlow id="sequenceFlow5" endPort="port25"
		startPort="port10">
		<fallbackEndPoint>
			<fg:Point id="point9" x="674" y="191" />
		</fallbackEndPoint>
		<fallbackStartPoint>
			<fg:Point id="point10" />
		</fallbackStartPoint>
		<label></label>
	</bg:SequenceFlow>
	<bg:Task id="task3" height="50" user="true" width="90" x="440"
		y="520">
		<label>用户任务3</label>
		<ports>
			<ciied:Port id="port27" clipOnShape="true" movable="false">
				<id>CENTER</id>
			</ciied:Port>
			<ciied:Port id="port28" y="0">
				<id>TOP</id>
			</ciied:Port>
			<ciied:Port id="port29" y="1">
				<id>BOTTOM</id>
			</ciied:Port>
		</ports>
	</bg:Task>
	<bg:SequenceFlow id="sequenceFlow6" endPort="port28"
		startPort="port12">
		<fallbackEndPoint>
			<fg:Point id="point11" x="623" y="568" />
		</fallbackEndPoint>
		<fallbackStartPoint>
			<fg:Point id="point12" />
		</fallbackStartPoint>
		<label></label>
	</bg:SequenceFlow>
	<bg:Task id="task4" height="50" user="true" width="90" x="750"
		y="520">
		<label>用户任务4</label>
		<ports>
			<ciied:Port id="port30" clipOnShape="true" movable="false">
				<id>CENTER</id>
			</ciied:Port>
			<ciied:Port id="port31" y="0">
				<id>TOP</id>
			</ciied:Port>
			<ciied:Port id="port32" y="1">
				<id>BOTTOM</id>
			</ciied:Port>
		</ports>
	</bg:Task>
	<bg:SequenceFlow id="sequenceFlow7" endPort="port31"
		startPort="port13">
		<fallbackEndPoint>
			<fg:Point id="point13" x="760" y="536" />
		</fallbackEndPoint>
		<fallbackStartPoint>
			<fg:Point id="point14" />
		</fallbackStartPoint>
		<label></label>
	</bg:SequenceFlow>
	<bg:EndEvent id="endEvent3" height="49" width="34" x="620"
		y="630">
		<label>结束3</label>
		<ports>
			<ciied:Port id="port33" clipOnShape="true" movable="false">
				<id>CENTER</id>
			</ciied:Port>
			<ciied:Port id="port34" x="1">
				<id>RIGHT</id>
			</ciied:Port>
			<ciied:Port id="port35" x="0">
				<id>LEFT</id>
			</ciied:Port>
		</ports>
	</bg:EndEvent>
	<bg:SequenceFlow id="sequenceFlow8" endPort="port35"
		startPort="port29">
		<fallbackEndPoint>
			<fg:Point id="point15" x="632" y="653" />
		</fallbackEndPoint>
		<fallbackStartPoint>
			<fg:Point id="point16" />
		</fallbackStartPoint>
		<label></label>
	</bg:SequenceFlow>
	<bg:SequenceFlow id="sequenceFlow9" endPort="port34"
		startPort="port32">
		<fallbackEndPoint>
			<fg:Point id="point17" x="688" y="651" />
		</fallbackEndPoint>
		<fallbackStartPoint>
			<fg:Point id="point18" />
		</fallbackStartPoint>
		<label></label>
	</bg:SequenceFlow>
</diagram>

 

通过XSLT转化后的文档格式:

 

<?xml version="1.0" encoding="utf-8"?>
<definitions xmlns="http://www.omg.org/spec/BPMN/20100524/MODEL"
	xmlns:ciied="com.ibm.ilog.elixir.diagram" xmlns:bg="bpm.graphic"
	xmlns:fn="http://www.w3.org/2005/02/xpath-functions" xmlns:omgdi="http://www.omg.org/spec/DD/20100524/DI"
	xmlns:omgdc="http://www.omg.org/spec/DD/20100524/DC" xmlns:bpmndi="http://www.omg.org/spec/BPMN/20100524/DI"
	xmlns:activiti="http://activiti.org/bpmn" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	targetNamespace="http://www.activiti.org/test" expressionLanguage="http://www.w3.org/1999/XPath"
	typeLanguage="http://www.w3.org/2001/XMLSchema">
	<process id="subGraph2" name="子流程">
		<startEvent id="startEvent1" name="开始" />
		<endEvent id="endEvent2" name="结束1" />
		<endEvent id="endEvent3" name="结束3" />
		<userTask id="task1" name="用户任务1" />
		<userTask id="task3" name="用户任务3" />
		<userTask id="task4" name="用户任务4" />
		<sequenceFlow id="sequenceFlow3" name="" sourceRef="startEvent1"
			targetRef="task1" />
		<sequenceFlow id="sequenceFlow4" name="" sourceRef="task1"
			targetRef="subProcess1" />
		<sequenceFlow id="sequenceFlow5" name="" sourceRef="subProcess1"
			targetRef="endEvent2" />
		<sequenceFlow id="sequenceFlow6" name="" sourceRef="subProcess1"
			targetRef="task3" />
		<sequenceFlow id="sequenceFlow7" name="" sourceRef="subProcess1"
			targetRef="task4" />
		<sequenceFlow id="sequenceFlow8" name="" sourceRef="task3"
			targetRef="endEvent3" />
		<sequenceFlow id="sequenceFlow9" name="" sourceRef="task4"
			targetRef="endEvent3" />
		<subProcess id="subProcess1" name="子流程">
			<startEvent id="startEvent2" name="开始2" />
			<endEvent id="endEvent1" name="结束2" />
			<userTask id="task2" name="用户任务2" />
			<sequenceFlow id="sequenceFlow1" name="" sourceRef="startEvent2"
				targetRef="task2" />
			<sequenceFlow id="sequenceFlow2" name="" sourceRef="task2"
				targetRef="endEvent1" />
		</subProcess>
	</process>
	<bpmndi:BPMNDiagram id="BPMNDiagram_subGraph2">
		<bpmndi:BPMNPlane bpmnElement="subGraph2" id="BPMNPlane_subGraph2">
			<bpmndi:BPMNShape bpmnElement="startEvent1"
				id="BPMNShape_startEvent1">
				<omgdc:Bounds height="31" width="31" x="60" y="119.5" />
			</bpmndi:BPMNShape>
			<bpmndi:BPMNShape bpmnElement="startEvent2"
				id="BPMNShape_startEvent2">
				<omgdc:Bounds height="32" width="32" x="389.0" y="292.5" />
			</bpmndi:BPMNShape>
			<bpmndi:BPMNShape bpmnElement="endEvent1" id="BPMNShape_endEvent1">
				<omgdc:Bounds height="34" width="34" x="740.0" y="291.0" />
			</bpmndi:BPMNShape>
			<bpmndi:BPMNShape bpmnElement="endEvent2" id="BPMNShape_endEvent2">
				<omgdc:Bounds height="34" width="34" x="740" y="120" />
			</bpmndi:BPMNShape>
			<bpmndi:BPMNShape bpmnElement="endEvent3" id="BPMNShape_endEvent3">
				<omgdc:Bounds height="34" width="34" x="620" y="630" />
			</bpmndi:BPMNShape>
			<bpmndi:BPMNShape bpmnElement="task1" id="BPMNShape_task1">
				<omgdc:Bounds height="50" width="90" x="230" y="110" />
			</bpmndi:BPMNShape>
			<bpmndi:BPMNShape bpmnElement="task2" id="BPMNShape_task2">
				<omgdc:Bounds height="50" width="90" x="540.0" y="283.0" />
			</bpmndi:BPMNShape>
			<bpmndi:BPMNShape bpmnElement="task3" id="BPMNShape_task3">
				<omgdc:Bounds height="50" width="90" x="440" y="520" />
			</bpmndi:BPMNShape>
			<bpmndi:BPMNShape bpmnElement="task4" id="BPMNShape_task4">
				<omgdc:Bounds height="50" width="90" x="750" y="520" />
			</bpmndi:BPMNShape>
			<bpmndi:BPMNShape bpmnElement="subProcess1"
				id="BPMNShape_subProcess1">
				<omgdc:Bounds height="210" width="570" x="360" y="230" />
			</bpmndi:BPMNShape>
			<bpmndi:BPMNEdge bpmnElement="sequenceFlow1" id="BPMNEdge_sequenceFlow1">
				<omgdi:waypoint x="421.0" y="308.5"></omgdi:waypoint>
				<omgdi:waypoint x="480.5" y="308.5"></omgdi:waypoint>
				<omgdi:waypoint x="480.5" y="308.0"></omgdi:waypoint>
				<omgdi:waypoint x="540.0" y="308.0"></omgdi:waypoint>
			</bpmndi:BPMNEdge>
			<bpmndi:BPMNEdge bpmnElement="sequenceFlow2" id="BPMNEdge_sequenceFlow2">
				<omgdi:waypoint x="630.0" y="308.0"></omgdi:waypoint>
				<omgdi:waypoint x="740.0" y="308.0"></omgdi:waypoint>
			</bpmndi:BPMNEdge>
			<bpmndi:BPMNEdge bpmnElement="sequenceFlow3" id="BPMNEdge_sequenceFlow3">
				<omgdi:waypoint x="91.0" y="135.0"></omgdi:waypoint>
				<omgdi:waypoint x="230.0" y="135.0"></omgdi:waypoint>
			</bpmndi:BPMNEdge>
			<bpmndi:BPMNEdge bpmnElement="sequenceFlow4" id="BPMNEdge_sequenceFlow4">
				<omgdi:waypoint x="275.0" y="160.0"></omgdi:waypoint>
				<omgdi:waypoint x="275.0" y="335.0"></omgdi:waypoint>
				<omgdi:waypoint x="360.0" y="335.0"></omgdi:waypoint>
			</bpmndi:BPMNEdge>
			<bpmndi:BPMNEdge bpmnElement="sequenceFlow5" id="BPMNEdge_sequenceFlow5">
				<omgdi:waypoint x="645.0" y="230.0"></omgdi:waypoint>
				<omgdi:waypoint x="645.0" y="137.0"></omgdi:waypoint>
				<omgdi:waypoint x="740.0" y="137.0"></omgdi:waypoint>
			</bpmndi:BPMNEdge>
			<bpmndi:BPMNEdge bpmnElement="sequenceFlow6" id="BPMNEdge_sequenceFlow6">
				<omgdi:waypoint x="640.0" y="440.0"></omgdi:waypoint>
				<omgdi:waypoint x="640.0" y="480.0"></omgdi:waypoint>
				<omgdi:waypoint x="485.0" y="480.0"></omgdi:waypoint>
				<omgdi:waypoint x="485.0" y="520.0"></omgdi:waypoint>
			</bpmndi:BPMNEdge>
			<bpmndi:BPMNEdge bpmnElement="sequenceFlow7" id="BPMNEdge_sequenceFlow7">
				<omgdi:waypoint x="650.0" y="440.0"></omgdi:waypoint>
				<omgdi:waypoint x="650.0" y="480.0"></omgdi:waypoint>
				<omgdi:waypoint x="795.0" y="480.0"></omgdi:waypoint>
				<omgdi:waypoint x="795.0" y="520.0"></omgdi:waypoint>
			</bpmndi:BPMNEdge>
			<bpmndi:BPMNEdge bpmnElement="sequenceFlow8" id="BPMNEdge_sequenceFlow8">
				<omgdi:waypoint x="485.0" y="570.0"></omgdi:waypoint>
				<omgdi:waypoint x="485.0" y="647.0"></omgdi:waypoint>
				<omgdi:waypoint x="620.0" y="647.0"></omgdi:waypoint>
			</bpmndi:BPMNEdge>
			<bpmndi:BPMNEdge bpmnElement="sequenceFlow9" id="BPMNEdge_sequenceFlow9">
				<omgdi:waypoint x="795.0" y="570.0"></omgdi:waypoint>
				<omgdi:waypoint x="795.0" y="647.0"></omgdi:waypoint>
				<omgdi:waypoint x="654.0" y="647.0"></omgdi:waypoint>
			</bpmndi:BPMNEdge>
		</bpmndi:BPMNPlane>
	</bpmndi:BPMNDiagram>
</definitions>

 

转成后,则直接通过以下api可发布至流程引擎:

 

Deployment deployment= repositoryService.createDeployment().name(bpmDefinition.getSubject()).addString(bpmDefinition.getSubject()+".bpmn20.xml",actFlowDefXml).deploy();

 

  • 大小: 47.2 KB
  • 大小: 61.5 KB
  • 大小: 34.9 KB
分享到:
评论

相关推荐

    Activiti在线流程设计器

    忙活了一个星期左右,查找各种资料,终于将Activiti的流程设计器分离出来,与SpringMVC,spring整合了起来,先把工程分享出来,等有时间了在慢慢讲解具体的整合步骤。工程下载之后直接可以运行,只需要改一下数据库...

    activiti-5.22.0zip下载

    3. **流程设计器**:Activiti提供了一个基于Web的流程设计器,使得非技术人员也能通过图形化界面设计和编辑流程,极大地降低了流程建模的门槛。 4. **数据库存储**:Activiti将流程实例、任务、变量等信息存储在...

    camunda-modeler-3.0.0-win-x64 activiti流程图插件

    总的来说,camunda-modeler-3.0.0-win-x64 activiti流程图插件是企业级流程管理和自动化的重要工具,结合了Camunda BPM的强大功能和Activiti的灵活性,提供了高效、直观的流程设计环境。通过这些底层库文件的支持,...

    Spring-activiti-ruoyi-activiti

    此外,为了调试和测试,你可以利用Activiti的工作流设计器(Activiti Modeler)进行流程模型的可视化编辑,然后导出XML文件用于部署。同时,Activiti的监控和历史查询功能可以帮助你追踪流程执行情况,进行问题排查...

    Activiti 6.0 流程设计器汉化

    Activiti 6.0 流程设计器汉化,替换Activiti-App下的activiti-app-logic-6.0.0.jar 文件

    RuoYi-activitiRuoYi-activitiRuoYi-activiti

    RuoYi-Activiti不仅提供了流程设计、流程实例跟踪、任务管理等基本功能,还支持自定义表单、权限控制、流程监控等高级特性。 二、Activiti基础 1. Activiti核心概念:Activiti是基于BPMN 2.0标准的工作流引擎,...

    activiti5.22-web流程设计器整合demo

    《Activiti 5.22 Web 流程设计器整合实战详解》 在信息化管理中,流程自动化扮演着至关重要的角色,而Activiti作为一款开源的工作流引擎,深受开发者喜爱。本示例“activiti5.22-web流程设计器整合demo”提供了一个...

    activiti-designer

    activiti-designer 学习和开发activiti的设计和流程必备插件

    activiti-explorer-eclipse项目

    1. **流程设计**:在Eclipse内直接设计流程图,使用BPMN 2.0元素,如开始事件、结束事件、任务、网关等。 2. **流程部署**:将设计完成的流程模型部署到Activiti引擎,使得流程实例可以在实际环境中运行。 3. **流程...

    Activiti工作流整合Web流程设计器整合

    在这个“Activiti工作流整合Web流程设计器整合”主题中,我们将深入探讨如何将Activiti与Web流程设计器集成,以实现直观、高效的流程设计和管理。 首先,我们要理解什么是Activiti。Activiti是由Alfresco开发的一款...

    activiti-explorer.rar_Activiti Explorer_Explorer_activiti_activi

    activiti 5.22 explorer的war包

    spring-boot-with-activiti-master.rar

    "spring-boot-with-activiti-master.rar"项目提供了一个完整的示例,展示了如何在Spring Boot环境中集成Activiti流程引擎,并利用Activiti的流程设计器进行流程设计。同时,项目还涵盖了BPMN XML与JSON之间的转换,...

    jeecgboot集成jeecg-boot-activiti1

    - **工作流编辑界面异常**:可能是Activiti编辑器的配置问题,需要检查网络连接或编辑器的版本兼容性。 - **token为空**:涉及到身份验证问题,检查Shiro或JWT的配置,确保Token的生成和验证正确无误。 9. **其他...

    activiti-modeler工作流网页版设计器

    3. **模型设计器**: Activiti-Modeler的工作流模型设计器提供了拖放功能,让用户可以轻松创建和编辑流程模型。通过这种方式,非技术人员也能理解并参与流程设计,提高了业务流程的可维护性和灵活性。 4. **集成项目...

    资料-最新工作流引擎Activiti7基础与进阶.zip

    Activiti7允许设置监听器来捕获流程中的特定事件,例如任务完成、流程结束等,从而实现自定义的行为。 8. 集成能力: Activiti7可轻松集成到Spring框架,支持RESTful API,方便与其他系统交互。同时,它还可以与...

    Activiti工作流的Web流程图设计器

    Activiti的Web流程图设计器,BPMN-JS也可在官网下载并配置,这里压缩包是配置好的 1、需要提前下载好Node.js(中文官网连接:http://nodejs.cn/),傻瓜式安装。 2、解压后在bpmnjs目录打开dos命令窗口,输入npm ...

    activiti-5.22.0官方版本 用于activiti-explorer.zip

    在这个特定的版本——activiti-5.22.0,我们关注的是一个用于流程设计的官方工具,即 activiti-explorer。这个工具为用户提供了一个直观的界面,以便于设计、部署和管理业务流程。 首先,让我们深入了解一下 ...

    activiti-designer-5.18.0.zip 官方

    3. **集成开发环境(IDE)支持**:作为Eclipse插件,Activiti Designer无缝集成到开发环境中,提供代码自动完成、错误检查和调试等功能,极大地提高了开发效率。 4. ** Activiti Engine 集成**:Designer不仅用于...

    activiti-bpmn-converter-5.18.0-sources.jar

    activiti-bpmn-converter-5.18.0-sources.jar

    jeecg-boot集成activiti demo.rar

    Activiti 是一个轻量级的、企业级的工作流引擎,支持BPMN 2.0标准,提供图形化的流程设计器,使得非技术人员也能理解并编辑流程。它的特点是高度可扩展,性能优异,易于集成,适用于各种复杂业务场景。 3. **Jeecg...

Global site tag (gtag.js) - Google Analytics