├── LICENSE
├── README.md
├── conf
├── activiti.properties
├── db.sql
├── go-workflow.sql
└── init.sql
├── db
└── conn.go
├── engine
├── activitiEngineAgenda.go
├── activityBehavior.go
├── behavior
│ ├── abstractCommandInterceptor.go
│ ├── abstractOperation.go
│ ├── command.go
│ ├── commandContext.go
│ ├── commandContextFactory.go
│ ├── commandContextInterceptor.go
│ ├── commandExecutor.go
│ ├── commandExecutorImpl.go
│ ├── commandInterceptor.go
│ ├── commandInvoker.go
│ ├── context.go
│ ├── continueProcessOperation.go
│ ├── converter.go
│ ├── defaultActivitiEngineAgenda.go
│ ├── endExecutionOperation.go
│ ├── exclusiveGatewayActivityBehavior.go
│ ├── flowNodeActivityBehavior.go
│ ├── inclusiveGatewayActivityBehavior.go
│ ├── processEngineConfiguration.go
│ ├── processUtils.go
│ ├── serviceImpl.go
│ ├── takeOutgoingSequenceFlowsOperation.go
│ ├── tiggerableActivityBehavior.go
│ ├── transactionContextInterceptor.go
│ ├── triggerExecutionOperation.go
│ ├── userAutoTaskActivityBehavior.go
│ └── userTaskActivityBehavior.go
├── cmd
│ ├── backTaskCmd.go
│ ├── completeCmd.go
│ ├── deployProcessCmd.go
│ ├── getTaskCmd.go
│ └── startProcessInstanceByKeyCmd.go
├── common
│ └── activitiCommon.go
├── entityImpl
│ ├── executionEntityImpl.go
│ └── taskEntityImpl.go
├── executionEntity.go
├── handler
│ ├── iActiviti.go
│ └── iActivitiDemo.go
├── manager
│ └── dbManager.go
├── operation.go
├── persistence
│ ├── defineManager.go
│ ├── deploymentManager.go
│ ├── historicActinstManager.go
│ ├── historicIdentityLinkManager.go
│ ├── historicProcessManager.go
│ ├── historicTaskManager.go
│ ├── historicVariableManager.go
│ ├── identityLinkManager.go
│ ├── processInstanceManager.go
│ ├── taskManager.go
│ └── variableManager.go
├── process.go
├── service
│ ├── repositoryService.go
│ ├── runtimeService.go
│ └── taskService.go
├── utils
│ ├── conditionUtil.go
│ └── executionGraphUtil.go
├── variable
│ ├── boolType.go
│ ├── defaultVariableTypes.go
│ ├── historicVariable.go
│ ├── intType.go
│ ├── mapType.go
│ ├── stringType.go
│ ├── valueFields.go
│ ├── variable.go
│ ├── variableInstanceEntity.go
│ ├── variableType.go
│ └── variableTypes.go
└── variableScope.go
├── entity
├── identityLinkEntity.go
├── processInstanceEntity.go
├── taskEntity.go
└── variableEntity.go
├── errs
├── errs.go
└── processError.go
├── event
├── activitiEntityEvent.go
├── activitiEvent.go
├── activitiEventDispatcher.go
├── activitiEventDispatcherImpl.go
├── activitiEventListener.go
├── activitiEventSupport.go
└── impl
│ ├── activitiEntityEventImpl.go
│ ├── activitiEventBuilder.go
│ └── activitiEventImpl.go
├── go.mod
├── main.go
├── model
├── bytearry.go
├── deployment.go
├── historicActinst.go
├── historicIdentityLink.go
├── historicProcinst.go
├── historicTask.go
├── identityLink.go
├── procinst.go
└── task.go
├── resources
├── process_demo.bpmn20.xml
├── userAuto.bpmn20.xml
└── userTest.bpmn20.xml
├── runtime
└── runtime.go
├── templates
└── index.html
├── test
└── process_test.go
└── web
├── handlers.go
└── response.go
/LICENSE:
--------------------------------------------------------------------------------
1 | Apache License
2 | Version 2.0, January 2004
3 | http://www.apache.org/licenses/
4 |
5 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
6 |
7 | 1. Definitions.
8 |
9 | "License" shall mean the terms and conditions for use, reproduction,
10 | and distribution as defined by Sections 1 through 9 of this document.
11 |
12 | "Licensor" shall mean the copyright owner or entity authorized by
13 | the copyright owner that is granting the License.
14 |
15 | "Legal Entity" shall mean the union of the acting entity and all
16 | other entities that control, are controlled by, or are under common
17 | control with that entity. For the purposes of this definition,
18 | "control" means (i) the power, direct or indirect, to cause the
19 | direction or management of such entity, whether by contract or
20 | otherwise, or (ii) ownership of fifty percent (50%) or more of the
21 | outstanding shares, or (iii) beneficial ownership of such entity.
22 |
23 | "You" (or "Your") shall mean an individual or Legal Entity
24 | exercising permissions granted by this License.
25 |
26 | "Source" form shall mean the preferred form for making modifications,
27 | including but not limited to software source code, documentation
28 | source, and configuration files.
29 |
30 | "Object" form shall mean any form resulting from mechanical
31 | transformation or translation of a Source form, including but
32 | not limited to compiled object code, generated documentation,
33 | and conversions to other media types.
34 |
35 | "Work" shall mean the work of authorship, whether in Source or
36 | Object form, made available under the License, as indicated by a
37 | copyright notice that is included in or attached to the work
38 | (an example is provided in the Appendix below).
39 |
40 | "Derivative Works" shall mean any work, whether in Source or Object
41 | form, that is based on (or derived from) the Work and for which the
42 | editorial revisions, annotations, elaborations, or other modifications
43 | represent, as a whole, an original work of authorship. For the purposes
44 | of this License, Derivative Works shall not include works that remain
45 | separable from, or merely link (or bind by name) to the interfaces of,
46 | the Work and Derivative Works thereof.
47 |
48 | "Contribution" shall mean any work of authorship, including
49 | the original version of the Work and any modifications or additions
50 | to that Work or Derivative Works thereof, that is intentionally
51 | submitted to Licensor for inclusion in the Work by the copyright owner
52 | or by an individual or Legal Entity authorized to submit on behalf of
53 | the copyright owner. For the purposes of this definition, "submitted"
54 | means any form of electronic, verbal, or written communication sent
55 | to the Licensor or its representatives, including but not limited to
56 | communication on electronic mailing lists, source code control systems,
57 | and issue tracking systems that are managed by, or on behalf of, the
58 | Licensor for the purpose of discussing and improving the Work, but
59 | excluding communication that is conspicuously marked or otherwise
60 | designated in writing by the copyright owner as "Not a Contribution."
61 |
62 | "Contributor" shall mean Licensor and any individual or Legal Entity
63 | on behalf of whom a Contribution has been received by Licensor and
64 | subsequently incorporated within the Work.
65 |
66 | 2. Grant of Copyright License. Subject to the terms and conditions of
67 | this License, each Contributor hereby grants to You a perpetual,
68 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable
69 | copyright license to reproduce, prepare Derivative Works of,
70 | publicly display, publicly perform, sublicense, and distribute the
71 | Work and such Derivative Works in Source or Object form.
72 |
73 | 3. Grant of Patent License. Subject to the terms and conditions of
74 | this License, each Contributor hereby grants to You a perpetual,
75 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable
76 | (except as stated in this section) patent license to make, have made,
77 | use, offer to sell, sell, import, and otherwise transfer the Work,
78 | where such license applies only to those patent claims licensable
79 | by such Contributor that are necessarily infringed by their
80 | Contribution(s) alone or by combination of their Contribution(s)
81 | with the Work to which such Contribution(s) was submitted. If You
82 | institute patent litigation against any entity (including a
83 | cross-claim or counterclaim in a lawsuit) alleging that the Work
84 | or a Contribution incorporated within the Work constitutes direct
85 | or contributory patent infringement, then any patent licenses
86 | granted to You under this License for that Work shall terminate
87 | as of the date such litigation is filed.
88 |
89 | 4. Redistribution. You may reproduce and distribute copies of the
90 | Work or Derivative Works thereof in any medium, with or without
91 | modifications, and in Source or Object form, provided that You
92 | meet the following conditions:
93 |
94 | (a) You must give any other recipients of the Work or
95 | Derivative Works a copy of this License; and
96 |
97 | (b) You must cause any modified files to carry prominent notices
98 | stating that You changed the files; and
99 |
100 | (c) You must retain, in the Source form of any Derivative Works
101 | that You distribute, all copyright, patent, trademark, and
102 | attribution notices from the Source form of the Work,
103 | excluding those notices that do not pertain to any part of
104 | the Derivative Works; and
105 |
106 | (d) If the Work includes a "NOTICE" text file as part of its
107 | distribution, then any Derivative Works that You distribute must
108 | include a readable copy of the attribution notices contained
109 | within such NOTICE file, excluding those notices that do not
110 | pertain to any part of the Derivative Works, in at least one
111 | of the following places: within a NOTICE text file distributed
112 | as part of the Derivative Works; within the Source form or
113 | documentation, if provided along with the Derivative Works; or,
114 | within a display generated by the Derivative Works, if and
115 | wherever such third-party notices normally appear. The contents
116 | of the NOTICE file are for informational purposes only and
117 | do not modify the License. You may add Your own attribution
118 | notices within Derivative Works that You distribute, alongside
119 | or as an addendum to the NOTICE text from the Work, provided
120 | that such additional attribution notices cannot be construed
121 | as modifying the License.
122 |
123 | You may add Your own copyright statement to Your modifications and
124 | may provide additional or different license terms and conditions
125 | for use, reproduction, or distribution of Your modifications, or
126 | for any such Derivative Works as a whole, provided Your use,
127 | reproduction, and distribution of the Work otherwise complies with
128 | the conditions stated in this License.
129 |
130 | 5. Submission of Contributions. Unless You explicitly state otherwise,
131 | any Contribution intentionally submitted for inclusion in the Work
132 | by You to the Licensor shall be under the terms and conditions of
133 | this License, without any additional terms or conditions.
134 | Notwithstanding the above, nothing herein shall supersede or modify
135 | the terms of any separate license agreement you may have executed
136 | with Licensor regarding such Contributions.
137 |
138 | 6. Trademarks. This License does not grant permission to use the trade
139 | names, trademarks, service marks, or product names of the Licensor,
140 | except as required for reasonable and customary use in describing the
141 | origin of the Work and reproducing the content of the NOTICE file.
142 |
143 | 7. Disclaimer of Warranty. Unless required by applicable law or
144 | agreed to in writing, Licensor provides the Work (and each
145 | Contributor provides its Contributions) on an "AS IS" BASIS,
146 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
147 | implied, including, without limitation, any warranties or conditions
148 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
149 | PARTICULAR PURPOSE. You are solely responsible for determining the
150 | appropriateness of using or redistributing the Work and assume any
151 | risks associated with Your exercise of permissions under this License.
152 |
153 | 8. Limitation of Liability. In no event and under no legal theory,
154 | whether in tort (including negligence), contract, or otherwise,
155 | unless required by applicable law (such as deliberate and grossly
156 | negligent acts) or agreed to in writing, shall any Contributor be
157 | liable to You for damages, including any direct, indirect, special,
158 | incidental, or consequential damages of any character arising as a
159 | result of this License or out of the use or inability to use the
160 | Work (including but not limited to damages for loss of goodwill,
161 | work stoppage, computer failure or malfunction, or any and all
162 | other commercial damages or losses), even if such Contributor
163 | has been advised of the possibility of such damages.
164 |
165 | 9. Accepting Warranty or Additional Liability. While redistributing
166 | the Work or Derivative Works thereof, You may choose to offer,
167 | and charge a fee for, acceptance of support, warranty, indemnity,
168 | or other liability obligations and/or rights consistent with this
169 | License. However, in accepting such obligations, You may act only
170 | on Your own behalf and on Your sole responsibility, not on behalf
171 | of any other Contributor, and only if You agree to indemnify,
172 | defend, and hold each Contributor harmless for any liability
173 | incurred by, or claims asserted against, such Contributor by reason
174 | of your accepting any such warranty or additional liability.
175 |
176 | END OF TERMS AND CONDITIONS
177 |
178 | APPENDIX: How to apply the Apache License to your work.
179 |
180 | To apply the Apache License to your work, attach the following
181 | boilerplate notice, with the fields enclosed by brackets "[]"
182 | replaced with your own identifying information. (Don't include
183 | the brackets!) The text should be enclosed in the appropriate
184 | comment syntax for the file format. We also recommend that a
185 | file or class name and description of purpose be included on the
186 | same "printed page" as the copyright notice for easier
187 | identification within third-party archives.
188 |
189 | Copyright [yyyy] [name of copyright owner]
190 |
191 | Licensed under the Apache License, Version 2.0 (the "License");
192 | you may not use this file except in compliance with the License.
193 | You may obtain a copy of the License at
194 |
195 | http://www.apache.org/licenses/LICENSE-2.0
196 |
197 | Unless required by applicable law or agreed to in writing, software
198 | distributed under the License is distributed on an "AS IS" BASIS,
199 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
200 | See the License for the specific language governing permissions and
201 | limitations under the License.
202 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | ## Go语言流程引擎go-activiti
2 | 项目传送门[go-activiti](https://github.com/lios/go-activiti)
3 |
4 | 参考[Activiti](https://github.com/Activiti/Activiti)实现,满足部分功能。项目还在完善中,欢迎activiti爱好者加入,Go语言她不香么。
5 |
6 |
7 | 现有能力
8 |
9 | - 节点类型,支持用户审批节点、排他网关、包容网关、并行网关
10 | - 流程功能,支持流程部署、流程发起、流程审批,流程驳回
11 | - 支持历史数据回溯
12 | - 全局事务
13 | - 全局事件监听,现支持节点事件处理
14 | - 节点事件回调
15 |
16 |
17 |
18 | BPMN文件解析,先使用的是JSON库,使用方便,但存在缺陷,不支持扩展后续完善件[process](https://github.com/lios/go-activiti/blob/master/engine/process.go)。
19 |
20 |
21 |
22 | ## 全局事务
23 |
24 | 参考activiti设计模式,依赖命令模式和责任链模式,使用gorm的事务能力,不需要关注事务。
25 |
26 | ```
27 | defer db.ClearTXDB()
28 | db.GORM_DB.Transaction(func(tx *gorm.DB) error {
29 | db.InitTXDB(tx)
30 | value, err = transactionContextInterceptor.Next.Execute(command)
31 | return err
32 | })
33 | ```
34 |
35 | ## **流程事件监听*
36 | 需实现ActivitiEventListener,将实现类加入配置文件
37 |
38 | ```java
39 | type ActivitiListener struct {
40 | name string
41 | }
42 |
43 | func (act ActivitiListener) OnEvent(event event.ActivitiEvent) error {
44 | fmt.Println(event)
45 | return nil
46 | }
47 | ```
48 |
49 | ```go
50 | configuration := behavior.GetProcessEngineConfiguration()
51 | eventListeners := make([]event.ActivitiEventListener, 0)
52 | eventListeners = append(eventListeners, ActivitiListener{})
53 | configuration.AddEventListeners(eventListeners)
54 | ```
55 |
56 | ## 节点事件回调
57 | 需实现IActiviti,注册构造器,参考iActivitiDemo.go文件
58 |
59 | ```java
60 | func init() {
61 | RegisterConstructor("userAuto", NewTestIActiviti)
62 | }
63 |
64 | func NewTestIActiviti(entity ExecutionEntity) IActiviti {
65 | return &TestIActiviti{
66 | Entity: entity,
67 | }
68 | }
69 | ```
70 |
71 | 后续计划:
72 |
73 |
74 | - 支持更多节点类型
75 | - bpmn解析完善,可扩展
76 | - 流程能力支持:流程跳转,撤销等等
77 | - 日志打印(优先)
78 | - 数据库默认值处理
79 | - 项目结构调整
80 |
81 | 期待您的加入。
82 |
83 |
--------------------------------------------------------------------------------
/conf/activiti.properties:
--------------------------------------------------------------------------------
1 | [mysql]
2 | username=root
3 | password=1234
4 | url=127.0.0.1:3306/go-workflow
5 | host=127.0.0.1
6 | port=3306
7 | dbname=go-workflow
8 | charset=utf8
9 |
10 |
--------------------------------------------------------------------------------
/conf/db.sql:
--------------------------------------------------------------------------------
1 | /*
2 | Navicat MySQL Data Transfer
3 |
4 | Source Server : 本地
5 | Source Server Version : 50018
6 | Source Host : localhost:3306
7 | Source Database : go-workflow
8 |
9 | Target Server Type : MYSQL
10 | Target Server Version : 50018
11 | File Encoding : 65001
12 |
13 | Date: 2020-07-07 23:57:52
14 | */
15 |
16 | SET FOREIGN_KEY_CHECKS=0;
17 |
18 | -- ----------------------------
19 | -- Table structure for bytearry
20 | -- ----------------------------
21 | DROP TABLE IF EXISTS `bytearry`;
22 | CREATE TABLE `bytearry` (
23 | `id` bigint(20) NOT NULL auto_increment COMMENT '主键id',
24 | `name` varchar(64) collate utf8_bin default NULL COMMENT '名称',
25 | `key` varchar(64) collate utf8_bin default NULL COMMENT '流程定义key',
26 | `version` bigint(2) default NULL COMMENT '版本',
27 | `deployment_id` bigint(64) default NULL COMMENT '流程部署id',
28 | `bytes` longblob COMMENT '资源文件',
29 | PRIMARY KEY (`id`)
30 | ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin;
31 |
32 | -- ----------------------------
33 | -- Table structure for deployment
34 | -- ----------------------------
35 | DROP TABLE IF EXISTS `deployment`;
36 | CREATE TABLE `deployment` (
37 | `id` bigint(20) NOT NULL auto_increment COMMENT '主键id',
38 | `name` varchar(64) collate utf8_bin default NULL COMMENT '名称',
39 | `key` varchar(64) collate utf8_bin default NULL COMMENT '流程定义key',
40 | `version` bigint(2) default NULL COMMENT '版本',
41 | `tenantI_id` bigint(64) default NULL COMMENT '租户id',
42 | `deploy_time` timestamp NOT NULL default CURRENT_TIMESTAMP on update CURRENT_TIMESTAMP COMMENT '部署时间',
43 | PRIMARY KEY (`id`)
44 | ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin;
45 |
46 | -- ----------------------------
47 | -- Table structure for identity_link
48 | -- ----------------------------
49 | DROP TABLE IF EXISTS `identity_link`;
50 | CREATE TABLE `identity_link` (
51 | `id` bigint(20) NOT NULL auto_increment COMMENT '主键id',
52 | `type` varchar(64) collate utf8_bin default NULL COMMENT '类型',
53 | `task_id` varchar(64) collate utf8_bin default NULL COMMENT '任务ID',
54 | `proc_inst_id` bigint(2) default NULL COMMENT '流程实例id',
55 | `group_id` bigint(64) default NULL COMMENT '组id',
56 | `user_id` timestamp NOT NULL default CURRENT_TIMESTAMP on update CURRENT_TIMESTAMP COMMENT '用户id',
57 | PRIMARY KEY (`id`)
58 | ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin;
59 |
60 | -- ----------------------------
61 | -- Table structure for process_instance
62 | -- ----------------------------
63 | DROP TABLE IF EXISTS `process_instance`;
64 | CREATE TABLE `process_instance` (
65 | `id` bigint(20) NOT NULL auto_increment COMMENT '主键id',
66 | `key` varchar(64) collate utf8_bin default NULL COMMENT '流程定义key',
67 | `name` varchar(64) collate utf8_bin default NULL COMMENT '名称',
68 | `version` bigint(2) default NULL COMMENT '版本',
69 | `business_key` varchar(64) collate utf8_bin default NULL,
70 | `tenant_id` varchar(64) collate utf8_bin default NULL COMMENT '租户id',
71 | `deployment_id` bigint(64) default NULL COMMENT '流程部署id',
72 | `start_time` timestamp NOT NULL default CURRENT_TIMESTAMP on update CURRENT_TIMESTAMP COMMENT '启动时间',
73 | `start_user_id` varchar(64) collate utf8_bin default NULL COMMENT '启动用户',
74 | PRIMARY KEY (`id`)
75 | ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin;
76 |
77 | -- ----------------------------
78 | -- Table structure for task
79 | -- ----------------------------
80 | DROP TABLE IF EXISTS `task`;
81 | CREATE TABLE `task` (
82 | `id` bigint(20) NOT NULL auto_increment COMMENT '主键id',
83 | `task_define_key` varchar(64) collate utf8_bin default NULL COMMENT '任务key',
84 | `task_define_name` varchar(64) collate utf8_bin default NULL COMMENT '任务名称',
85 | `version` bigint(2) default NULL COMMENT '版本',
86 | `tenant_id` varchar(64) collate utf8_bin default NULL COMMENT '租户id',
87 | `deployment_id` bigint(64) default NULL COMMENT '流程部署id',
88 | `start_time` timestamp NOT NULL default CURRENT_TIMESTAMP on update CURRENT_TIMESTAMP COMMENT '启动时间',
89 | `assignee` varchar(64) collate utf8_bin default NULL COMMENT '审批人',
90 | `proc_inst_id` bigint(64) default NULL COMMENT '实例iD',
91 | PRIMARY KEY (`id`)
92 | ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin;
93 |
94 | -- ----------------------------
95 | -- Table structure for task
96 | -- ----------------------------
97 | DROP TABLE IF EXISTS `variable`;
98 | CREATE TABLE `variable` (
99 | `id` bigint(20) NOT NULL auto_increment COMMENT '主键id',
100 | `version` bigint(2) default NULL COMMENT '版本',
101 | `task_id` varchar(64) collate utf8_bin default NULL COMMENT '任务ID',
102 | `proc_inst_id` bigint(2) default NULL COMMENT '流程实例id',
103 | `name` varchar(64) collate utf8_bin default NULL COMMENT '变量名',
104 | `type` varchar(10) default NULL COMMENT '类型',
105 | `number` int default NULL COMMENT '类型',
106 | `date` datetime default NULL COMMENT '时间类型',
107 | `float` double collate utf8_bin default NULL COMMENT 'double',
108 | `text` varchar(4000) default NULL COMMENT '字符',
109 | `blob` longblob default NULL COMMENT '字符串',
110 | PRIMARY KEY (`id`)
111 | ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin;
112 |
113 |
--------------------------------------------------------------------------------
/conf/go-workflow.sql:
--------------------------------------------------------------------------------
1 | /*
2 | Navicat MySQL Data Transfer
3 |
4 | Source Server : 本地
5 | Source Server Version : 50018
6 | Source Host : localhost:3306
7 | Source Database : go-workflow
8 |
9 | Target Server Type : MYSQL
10 | Target Server Version : 50018
11 | File Encoding : 65001
12 |
13 | Date: 2020-07-25 22:11:13
14 | */
15 |
16 | SET FOREIGN_KEY_CHECKS=0;
17 |
18 | -- ----------------------------
19 | -- Table structure for bytearry
20 | -- ----------------------------
21 | DROP TABLE IF EXISTS `bytearry`;
22 | CREATE TABLE `bytearry` (
23 | `id` bigint(20) NOT NULL auto_increment COMMENT '主键id',
24 | `name` varchar(64) collate utf8_bin default NULL COMMENT '名称',
25 | `key` varchar(64) collate utf8_bin default NULL COMMENT '流程定义key',
26 | `version` bigint(2) default NULL COMMENT '版本',
27 | `deployment_id` bigint(64) default NULL COMMENT '流程部署id',
28 | `bytes` longblob COMMENT '资源文件',
29 | PRIMARY KEY (`id`)
30 | ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin;
31 |
32 | -- ----------------------------
33 | -- Table structure for deployment
34 | -- ----------------------------
35 | DROP TABLE IF EXISTS `deployment`;
36 | CREATE TABLE `deployment` (
37 | `id` bigint(20) NOT NULL auto_increment COMMENT '主键id',
38 | `name` varchar(64) collate utf8_bin default NULL COMMENT '名称',
39 | `key` varchar(64) collate utf8_bin default NULL COMMENT '流程定义key',
40 | `version` bigint(2) default NULL COMMENT '版本',
41 | `tenant_id` varchar(64) default NULL COMMENT '租户id',
42 | `deploy_time` timestamp NOT NULL default CURRENT_TIMESTAMP on update CURRENT_TIMESTAMP COMMENT '部署时间',
43 | PRIMARY KEY (`id`)
44 | ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin;
45 |
46 | -- ----------------------------
47 | -- Table structure for identity_link
48 | -- ----------------------------
49 | DROP TABLE IF EXISTS `identity_link`;
50 | CREATE TABLE `identity_link` (
51 | `id` bigint(20) NOT NULL auto_increment COMMENT '主键id',
52 | `type` varchar(64) collate utf8_bin default NULL COMMENT '类型',
53 | `task_id` varchar(64) collate utf8_bin default NULL COMMENT '任务ID',
54 | `proc_inst_id` bigint(2) default NULL COMMENT '流程实例id',
55 | `group_id` bigint(64) default NULL COMMENT '组id',
56 | `user_id` timestamp NOT NULL default CURRENT_TIMESTAMP on update CURRENT_TIMESTAMP COMMENT '用户id',
57 | PRIMARY KEY (`id`)
58 | ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin;
59 |
60 | -- ----------------------------
61 | -- Table structure for process_instance
62 | -- ----------------------------
63 | DROP TABLE IF EXISTS `process_instance`;
64 | CREATE TABLE `process_instance` (
65 | `id` bigint(20) NOT NULL auto_increment COMMENT '主键id',
66 | `key` varchar(64) collate utf8_bin default NULL COMMENT '流程定义key',
67 | `name` varchar(64) collate utf8_bin default NULL COMMENT '名称',
68 | `version` bigint(2) default NULL COMMENT '版本',
69 | `business_key` varchar(64) collate utf8_bin default NULL,
70 | `tenant_id` varchar(64) collate utf8_bin default NULL COMMENT '租户id',
71 | `deployment_id` bigint(20) default NULL COMMENT '流程部署id',
72 | `start_time` timestamp NOT NULL default CURRENT_TIMESTAMP on update CURRENT_TIMESTAMP COMMENT '启动时间',
73 | `start_user_id` varchar(64) collate utf8_bin default NULL COMMENT '启动用户',
74 | `process_define_id` bigint(20) default NULL,
75 | PRIMARY KEY (`id`)
76 | ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin;
77 |
78 | -- ----------------------------
79 | -- Table structure for task
80 | -- ----------------------------
81 | DROP TABLE IF EXISTS `task`;
82 | CREATE TABLE `task` (
83 | `id` bigint(20) NOT NULL auto_increment COMMENT '主键id',
84 | `task_define_key` varchar(64) collate utf8_bin default NULL COMMENT '任务key',
85 | `task_define_name` varchar(64) collate utf8_bin default NULL COMMENT '任务名称',
86 | `version` bigint(2) default NULL COMMENT '版本',
87 | `tenant_id` varchar(64) collate utf8_bin default NULL COMMENT '租户id',
88 | `deployment_id` bigint(64) default NULL COMMENT '流程部署id',
89 | `start_time` timestamp NOT NULL default CURRENT_TIMESTAMP on update CURRENT_TIMESTAMP COMMENT '启动时间',
90 | `assignee` varchar(64) collate utf8_bin default NULL COMMENT '审批人',
91 | `proc_inst_id` bigint(64) default NULL COMMENT '实例iD',
92 | PRIMARY KEY (`id`)
93 | ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin;
94 |
95 | -- ----------------------------
96 | -- Table structure for variable
97 | -- ----------------------------
98 | DROP TABLE IF EXISTS `variable`;
99 | CREATE TABLE `variable` (
100 | `id` bigint(20) NOT NULL auto_increment COMMENT '主键id',
101 | `version` bigint(2) default NULL COMMENT '版本',
102 | `task_id` varchar(64) collate utf8_bin default NULL COMMENT '任务ID',
103 | `proc_inst_id` bigint(2) default NULL COMMENT '流程实例id',
104 | `name` varchar(64) collate utf8_bin default NULL COMMENT '变量名',
105 | `type` varchar(10) collate utf8_bin default NULL COMMENT '类型',
106 | `number` int(11) default NULL COMMENT '类型',
107 | `date` datetime default NULL COMMENT '时间类型',
108 | `float` double default NULL COMMENT 'double',
109 | `text` varchar(4000) collate utf8_bin default NULL COMMENT '字符',
110 | `blob` longblob COMMENT '字符串',
111 | PRIMARY KEY (`id`)
112 | ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin;
113 |
114 | -- ----------------------------
115 | -- Table structure for hi_identity_link
116 | -- ----------------------------
117 | DROP TABLE IF EXISTS `hi_identity_link`;
118 | CREATE TABLE `hi_identity_link` (
119 | `id` bigint(20) NOT NULL auto_increment COMMENT '主键id',
120 | `type` varchar(64) collate utf8_bin default NULL COMMENT '类型',
121 | `task_id` varchar(64) collate utf8_bin default NULL COMMENT '任务ID',
122 | `proc_inst_id` bigint(2) default NULL COMMENT '流程实例id',
123 | `group_id` bigint(64) default NULL COMMENT '组id',
124 | `user_id` timestamp NOT NULL default CURRENT_TIMESTAMP on update CURRENT_TIMESTAMP COMMENT '用户id',
125 | PRIMARY KEY (`id`)
126 | ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin;
127 |
128 | -- ----------------------------
129 | -- Table structure for hi_process_instance
130 | -- ----------------------------
131 | DROP TABLE IF EXISTS `hi_process_instance`;
132 | CREATE TABLE `hi_process_instance` (
133 | `id` bigint(20) NOT NULL auto_increment COMMENT '主键id',
134 | `key` varchar(64) collate utf8_bin default NULL COMMENT '流程定义key',
135 | `name` varchar(64) collate utf8_bin default NULL COMMENT '名称',
136 | `version` bigint(2) default NULL COMMENT '版本',
137 | `business_key` varchar(64) collate utf8_bin default NULL,
138 | `tenant_id` varchar(64) collate utf8_bin default NULL COMMENT '租户id',
139 | `deployment_id` bigint(20) default NULL COMMENT '流程部署id',
140 | `start_time` timestamp NULL default NULL COMMENT '启动时间',
141 | `end_time` timestamp NULL default NULL COMMENT '结束时间',
142 | `start_user_id` varchar(64) collate utf8_bin default NULL COMMENT '启动用户',
143 | `process_define_id` bigint(20) default NULL,
144 | `proc_inst_id` bigint(64) default NULL COMMENT '实例id',
145 | PRIMARY KEY (`id`)
146 | ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin;
147 |
148 | -- ----------------------------
149 | -- Table structure for hi_task
150 | -- ----------------------------
151 | DROP TABLE IF EXISTS `hi_task`;
152 | CREATE TABLE `hi_task` (
153 | `id` bigint(20) NOT NULL auto_increment COMMENT '主键id',
154 | `task_define_key` varchar(64) collate utf8_bin default NULL COMMENT '任务key',
155 | `task_define_name` varchar(64) collate utf8_bin default NULL COMMENT '任务名称',
156 | `version` bigint(2) default NULL COMMENT '版本',
157 | `tenant_id` varchar(64) collate utf8_bin default NULL COMMENT '租户id',
158 | `deployment_id` bigint(64) default NULL COMMENT '流程部署id',
159 | `start_time` timestamp NULL default NULL COMMENT '启动时间',
160 | `end_time` timestamp NULL default NULL COMMENT '结束时间',
161 | `assignee` varchar(64) collate utf8_bin default NULL COMMENT '审批人',
162 | `proc_inst_id` bigint(64) default NULL COMMENT '实例id',
163 | `task_id` bigint(64) default NULL COMMENT '运行任务id',
164 | PRIMARY KEY (`id`)
165 | ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin;
166 |
167 |
168 | -- ----------------------------
169 | -- Table structure for hi_variable
170 | -- ----------------------------
171 | DROP TABLE IF EXISTS `hi_variable`;
172 | CREATE TABLE `hi_variable` (
173 | `id` bigint(20) NOT NULL auto_increment COMMENT '主键id',
174 | `version` bigint(2) default NULL COMMENT '版本',
175 | `task_id` varchar(64) collate utf8_bin default NULL COMMENT '任务ID',
176 | `proc_inst_id` bigint(2) default NULL COMMENT '流程实例id',
177 | `name` varchar(64) collate utf8_bin default NULL COMMENT '变量名',
178 | `type` varchar(10) collate utf8_bin default NULL COMMENT '类型',
179 | `number` int(11) default NULL COMMENT '类型',
180 | `date` datetime default NULL COMMENT '时间类型',
181 | `float` double default NULL COMMENT 'double',
182 | `text` varchar(4000) collate utf8_bin default NULL COMMENT '字符',
183 | `blob` longblob COMMENT '字符串',
184 | PRIMARY KEY (`id`)
185 | ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin;
186 |
187 | -- ----------------------------
188 | -- Table structure for hi_actinst
189 | -- ----------------------------
190 | DROP TABLE IF EXISTS `hi_actinst`;
191 | CREATE TABLE `hi_actinst` (
192 | `id` bigint(20) NOT NULL auto_increment COMMENT '主键id',
193 | `task_id` varchar(64) collate utf8_bin default NULL COMMENT '任务ID',
194 | `proc_inst_id` bigint(2) default NULL COMMENT '流程实例id',
195 | `act_id` varchar(64) collate utf8_bin default NULL COMMENT '实例Id',
196 | `act_name` varchar(64) collate utf8_bin default NULL COMMENT '实例名称',
197 | `act_type` varchar(10) collate utf8_bin default NULL COMMENT '实例类型',
198 | `start_time` timestamp NULL default NULL COMMENT '启动时间',
199 | `end_time` timestamp NULL default NULL COMMENT '结束时间',
200 | `assignee` varchar(64) collate utf8_bin default NULL COMMENT '审批人',
201 | `start_user_id` varchar(64) collate utf8_bin default NULL COMMENT '启动用户',
202 | `process_define_id` bigint(20) default NULL,
203 | `tenant_id` varchar(64) collate utf8_bin default NULL COMMENT '租户id',
204 | PRIMARY KEY (`id`)
205 | ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin;
206 |
207 |
--------------------------------------------------------------------------------
/conf/init.sql:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lios/go-activiti/8b75618ebe7d928903c4643a2f9b15ecad9c4c31/conf/init.sql
--------------------------------------------------------------------------------
/db/conn.go:
--------------------------------------------------------------------------------
1 | package db
2 |
3 | import (
4 | "errors"
5 | "fmt"
6 | "github.com/Unknwon/goconfig"
7 | _ "github.com/go-sql-driver/mysql"
8 | "github.com/jinzhu/gorm"
9 | "github.com/lios/go-activiti/runtime"
10 | "os"
11 | "os/exec"
12 | "path/filepath"
13 | "strings"
14 | "sync"
15 | )
16 |
17 | var GORM_DB *gorm.DB
18 |
19 | var TXDB *sync.Map
20 |
21 | var DNS string
22 |
23 | var ROOT string
24 |
25 | const mainIniPath = "/conf/activiti.properties"
26 |
27 | func init() {
28 | curFilename := os.Args[0]
29 | binaryPath, err := exec.LookPath(curFilename)
30 | if err != nil {
31 | panic(err)
32 | }
33 |
34 | binaryPath, err = filepath.Abs(binaryPath)
35 | if err != nil {
36 | panic(err)
37 | }
38 |
39 | ROOT = filepath.Dir(filepath.Dir(binaryPath))
40 |
41 | configPath := ROOT + mainIniPath
42 |
43 | if !fileExist(configPath) {
44 | curDir, _ := os.Getwd()
45 | pos := strings.LastIndex(curDir, "src")
46 | if pos == -1 {
47 | // panic("can't find " + mainIniPath)
48 | fmt.Println("can't find " + mainIniPath)
49 | } else {
50 | ROOT = curDir[:pos]
51 |
52 | configPath = ROOT + mainIniPath
53 | }
54 | }
55 | configFile, err := goconfig.LoadConfigFile(configPath)
56 | if err != nil {
57 | panic(err)
58 | }
59 | TXDB = new(sync.Map)
60 | mysqlConfig, err := configFile.GetSection("mysql")
61 | if err != nil {
62 | fmt.Println("get mysql conf error:", err)
63 | return
64 | }
65 |
66 | fillDns(mysqlConfig)
67 | // 启动时就打开数据库连接
68 | if err = initEngine(); err != nil {
69 | panic(err)
70 | }
71 | // 测试数据库连接是否 OK
72 | if err = GORM_DB.DB().Ping(); err != nil {
73 | panic(err)
74 | }
75 | }
76 |
77 | var (
78 | ConnectDBErr = errors.New("connect db error")
79 | UseDBErr = errors.New("use db error")
80 | )
81 |
82 | func fillDns(mysqlConfig map[string]string) {
83 | DNS = fmt.Sprintf("%s:%s@tcp(%s:%s)/%s?charset=%s&parseTime=True&loc=Local",
84 | mysqlConfig["username"],
85 | mysqlConfig["password"],
86 | mysqlConfig["host"],
87 | mysqlConfig["port"],
88 | mysqlConfig["dbname"],
89 | mysqlConfig["charset"])
90 | }
91 |
92 | func initEngine() error {
93 | var err error
94 | GORM_DB, err = gorm.Open("mysql", DNS)
95 | if err != nil {
96 | return err
97 | }
98 | GORM_DB.LogMode(true)
99 | return nil
100 | }
101 |
102 | func InitTXDB(db *gorm.DB) {
103 | TXDB.Store(runtime.GoroutineId(), db)
104 | }
105 |
106 | func ClearTXDB() {
107 | TXDB.Delete(runtime.GoroutineId())
108 | }
109 |
110 | func DB() *gorm.DB {
111 | db, ok := TXDB.Load(runtime.GoroutineId())
112 | if !ok {
113 | panic("TXDB not init")
114 | }
115 | return db.(*gorm.DB)
116 | }
117 | func fileExist(filename string) bool {
118 | _, err := os.Stat(filename)
119 | return err == nil || os.IsExist(err)
120 | }
121 |
--------------------------------------------------------------------------------
/engine/activitiEngineAgenda.go:
--------------------------------------------------------------------------------
1 | package engine
2 |
3 | type ActivitiEngineAgenda interface {
4 | IsEmpty() bool
5 |
6 | PlanOperation(operation Operation)
7 |
8 | GetNextOperation() Operation
9 |
10 | PlanContinueProcessOperation(execution ExecutionEntity)
11 |
12 | //planContinueProcessSynchronousOperation(execution ExecutionEntity)
13 | //
14 | //planContinueProcessInCompensation(execution ExecutionEntity)
15 | //
16 | //planContinueMultiInstanceOperation(execution ExecutionEntity)
17 |
18 | PlanTakeOutgoingSequenceFlowsOperation(execution ExecutionEntity, evaluateConditions bool)
19 |
20 | PlanEndExecutionOperation(execution ExecutionEntity)
21 |
22 | PlanTriggerExecutionOperation(execution ExecutionEntity)
23 | //
24 | //planDestroyScopeOperation(execution ExecutionEntity)
25 | //
26 | //planExecuteInactiveBehaviorsOperation()
27 |
28 | }
29 |
--------------------------------------------------------------------------------
/engine/activityBehavior.go:
--------------------------------------------------------------------------------
1 | package engine
2 |
3 | type ActivityBehavior interface {
4 | Execute(execution ExecutionEntity) error
5 | }
6 |
--------------------------------------------------------------------------------
/engine/behavior/abstractCommandInterceptor.go:
--------------------------------------------------------------------------------
1 | package behavior
2 |
3 | type AbstractCommandInterceptor struct {
4 | Next CommandInterceptor
5 | }
6 |
--------------------------------------------------------------------------------
/engine/behavior/abstractOperation.go:
--------------------------------------------------------------------------------
1 | package behavior
2 |
3 | import (
4 | "github.com/lios/go-activiti/engine"
5 | )
6 |
7 | type AbstractOperation struct {
8 | CommandContext CommandContext
9 | Execution engine.ExecutionEntity
10 | }
11 |
--------------------------------------------------------------------------------
/engine/behavior/command.go:
--------------------------------------------------------------------------------
1 | package behavior
2 |
3 | type Command interface {
4 | Execute(interceptor CommandContext) (interface{}, error)
5 | }
6 |
--------------------------------------------------------------------------------
/engine/behavior/commandContext.go:
--------------------------------------------------------------------------------
1 | package behavior
2 |
3 | import (
4 | "github.com/lios/go-activiti/engine"
5 | . "github.com/lios/go-activiti/engine/persistence"
6 | )
7 |
8 | type CommandContext struct {
9 | Command Command
10 | Agenda engine.ActivitiEngineAgenda
11 | ProcessEngineConfiguration ProcessEngineConfiguration
12 | }
13 |
14 | func GetProcessInstanceManager() ProcessInstanceManager {
15 | return ProcessInstanceManager{}
16 | }
17 |
--------------------------------------------------------------------------------
/engine/behavior/commandContextFactory.go:
--------------------------------------------------------------------------------
1 | package behavior
2 |
3 | type CommandContextFactory struct {
4 | }
5 |
6 | func (factory CommandContextFactory) CreateCommandContext(command Command) CommandContext {
7 | context := CommandContext{Command: command, Agenda: &DefaultActivitiEngineAgenda{}}
8 | return context
9 | }
10 |
--------------------------------------------------------------------------------
/engine/behavior/commandContextInterceptor.go:
--------------------------------------------------------------------------------
1 | package behavior
2 |
3 | type CommandContextInterceptor struct {
4 | Next CommandInterceptor
5 | ProcessEngineConfiguration *ProcessEngineConfiguration
6 | CommandContextFactory CommandContextFactory
7 | }
8 |
9 | func (commandContext CommandContextInterceptor) Execute(command Command) (interface{}, error) {
10 | context, err := GetCommandContext()
11 | if err != nil {
12 | context = commandContext.CommandContextFactory.CreateCommandContext(command)
13 | }
14 | SetCommandContext(context)
15 | return commandContext.Next.Execute(command)
16 | }
17 |
18 | func (commandContext *CommandContextInterceptor) SetNext(next CommandInterceptor) {
19 | commandContext.Next = next
20 | }
21 |
--------------------------------------------------------------------------------
/engine/behavior/commandExecutor.go:
--------------------------------------------------------------------------------
1 | package behavior
2 |
3 | type CommandExecutor interface {
4 | Exe(conf Command) (interface{}, error)
5 | }
6 |
--------------------------------------------------------------------------------
/engine/behavior/commandExecutorImpl.go:
--------------------------------------------------------------------------------
1 | package behavior
2 |
3 | type CommandExecutorImpl struct {
4 | First CommandInterceptor
5 | }
6 |
7 | func (comm CommandExecutorImpl) Exe(conf Command) (interface{}, error) {
8 | return comm.First.Execute(conf)
9 | }
10 |
--------------------------------------------------------------------------------
/engine/behavior/commandInterceptor.go:
--------------------------------------------------------------------------------
1 | package behavior
2 |
3 | type CommandInterceptor interface {
4 | Execute(command Command) (interface{}, error)
5 |
6 | SetNext(next CommandInterceptor)
7 | }
8 |
--------------------------------------------------------------------------------
/engine/behavior/commandInvoker.go:
--------------------------------------------------------------------------------
1 | package behavior
2 |
3 | type CommandInvoker struct {
4 | Next CommandInterceptor
5 | }
6 |
7 | func (commandInvoker CommandInvoker) Execute(command Command) (result interface{}, err error) {
8 | context, err := GetCommandContext()
9 | if err != nil {
10 | return nil, err
11 | }
12 | result, err = command.Execute(context)
13 | if err != nil {
14 | return nil, err
15 | }
16 | err = executeOperations(context)
17 | return result, err
18 | }
19 |
20 | func executeOperations(context CommandContext) (err error) {
21 | for !context.Agenda.IsEmpty() {
22 | err = context.Agenda.GetNextOperation().Run()
23 | if err != nil {
24 | return err
25 | }
26 | }
27 | return err
28 | }
29 |
30 | func (commandInvoker *CommandInvoker) SetNext(next CommandInterceptor) {
31 | commandInvoker.Next = next
32 | }
33 |
--------------------------------------------------------------------------------
/engine/behavior/context.go:
--------------------------------------------------------------------------------
1 | package behavior
2 |
3 | import (
4 | "container/list"
5 | "github.com/lios/go-activiti/engine"
6 | "github.com/lios/go-activiti/errs"
7 | )
8 |
9 | var (
10 | Stack list.List
11 | )
12 |
13 | type Context struct {
14 | }
15 |
16 | func SetCommandContext(commandContext CommandContext) {
17 | Stack.PushFront(commandContext)
18 | }
19 |
20 | func GetCommandContext() (CommandContext, error) {
21 | if Stack.Len() <= 0 {
22 | return CommandContext{}, errs.ProcessError{}
23 | }
24 | return Stack.Front().Value.(CommandContext), nil
25 | }
26 |
27 | func GetAgenda() engine.ActivitiEngineAgenda {
28 | return Stack.Front().Value.(CommandContext).Agenda
29 | }
30 |
--------------------------------------------------------------------------------
/engine/behavior/continueProcessOperation.go:
--------------------------------------------------------------------------------
1 | package behavior
2 |
3 | import (
4 | "github.com/lios/go-activiti/engine"
5 | . "github.com/lios/go-activiti/engine/manager"
6 | )
7 |
8 | type ContinueProcessOperation struct {
9 | AbstractOperation
10 | }
11 |
12 | func (cont *ContinueProcessOperation) Run() (err error) {
13 | element := cont.Execution.GetCurrentFlowElement()
14 | if element != nil {
15 | flow, ok := element.(engine.SequenceFlow)
16 | if !ok {
17 | err = cont.continueThroughFlowNode(element)
18 | } else {
19 | cont.continueThroughSequenceFlow(flow)
20 | }
21 | }
22 | return err
23 | }
24 |
25 | func (cont *ContinueProcessOperation) continueThroughSequenceFlow(sequenceFlow engine.SequenceFlow) {
26 | flowElement := sequenceFlow.TargetFlowElement
27 | cont.Execution.SetCurrentFlowElement(flowElement)
28 | GetAgenda().PlanContinueProcessOperation(cont.Execution)
29 | }
30 |
31 | func (cont *ContinueProcessOperation) continueThroughFlowNode(element engine.FlowElement) (err error) {
32 | historicActinstManager := GetHistoricActinstManager()
33 | historicActinstManager.RecordActivityStart(cont.Execution)
34 | behavior := element.GetBehavior()
35 | if behavior != nil {
36 | err = behavior.Execute(cont.Execution)
37 | } else {
38 | GetAgenda().PlanTakeOutgoingSequenceFlowsOperation(cont.Execution, true)
39 | }
40 | return err
41 | }
42 |
--------------------------------------------------------------------------------
/engine/behavior/converter.go:
--------------------------------------------------------------------------------
1 | package behavior
2 |
3 | import (
4 | "encoding/xml"
5 | . "github.com/lios/go-activiti/engine"
6 | "github.com/lios/go-activiti/model"
7 | )
8 |
9 | func FindCurrentTask(bytearries model.Bytearry, taskDefineKey string) FlowElement {
10 | process := ConverterBpmn(bytearries)
11 | flowElement := process.FlowMap[taskDefineKey]
12 | return flowElement
13 | }
14 | func GetBpmn(bytes model.Bytearry) Process {
15 | return ConverterBpmn(bytes)
16 | }
17 | func ConverterBpmn(bytes model.Bytearry) Process {
18 | process, err := GetProcess(bytes.Id)
19 | if err == nil {
20 | return process
21 | }
22 | process = Converter([]byte(bytes.Bytes))
23 | SetProcess(bytes.Id, process)
24 | return process
25 | }
26 |
27 | func Converter(bytes []byte) Process {
28 | define := new(Definitions)
29 | xml.Unmarshal(bytes, &define)
30 | processes := define.Process
31 | if processes != nil {
32 | for j, p := range processes {
33 | flowMap := make(map[string]FlowElement, 0)
34 | processes[j].FlowMap = flowMap
35 | processes[j].Name = p.Documentation
36 | start := p.StartEvent
37 | if start != nil {
38 | for i, sta := range start {
39 | //flowMap[sta.Id] = start[i]
40 | processes[j].FlowMap[sta.Id] = start[i]
41 | processes[j].InitialFlowElement = start[i]
42 | }
43 | }
44 | se := p.SequenceFlow
45 | if se != nil {
46 | for i, s := range se {
47 | processes[j].FlowMap[s.Id] = se[i]
48 | }
49 | }
50 | user := p.UserTask
51 | if user != nil {
52 | for i, u := range user {
53 | assignments := checkAssignments(u)
54 | var behavior ActivityBehavior
55 | if !assignments {
56 | behavior = UserAutoTaskActivityBehavior{UserTask: user[i], ProcessKey: p.Id}
57 | } else {
58 | behavior = UserTaskActivityBehavior{UserTask: user[i], ProcessKey: p.Id}
59 | }
60 | user[i].SetBehavior(behavior)
61 | processes[j].FlowMap[u.Id] = user[i]
62 | }
63 | }
64 | end := p.EndEvent
65 | if end != nil {
66 | for i, e := range end {
67 | processes[j].FlowMap[e.Id] = end[i]
68 | }
69 | }
70 | exclusiveGateways := p.ExclusiveGateway
71 | if exclusiveGateways != nil {
72 | for i, exclusiveGateway := range exclusiveGateways {
73 | behavior := ExclusiveGatewayActivityBehavior{}
74 | exclusiveGateways[i].SetBehavior(behavior)
75 | processes[j].FlowMap[exclusiveGateway.Id] = exclusiveGateways[i]
76 | }
77 | }
78 | inclusiveGateways := p.InclusiveGateway
79 | if inclusiveGateways != nil {
80 | for i, inclusiveGateway := range inclusiveGateways {
81 | behavior := InclusiveGatewayActivityBehavior{}
82 | inclusiveGateways[i].SetBehavior(behavior)
83 | processes[j].FlowMap[inclusiveGateway.Id] = inclusiveGateways[i]
84 | }
85 | }
86 | flows := make([]FlowElement, len(flowMap))
87 | count := 0
88 | for _, v := range flowMap {
89 | flows[count] = v
90 | count++
91 | }
92 | processes[j].Flow = flows
93 | }
94 | }
95 | ConvertXMLToElement(define)
96 | return define.Process[0]
97 | }
98 |
99 | //设置元素的出入口
100 | func ConvertXMLToElement(model *Definitions) {
101 | processes := model.Process
102 | if processes != nil {
103 | for j, p := range processes {
104 | flows := p.Flow
105 | for i := range flows {
106 | value, ok := flows[i].(SequenceFlow)
107 | if ok {
108 | SourceRef := value.SourceRef
109 | //上一个节点
110 | lastFlow := processes[j].FlowMap[SourceRef]
111 | if lastFlow != nil {
112 | var outgoing = lastFlow.GetOutgoing()
113 | if outgoing == nil {
114 | outgoing = make([]FlowElement, 0)
115 | }
116 | newOut := append(outgoing, flows[i])
117 | //设置上一个节点出口
118 | lastFlow.SetOutgoing(newOut)
119 | //设置当前连线入口
120 | flows[i].SetSourceFlowElement(lastFlow)
121 |
122 | }
123 | //下一个节点
124 | TargetRef := value.TargetRef
125 | nextFlow := processes[j].FlowMap[TargetRef]
126 | if nextFlow != nil {
127 | incoming := nextFlow.GetIncoming()
128 | if incoming == nil {
129 | incoming = make([]FlowElement, 0)
130 | }
131 | newIn := append(incoming, flows[i])
132 | m := make([]*FlowElement, 1)
133 | m[0] = &nextFlow
134 | //设置当前连线出口
135 | flows[i].SetTargetFlowElement(nextFlow)
136 | //设置下一个节点入口
137 | nextFlow.SetIncoming(newIn)
138 | }
139 | }
140 | }
141 | }
142 | }
143 | }
144 |
145 | func checkAssignments(task UserTask) bool {
146 | users := task.CandidateUsers
147 | groups := task.CandidateGroups
148 | if (users == nil || len(users) < 1) && (groups == nil || len(groups) < 1) {
149 | return false
150 | }
151 | return true
152 | }
153 |
--------------------------------------------------------------------------------
/engine/behavior/defaultActivitiEngineAgenda.go:
--------------------------------------------------------------------------------
1 | package behavior
2 |
3 | import (
4 | "container/list"
5 | "github.com/lios/go-activiti/engine"
6 | )
7 |
8 | type DefaultActivitiEngineAgenda struct {
9 | Operations list.List
10 | }
11 |
12 | //判断是否为空
13 | func (agenda *DefaultActivitiEngineAgenda) IsEmpty() bool {
14 | return agenda.Operations.Len() == 0
15 | }
16 |
17 | //设置后续操作
18 | func (agenda *DefaultActivitiEngineAgenda) PlanOperation(operation engine.Operation) {
19 | agenda.Operations.PushFront(operation)
20 | }
21 |
22 | func (agenda *DefaultActivitiEngineAgenda) GetNextOperation() engine.Operation {
23 | value := agenda.Operations.Front()
24 | agenda.Operations.Remove(value)
25 | return value.Value.(engine.Operation)
26 | }
27 |
28 | //获取下一步操作
29 | func (agenda *DefaultActivitiEngineAgenda) getNextOperation() engine.Operation {
30 | return agenda.Operations.Front().Value.(engine.Operation)
31 | }
32 |
33 | //连线继续执行
34 | func (agenda *DefaultActivitiEngineAgenda) PlanContinueProcessOperation(execution engine.ExecutionEntity) {
35 | agenda.PlanOperation(&ContinueProcessOperation{AbstractOperation{Execution: execution}})
36 | }
37 |
38 | //任务出口执行
39 | func (agenda *DefaultActivitiEngineAgenda) PlanTriggerExecutionOperation(execution engine.ExecutionEntity) {
40 | agenda.PlanOperation(&TriggerExecutionOperation{AbstractOperation{Execution: execution}})
41 | }
42 |
43 | //连线出口设置
44 | func (agenda *DefaultActivitiEngineAgenda) PlanTakeOutgoingSequenceFlowsOperation(execution engine.ExecutionEntity, valuateConditions bool) {
45 | agenda.PlanOperation(&TakeOutgoingSequenceFlowsOperation{AbstractOperation: AbstractOperation{Execution: execution}, EvaluateConditions: valuateConditions})
46 | }
47 |
48 | //任务结束
49 | func (agenda *DefaultActivitiEngineAgenda) PlanEndExecutionOperation(execution engine.ExecutionEntity) {
50 | agenda.PlanOperation(&EndExecutionOperation{AbstractOperation: AbstractOperation{Execution: execution}})
51 | }
52 |
--------------------------------------------------------------------------------
/engine/behavior/endExecutionOperation.go:
--------------------------------------------------------------------------------
1 | package behavior
2 |
3 | import (
4 | "github.com/lios/go-activiti/engine"
5 | . "github.com/lios/go-activiti/engine/manager"
6 | )
7 |
8 | type EndExecutionOperation struct {
9 | AbstractOperation
10 | }
11 |
12 | func (end *EndExecutionOperation) Run() (err error) {
13 | err = deleteDataForExecution(end.Execution)
14 | if err != nil {
15 | return err
16 | }
17 | manager := GetProcessInstanceManager()
18 | err = manager.DeleteProcessInstance(end.Execution.GetProcessInstanceId())
19 | return err
20 | }
21 |
22 | func deleteDataForExecution(entity engine.ExecutionEntity) (err error) {
23 | taskManager := GetTaskManager()
24 | tasks, errSelect := taskManager.FindByProcessInstanceId(entity.GetProcessInstanceId())
25 | if errSelect == nil {
26 | for _, task := range tasks {
27 | taskManager.DeleteTask(task)
28 | }
29 | }
30 |
31 | identityLinkManager := GetIdentityLinkManager()
32 | identityLinks, errSelect := identityLinkManager.SelectByProcessInstanceId(entity.GetProcessInstanceId())
33 | if errSelect == nil {
34 | for _, identityLink := range identityLinks {
35 | err := identityLinkManager.Delete(identityLink.Id)
36 | if err != nil {
37 | return err
38 | }
39 | }
40 | }
41 | variableManager := GetVariableManager()
42 | variables, err := variableManager.SelectByProcessInstanceId(entity.GetProcessInstanceId())
43 | if err == nil {
44 | for _, variable := range variables {
45 | err = variableManager.Delete(variable.Id)
46 | if err != nil {
47 | return err
48 | }
49 | }
50 | }
51 | return err
52 | }
53 |
--------------------------------------------------------------------------------
/engine/behavior/exclusiveGatewayActivityBehavior.go:
--------------------------------------------------------------------------------
1 | package behavior
2 |
3 | import (
4 | "github.com/lios/go-activiti/engine"
5 | "github.com/lios/go-activiti/engine/utils"
6 | )
7 |
8 | type ExclusiveGatewayActivityBehavior struct {
9 | }
10 |
11 | //排他网关
12 | func (exclusive ExclusiveGatewayActivityBehavior) Execute(execution engine.ExecutionEntity) (err error) {
13 | err = exclusive.Leave(execution)
14 | return err
15 | }
16 |
17 | func (exclusive ExclusiveGatewayActivityBehavior) Leave(execution engine.ExecutionEntity) (err error) {
18 | element := execution.GetCurrentFlowElement()
19 | exclusiveGateway, ok := element.(engine.ExclusiveGateway)
20 | var outgoingSequenceFlow engine.FlowElement
21 | var defaultSequenceFlow engine.FlowElement
22 | if ok {
23 | defaultSequenceFlowId := exclusiveGateway.DefaultFlow
24 | sequenceFlowIterator := exclusiveGateway.GetOutgoing()
25 | if sequenceFlowIterator != nil && len(sequenceFlowIterator) > 0 {
26 | for _, sequenceFlow := range sequenceFlowIterator {
27 | flow := (sequenceFlow).(engine.SequenceFlow)
28 | conditionEvaluatesToTrue := utils.HasTrueCondition(flow, execution)
29 | if conditionEvaluatesToTrue && defaultSequenceFlowId != "" && defaultSequenceFlowId != flow.Id {
30 | outgoingSequenceFlow = sequenceFlow
31 | }
32 | if defaultSequenceFlowId != "" && defaultSequenceFlowId == flow.Id {
33 | defaultSequenceFlow = sequenceFlow
34 | }
35 | }
36 |
37 | }
38 | }
39 | if outgoingSequenceFlow != nil {
40 | execution.SetCurrentFlowElement(outgoingSequenceFlow)
41 | } else {
42 | if defaultSequenceFlow != nil {
43 | execution.SetCurrentFlowElement(defaultSequenceFlow)
44 | }
45 | }
46 | //执行出口逻辑,设置条件判断
47 | GetAgenda().PlanTakeOutgoingSequenceFlowsOperation(execution, true)
48 | return nil
49 | }
50 |
--------------------------------------------------------------------------------
/engine/behavior/flowNodeActivityBehavior.go:
--------------------------------------------------------------------------------
1 | package behavior
2 |
3 | import (
4 | "github.com/lios/go-activiti/engine"
5 | )
6 |
7 | type FlowNodeActivityBehavior interface {
8 | Leave(execution engine.ExecutionEntity) error
9 | }
10 |
--------------------------------------------------------------------------------
/engine/behavior/inclusiveGatewayActivityBehavior.go:
--------------------------------------------------------------------------------
1 | package behavior
2 |
3 | import (
4 | "github.com/lios/go-activiti/engine"
5 | . "github.com/lios/go-activiti/engine/manager"
6 | "github.com/lios/go-activiti/engine/utils"
7 | )
8 |
9 | type InclusiveGatewayActivityBehavior struct {
10 | }
11 |
12 | //包容网关
13 | func (exclusive InclusiveGatewayActivityBehavior) Execute(execution engine.ExecutionEntity) error {
14 | return exclusive.Leave(execution)
15 | }
16 |
17 | //执行逻辑:获取当前所有执行的节点,判断是否可达当前网关可以停止执行,等待完成
18 | func (exclusive InclusiveGatewayActivityBehavior) Leave(execution engine.ExecutionEntity) error {
19 | processInstanceId := execution.GetProcessInstanceId()
20 | taskManager := GetTaskManager()
21 | //查询当前执行节点
22 | tasks, errS := taskManager.FindByProcessInstanceId(processInstanceId)
23 | var oneExecutionCanReachGateway = false
24 | if errS != nil {
25 | bytearry, err := GetDefineManager().GetBytearry(execution.GetProcessDefineId())
26 | if err != nil {
27 | return err
28 | }
29 | process := GetBpmn(bytearry)
30 | for _, task := range tasks {
31 | if task.TaskDefineKey != execution.GetCurrentActivityId() {
32 | //判断是否可以继续执行
33 | oneExecutionCanReachGateway = utils.IsReachable(process, task.TaskDefineKey, execution.GetCurrentActivityId())
34 | } else {
35 | oneExecutionCanReachGateway = true
36 | }
37 | }
38 | }
39 | if !oneExecutionCanReachGateway {
40 | //执行出口逻辑,设置条件判断
41 | GetAgenda().PlanTakeOutgoingSequenceFlowsOperation(execution, true)
42 | }
43 | return nil
44 | }
45 |
--------------------------------------------------------------------------------
/engine/behavior/processEngineConfiguration.go:
--------------------------------------------------------------------------------
1 | package behavior
2 |
3 | import (
4 | . "github.com/lios/go-activiti/engine/variable"
5 | . "github.com/lios/go-activiti/event"
6 | )
7 |
8 | var processEngineConfiguration ProcessEngineConfiguration
9 |
10 | type ProcessEngineConfiguration struct {
11 | CommandInvoker CommandInterceptor
12 | CommandInterceptors []CommandInterceptor
13 | EventListeners []ActivitiEventListener
14 | Service ServiceImpl
15 | CommandExecutor CommandExecutor
16 | CommandContextFactory CommandContextFactory
17 | VariableTypes VariableTypes
18 | EventDispatcher ActivitiEventDispatcher
19 | }
20 |
21 | func GetProcessEngineConfiguration() *ProcessEngineConfiguration {
22 | return &processEngineConfiguration
23 | }
24 | func init() {
25 | processEngineConfiguration = ProcessEngineConfiguration{}
26 | initCommandContextFactory()
27 | initCommandInvoker()
28 | initCommandInterceptors()
29 | initCommandExecutor()
30 | initService()
31 | initCommandContext(processEngineConfiguration)
32 | initVariableTypes()
33 | initEventDispatcher()
34 | }
35 |
36 | func initCommandContext(configuration ProcessEngineConfiguration) {
37 | //context := CommandContext{}
38 | }
39 |
40 | func (processEngineConfiguration ProcessEngineConfiguration) AddEventListeners(eventListeners []ActivitiEventListener) {
41 | var EventListeners []ActivitiEventListener
42 | dispatcher := GetEventDispatcher()
43 | if len(eventListeners) > 0 {
44 | for _, listener := range eventListeners {
45 | EventListeners = append(EventListeners, listener)
46 | dispatcher.AddEventListener(listener)
47 | }
48 | }
49 | SetEventDispatcher(dispatcher)
50 | processEngineConfiguration.EventListeners = EventListeners
51 | }
52 |
53 | func getDefaultCommandInterceptors() []CommandInterceptor {
54 | var interceptors []CommandInterceptor
55 | interceptors = append(interceptors, &CommandContextInterceptor{CommandContextFactory: processEngineConfiguration.CommandContextFactory})
56 | //interceptors = append(interceptors, CommandInvoker{})
57 | interceptors = append(interceptors, &TransactionContextInterceptor{})
58 | return interceptors
59 | }
60 | func initCommandInvoker() {
61 | commandInvoker := CommandInvoker{}
62 | processEngineConfiguration.CommandInvoker = &commandInvoker
63 | }
64 |
65 | func initCommandInterceptors() {
66 | interceptors := getDefaultCommandInterceptors()
67 | interceptors = append(interceptors, processEngineConfiguration.CommandInvoker)
68 | processEngineConfiguration.CommandInterceptors = interceptors
69 | }
70 |
71 | func initCommandExecutor() {
72 | if processEngineConfiguration.CommandExecutor == nil {
73 | first := initInterceptorChain(processEngineConfiguration.CommandInterceptors)
74 | commandExecutor := CommandExecutorImpl{First: first}
75 | processEngineConfiguration.CommandExecutor = commandExecutor
76 | }
77 | }
78 | func initService() {
79 | serviceImpl := ServiceImpl{CommandExecutor: processEngineConfiguration.CommandExecutor}
80 | SetServiceImpl(serviceImpl)
81 | processEngineConfiguration.Service = serviceImpl
82 | }
83 |
84 | func initInterceptorChain(interceptors []CommandInterceptor) CommandInterceptor {
85 | if len(interceptors) > 0 {
86 | for i := 0; i < len(interceptors)-1; i++ {
87 | interceptor := interceptors[i]
88 | interceptor.SetNext(interceptors[i+1])
89 | }
90 | }
91 | return interceptors[0]
92 | }
93 |
94 | func initCommandContextFactory() {
95 | factory := CommandContextFactory{}
96 | processEngineConfiguration.CommandContextFactory = factory
97 | }
98 |
99 | func initVariableTypes() {
100 | defaultVariableTypes := DefaultVariableTypes{}
101 | defaultVariableTypes.AddType(BooleanType{})
102 | defaultVariableTypes.AddType(IntType{})
103 | defaultVariableTypes.AddType(StringType{})
104 | defaultVariableTypes.AddType(MapType{})
105 | processEngineConfiguration.VariableTypes = defaultVariableTypes
106 | }
107 |
108 | func initEventDispatcher() {
109 | eventDispatcher := processEngineConfiguration.EventDispatcher
110 | if processEngineConfiguration.EventDispatcher == nil {
111 | eventDispatcher = ActivitiEventDispatcherImpl{EventSupport: &ActivitiEventSupport{}, Enabled: true}
112 | }
113 | if processEngineConfiguration.EventListeners != nil && len(processEngineConfiguration.EventListeners) > 0 {
114 | for _, listenerToAdd := range processEngineConfiguration.EventListeners {
115 | eventDispatcher.AddEventListener(listenerToAdd)
116 | }
117 | }
118 | processEngineConfiguration.EventDispatcher = eventDispatcher
119 | SetEventDispatcher(eventDispatcher)
120 | }
121 |
--------------------------------------------------------------------------------
/engine/behavior/processUtils.go:
--------------------------------------------------------------------------------
1 | package behavior
2 |
3 | import (
4 | . "github.com/lios/go-activiti/engine"
5 | . "github.com/lios/go-activiti/engine/manager"
6 | "github.com/lios/go-activiti/errs"
7 | "sync"
8 | )
9 |
10 | var flowMap *sync.Map
11 |
12 | type ProcessUtils struct {
13 | ProcessId int64
14 | }
15 |
16 | func init() {
17 | flowMap = new(sync.Map)
18 | }
19 | func (processUtil *ProcessUtils) GetCurrentTask(taskId int) (FlowElement, error) {
20 | manager := GetTaskManager()
21 | task, err := manager.FindById(taskId)
22 | if err != nil {
23 | return nil, err
24 | }
25 | processUtil.ProcessId = task.ProcessInstanceId
26 | processUtil.LoadProcess()
27 | defineManager := GetDefineManager()
28 | bytearry, err := defineManager.FindProcessByTask(task.ProcessInstanceId)
29 | if err != nil {
30 | return nil, err
31 | }
32 | currentTask := FindCurrentTask(bytearry, task.TaskDefineKey)
33 | return currentTask, nil
34 | }
35 |
36 | func (processUtil *ProcessUtils) GetFlowElement(flowElementId string) (FlowElement, error) {
37 | flowM, ok := flowMap.Load(processUtil.ProcessId)
38 | if !ok {
39 |
40 | }
41 | flowElements, isOk := flowM.(map[string]FlowElement)
42 | if isOk {
43 | flowElement := flowElements[flowElementId]
44 | return flowElement, nil
45 | }
46 | return nil, errs.ProcessError{Code: "1003", Msg: "not find"}
47 | }
48 |
49 | func (processUtil *ProcessUtils) LoadProcess() error {
50 | defineManager := GetDefineManager()
51 | bytearry, err := defineManager.FindProcessByTask(processUtil.ProcessId)
52 | if err != nil {
53 | return err
54 | }
55 | process := ConverterBpmn(bytearry)
56 | flowMap.Store(processUtil.ProcessId, process.FlowMap)
57 | return nil
58 | }
59 |
--------------------------------------------------------------------------------
/engine/behavior/serviceImpl.go:
--------------------------------------------------------------------------------
1 | package behavior
2 |
3 | var serviceImpl ServiceImpl
4 |
5 | type ServiceImpl struct {
6 | CommandExecutor CommandExecutor
7 | }
8 |
9 | func (serviceImpl *ServiceImpl) SetCommandExecutor(commandExecutor CommandExecutor) {
10 | serviceImpl.CommandExecutor = commandExecutor
11 | }
12 |
13 | func GetServiceImpl() ServiceImpl {
14 | return serviceImpl
15 | }
16 |
17 | func SetServiceImpl(service ServiceImpl) {
18 | serviceImpl = service
19 | }
20 |
--------------------------------------------------------------------------------
/engine/behavior/takeOutgoingSequenceFlowsOperation.go:
--------------------------------------------------------------------------------
1 | package behavior
2 |
3 | import (
4 | . "github.com/lios/go-activiti/engine"
5 | . "github.com/lios/go-activiti/engine/manager"
6 | "github.com/lios/go-activiti/engine/utils"
7 | )
8 |
9 | type TakeOutgoingSequenceFlowsOperation struct {
10 | AbstractOperation
11 | EvaluateConditions bool
12 | }
13 |
14 | func (task TakeOutgoingSequenceFlowsOperation) Run() (err error) {
15 | currentFlowElement := task.getCurrentFlowElement()
16 | _, ok := currentFlowElement.(SequenceFlow)
17 | if ok {
18 | task.handleSequenceFlow()
19 | } else {
20 | err = task.handleFlowNode()
21 | }
22 | return err
23 | }
24 |
25 | //处理节点
26 | func (task TakeOutgoingSequenceFlowsOperation) handleFlowNode() (err error) {
27 | execution := task.Execution
28 | currentFlowElement := task.Execution.GetCurrentFlowElement()
29 | err = task.handleActivityEnd(currentFlowElement)
30 | if err != nil {
31 | return err
32 | }
33 | gateway, ok := currentFlowElement.(Gateway)
34 | var defaultSequenceFlowId = ""
35 | if ok {
36 | defaultSequenceFlowId = gateway.DefaultFlow
37 | }
38 | flowElements := currentFlowElement.GetOutgoing()
39 | var outgoingSequenceFlows = make([]FlowElement, 0)
40 | if len(flowElements) > 0 {
41 | for _, flowElement := range flowElements {
42 | sequenceFlow := (flowElement).(SequenceFlow)
43 | if !task.EvaluateConditions || utils.HasTrueCondition(sequenceFlow, execution) {
44 | outgoingSequenceFlows = append(outgoingSequenceFlows, flowElement)
45 | }
46 | }
47 | if outgoingSequenceFlows != nil && len(outgoingSequenceFlows) == 0 {
48 | if defaultSequenceFlowId != "" {
49 | for _, flowElement := range flowElements {
50 | if defaultSequenceFlowId == (flowElement).GetId() {
51 | outgoingSequenceFlows = append(outgoingSequenceFlows, flowElement)
52 | }
53 | }
54 | }
55 | }
56 | }
57 |
58 | if len(outgoingSequenceFlows) == 0 {
59 | if flowElements == nil || len(flowElements) == 0 {
60 | GetAgenda().PlanEndExecutionOperation(execution)
61 | } else {
62 | panic("No outgoing sequence flow of element")
63 | }
64 | } else {
65 | for _, outgoingExecution := range outgoingSequenceFlows {
66 | execution.SetCurrentFlowElement(outgoingExecution)
67 | GetAgenda().PlanContinueProcessOperation(execution)
68 | }
69 | }
70 | return err
71 | }
72 |
73 | //处理连线
74 | func (task TakeOutgoingSequenceFlowsOperation) handleSequenceFlow() {
75 | GetAgenda().PlanContinueProcessOperation(task.Execution)
76 | }
77 |
78 | //获取当前活动节点
79 | func (task TakeOutgoingSequenceFlowsOperation) getCurrentFlowElement() FlowElement {
80 | execution := task.Execution
81 | currentFlowElement := execution.GetCurrentFlowElement()
82 | if currentFlowElement != nil {
83 | return currentFlowElement
84 | }
85 | return nil
86 | }
87 |
88 | func (task TakeOutgoingSequenceFlowsOperation) handleActivityEnd(element FlowElement) (err error) {
89 | historicActinstManager := GetHistoricActinstManager()
90 | err = historicActinstManager.RecordTaskCreated(element, task.Execution)
91 | return err
92 | }
93 |
--------------------------------------------------------------------------------
/engine/behavior/tiggerableActivityBehavior.go:
--------------------------------------------------------------------------------
1 | package behavior
2 |
3 | import (
4 | "github.com/lios/go-activiti/engine"
5 | )
6 |
7 | type TriggerableActivityBehavior interface {
8 | Trigger(entity engine.ExecutionEntity)
9 | }
10 |
--------------------------------------------------------------------------------
/engine/behavior/transactionContextInterceptor.go:
--------------------------------------------------------------------------------
1 | package behavior
2 |
3 | import (
4 | "github.com/jinzhu/gorm"
5 | "github.com/lios/go-activiti/db"
6 | )
7 |
8 | type TransactionContextInterceptor struct {
9 | Next CommandInterceptor
10 | }
11 |
12 | func (transactionContextInterceptor TransactionContextInterceptor) Execute(command Command) (value interface{}, err error) {
13 | defer db.ClearTXDB()
14 | db.GORM_DB.Transaction(func(tx *gorm.DB) error {
15 | db.InitTXDB(tx)
16 | value, err = transactionContextInterceptor.Next.Execute(command)
17 | return err
18 | })
19 | return value, err
20 | }
21 |
22 | func (transactionContextInterceptor *TransactionContextInterceptor) SetNext(next CommandInterceptor) {
23 | transactionContextInterceptor.Next = next
24 | }
25 |
--------------------------------------------------------------------------------
/engine/behavior/triggerExecutionOperation.go:
--------------------------------------------------------------------------------
1 | package behavior
2 |
3 | import (
4 | "github.com/lios/go-activiti/engine"
5 | )
6 |
7 | type TriggerExecutionOperation struct {
8 | AbstractOperation
9 | }
10 |
11 | func (trigger TriggerExecutionOperation) Run() (err error) {
12 | element := trigger.getCurrentFlowElement(trigger.Execution)
13 | behavior := element.GetBehavior()
14 | operation := behavior.(TriggerableActivityBehavior)
15 | operation.Trigger(trigger.Execution)
16 | return err
17 | }
18 |
19 | func (trigger TriggerExecutionOperation) getCurrentFlowElement(execut engine.ExecutionEntity) engine.FlowElement {
20 | currentFlowElement := execut.GetCurrentFlowElement()
21 | if currentFlowElement != nil {
22 | return currentFlowElement
23 | }
24 | return nil
25 | }
26 |
--------------------------------------------------------------------------------
/engine/behavior/userAutoTaskActivityBehavior.go:
--------------------------------------------------------------------------------
1 | package behavior
2 |
3 | import (
4 | "github.com/lios/go-activiti/engine"
5 | . "github.com/lios/go-activiti/engine/common"
6 | . "github.com/lios/go-activiti/engine/handler"
7 | . "github.com/lios/go-activiti/engine/persistence"
8 | . "github.com/lios/go-activiti/model"
9 | "reflect"
10 | "time"
11 | )
12 |
13 | type UserAutoTaskActivityBehavior struct {
14 | UserTask engine.UserTask
15 | ProcessKey string
16 | }
17 |
18 | //自动通过用户节点处理
19 | func (user UserAutoTaskActivityBehavior) Execute(execution engine.ExecutionEntity) (err error) {
20 | task := Task{}
21 | task.ProcessInstanceId = execution.GetProcessInstanceId()
22 | task.Assignee = user.UserTask.Assignee
23 | task.StartTime = time.Now()
24 | task.TaskDefineKey = user.UserTask.Id
25 | task.TaskDefineName = user.UserTask.Name
26 | manager := TaskManager{Task: &task}
27 | err = manager.Insert(execution)
28 |
29 | activitiConstructor, err := GetConstructorByName(user.ProcessKey)
30 | if err != nil {
31 | manager.DeleteTask(task)
32 | GetAgenda().PlanTriggerExecutionOperation(execution)
33 | return nil
34 | }
35 | constructor := activitiConstructor(execution)
36 | reflectConstructor := reflect.ValueOf(constructor)
37 | taskParams := []reflect.Value{reflectConstructor}
38 |
39 | method, b := reflectConstructor.Type().MethodByName(user.UserTask.Name)
40 | if !b {
41 | manager.DeleteTask(task)
42 | GetAgenda().PlanTriggerExecutionOperation(execution)
43 | return err
44 | }
45 |
46 | callResponse := method.Func.Call(taskParams)
47 |
48 | code := callResponse[0].Interface()
49 | errRes := callResponse[1].Interface()
50 | code = code.(string)
51 | if code != ACTIVITI_HANDLER_CODE {
52 | err := errRes.(error)
53 | return err
54 | }
55 | manager.DeleteTask(task)
56 | GetAgenda().PlanTriggerExecutionOperation(execution)
57 | return err
58 | }
59 |
60 | //普通用户节点处理
61 | func (user UserAutoTaskActivityBehavior) Trigger(execution engine.ExecutionEntity) {
62 | user.Leave(execution)
63 | }
64 |
65 | func (user UserAutoTaskActivityBehavior) Leave(execution engine.ExecutionEntity) {
66 | element := execution.GetCurrentFlowElement()
67 | execution.SetCurrentFlowElement(element)
68 | GetAgenda().PlanTakeOutgoingSequenceFlowsOperation(execution, true)
69 | }
70 |
--------------------------------------------------------------------------------
/engine/behavior/userTaskActivityBehavior.go:
--------------------------------------------------------------------------------
1 | package behavior
2 |
3 | import (
4 | "github.com/lios/go-activiti/engine"
5 | . "github.com/lios/go-activiti/engine/common"
6 | . "github.com/lios/go-activiti/engine/handler"
7 | . "github.com/lios/go-activiti/engine/manager"
8 | . "github.com/lios/go-activiti/engine/persistence"
9 | "github.com/lios/go-activiti/event"
10 | . "github.com/lios/go-activiti/event/impl"
11 | . "github.com/lios/go-activiti/model"
12 | "time"
13 | )
14 |
15 | type UserTaskActivityBehavior struct {
16 | UserTask engine.UserTask
17 | ProcessKey string
18 | }
19 |
20 | //普通用户节点处理
21 | func (user UserTaskActivityBehavior) Execute(execution engine.ExecutionEntity) (err error) {
22 | task := Task{}
23 | task.ProcessInstanceId = execution.GetProcessInstanceId()
24 | task.Assignee = user.UserTask.Assignee
25 | task.StartTime = time.Now()
26 | task.TaskDefineKey = user.UserTask.Id
27 | task.TaskDefineName = user.UserTask.Name
28 | manager := TaskManager{Task: &task}
29 | err = manager.Insert(execution)
30 | if err != nil {
31 | return err
32 | }
33 | err = handleAssignments(user.UserTask, task.Id, task.ProcessInstanceId)
34 |
35 | // All properties set, now firing 'create' events
36 | if GetProcessEngineConfiguration().EventDispatcher.IsEnabled() {
37 | activitiEntityEvent, err := CreateEntityEvent(event.TASK_CREATED, task)
38 | if err != nil {
39 | return err
40 | }
41 | GetProcessEngineConfiguration().EventDispatcher.DispatchEvent(activitiEntityEvent)
42 | }
43 | extensionElements := user.UserTask.ExtensionElements
44 | if extensionElements.TaskListener != nil && len(extensionElements.TaskListener) > 0 {
45 | taskListeners := extensionElements.TaskListener
46 | for _, listener := range taskListeners {
47 | if listener.EventType == TASK_TYPE_CREATE {
48 | err = PerformTaskListener(execution, user.UserTask, user.ProcessKey)
49 | if err != nil {
50 | return err
51 | }
52 | }
53 | }
54 | }
55 | return err
56 | }
57 |
58 | //保存候选用户
59 | func handleAssignments(user engine.UserTask, taskId, processInstanceId int64) (err error) {
60 | users := user.CandidateUsers
61 | if len(users) >= 0 {
62 | for _, user := range users {
63 | link := IdentityLink{}
64 | link.TaskId = taskId
65 | link.ProcessInstanceId = processInstanceId
66 | link.UserId = user
67 | identityLinkManager := GetIdentityLinkManager()
68 | identityLinkManager.IdentityLink = link
69 | err = identityLinkManager.CreateIdentityLink()
70 | if err != nil {
71 | return err
72 | }
73 | }
74 | }
75 | return err
76 | }
77 |
78 | //普通用户节点处理
79 | func (user UserTaskActivityBehavior) Trigger(execution engine.ExecutionEntity) {
80 | user.Leave(execution)
81 | }
82 |
83 | func (user UserTaskActivityBehavior) Leave(execution engine.ExecutionEntity) {
84 | element := execution.GetCurrentFlowElement()
85 | execution.SetCurrentFlowElement(element)
86 | GetAgenda().PlanTakeOutgoingSequenceFlowsOperation(execution, true)
87 | }
88 |
--------------------------------------------------------------------------------
/engine/cmd/backTaskCmd.go:
--------------------------------------------------------------------------------
1 | package cmd
2 |
3 | import (
4 | . "github.com/lios/go-activiti/engine"
5 | "github.com/lios/go-activiti/engine/behavior"
6 | . "github.com/lios/go-activiti/engine/manager"
7 | "github.com/pborman/uuid"
8 | )
9 |
10 | type BackTaskCmd struct {
11 | TaskId int
12 | TargetFlowId string
13 | Comment string
14 | }
15 |
16 | func (backTaskCmd BackTaskCmd) Execute(interceptor behavior.CommandContext) (interface{}, error) {
17 | manager := GetTaskManager()
18 | task, err := manager.FindById(backTaskCmd.TaskId)
19 | if err != nil {
20 | return task, err
21 | }
22 | processUtils := behavior.ProcessUtils{}
23 | currentTask, err := processUtils.GetCurrentTask(backTaskCmd.TaskId)
24 | if err != nil {
25 | return false, nil
26 | }
27 | sourceElement := currentTask.GetOutgoing()
28 | targetFlowElement, err := processUtils.GetFlowElement(backTaskCmd.TargetFlowId)
29 | sequenceFlows := createTask(targetFlowElement, currentTask.GetId(), backTaskCmd.TargetFlowId)
30 | currentTask.SetOutgoing(sequenceFlows)
31 | _, err = behavior.GetServiceImpl().CommandExecutor.Exe(CompleteCmd{backTaskCmd.TaskId, nil, true})
32 | if err != nil {
33 | return false, nil
34 | }
35 | currentTask.SetOutgoing(sourceElement)
36 | return true, err
37 | }
38 |
39 | func createTask(element FlowElement, sourceRef, targetRef string) []FlowElement {
40 | sequenceFlow := SequenceFlow{}
41 | flow := Flow{}
42 | sequenceFlow.Flow = &flow
43 | sequenceFlow.Id = uuid.New()
44 | sequenceFlow.SourceRef = sourceRef
45 | sequenceFlow.TargetRef = targetRef
46 | sequenceFlow.SetTargetFlowElement(element)
47 | flowElement := make([]FlowElement, 0)
48 | flowElement = append(flowElement, sequenceFlow)
49 | return flowElement
50 | }
51 |
--------------------------------------------------------------------------------
/engine/cmd/completeCmd.go:
--------------------------------------------------------------------------------
1 | package cmd
2 |
3 | import (
4 | "github.com/lios/go-activiti/engine"
5 | "github.com/lios/go-activiti/engine/behavior"
6 | "github.com/lios/go-activiti/engine/common"
7 | . "github.com/lios/go-activiti/engine/entityImpl"
8 | "github.com/lios/go-activiti/engine/handler"
9 | . "github.com/lios/go-activiti/engine/manager"
10 | "github.com/lios/go-activiti/event"
11 | "github.com/lios/go-activiti/event/impl"
12 | "github.com/lios/go-activiti/model"
13 | )
14 |
15 | type CompleteCmd struct {
16 | TaskId int
17 | Variables map[string]interface{}
18 | LocalScope bool
19 | }
20 |
21 | func (taskCmd CompleteCmd) Execute(interceptor behavior.CommandContext) (interface{}, error) {
22 | manager := GetTaskManager()
23 | task, err := manager.FindById(taskCmd.TaskId)
24 | if err != nil {
25 | return task, err
26 | }
27 | taskCmd.executeTaskComplete(task, interceptor)
28 | return task, err
29 | }
30 |
31 | func (taskCmd CompleteCmd) executeTaskComplete(task model.Task, interceptor behavior.CommandContext) (err error) {
32 |
33 | // All properties set, now firing 'create' events
34 | if event.GetEventDispatcher().IsEnabled() {
35 | activitiEntityEvent, err := impl.CreateEntityEvent(event.TASK_COMPLETED, task)
36 | if err != nil {
37 | return err
38 | }
39 | event.GetEventDispatcher().DispatchEvent(activitiEntityEvent)
40 | }
41 | err = deleteTask(task)
42 | if err != nil {
43 | return err
44 | }
45 | defineManager := GetDefineManager()
46 | bytearry, err := defineManager.FindProcessByTask(task.ProcessInstanceId)
47 | if err != nil {
48 | return err
49 | }
50 | currentTask := behavior.FindCurrentTask(bytearry, task.TaskDefineKey)
51 | taskExecution := TaskEntityImpl{}
52 | execution := ExecutionEntityImpl{}
53 | execution.SetCurrentFlowElement(currentTask)
54 | execution.SetCurrentActivityId(task.TaskDefineKey)
55 | processInstanceManager := behavior.GetProcessInstanceManager()
56 | instance := processInstanceManager.GetProcessInstance(task.ProcessInstanceId)
57 | execution.SetProcessDefineId(instance.ProcessDefineId)
58 | execution.SetProcessInstanceId(task.ProcessInstanceId)
59 | taskExecution.SetTaskId(task.Id)
60 | taskExecution.ExecutionEntityImpl = execution
61 | if taskCmd.LocalScope {
62 | err = SetVariable(&taskExecution, taskCmd.Variables)
63 | } else {
64 | err = SetVariable(&execution, taskCmd.Variables)
65 | }
66 | if err != nil {
67 | return err
68 | }
69 | userTask, ok := currentTask.(engine.UserTask)
70 | if ok {
71 | taskListeners := userTask.ExtensionElements.TaskListener
72 | for _, listener := range taskListeners {
73 | if listener.EventType == common.TASK_TYPE_COMPLETED {
74 | err = handler.PerformTaskListener(&execution, userTask, instance.Key)
75 | if err != nil {
76 | return err
77 | }
78 | }
79 | }
80 | }
81 | interceptor.Agenda.PlanTriggerExecutionOperation(&taskExecution)
82 | return nil
83 | }
84 |
85 | func deleteTask(task model.Task) (err error) {
86 | manager := GetTaskManager()
87 | return manager.DeleteTask(task)
88 | }
89 |
--------------------------------------------------------------------------------
/engine/cmd/deployProcessCmd.go:
--------------------------------------------------------------------------------
1 | package cmd
2 |
3 | import (
4 | "github.com/lios/go-activiti/engine/behavior"
5 | "github.com/lios/go-activiti/engine/persistence"
6 | )
7 |
8 | type DeploymentCmd struct {
9 | Name string
10 | Key string
11 | TenantId string
12 | Bytes []byte
13 | }
14 |
15 | func (deploy DeploymentCmd) Execute(interceptor behavior.CommandContext) (interface{}, error) {
16 | deploymentManager := persistence.DeploymentManager{}
17 | err := deploymentManager.Deployment(deploy.Name, deploy.Key, deploy.Bytes)
18 | return nil, err
19 | }
20 |
--------------------------------------------------------------------------------
/engine/cmd/getTaskCmd.go:
--------------------------------------------------------------------------------
1 | package cmd
2 |
3 | import (
4 | "github.com/lios/go-activiti/engine/behavior"
5 | . "github.com/lios/go-activiti/engine/manager"
6 | )
7 |
8 | type GetTaskCmd struct {
9 | UserId string
10 | GroupId string
11 | }
12 |
13 | func (getTaskCmd GetTaskCmd) Execute(interceptor behavior.CommandContext) (interface{}, error) {
14 | manager := GetTaskManager()
15 | taskResult, err := manager.QueryUndoTask(getTaskCmd.UserId, getTaskCmd.GroupId)
16 | if err != nil {
17 | return taskResult, err
18 | }
19 | return taskResult, err
20 | }
21 |
--------------------------------------------------------------------------------
/engine/cmd/startProcessInstanceByKeyCmd.go:
--------------------------------------------------------------------------------
1 | package cmd
2 |
3 | import (
4 | "github.com/lios/go-activiti/engine"
5 | "github.com/lios/go-activiti/engine/behavior"
6 | . "github.com/lios/go-activiti/engine/entityImpl"
7 | . "github.com/lios/go-activiti/engine/manager"
8 | . "github.com/lios/go-activiti/engine/persistence"
9 | . "github.com/lios/go-activiti/model"
10 | "time"
11 | )
12 |
13 | type StartProcessInstanceByKeyCmd struct {
14 | ProcessDefinitionKey string
15 | Variables map[string]interface{}
16 | BusinessKey string
17 | TenantId string
18 | }
19 |
20 | func (start StartProcessInstanceByKeyCmd) Execute(interceptor behavior.CommandContext) (interface{}, error) {
21 | defineManager := GetDefineManager()
22 | bytearries, err := defineManager.FindDeployedProcessDefinitionByKey(start.ProcessDefinitionKey)
23 | if err != nil {
24 | return nil, err
25 | }
26 | //解析xml数据
27 | process := behavior.GetBpmn(*bytearries[0])
28 | instance := ProcessInstance{}
29 | instance.BusinessKey = start.BusinessKey
30 | instance.TenantId = start.TenantId
31 | instance.StartTime = time.Now()
32 | instance.Key = process.Id
33 | instance.Name = process.Name
34 | instance.ProcessDefineId = bytearries[0].Id
35 | instance.DeploymentId = bytearries[0].DeploymentId
36 | //生成流程实例
37 | manager := ProcessInstanceManager{Instance: &instance}
38 | manager.CreateProcessInstance()
39 | //获取开始节点
40 | flowElement := process.InitialFlowElement
41 | element := flowElement.(engine.StartEvent)
42 | execution := ExecutionEntityImpl{ProcessInstanceId: instance.Id}
43 | execution.SetCurrentFlowElement(element)
44 | execution.SetProcessDefineId(bytearries[0].Id)
45 | execution.SetCurrentActivityId(element.GetId())
46 | //保存流程变量
47 | err = SetVariable(&execution, start.Variables)
48 | if err != nil {
49 | return nil, err
50 | }
51 | context, err := behavior.GetCommandContext()
52 | if err == nil {
53 | context.Agenda.PlanContinueProcessOperation(&execution)
54 | }
55 | return process, nil
56 | }
57 |
--------------------------------------------------------------------------------
/engine/common/activitiCommon.go:
--------------------------------------------------------------------------------
1 | package common
2 |
3 | const (
4 | ACTIVITI_HANDLER_CODE = "OK"
5 | TASK_TYPE_CREATE = "create"
6 | TASK_TYPE_COMPLETED = "complete"
7 | TASK_TYPE_ASSIGNED = "assignment"
8 | )
9 |
--------------------------------------------------------------------------------
/engine/entityImpl/executionEntityImpl.go:
--------------------------------------------------------------------------------
1 | package entityImpl
2 |
3 | import (
4 | "github.com/lios/go-activiti/engine"
5 | . "github.com/lios/go-activiti/engine/behavior"
6 | . "github.com/lios/go-activiti/engine/manager"
7 | . "github.com/lios/go-activiti/engine/persistence"
8 | . "github.com/lios/go-activiti/engine/variable"
9 | "github.com/lios/go-activiti/errs"
10 | "reflect"
11 | )
12 |
13 | type ExecutionEntityImpl struct {
14 | BusinessKey string
15 | CurrentFlowElement engine.FlowElement
16 | DeploymentId int
17 | ProcessInstanceId int64
18 | ProcessDefineId int64
19 | CurrentActivityId string
20 | }
21 |
22 | func (execution *ExecutionEntityImpl) SetBusinessKey(businessKey string) {
23 | execution.BusinessKey = businessKey
24 | }
25 |
26 | func (execution ExecutionEntityImpl) GetCurrentFlowElement() engine.FlowElement {
27 | return execution.CurrentFlowElement
28 | }
29 |
30 | func (execution *ExecutionEntityImpl) SetCurrentFlowElement(flow engine.FlowElement) {
31 | execution.CurrentFlowElement = flow
32 | execution.CurrentActivityId = flow.GetId()
33 | }
34 |
35 | func (execution ExecutionEntityImpl) GetDeploymentId() int {
36 | return execution.DeploymentId
37 | }
38 |
39 | func (execution *ExecutionEntityImpl) SetDeploymentId(deploymentId int) {
40 | execution.DeploymentId = deploymentId
41 | }
42 |
43 | func (execution ExecutionEntityImpl) GetProcessInstanceId() int64 {
44 | return execution.ProcessInstanceId
45 | }
46 |
47 | func (execution *ExecutionEntityImpl) SetProcessInstanceId(processInstanceId int64) {
48 | execution.ProcessInstanceId = processInstanceId
49 | }
50 |
51 | func (execution *ExecutionEntityImpl) GetProcessDefineId() int64 {
52 | return execution.ProcessDefineId
53 | }
54 |
55 | func (execution *ExecutionEntityImpl) SetProcessDefineId(processDefineId int64) {
56 | execution.ProcessDefineId = processDefineId
57 | }
58 |
59 | func (execution *ExecutionEntityImpl) GetCurrentActivityId() string {
60 | return execution.CurrentActivityId
61 | }
62 |
63 | func (execution *ExecutionEntityImpl) SetCurrentActivityId(currentActivityId string) {
64 | execution.CurrentActivityId = currentActivityId
65 | }
66 |
67 | func (execution *ExecutionEntityImpl) GetTaskId() int64 {
68 | return -1
69 | }
70 |
71 | func (execution *ExecutionEntityImpl) SetTaskId(taskId int64) {
72 |
73 | }
74 | func (execution *ExecutionEntityImpl) GetProcessVariable() map[string]interface{} {
75 | return execution.GetVariable()
76 | }
77 |
78 | func (execution *ExecutionEntityImpl) GetVariable() map[string]interface{} {
79 | variableManager := GetVariableManager()
80 | variables, err := variableManager.SelectByProcessInstanceId(execution.GetProcessInstanceId())
81 | if err == nil {
82 | return execution.HandleVariable(variables)
83 | }
84 | return nil
85 | }
86 |
87 | func (execution *ExecutionEntityImpl) HandleVariable(variables []Variable) map[string]interface{} {
88 | engineConfiguration := GetProcessEngineConfiguration()
89 | variableTypes := engineConfiguration.VariableTypes
90 | var variableMap = make(map[string]interface{}, 0)
91 | for _, variable := range variables {
92 | variableType := variableTypes.GetVariableType(variable.Type)
93 | value := variableType.GetValue(&variable)
94 | variableMap[variable.Name] = value
95 | }
96 | return variableMap
97 | }
98 |
99 | //保存流程变量
100 | func SetVariable(execution engine.ExecutionEntity, variables map[string]interface{}) error {
101 | engineConfiguration := GetProcessEngineConfiguration()
102 | variableTypes := engineConfiguration.VariableTypes
103 | variableManager := GetVariableManager()
104 | if variables != nil && len(variables) > 0 {
105 | for k, v := range variables {
106 | kind := reflect.TypeOf(v).Kind()
107 | variableType := variableTypes.GetVariableType(kind.String())
108 | if variableType == nil {
109 | return errs.ProcessError{Code: "1001", Msg: "no type"}
110 | }
111 | variable := variableManager.Create(k, variableType, v)
112 | //存在更新
113 | specificVariable, e := execution.GetSpecificVariable(k)
114 | if e != nil {
115 | variable.Version = specificVariable.Version + 1
116 | }
117 | execution.SetScope(variable)
118 | variableManager.Variable = variable
119 | err := variableManager.Insert()
120 | if err != nil {
121 | return err
122 | }
123 | }
124 | }
125 | return nil
126 | }
127 |
128 | func (execution *ExecutionEntityImpl) GetSpecificVariable(variableName string) (Variable, error) {
129 | variableManager := VariableManager{}
130 | return variableManager.SelectProcessInstanceId(variableName, execution.ProcessInstanceId)
131 | }
132 |
133 | func (execution *ExecutionEntityImpl) SetScope(variable *Variable) {
134 | variable.ProcessInstanceId = execution.ProcessInstanceId
135 | }
136 |
--------------------------------------------------------------------------------
/engine/entityImpl/taskEntityImpl.go:
--------------------------------------------------------------------------------
1 | package entityImpl
2 |
3 | import (
4 | . "github.com/lios/go-activiti/engine/manager"
5 | . "github.com/lios/go-activiti/engine/persistence"
6 | . "github.com/lios/go-activiti/engine/variable"
7 | )
8 |
9 | type TaskEntityImpl struct {
10 | ExecutionEntityImpl
11 | TaskId int64
12 | Variables map[string]interface{}
13 | }
14 |
15 | func (task *TaskEntityImpl) GetTaskId() int64 {
16 | return task.TaskId
17 | }
18 |
19 | func (task *TaskEntityImpl) SetTaskId(taskId int64) {
20 | task.TaskId = taskId
21 | }
22 |
23 | func (task *TaskEntityImpl) GetVariable() map[string]interface{} {
24 | variableManager := GetVariableManager()
25 | variables, err := variableManager.SelectByTaskId(task.TaskId)
26 | if err != nil {
27 | return task.HandleVariable(variables)
28 | }
29 | return nil
30 | }
31 |
32 | func (task *TaskEntityImpl) GetSpecificVariable(variableName string) (Variable, error) {
33 | variableManager := VariableManager{}
34 | return variableManager.SelectTaskId(variableName, task.TaskId)
35 | }
36 |
37 | func (task *TaskEntityImpl) SetScope(variable *Variable) {
38 | variable.TaskId = task.TaskId
39 | }
40 |
--------------------------------------------------------------------------------
/engine/executionEntity.go:
--------------------------------------------------------------------------------
1 | package engine
2 |
3 | import (
4 | "github.com/lios/go-activiti/engine/variable"
5 | )
6 |
7 | type ExecutionEntity interface {
8 | SetBusinessKey(businessKey string)
9 |
10 | GetCurrentFlowElement() FlowElement
11 |
12 | SetCurrentFlowElement(flow FlowElement)
13 |
14 | GetDeploymentId() int
15 |
16 | SetDeploymentId(deploymentId int)
17 |
18 | GetProcessInstanceId() int64
19 |
20 | SetProcessInstanceId(processInstanceId int64)
21 |
22 | GetProcessDefineId() int64
23 |
24 | SetProcessDefineId(processDefineId int64)
25 |
26 | GetCurrentActivityId() string
27 |
28 | SetCurrentActivityId(currentActivityId string)
29 |
30 | //SetVariable(execution ExecutionEntity,variables map[string]interface{}) error
31 |
32 | GetSpecificVariable(variableName string) (variable.Variable, error)
33 |
34 | SetScope(variable *variable.Variable)
35 |
36 | GetVariable() map[string]interface{}
37 |
38 | GetProcessVariable() map[string]interface{}
39 |
40 | GetTaskId() int64
41 |
42 | SetTaskId(taskId int64)
43 | }
44 |
--------------------------------------------------------------------------------
/engine/handler/iActiviti.go:
--------------------------------------------------------------------------------
1 | package handler
2 |
3 | import (
4 | . "github.com/lios/go-activiti/engine"
5 | . "github.com/lios/go-activiti/engine/common"
6 | "github.com/lios/go-activiti/errs"
7 | "reflect"
8 | "sync"
9 | )
10 |
11 | var gConstructorMap map[string]ActivitiConstructor
12 | var lock sync.Mutex
13 |
14 | func init() {
15 | gConstructorMap = make(map[string]ActivitiConstructor, 0)
16 | }
17 |
18 | type IActiviti interface {
19 | GetInPut() interface{}
20 | GetOutPut() interface{}
21 | }
22 |
23 | type ActivitiConstructor func(entity ExecutionEntity) IActiviti
24 |
25 | func RegisterConstructor(name string, constructor ActivitiConstructor) error {
26 | lock.Lock()
27 | defer lock.Unlock()
28 | _, ok := gConstructorMap[name]
29 | if !ok {
30 | gConstructorMap[name] = constructor
31 | } else {
32 | return errs.ProcessError{Code: "1005", Msg: "name has register"}
33 | }
34 | return nil
35 | }
36 |
37 | func GetConstructorByName(name string) (ActivitiConstructor, error) {
38 | lock.Lock()
39 | defer lock.Unlock()
40 | constructor, ok := gConstructorMap[name]
41 | if !ok {
42 | return nil, errs.ProcessError{Code: "1006", Msg: "name not find"}
43 | }
44 | return constructor, nil
45 | }
46 |
47 | func PerformTaskListener(entity ExecutionEntity, task UserTask, processKey string) error {
48 | activitiConstructor, err := GetConstructorByName(processKey)
49 | if err != nil {
50 | return err
51 | }
52 | constructor := activitiConstructor(entity)
53 | reflectConstructor := reflect.ValueOf(constructor)
54 | taskParams := []reflect.Value{reflectConstructor}
55 |
56 | method, b := reflectConstructor.Type().MethodByName(task.Name)
57 | if !b {
58 | return nil
59 | }
60 |
61 | callResponse := method.Func.Call(taskParams)
62 | code := callResponse[0].Interface()
63 | errRes := callResponse[1].Interface()
64 | code = code.(string)
65 | if code != ACTIVITI_HANDLER_CODE {
66 | err := errRes.(error)
67 | return err
68 | }
69 | return nil
70 | }
71 |
--------------------------------------------------------------------------------
/engine/handler/iActivitiDemo.go:
--------------------------------------------------------------------------------
1 | package handler
2 |
3 | import (
4 | "fmt"
5 | . "github.com/lios/go-activiti/engine"
6 | "github.com/lios/go-activiti/engine/common"
7 | )
8 |
9 | func init() {
10 | RegisterConstructor("userAuto", NewTestIActiviti)
11 | }
12 |
13 | func NewTestIActiviti(entity ExecutionEntity) IActiviti {
14 | return &TestIActiviti{
15 | Entity: entity,
16 | }
17 | }
18 |
19 | type TestIActiviti struct {
20 | Entity ExecutionEntity
21 | InPut string
22 | OutPut string
23 | }
24 |
25 | func (test *TestIActiviti) GetInPut() interface{} {
26 | return test.InPut
27 | }
28 |
29 | func (test *TestIActiviti) GetOutPut() interface{} {
30 | return test.OutPut
31 | }
32 |
33 | func (test *TestIActiviti) User001() (code interface{}, err error) {
34 | variable := test.Entity.GetVariable()
35 | fmt.Println(variable)
36 | return common.ACTIVITI_HANDLER_CODE, nil
37 | }
38 |
39 | func (test *TestIActiviti) User002() (code interface{}, err error) {
40 | return common.ACTIVITI_HANDLER_CODE, nil
41 | }
42 |
--------------------------------------------------------------------------------
/engine/manager/dbManager.go:
--------------------------------------------------------------------------------
1 | package manager
2 |
3 | import . "github.com/lios/go-activiti/engine/persistence"
4 |
5 | func GetTaskManager() TaskManager {
6 | return TaskManager{}
7 | }
8 |
9 | func GetDefineManager() DefineManager {
10 | return DefineManager{}
11 | }
12 | func GetVariableManager() VariableManager {
13 | return VariableManager{}
14 | }
15 |
16 | func GetIdentityLinkManager() IdentityLinkManager {
17 | return IdentityLinkManager{}
18 | }
19 |
20 | func GetHistoricActinstManager() HistoricActinstManager {
21 | return HistoricActinstManager{}
22 | }
23 |
24 | func GetHistoricTaskManager() HistoricTaskManager {
25 | return HistoricTaskManager{}
26 | }
27 |
28 | func GetHistoricProcessManager() HistoricProcessManager {
29 | return HistoricProcessManager{}
30 | }
31 |
--------------------------------------------------------------------------------
/engine/operation.go:
--------------------------------------------------------------------------------
1 | package engine
2 |
3 | type Operation interface {
4 | Run() error
5 | }
6 |
--------------------------------------------------------------------------------
/engine/persistence/defineManager.go:
--------------------------------------------------------------------------------
1 | package persistence
2 |
3 | import (
4 | "github.com/lios/go-activiti/db"
5 | "github.com/lios/go-activiti/errs"
6 | . "github.com/lios/go-activiti/model"
7 | "github.com/prometheus/common/log"
8 | )
9 |
10 | type DefineManager struct {
11 | }
12 |
13 | func (define DefineManager) FindDeployedProcessDefinitionByKey(key string) ([]*Bytearry, error) {
14 | bytearries := make([]*Bytearry, 0)
15 | err := db.DB().Where("`key`=?", key).Where("deployment_id != 0").Order("version DESC", true).Find(&bytearries).Error
16 | return bytearries, err
17 | }
18 |
19 | func (define DefineManager) GetBytearry(processDefineId int64) (Bytearry, error) {
20 | bytearries := Bytearry{}
21 | err := db.DB().Where("id=?", processDefineId).First(&bytearries).Error
22 | if err != nil {
23 | log.Infoln("Find bytearry by err", err)
24 | return bytearries, err
25 | }
26 | return bytearries, nil
27 | }
28 |
29 | func (define DefineManager) CreateByteArry(name string, key string, bytes string) error {
30 | bytearries, err := define.FindDeployedProcessDefinitionByKey(key)
31 | if err != nil {
32 | return err
33 | }
34 | var verion = 0
35 | if bytearries != nil && len(bytearries) > 0 {
36 | verion = bytearries[0].Version
37 | verion++
38 | }
39 | byteArry := Bytearry{Name: name, Bytes: bytes, Key: key, Version: verion}
40 | err = db.DB().Create(&byteArry).Error
41 | if err != nil {
42 | log.Infoln("Create bytearry err", err)
43 | return err
44 | }
45 | return nil
46 | }
47 |
48 | func (define DefineManager) FindProcessByTask(processInstanceId int64) (Bytearry, error) {
49 | bytearries := make([]Bytearry, 0)
50 | var sql = "SELECT b.* FROM bytearry b " +
51 | "LEFT JOIN process_instance p on b.id = p.process_define_id " +
52 | "WHERE p.id = ? "
53 | err := db.DB().Raw(sql, processInstanceId).Find(&bytearries).Error
54 | if err != nil {
55 | return Bytearry{}, err
56 | }
57 | if bytearries != nil && len(bytearries) > 0 {
58 | return bytearries[0], nil
59 | }
60 | return Bytearry{}, errs.ProcessError{Code: "1001", Msg: "Not Find"}
61 | }
62 |
--------------------------------------------------------------------------------
/engine/persistence/deploymentManager.go:
--------------------------------------------------------------------------------
1 | package persistence
2 |
3 | import (
4 | "github.com/lios/go-activiti/db"
5 | . "github.com/lios/go-activiti/model"
6 | "github.com/prometheus/common/log"
7 | "time"
8 | )
9 |
10 | type DeploymentManager struct {
11 | }
12 |
13 | func (define DeploymentManager) Deployment(name string, key string, bytes []byte) (err error) {
14 | deployment := Deployment{Name: name, Key: key, DeployTime: time.Now()}
15 | err = db.DB().Create(&deployment).Error
16 | if err != nil {
17 | log.Infoln("Create deployment err", err)
18 | return err
19 | }
20 | defineManager := DefineManager{}
21 | bytearries, err := defineManager.FindDeployedProcessDefinitionByKey(key)
22 | if err != nil {
23 | return err
24 | }
25 | var verion = 0
26 | if bytearries != nil && len(bytearries) > 0 {
27 | verion = bytearries[0].Version
28 | verion++
29 | }
30 | byte := Bytearry{Name: name, Key: key, Bytes: string(bytes), DeploymentId: deployment.Id, Version: verion}
31 | err = db.DB().Create(&byte).Error
32 | if err != nil {
33 | log.Infoln("Create bytearry err", err)
34 | return err
35 | }
36 | return nil
37 | }
38 |
--------------------------------------------------------------------------------
/engine/persistence/historicActinstManager.go:
--------------------------------------------------------------------------------
1 | package persistence
2 |
3 | import (
4 | "github.com/lios/go-activiti/db"
5 | "github.com/lios/go-activiti/engine"
6 | . "github.com/lios/go-activiti/model"
7 | "github.com/prometheus/common/log"
8 | "reflect"
9 | "time"
10 | )
11 |
12 | type HistoricActinstManager struct {
13 | HistoricActinst HistoricActinst
14 | }
15 |
16 | func (historicActinstManager HistoricActinstManager) Insert() {
17 | err := db.DB().Create(&historicActinstManager.HistoricActinst).Error
18 | if err != nil {
19 | log.Infoln("Create HistoricActinst Err", err)
20 | }
21 | }
22 |
23 | func (historicActinstManager HistoricActinstManager) RecordActivityStart(entity engine.ExecutionEntity) {
24 | historicActinst := HistoricActinst{}
25 | historicActinst.ProcessDefineId = entity.GetProcessDefineId()
26 | historicActinst.ProcessInstanceId = entity.GetProcessInstanceId()
27 | historicActinst.ActId = entity.GetCurrentActivityId()
28 | if entity.GetCurrentFlowElement() != nil {
29 | historicActinst.ActName = entity.GetCurrentFlowElement().GetName()
30 | historicActinst.ActType = historicActinstManager.parseActivityType(entity.GetCurrentFlowElement())
31 | }
32 | historicActinst.StartTime = time.Now()
33 | historicActinstManager.HistoricActinst = historicActinst
34 | historicActinstManager.Insert()
35 | }
36 |
37 | func (historicActinstManager HistoricActinstManager) FindUnfinishedHistoricActivityInstancesByExecutionAndActivityId(processInstanceId int64, actId string) (HistoricActinst, error) {
38 | historicActinst := HistoricActinst{}
39 | err := db.DB().Where("act_id = ?", actId).Where("proc_inst_id = ?", processInstanceId).First(&historicActinst).Error
40 | if err != nil {
41 | log.Infoln("Select HistoricActinst err: ", err)
42 | return HistoricActinst{}, err
43 | }
44 | return historicActinst, nil
45 | }
46 |
47 | func (historicActinstManager HistoricActinstManager) Update() (err error) {
48 | err = db.DB().Model(&HistoricActinst{}).Where("act_id = ?", historicActinstManager.HistoricActinst.ActId).
49 | Where("proc_inst_id = ?", historicActinstManager.HistoricActinst.ProcessInstanceId).
50 | Update(&historicActinstManager.HistoricActinst).Error
51 | if err != nil {
52 | log.Infoln("Update HistoricActinst err: ", err)
53 | }
54 | return err
55 | }
56 | func (historicActinstManager HistoricActinstManager) UpdateProcessInstanceId() (err error) {
57 | err = db.DB().Model(&HistoricActinst{}).Where("proc_inst_id = ?", historicActinstManager.HistoricActinst.ProcessInstanceId).
58 | Update(&historicActinstManager.HistoricActinst).Error
59 | if err != nil {
60 | log.Infoln("Update HistoricActinst err: ", err)
61 | }
62 | return err
63 | }
64 |
65 | func (historicActinstManager HistoricActinstManager) UpdateTaskId() (err error) {
66 | err = db.DB().Model(&HistoricActinst{}).Where("task_id = ?", historicActinstManager.HistoricActinst.TaskId).
67 | Update(&historicActinstManager.HistoricActinst).Error
68 | if err != nil {
69 | log.Infoln("Update HistoricActinst err: ", err)
70 | }
71 | return err
72 | }
73 |
74 | func (historicActinstManager HistoricActinstManager) RecordTaskCreated(element engine.FlowElement, entity engine.ExecutionEntity) (err error) {
75 | var actinst = HistoricActinst{}
76 | actinst, err = historicActinstManager.FindUnfinishedHistoricActivityInstancesByExecutionAndActivityId(entity.GetProcessInstanceId(), element.GetId())
77 | if err == nil {
78 | actinst.EndTime = time.Now()
79 | historicActinstManager.HistoricActinst = actinst
80 | err = historicActinstManager.Update()
81 | }
82 | return err
83 | }
84 |
85 | func (historicActinstManager HistoricActinstManager) parseActivityType(element engine.FlowElement) string {
86 | typeOf := reflect.TypeOf(element)
87 | return typeOf.Name()
88 | }
89 |
--------------------------------------------------------------------------------
/engine/persistence/historicIdentityLinkManager.go:
--------------------------------------------------------------------------------
1 | package persistence
2 |
3 | import (
4 | "github.com/lios/go-activiti/db"
5 | "github.com/lios/go-activiti/model"
6 | "github.com/prometheus/common/log"
7 | )
8 |
9 | type HistoricIdentityLinkManager struct {
10 | HistoricIdentityLink model.HistoricIdentityLink
11 | }
12 |
13 | func (historicIdentityLink HistoricIdentityLinkManager) Insert() (err error) {
14 | err = db.DB().Create(&historicIdentityLink.HistoricIdentityLink).Error
15 | if err != nil {
16 | log.Infoln("Create HistoricIdentityLink Err", err)
17 | }
18 | return err
19 | }
20 |
--------------------------------------------------------------------------------
/engine/persistence/historicProcessManager.go:
--------------------------------------------------------------------------------
1 | package persistence
2 |
3 | import (
4 | "github.com/lios/go-activiti/db"
5 | . "github.com/lios/go-activiti/model"
6 | "github.com/prometheus/common/log"
7 | )
8 |
9 | type HistoricProcessManager struct {
10 | HistoricProcess HistoricProcess
11 | }
12 |
13 | func (historicProcessManager HistoricProcessManager) Insert() (err error) {
14 | err = db.DB().Create(&historicProcessManager.HistoricProcess).Error
15 | if err != nil {
16 | log.Infoln("Create HistoricActinst Err", err)
17 | }
18 | return err
19 | }
20 |
21 | func (historicProcessManager HistoricProcessManager) MarkEnded() (err error) {
22 | historicProcess := historicProcessManager.HistoricProcess
23 | err = db.DB().Where("proc_inst_id=?", historicProcess.ProcessInstanceId).Update(&historicProcess).Error
24 | if err != nil {
25 | log.Infoln("delete HistoricProcess Err", err)
26 | return err
27 | }
28 | historicActinst := HistoricActinst{}
29 | historicActinst.EndTime = historicProcess.EndTime
30 | historicProcess.ProcessInstanceId = historicProcess.Id
31 | historicActinstManager := HistoricActinstManager{}
32 | historicActinstManager.HistoricActinst = historicActinst
33 | err = historicActinstManager.UpdateProcessInstanceId()
34 | return err
35 | }
36 |
--------------------------------------------------------------------------------
/engine/persistence/historicTaskManager.go:
--------------------------------------------------------------------------------
1 | package persistence
2 |
3 | import (
4 | "github.com/lios/go-activiti/db"
5 | . "github.com/lios/go-activiti/model"
6 | "github.com/prometheus/common/log"
7 | )
8 |
9 | type HistoricTaskManager struct {
10 | HistoricTask HistoricTask
11 | }
12 |
13 | func (historicTaskManager HistoricTaskManager) Insert() (err error) {
14 | err = db.DB().Create(&historicTaskManager.HistoricTask).Error
15 | if err != nil {
16 | log.Infoln("Create HistoricTask Err", err)
17 | }
18 | return err
19 | }
20 |
21 | func (historicTaskManager HistoricTaskManager) MarkEnded() (err error) {
22 | err = db.DB().Model(&HistoricTask{}).Where("task_id=?", historicTaskManager.HistoricTask.TaskId).Update(&historicTaskManager.HistoricTask).Error
23 | if err != nil {
24 | log.Infoln("Update HistoricTask Err", err)
25 | }
26 | return err
27 | }
28 |
--------------------------------------------------------------------------------
/engine/persistence/historicVariableManager.go:
--------------------------------------------------------------------------------
1 | package persistence
2 |
3 | import (
4 | "github.com/lios/go-activiti/db"
5 | "github.com/lios/go-activiti/engine/variable"
6 | "github.com/prometheus/common/log"
7 | )
8 |
9 | type HistoricVariableManager struct {
10 | HistoricVariable variable.HistoricVariable
11 | }
12 |
13 | func (historicVariableManager HistoricVariableManager) Insert() (err error) {
14 | err = db.DB().Create(&historicVariableManager.HistoricVariable).Error
15 | if err != nil {
16 | log.Infoln("Create HistoricVariable Err ", err)
17 | }
18 | return err
19 | }
20 |
--------------------------------------------------------------------------------
/engine/persistence/identityLinkManager.go:
--------------------------------------------------------------------------------
1 | package persistence
2 |
3 | import (
4 | "github.com/lios/go-activiti/db"
5 | "github.com/lios/go-activiti/errs"
6 | . "github.com/lios/go-activiti/model"
7 | "github.com/prometheus/common/log"
8 | )
9 |
10 | type IdentityLinkManager struct {
11 | IdentityLink IdentityLink
12 | }
13 |
14 | //创建流程实例
15 | func (identityLinkManager IdentityLinkManager) CreateIdentityLink() (err error) {
16 | err = db.DB().Create(&identityLinkManager.IdentityLink).Error
17 | if err != nil {
18 | log.Infoln("Create IdentityLink Err ", err)
19 | return err
20 | }
21 | err = identityLinkManager.createHistoricIdentityLink()
22 | return err
23 | }
24 |
25 | func (identityLinkManager IdentityLinkManager) SelectByProcessInstanceId(processInstanceId int64) ([]IdentityLink, error) {
26 | identityLink := make([]IdentityLink, 0)
27 | err := db.DB().Where("proc_inst_id = ?", processInstanceId).Find(&identityLink).Error
28 | if err != nil {
29 | log.Infoln("Select Variable err: ", err)
30 | }
31 | if identityLink == nil || len(identityLink) <= 0 {
32 | return []IdentityLink{}, errs.ProcessError{Code: "1001", Msg: "Not find"}
33 | }
34 | return identityLink, nil
35 | }
36 |
37 | func (identityLinkManager IdentityLinkManager) SelectByTaskId(taskId int64) ([]IdentityLink, error) {
38 | identityLink := make([]IdentityLink, 0)
39 | err := db.DB().Where("task_id = ?", taskId).Find(&identityLink).Error
40 | if err != nil {
41 | log.Infoln("Select Variable err: ", err)
42 | }
43 | if identityLink != nil && len(identityLink) > 0 {
44 | return identityLink, nil
45 | }
46 | return identityLink, errs.ProcessError{Code: "1001", Msg: "Not Find"}
47 | }
48 |
49 | func (identityLinkManager IdentityLinkManager) Delete(identityLinkId int64) (err error) {
50 | identityLink := IdentityLink{}
51 | err = db.DB().Where("id=?", identityLinkId).Delete(&identityLink).Error
52 | if err != nil {
53 | log.Infoln("Delete identityLink err: ", err)
54 | }
55 | return err
56 | }
57 |
58 | func (identityLinkManager IdentityLinkManager) createHistoricIdentityLink() (err error) {
59 | identityLink := identityLinkManager.IdentityLink
60 | historicIdentityLink := HistoricIdentityLink{}
61 | historicIdentityLink.UserId = identityLink.UserId
62 | historicIdentityLink.TaskId = identityLink.TaskId
63 | historicIdentityLink.ProcessInstanceId = identityLink.ProcessInstanceId
64 | historicIdentityLinkManager := HistoricIdentityLinkManager{}
65 | historicIdentityLinkManager.HistoricIdentityLink = historicIdentityLink
66 | err = historicIdentityLinkManager.Insert()
67 | return err
68 | }
69 |
--------------------------------------------------------------------------------
/engine/persistence/processInstanceManager.go:
--------------------------------------------------------------------------------
1 | package persistence
2 |
3 | import (
4 | "github.com/lios/go-activiti/db"
5 | . "github.com/lios/go-activiti/model"
6 | "github.com/prometheus/common/log"
7 | "time"
8 | )
9 |
10 | type ProcessInstanceManager struct {
11 | Instance *ProcessInstance
12 | }
13 |
14 | //创建流程实例
15 | func (processInstanceManager *ProcessInstanceManager) CreateProcessInstance() {
16 | err := db.DB().Create(&processInstanceManager.Instance).Error
17 | if err != nil {
18 | log.Infoln("create processInstance err", err)
19 | }
20 |
21 | processInstanceManager.createHistoricProcessInstance()
22 | }
23 |
24 | //查询流程实例
25 | func (processInstanceManager *ProcessInstanceManager) GetProcessInstance(processInstanceId int64) ProcessInstance {
26 | instance := ProcessInstance{}
27 | err := db.DB().Where("id = ?", processInstanceId).Find(&instance).Error
28 | if err != nil {
29 | log.Infoln("create processInstance err", err)
30 | }
31 | return instance
32 | }
33 |
34 | //删除流程实例
35 | func (processInstanceManager ProcessInstanceManager) DeleteProcessInstance(processInstanceId int64) (err error) {
36 | err = db.DB().Where("id = ?", processInstanceId).Delete(&ProcessInstance{}).Error
37 | if err != nil {
38 | log.Infoln("delete processInstance err ", err)
39 | return err
40 | }
41 | err = processInstanceManager.recordActivityEnd(processInstanceId)
42 | return err
43 | }
44 |
45 | func (processInstanceManager ProcessInstanceManager) recordActivityEnd(processInstanceId int64) (err error) {
46 | historicProcessManager := HistoricProcessManager{}
47 | historicProcess := HistoricProcess{}
48 | historicProcess.ProcessInstanceId = processInstanceId
49 | historicProcess.EndTime = time.Now()
50 | historicProcessManager.HistoricProcess = historicProcess
51 | err = historicProcessManager.MarkEnded()
52 | return err
53 | }
54 |
55 | func (processInstanceManager *ProcessInstanceManager) createHistoricProcessInstance() (err error) {
56 | processInstance := processInstanceManager.Instance
57 | historicProcess := HistoricProcess{}
58 | //historicProcess.ProcessInstanceEntity = processInstance.ProcessInstanceEntity
59 | historicProcess.ProcessInstanceId = processInstance.Id
60 | historicProcess.DeploymentId = processInstance.DeploymentId
61 | historicProcess.TenantId = processInstance.TenantId
62 | historicProcess.StartTime = processInstance.StartTime
63 | historicProcess.Name = processInstance.Name
64 | historicProcess.BusinessKey = processInstance.BusinessKey
65 | historicProcess.StartUserId = processInstance.StartUserId
66 | historicProcess.Key = processInstance.Key
67 | historicProcess.ProcessDefineId = processInstance.ProcessDefineId
68 |
69 | historicProcessManager := HistoricProcessManager{}
70 | historicProcessManager.HistoricProcess = historicProcess
71 | return historicProcessManager.Insert()
72 | }
73 |
--------------------------------------------------------------------------------
/engine/persistence/taskManager.go:
--------------------------------------------------------------------------------
1 | package persistence
2 |
3 | import (
4 | "fmt"
5 | "github.com/lios/go-activiti/db"
6 | "github.com/lios/go-activiti/engine"
7 | . "github.com/lios/go-activiti/entity"
8 | "github.com/lios/go-activiti/errs"
9 | . "github.com/lios/go-activiti/model"
10 | "github.com/prometheus/common/log"
11 | "time"
12 | )
13 |
14 | type TaskManager struct {
15 | Task *Task
16 | }
17 |
18 | func (taskManager TaskManager) Insert(execution engine.ExecutionEntity) (err error) {
19 | err = db.DB().Create(taskManager.Task).Error
20 | if err == nil {
21 | err = taskManager.recordTaskCreated(taskManager.Task, execution)
22 | }
23 | //dispatcher := event.GetEventDispatcher()
24 | //dispatcher.DispatchEvent(CreateEntityEvent())
25 | return err
26 | }
27 |
28 | func (taskManager TaskManager) recordTaskCreated(task *Task, entity engine.ExecutionEntity) (err error) {
29 | historicTaskManager := HistoricTaskManager{}
30 | historicTask := taskManager.createHistoricTask(task)
31 | historicTaskManager.HistoricTask = historicTask
32 | err = historicTaskManager.Insert()
33 | if err != nil {
34 | historicActinstManager := HistoricActinstManager{}
35 | actinst, err := historicActinstManager.FindUnfinishedHistoricActivityInstancesByExecutionAndActivityId(entity.GetProcessInstanceId(), task.TaskDefineKey)
36 | if err == nil {
37 | actinst.Assignee = task.Assignee
38 | actinst.TaskId = task.Id
39 | historicActinstManager.HistoricActinst = actinst
40 | err = historicActinstManager.Update()
41 | }
42 | }
43 | return err
44 | }
45 |
46 | func (taskManager TaskManager) createHistoricTask(task *Task) HistoricTask {
47 | historicTask := HistoricTask{}
48 | //historicTask.TaskEntity = task.TaskEntity
49 | historicTask.TaskId = task.Id
50 | historicTask.ProcessInstanceId = task.ProcessInstanceId
51 | historicTask.StartTime = task.StartTime
52 | historicTask.TenantId = task.TenantId
53 | historicTask.Assignee = task.Assignee
54 | historicTask.TaskDefineKey = task.TaskDefineKey
55 | historicTask.DeploymentId = task.DeploymentId
56 | historicTask.TaskDefineName = task.TaskDefineName
57 | return historicTask
58 | }
59 |
60 | func (taskManager TaskManager) FindById(taskId int) (Task, error) {
61 | task := Task{}
62 | err := db.DB().Where("id= ?", taskId).First(&task).Error
63 | if err != nil {
64 | log.Infoln("Select FindById Err ", err)
65 | return task, err
66 | }
67 | return task, nil
68 | }
69 |
70 | func (taskManager TaskManager) FindByProcessInstanceId(processInstanceId int64) (task []Task, err error) {
71 | task = make([]Task, 0)
72 | err = db.DB().Where("proc_inst_id=?", processInstanceId).Find(&task).Error
73 | if err != nil {
74 | log.Infoln("Select FindByProcessInstanceId err ", err)
75 | }
76 | if task == nil || len(task) <= 0 {
77 | return task, errs.ProcessError{Code: "1001", Msg: "Not find"}
78 | }
79 | return task, err
80 | }
81 |
82 | func (taskManager TaskManager) DeleteTask(task Task) (err error) {
83 | err = db.DB().Where("id = ?", task.Id).Delete(&task).Error
84 | if err != nil {
85 | return err
86 | }
87 | identityLinkManager := IdentityLinkManager{}
88 | identityLinks, errSelect := identityLinkManager.SelectByTaskId(task.Id)
89 | if errSelect == nil {
90 | for _, identityLink := range identityLinks {
91 | err = identityLinkManager.Delete(identityLink.Id)
92 | if err != nil {
93 | return err
94 | }
95 | }
96 | }
97 | variableManager := VariableManager{}
98 | variables, errSelect := variableManager.SelectByTaskId(task.Id)
99 | if errSelect == nil {
100 | for _, variable := range variables {
101 | err = variableManager.Delete(variable.Id)
102 | if err != nil {
103 | return err
104 | }
105 | }
106 | }
107 | err = recordTaskEnd(task)
108 | return err
109 | }
110 |
111 | func recordTaskEnd(task Task) (err error) {
112 | historicTaskManager := HistoricTaskManager{}
113 | historicTask := HistoricTask{}
114 | historicTask.TaskId = task.Id
115 | historicTask.EndTime = time.Now()
116 | historicTaskManager.HistoricTask = historicTask
117 | err = historicTaskManager.MarkEnded()
118 | if err != nil {
119 | return err
120 | }
121 |
122 | historicActinst := HistoricActinst{}
123 | historicActinst.EndTime = historicTask.EndTime
124 | historicActinst.TaskId = historicTask.TaskId
125 | historicActinstManager := HistoricActinstManager{}
126 | historicActinstManager.HistoricActinst = historicActinst
127 | return historicActinstManager.UpdateTaskId()
128 | }
129 |
130 | func (taskManager TaskManager) QueryUndoTask(userId, groupId string) (taskResult []TaskEntity, err error) {
131 | taskResult = make([]TaskEntity, 0)
132 | var sql = "SELECT t.*,i.user_id,i.group_id FROM task t " +
133 | "LEFT JOIN identity_link i on t.id = i.task_id " +
134 | "WHERE 1=1 "
135 | if userId != "" {
136 | sql += fmt.Sprintf("AND i.user_id = '%s' ", userId)
137 | }
138 | if groupId != "" {
139 | sql += fmt.Sprintf("AND i.group_id = '%s' ", groupId)
140 | }
141 | err = db.DB().Raw(sql).Find(&taskResult).Error
142 | if err != nil {
143 | return taskResult, err
144 | }
145 | return taskResult, nil
146 | }
147 |
--------------------------------------------------------------------------------
/engine/persistence/variableManager.go:
--------------------------------------------------------------------------------
1 | package persistence
2 |
3 | import (
4 | "github.com/lios/go-activiti/db"
5 | . "github.com/lios/go-activiti/engine/variable"
6 | "github.com/lios/go-activiti/errs"
7 | "github.com/prometheus/common/log"
8 | )
9 |
10 | type VariableManager struct {
11 | Variable *Variable
12 | }
13 |
14 | func (define VariableManager) Create(name string, variableType VariableType, value interface{}) *Variable {
15 | variable := Variable{}
16 | variable.Version = 0
17 | variable.Name = name
18 | variable.Type = variableType.GetTypeName()
19 | variable.SetValue(value, variableType)
20 | return &variable
21 |
22 | }
23 |
24 | func (defineManager VariableManager) Insert() (err error) {
25 | err = db.DB().Create(&defineManager.Variable).Error
26 | if err != nil {
27 | log.Infoln("Create Variable Error", err)
28 | return err
29 | }
30 | err = defineManager.createHistoricVariable()
31 | return err
32 | }
33 |
34 | func (defineManager VariableManager) createHistoricVariable() (err error) {
35 | variable := defineManager.Variable
36 | historicVariable := HistoricVariable{}
37 |
38 | historicVariable.TaskId = variable.TaskId
39 | historicVariable.ProcessInstanceId = variable.ProcessInstanceId
40 | historicVariable.Name = variable.Name
41 | historicVariable.Version = variable.Version
42 | historicVariable.Type = variable.Type
43 | historicVariable.Text = variable.Text
44 | historicVariable.Number = variable.Number
45 | historicVariable.Date = variable.Date
46 | historicVariable.Float = variable.Float
47 | historicVariable.Blob = variable.Blob
48 |
49 | historicVariableManager := HistoricVariableManager{}
50 | historicVariableManager.HistoricVariable = historicVariable
51 | return historicVariableManager.Insert()
52 | }
53 |
54 | func (defineManager VariableManager) SelectProcessInstanceId(name string, processInstanceId int64) (Variable, error) {
55 | variables := Variable{}
56 | err := db.DB().Where("proc_inst_id = ?", processInstanceId).Where("name = ?", name).First(&variables).Error
57 | if err != nil {
58 | log.Infoln("Select Variable err: ", err)
59 | return Variable{}, err
60 | }
61 | return variables, nil
62 | }
63 |
64 | func (variableManager VariableManager) SelectTaskId(name string, taskId int64) (Variable, error) {
65 | variables := Variable{}
66 | err := db.DB().Where("task_id = ?", taskId).Where("name = ?", name).First(&variables).Error
67 | if err != nil {
68 | log.Infoln("根据[taskId] 查询流程变量异常", err)
69 | return Variable{}, err
70 | }
71 | return variables, nil
72 | }
73 |
74 | func (variableManager VariableManager) SelectByProcessInstanceId(processInstanceId int64) ([]Variable, error) {
75 | variables := make([]Variable, 0)
76 | err := db.DB().Where("proc_inst_id = ?", processInstanceId).Find(&variables).Error
77 | if err != nil {
78 | log.Infoln("Select Variable err: ", err)
79 | return variables, err
80 | }
81 | if variables != nil && len(variables) > 0 {
82 | return variables, nil
83 | }
84 | return variables, errs.ProcessError{Code: "1001", Msg: "Not Find"}
85 | }
86 |
87 | func (variableManager VariableManager) SelectByTaskId(taskId int64) ([]Variable, error) {
88 | variables := make([]Variable, 0)
89 | err := db.DB().Where("task_id = ?", taskId).Find(&variables).Error
90 | if err != nil {
91 | log.Infoln("Select Variable err: ", err)
92 | return variables, err
93 | }
94 | if variables != nil && len(variables) > 0 {
95 | return variables, nil
96 | }
97 | return variables, errs.ProcessError{Code: "1001", Msg: "Not Find"}
98 | }
99 |
100 | func (variableManager VariableManager) Delete(variableId int64) error {
101 | variable := Variable{}
102 | err := db.DB().Where("id=?", variableId).Delete(variable).Error
103 | if err != nil {
104 | log.Infoln("delete Variable err: ", err)
105 | }
106 | return err
107 | }
108 |
--------------------------------------------------------------------------------
/engine/process.go:
--------------------------------------------------------------------------------
1 | package engine
2 |
3 | import (
4 | "encoding/xml"
5 | "github.com/lios/go-activiti/errs"
6 | )
7 |
8 | var (
9 | //将元素存入map
10 | processMap = make(map[int64]Process, 0)
11 | )
12 |
13 | //流程定义对象
14 | type Definitions struct {
15 | DefinitionsName xml.Name `xml:"definitions"`
16 | Xmlns string `xml:"xmlns,attr"`
17 | Xsi string `xml:"xsi,attr"`
18 | Xsd string `xml:"xsd,attr"`
19 | Activiti string `xml:"activiti,attr"`
20 | Bpmndi string `xml:"bpmndi,attr"`
21 | Omgdc string `xml:"omgdc,attr"`
22 | Omgdi string `xml:"omgdi,attr"`
23 | TypeLanguage string `xml:"typeLanguage,attr"`
24 | RgetNamespace string `xml:"rgetNamespace,attr"`
25 | ExpressionLanguage string `xml:"expressionLanguage,attr"`
26 | TargetNamespace string `xml:"targetNamespace,attr"`
27 | Process []Process `xml:"process"`
28 | Message []Message `xml:"message"`
29 | }
30 | type Process struct {
31 | ProcessName xml.Name `xml:"process"`
32 | Id string `xml:"id,attr"`
33 | Name string `xml:"name,attr"`
34 | Documentation string `xml:"documentation"`
35 | IsExecutable string `xml:"isExecutable,attr"`
36 | StartEvent []StartEvent `xml:"startEvent"`
37 | EndEvent []EndEvent `xml:"endEvent"`
38 | UserTask []UserTask `xml:"userTask"`
39 | SequenceFlow []SequenceFlow `xml:"sequenceFlow"`
40 | ExclusiveGateway []ExclusiveGateway `xml:"exclusiveGateway"`
41 | InclusiveGateway []InclusiveGateway `xml:"inclusiveGateway"`
42 | ParallelGateway []ParallelGateway `xml:"parallelGateway"`
43 | BoundaryEvent []BoundaryEvent `xml:"boundaryEvent"`
44 | IntermediateCatchEvent []IntermediateCatchEvent `xml:"intermediateCatchEvent"`
45 | SubProcess []SubProcess `xml:"subProcess"`
46 | Flow []FlowElement
47 | InitialFlowElement FlowElement
48 | FlowMap map[string]FlowElement
49 | }
50 |
51 | //子流程
52 | type SubProcess struct {
53 | *Process
54 | SubProcessName xml.Name `xml:"subProcess"`
55 | }
56 |
57 | //消息订阅
58 | type Message struct {
59 | *BaseElement
60 | MessageName xml.Name `xml:"message"`
61 | }
62 |
63 | //通用字段
64 | type BaseElement struct {
65 | Id string `xml:"id,attr"`
66 | Name string `xml:"name,attr"`
67 | }
68 |
69 | //父类实现体
70 | type Flow struct {
71 | BaseElement
72 | Id string `xml:"id,attr"`
73 | Name string `xml:"name,attr"`
74 | IncomingFlow []FlowElement
75 | OutgoingFlow []FlowElement
76 | SourceFlowElement FlowElement
77 | TargetFlowElement FlowElement
78 | Behavior ActivityBehavior
79 | }
80 |
81 | //开始节点
82 | type StartEvent struct {
83 | *Flow
84 | StartEventName xml.Name `xml:"startEvent"`
85 | Initiator string `xml:"initiator,attr"`
86 | FormKey string `xml:"formKey,attr"`
87 | }
88 |
89 | //结束节点
90 | type EndEvent struct {
91 | *Flow
92 | EndEventName xml.Name `xml:"endEvent"`
93 | }
94 |
95 | //用户任务
96 | type UserTask struct {
97 | *Flow
98 | UserTaskName xml.Name `xml:"userTask"`
99 | Assignee string `xml:"assignee,attr"`
100 | CandidateUsers []string `xml:"candidateUsers,attr"`
101 | CandidateGroups []string `xml:"candidateGroups,attr"`
102 | ExtensionElements ExtensionElements `xml:"extensionElements"`
103 | }
104 |
105 | type ExtensionElements struct {
106 | ExtensionElementName xml.Name `xml:"extensionElements"`
107 | TaskListener []TaskListener `xml:"taskListener"`
108 | }
109 | type TaskListener struct {
110 | TaskListenerName xml.Name `xml:"taskListener"`
111 | EventType string `xml:"event,attr"`
112 | }
113 |
114 | //连线
115 | type SequenceFlow struct {
116 | *Flow
117 | SequenceFlowName xml.Name `xml:"sequenceFlow"`
118 | Id string `xml:"id,attr"`
119 | SourceRef string `xml:"sourceRef,attr"`
120 | TargetRef string `xml:"targetRef,attr"`
121 | ConditionExpression string `xml:"conditionExpression"`
122 | }
123 | type Gateway struct {
124 | *Flow
125 | DefaultFlow string
126 | }
127 |
128 | //排他网关
129 | type ExclusiveGateway struct {
130 | *Gateway
131 | }
132 |
133 | //包容网关
134 | type InclusiveGateway struct {
135 | *Gateway
136 | }
137 |
138 | //并行网关
139 | type ParallelGateway struct {
140 | *Gateway
141 | }
142 |
143 | //边界事件
144 | type BoundaryEvent struct {
145 | *Flow
146 | BoundaryEventName xml.Name `xml:"boundaryEvent"`
147 | AttachedToRef string `xml:"attachedToRef,attr"`
148 | CancelActivity string `xml:"cancelActivity,attr"`
149 | TimerEventDefinition TimerEventDefinition `xml:"timerEventDefinition"`
150 | }
151 |
152 | //定时任务
153 | type TimerEventDefinition struct {
154 | TimerEventDefinitionName xml.Name `xml:"timerEventDefinition"`
155 | TimeDuration string `xml:"timeDuration"`
156 | }
157 |
158 | //中间抛出事件
159 | type IntermediateCatchEvent struct {
160 | *Flow
161 | IntermediateCatchEventName xml.Name `xml:"intermediateCatchEvent"`
162 | MessageEventDefinition MessageEventDefinition `xml:"messageEventDefinition"`
163 | }
164 |
165 | //消息事件
166 | type MessageEventDefinition struct {
167 | MessageEventDefinitionName xml.Name `xml:"messageEventDefinition"`
168 | MessageRef string `xml:"messageRef,attr"`
169 | }
170 |
171 | //接口
172 | type FlowElement interface {
173 | SetIncoming(f []FlowElement)
174 | SetOutgoing(f []FlowElement)
175 | GetIncoming() []FlowElement
176 | GetOutgoing() []FlowElement
177 |
178 | SetSourceFlowElement(f FlowElement)
179 | SetTargetFlowElement(f FlowElement)
180 | GetSourceFlowElement() FlowElement
181 | GetTargetFlowElement() FlowElement
182 |
183 | GetBehavior() ActivityBehavior
184 | SetBehavior(behavior ActivityBehavior)
185 |
186 | GetId() string
187 | GetName() string
188 | }
189 |
190 | func SetProcess(defineId int64, process Process) {
191 | //_,err := processMap[process.Id]
192 | processMap[defineId] = process
193 | }
194 |
195 | func GetProcess(id int64) (Process, error) {
196 | process, ok := processMap[id]
197 | if !ok {
198 | return Process{}, errs.ProcessError{}
199 | }
200 | return process, nil
201 | }
202 |
203 | func (pocess Process) GetFlowElement(flowElementId string) FlowElement {
204 | return pocess.FlowMap[flowElementId]
205 | }
206 |
207 | func (flow *Flow) SetIncoming(f []FlowElement) {
208 | flow.IncomingFlow = f
209 | }
210 | func (flow *Flow) SetOutgoing(f []FlowElement) {
211 | flow.OutgoingFlow = f
212 | }
213 |
214 | func (flow *Flow) GetIncoming() []FlowElement {
215 | return flow.IncomingFlow
216 | }
217 | func (flow *Flow) GetOutgoing() []FlowElement {
218 | return flow.OutgoingFlow
219 | }
220 |
221 | func (flow *Flow) SetSourceFlowElement(f FlowElement) {
222 | flow.SourceFlowElement = f
223 | }
224 | func (flow *Flow) SetTargetFlowElement(f FlowElement) {
225 | flow.TargetFlowElement = f
226 | }
227 |
228 | func (flow *Flow) GetSourceFlowElement() FlowElement {
229 | return flow.SourceFlowElement
230 | }
231 | func (flow *Flow) GetTargetFlowElement() FlowElement {
232 | return flow.TargetFlowElement
233 | }
234 |
235 | func (flow *Flow) GetBehavior() ActivityBehavior {
236 | return flow.Behavior
237 | }
238 | func (flow *Flow) SetBehavior(behavior ActivityBehavior) {
239 | flow.Behavior = behavior
240 | }
241 |
242 | func (flow *Flow) GetId() string {
243 | return flow.Id
244 | }
245 |
246 | func (flow *Flow) GetName() string {
247 | return flow.Name
248 | }
249 |
--------------------------------------------------------------------------------
/engine/service/repositoryService.go:
--------------------------------------------------------------------------------
1 | package engine
2 |
3 | import (
4 | "github.com/lios/go-activiti/engine/behavior"
5 | "github.com/lios/go-activiti/engine/cmd"
6 | )
7 |
8 | type RepositoryService struct {
9 | }
10 |
11 | //流程部署
12 | func (this RepositoryService) Deploy(name string, key string, bytes []byte) {
13 | behavior.GetServiceImpl().CommandExecutor.Exe(cmd.DeploymentCmd{Name: name, Key: key, Bytes: bytes})
14 | }
15 |
--------------------------------------------------------------------------------
/engine/service/runtimeService.go:
--------------------------------------------------------------------------------
1 | package engine
2 |
3 | import (
4 | "github.com/lios/go-activiti/engine/behavior"
5 | "github.com/lios/go-activiti/engine/cmd"
6 | )
7 |
8 | type RuntimeService struct {
9 | behavior.ServiceImpl
10 | }
11 |
12 | //发起流程
13 | func (runtime RuntimeService) StartProcessInstanceByKey(processDefinitionKey string, variables map[string]interface{},
14 | businessKey string, tenantId string) {
15 | behavior.GetServiceImpl().CommandExecutor.Exe(cmd.StartProcessInstanceByKeyCmd{ProcessDefinitionKey: processDefinitionKey,
16 | Variables: variables, TenantId: tenantId, BusinessKey: businessKey})
17 | }
18 |
--------------------------------------------------------------------------------
/engine/service/taskService.go:
--------------------------------------------------------------------------------
1 | package engine
2 |
3 | import (
4 | "github.com/lios/go-activiti/engine/behavior"
5 | "github.com/lios/go-activiti/engine/cmd"
6 | . "github.com/lios/go-activiti/entity"
7 | . "github.com/lios/go-activiti/model"
8 | )
9 |
10 | type TaskService struct {
11 | }
12 |
13 | //查询待审批任务
14 | func (taskService TaskService) QueryUndoTask(userId, groupId string) ([]TaskEntity, error) {
15 | exe, err := behavior.GetServiceImpl().CommandExecutor.Exe(cmd.GetTaskCmd{UserId: userId, GroupId: groupId})
16 | if err != nil {
17 | return nil, err
18 | }
19 | results, ok := exe.([]TaskEntity)
20 | if ok {
21 | return results, nil
22 | }
23 | return nil, err
24 | }
25 |
26 | //流程审批完成
27 | func (taskService TaskService) Complete(taskId int, variables map[string]interface{}, localScope bool) (Task, error) {
28 | var task Task
29 | exe, err := behavior.GetServiceImpl().CommandExecutor.Exe(cmd.CompleteCmd{TaskId: taskId, Variables: variables, LocalScope: localScope})
30 | if err != nil {
31 | return task, err
32 | }
33 | return exe.(Task), nil
34 | }
35 |
36 | //查询待审批任务
37 | func (taskService TaskService) BackTask(taskId int, targetFlowId string) (bool, error) {
38 | exe, err := behavior.GetServiceImpl().CommandExecutor.Exe(cmd.BackTaskCmd{TaskId: taskId, TargetFlowId: targetFlowId})
39 | if err != nil {
40 | return false, err
41 | }
42 | return exe.(bool), nil
43 | }
44 |
--------------------------------------------------------------------------------
/engine/utils/conditionUtil.go:
--------------------------------------------------------------------------------
1 | package utils
2 |
3 | import (
4 | . "github.com/heartlhj/go-expression/expression"
5 | . "github.com/heartlhj/go-expression/expression/spel"
6 | "github.com/lios/go-activiti/engine"
7 | )
8 |
9 | var (
10 | context = StandardEvaluationContext{}
11 | parser = SpelExpressionParser{}
12 | )
13 |
14 | type ConditionUtil struct {
15 | }
16 |
17 | func HasTrueCondition(sequenceFlow engine.SequenceFlow, execution engine.ExecutionEntity) bool {
18 | var conditionExpression = sequenceFlow.ConditionExpression
19 | if conditionExpression != "" {
20 | variable := execution.GetProcessVariable()
21 | context.SetVariables(variable)
22 | valueContext := parser.ParseExpression(conditionExpression).GetValueContext(&context)
23 | b, ok := valueContext.(bool)
24 | if ok {
25 | return b
26 | }
27 | return false
28 | } else {
29 | return true
30 | }
31 |
32 | }
33 |
--------------------------------------------------------------------------------
/engine/utils/executionGraphUtil.go:
--------------------------------------------------------------------------------
1 | package utils
2 |
3 | import . "github.com/lios/go-activiti/engine"
4 |
5 | type ExecutionGraphUtil struct {
6 | }
7 |
8 | func IsReachable(process Process, sourceElementId string, targetElementId string) bool {
9 | sourceFlowElement := process.FlowMap[sourceElementId]
10 | sourceFlow, ok := sourceFlowElement.(SequenceFlow)
11 | if !ok {
12 | element := sourceFlow.GetTargetFlowElement()
13 | flow, _ := (element).(SequenceFlow)
14 | sourceFlow = flow
15 | }
16 |
17 | targetFlowElement := process.FlowMap[targetElementId]
18 | targetFlow, ok := targetFlowElement.(SequenceFlow)
19 | if !ok {
20 | element := targetFlow.GetTargetFlowElement()
21 | flow, _ := (element).(SequenceFlow)
22 | targetFlow = flow
23 | }
24 | var visitedElements = make(map[string]FlowElement, 0)
25 | return isReachable(process, sourceFlow, targetFlow, visitedElements)
26 |
27 | }
28 |
29 | func isReachable(process Process, sourceElement FlowElement, targetElement FlowElement, visitedElements map[string]FlowElement) bool {
30 | if sourceElement.GetId() == targetElement.GetId() {
31 | return true
32 | }
33 | visitedElements[sourceElement.GetId()] = sourceElement
34 | outgoing := sourceElement.GetOutgoing()
35 | if outgoing != nil && len(outgoing) > 0 {
36 | for _, value := range outgoing {
37 | sequenceFlowTarget := (value).GetTargetFlowElement()
38 | if sequenceFlowTarget != nil && visitedElements[(sequenceFlowTarget).GetId()] != nil {
39 | var reachable = isReachable(process, sequenceFlowTarget, targetElement, visitedElements)
40 | if reachable {
41 | return true
42 | }
43 | }
44 | }
45 | }
46 | return false
47 | }
48 |
--------------------------------------------------------------------------------
/engine/variable/boolType.go:
--------------------------------------------------------------------------------
1 | package variable
2 |
3 | type BooleanType struct {
4 | }
5 |
6 | func (boolType BooleanType) GetTypeName() string {
7 | return "bool"
8 | }
9 |
10 | func (boolType BooleanType) GetValue(valueFields ValueFields) interface{} {
11 | return valueFields.GetTextValue() == "true"
12 | }
13 |
14 | func (boolType BooleanType) SetValue(value interface{}, valueFields ValueFields) {
15 | b, ok := value.(bool)
16 | if ok {
17 | if b {
18 | valueFields.SetTextValue("true")
19 | } else {
20 | valueFields.SetTextValue("false")
21 | }
22 | }
23 | valueFields.SetBlobValue("")
24 | }
25 |
--------------------------------------------------------------------------------
/engine/variable/defaultVariableTypes.go:
--------------------------------------------------------------------------------
1 | package variable
2 |
3 | var (
4 | typesList = make(map[string]VariableType, 0)
5 | )
6 |
7 | type DefaultVariableTypes struct {
8 | }
9 |
10 | func (variableTypes DefaultVariableTypes) AddType(variableType VariableType) {
11 | typesList[variableType.GetTypeName()] = variableType
12 | }
13 |
14 | func (variableTypes DefaultVariableTypes) GetVariableType(typeName string) VariableType {
15 | return typesList[typeName]
16 | }
17 |
--------------------------------------------------------------------------------
/engine/variable/historicVariable.go:
--------------------------------------------------------------------------------
1 | package variable
2 |
3 | import (
4 | "time"
5 | )
6 |
7 | type HistoricVariable struct {
8 | Id int64
9 | Version int64 `gorm:"column:version"`
10 | TaskId int64 `gorm:"column:task_id"`
11 | ProcessInstanceId int64 `gorm:"column:proc_inst_id"`
12 | Name string `gorm:"column:name"`
13 | Type string `gorm:"column:type"`
14 | Date time.Time `gorm:"column:date"`
15 | Number int `gorm:"column:number"`
16 | Float float64 `gorm:"column:float"`
17 | Text string `gorm:"column:text"`
18 | Blob string `gorm:"column:blob"`
19 | }
20 |
21 | func (HistoricVariable) TableName() string {
22 | return "hi_variable"
23 | }
24 |
25 | func (variable HistoricVariable) GetName() string {
26 | return variable.Name
27 | }
28 |
29 | func (variable HistoricVariable) GetProcessInstanceId() int64 {
30 | return variable.ProcessInstanceId
31 | }
32 |
33 | func (variable HistoricVariable) GetTaskId() int64 {
34 | return variable.TaskId
35 | }
36 |
37 | func (variable HistoricVariable) GetNumberValue() int {
38 | return variable.Number
39 | }
40 |
41 | func (variable *HistoricVariable) SetNumberValue(value int) {
42 | variable.Number = value
43 | }
44 |
45 | func (variable HistoricVariable) GetTextValue() string {
46 | return variable.Text
47 | }
48 |
49 | func (variable *HistoricVariable) SetTextValue(value string) {
50 | variable.Text = value
51 | }
52 |
53 | func (variable *HistoricVariable) SetValue(value interface{}, variableType VariableType) {
54 | variableType.SetValue(value, variable)
55 | }
56 |
57 | func (variable *HistoricVariable) SetBlobValue(value string) {
58 | variable.Blob = value
59 | }
60 |
61 | func (variable HistoricVariable) GetBlobValue() string {
62 | return variable.Blob
63 | }
64 |
--------------------------------------------------------------------------------
/engine/variable/intType.go:
--------------------------------------------------------------------------------
1 | package variable
2 |
3 | type IntType struct {
4 | }
5 |
6 | func (intType IntType) GetTypeName() string {
7 | return "int"
8 | }
9 |
10 | func (intType IntType) GetValue(valueFields ValueFields) interface{} {
11 | return valueFields.GetNumberValue()
12 | }
13 |
14 | func (intType IntType) SetValue(value interface{}, valueFields ValueFields) {
15 | valueInt, ok := value.(int)
16 | if ok {
17 | valueFields.SetNumberValue(valueInt)
18 | }
19 | valueFields.SetBlobValue("")
20 | }
21 |
--------------------------------------------------------------------------------
/engine/variable/mapType.go:
--------------------------------------------------------------------------------
1 | package variable
2 |
3 | import "encoding/json"
4 |
5 | type MapType struct {
6 | }
7 |
8 | func (mapType MapType) GetTypeName() string {
9 | return "map"
10 | }
11 |
12 | func (mapType MapType) GetValue(valueFields ValueFields) interface{} {
13 | var tempMap map[string]interface{}
14 | err := json.Unmarshal([]byte(valueFields.GetTextValue()), &tempMap)
15 | if err != nil {
16 | panic(err)
17 | }
18 | return tempMap
19 | }
20 |
21 | func (mapType MapType) SetValue(value interface{}, valueFields ValueFields) {
22 | b, ok := value.(map[string]interface{})
23 | if ok {
24 | dataType, _ := json.Marshal(b)
25 | dataString := string(dataType)
26 | valueFields.SetTextValue(dataString)
27 | }
28 | }
29 |
--------------------------------------------------------------------------------
/engine/variable/stringType.go:
--------------------------------------------------------------------------------
1 | package variable
2 |
3 | type StringType struct {
4 | }
5 |
6 | func (stringType StringType) GetTypeName() string {
7 | return "string"
8 | }
9 |
10 | func (stringType StringType) GetValue(valueFields ValueFields) interface{} {
11 | return valueFields.GetTextValue()
12 | }
13 |
14 | func (stringType StringType) SetValue(value interface{}, valueFields ValueFields) {
15 | b, ok := value.(string)
16 | if ok {
17 | valueFields.SetTextValue(b)
18 | }
19 | valueFields.SetBlobValue("")
20 | }
21 |
--------------------------------------------------------------------------------
/engine/variable/valueFields.go:
--------------------------------------------------------------------------------
1 | package variable
2 |
3 | type ValueFields interface {
4 | GetName() string
5 |
6 | GetProcessInstanceId() int64
7 |
8 | GetTaskId() int64
9 |
10 | GetNumberValue() int
11 |
12 | SetNumberValue(value int)
13 |
14 | GetTextValue() string
15 |
16 | SetTextValue(value string)
17 |
18 | SetBlobValue(value string)
19 |
20 | GetBlobValue() string
21 | }
22 |
--------------------------------------------------------------------------------
/engine/variable/variable.go:
--------------------------------------------------------------------------------
1 | package variable
2 |
3 | import (
4 | "time"
5 | )
6 |
7 | type Variable struct {
8 | Id int64
9 | Version int64 `gorm:"column:version"`
10 | TaskId int64 `gorm:"column:task_id"`
11 | ProcessInstanceId int64 `gorm:"column:proc_inst_id"`
12 | Name string `gorm:"column:name"`
13 | Type string `gorm:"column:type"`
14 | Date time.Time `gorm:"column:date"`
15 | Number int `gorm:"column:number"`
16 | Float float64 `gorm:"column:float"`
17 | Text string `gorm:"column:text"`
18 | Blob string `gorm:"column:blob"`
19 | }
20 |
21 | func (Variable) TableName() string {
22 | return "variable"
23 | }
24 |
25 | func (variable Variable) GetName() string {
26 | return variable.Name
27 | }
28 |
29 | func (variable Variable) GetProcessInstanceId() int64 {
30 | return variable.ProcessInstanceId
31 | }
32 |
33 | func (variable Variable) GetTaskId() int64 {
34 | return variable.TaskId
35 | }
36 |
37 | func (variable Variable) GetNumberValue() int {
38 | return variable.Number
39 | }
40 |
41 | func (variable *Variable) SetNumberValue(value int) {
42 | variable.Number = value
43 | }
44 |
45 | func (variable Variable) GetTextValue() string {
46 | return variable.Text
47 | }
48 |
49 | func (variable *Variable) SetTextValue(value string) {
50 | variable.Text = value
51 | }
52 |
53 | func (variable *Variable) SetValue(value interface{}, variableType VariableType) {
54 | variableType.SetValue(value, variable)
55 | }
56 |
57 | func (variable *Variable) SetBlobValue(value string) {
58 | variable.Blob = value
59 | }
60 |
61 | func (variable Variable) GetBlobValue() string {
62 | return variable.Blob
63 | }
64 |
--------------------------------------------------------------------------------
/engine/variable/variableInstanceEntity.go:
--------------------------------------------------------------------------------
1 | package variable
2 |
3 | type VariableInstanceEntit interface {
4 | GetType() VariableType
5 |
6 | SetType(variableType VariableType)
7 | }
8 |
--------------------------------------------------------------------------------
/engine/variable/variableType.go:
--------------------------------------------------------------------------------
1 | package variable
2 |
3 | type VariableType interface {
4 | GetTypeName() string
5 |
6 | GetValue(valueFields ValueFields) interface{}
7 |
8 | SetValue(value interface{}, valueFields ValueFields)
9 | }
10 |
--------------------------------------------------------------------------------
/engine/variable/variableTypes.go:
--------------------------------------------------------------------------------
1 | package variable
2 |
3 | type VariableTypes interface {
4 | AddType(variableType VariableType)
5 |
6 | GetVariableType(typeName string) VariableType
7 | }
8 |
--------------------------------------------------------------------------------
/engine/variableScope.go:
--------------------------------------------------------------------------------
1 | package engine
2 |
3 | type VariableScope interface {
4 | SetVariable(variableName string, value interface{})
5 | }
6 |
--------------------------------------------------------------------------------
/entity/identityLinkEntity.go:
--------------------------------------------------------------------------------
1 | package entity
2 |
3 | type IdentityLinkEntity struct {
4 | }
5 |
--------------------------------------------------------------------------------
/entity/processInstanceEntity.go:
--------------------------------------------------------------------------------
1 | package entity
2 |
3 | type ProcessInstanceEntity struct {
4 | }
5 |
--------------------------------------------------------------------------------
/entity/taskEntity.go:
--------------------------------------------------------------------------------
1 | package entity
2 |
3 | import "time"
4 |
5 | type TaskEntity struct {
6 | Id int64 `json:"id"`
7 | TaskDefineKey string `json:"task_define_key"`
8 | TaskDefineName string `json:"task_define_name"`
9 | TenantId string `json:"tenant_id"`
10 | DeploymentId int `json:"deployment_id"`
11 | StartTime time.Time `json:"start_time"`
12 | Assignee string `json:"assignee"`
13 | ProcInstId int64 `json:"proc_inst_id"`
14 | UserId string `json:"user_id"`
15 | GroupId string `json:"group_id"`
16 | }
17 |
--------------------------------------------------------------------------------
/entity/variableEntity.go:
--------------------------------------------------------------------------------
1 | package entity
2 |
3 | type VariableEntity struct {
4 | }
5 |
--------------------------------------------------------------------------------
/errs/errs.go:
--------------------------------------------------------------------------------
1 | package errs
2 |
3 | type Err struct {
4 | Error string `json:"error"`
5 | ErrorCode string `json:"error_code"`
6 | }
7 |
8 | type ErrResponse struct {
9 | HttpSC int
10 | Error Err
11 | }
12 |
13 | var (
14 | ErrorRequestBodyParseFailed = ErrResponse{HttpSC: 400, Error: Err{Error: "Request body is not correct", ErrorCode: "001"}}
15 | ErrorNotAuthUser = ErrResponse{HttpSC: 401, Error: Err{Error: "User authentication failed", ErrorCode: "002"}}
16 | ErrorDBError = ErrResponse{HttpSC: 500, Error: Err{Error: "DB ops failed", ErrorCode: "003"}}
17 | ErrorInternalFaults = ErrResponse{HttpSC: 500, Error: Err{Error: "Internal service error", ErrorCode: "004"}}
18 | )
19 |
--------------------------------------------------------------------------------
/errs/processError.go:
--------------------------------------------------------------------------------
1 | package errs
2 |
3 | type ProcessError struct {
4 | Code string
5 | Msg string
6 | }
7 |
8 | func (error ProcessError) Error() string {
9 | return error.Code + "---" + error.Msg
10 | }
11 |
--------------------------------------------------------------------------------
/event/activitiEntityEvent.go:
--------------------------------------------------------------------------------
1 | package event
2 |
3 | type ActivitiEntityEvent interface {
4 | ActivitiEvent
5 | GetEntity() interface{}
6 | }
7 |
--------------------------------------------------------------------------------
/event/activitiEvent.go:
--------------------------------------------------------------------------------
1 | package event
2 |
3 | type ActivitiEventType string
4 |
5 | const (
6 | TASK_CREATED ActivitiEventType = "TASK_CREATED"
7 |
8 | TASK_ASSIGNED ActivitiEventType = "TASK_ASSIGNED"
9 |
10 | TASK_COMPLETED ActivitiEventType = "TASK_COMPLETED"
11 | )
12 |
13 | type ActivitiEvent interface {
14 | GetType() ActivitiEventType
15 | }
16 |
--------------------------------------------------------------------------------
/event/activitiEventDispatcher.go:
--------------------------------------------------------------------------------
1 | package event
2 |
3 | type ActivitiEventDispatcher interface {
4 | AddEventListener(listenerToAdd ActivitiEventListener)
5 |
6 | RemoveEventListener(listenerToRemove ActivitiEventListener)
7 |
8 | DispatchEvent(event ActivitiEvent)
9 |
10 | SetEnabled(enabled bool)
11 |
12 | IsEnabled() bool
13 | }
14 |
--------------------------------------------------------------------------------
/event/activitiEventDispatcherImpl.go:
--------------------------------------------------------------------------------
1 | package event
2 |
3 | var eventDispatcher ActivitiEventDispatcher
4 |
5 | type ActivitiEventDispatcherImpl struct {
6 | EventSupport *ActivitiEventSupport
7 | Enabled bool
8 | }
9 |
10 | func SetEventDispatcher(event ActivitiEventDispatcher) {
11 | eventDispatcher = event
12 | }
13 |
14 | func GetEventDispatcher() ActivitiEventDispatcher {
15 | return eventDispatcher
16 | }
17 | func (eventDispatcher ActivitiEventDispatcherImpl) AddEventListener(listenerToAdd ActivitiEventListener) {
18 | eventDispatcher.EventSupport.AddEventListener(listenerToAdd)
19 | }
20 |
21 | func (eventDispatcher ActivitiEventDispatcherImpl) RemoveEventListener(listenerToRemove ActivitiEventListener) {
22 | }
23 |
24 | func (eventDispatcher ActivitiEventDispatcherImpl) DispatchEvent(event ActivitiEvent) {
25 | if eventDispatcher.Enabled {
26 | eventDispatcher.EventSupport.DispatchEvent(event)
27 | }
28 | }
29 |
30 | func (eventDispatcher ActivitiEventDispatcherImpl) SetEnabled(enabled bool) {
31 | eventDispatcher.Enabled = enabled
32 | }
33 |
34 | func (eventDispatcher ActivitiEventDispatcherImpl) IsEnabled() bool {
35 | return eventDispatcher.Enabled
36 | }
37 |
--------------------------------------------------------------------------------
/event/activitiEventListener.go:
--------------------------------------------------------------------------------
1 | package event
2 |
3 | type ActivitiEventListener interface {
4 | OnEvent(event ActivitiEvent) error
5 | }
6 |
--------------------------------------------------------------------------------
/event/activitiEventSupport.go:
--------------------------------------------------------------------------------
1 | package event
2 |
3 | import . "github.com/lios/go-activiti/errs"
4 |
5 | type ActivitiEventSupport struct {
6 | EventListeners []ActivitiEventListener
7 | }
8 |
9 | func (activitiEventSupport *ActivitiEventSupport) AddEventListener(listenerToAdd ActivitiEventListener) (err error) {
10 | if listenerToAdd == nil {
11 | err = ProcessError{Msg: "Listener cannot be null."}
12 | }
13 | activitiEventSupport.EventListeners = append(activitiEventSupport.EventListeners, listenerToAdd)
14 | return err
15 | }
16 |
17 | func (activitiEventSupport ActivitiEventSupport) DispatchEvent(event ActivitiEvent) (err error) {
18 | if event == nil {
19 | err = ProcessError{Msg: "Event cannot be null."}
20 | return err
21 | }
22 |
23 | if len(event.GetType()) == 0 {
24 | err = ProcessError{Msg: "Event type cannot be null."}
25 | return err
26 | }
27 |
28 | // Call global listeners
29 | if activitiEventSupport.EventListeners != nil && len(activitiEventSupport.EventListeners) > 0 {
30 | for _, listener := range activitiEventSupport.EventListeners {
31 | err = dispatchEvent(event, listener)
32 | if err != nil {
33 | return err
34 | }
35 | }
36 | }
37 | return err
38 | }
39 |
40 | func dispatchEvent(event ActivitiEvent, listener ActivitiEventListener) error {
41 | return listener.OnEvent(event)
42 | }
43 |
--------------------------------------------------------------------------------
/event/impl/activitiEntityEventImpl.go:
--------------------------------------------------------------------------------
1 | package impl
2 |
3 | import . "github.com/lios/go-activiti/event"
4 |
5 | type ActivitiEntityEventImpl struct {
6 | ActivitiEntityEvent
7 | ActivitiEventImpl
8 | Entity interface{}
9 | }
10 |
11 | func (ActivitiEntityEventImpl) GetType() ActivitiEventType {
12 | return TASK_CREATED
13 | }
14 |
--------------------------------------------------------------------------------
/event/impl/activitiEventBuilder.go:
--------------------------------------------------------------------------------
1 | package impl
2 |
3 | import (
4 | "github.com/lios/go-activiti/errs"
5 | . "github.com/lios/go-activiti/event"
6 | )
7 |
8 | type ActivitiEventBuilder struct {
9 | }
10 |
11 | func CreateEvent() ActivitiEvent {
12 | return nil
13 | }
14 |
15 | func CreateEntityEvent(eventType ActivitiEventType, entity interface{}) (ActivitiEntityEvent, error) {
16 | entityEventImpl := ActivitiEntityEventImpl{}
17 | entityEventImpl.ActivitiEventImpl = ActivitiEventImpl{}
18 | entityEventImpl.EventType = eventType
19 | var err error = nil
20 | if entity == nil {
21 | err = errs.ProcessError{Msg: "Entity cannot be null."}
22 | }
23 | entityEventImpl.Entity = entity
24 | return entityEventImpl, err
25 | }
26 |
--------------------------------------------------------------------------------
/event/impl/activitiEventImpl.go:
--------------------------------------------------------------------------------
1 | package impl
2 |
3 | import . "github.com/lios/go-activiti/event"
4 |
5 | type ActivitiEventImpl struct {
6 | EventType ActivitiEventType
7 | ExecutionId string
8 | ProcessInstanceId string
9 | ProcessDefinitionId string
10 | }
11 |
12 | func (activitiEvent ActivitiEventImpl) GetType() ActivitiEventType {
13 | return activitiEvent.EventType
14 | }
15 |
16 | func (activitiEvent ActivitiEventImpl) SetType(eventType ActivitiEventType) {
17 | activitiEvent.EventType = eventType
18 | }
19 | func (activitiEvent ActivitiEventImpl) GetProcessDefinitionId() string {
20 | return activitiEvent.ProcessDefinitionId
21 | }
22 |
23 | func (activitiEvent ActivitiEventImpl) SetProcessDefinitionId(processDefinitionId string) {
24 | activitiEvent.ProcessDefinitionId = processDefinitionId
25 | }
26 |
27 | func (activitiEvent ActivitiEventImpl) GetProcessInstanceId() string {
28 | return activitiEvent.ProcessInstanceId
29 | }
30 |
31 | func (activitiEvent ActivitiEventImpl) SetProcessInstanceId(processInstanceId string) {
32 | activitiEvent.ProcessInstanceId = processInstanceId
33 | }
34 |
--------------------------------------------------------------------------------
/go.mod:
--------------------------------------------------------------------------------
1 | module github.com/lios/go-activiti
2 |
3 | go 1.12
4 |
5 | require (
6 | github.com/Unknwon/goconfig v0.0.0-20190425194916-3dba17dd7b9e //
7 | github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751 // indirect
8 | github.com/go-sql-driver/mysql v1.5.0
9 | github.com/heartlhj/go-expression v0.1.2-fix
10 | github.com/jinzhu/gorm v1.9.15
11 | github.com/julienschmidt/httprouter v1.3.0
12 | github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
13 | github.com/pborman/uuid v1.2.0
14 | github.com/prometheus/common v0.13.0
15 | )
16 |
--------------------------------------------------------------------------------
/main.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import (
4 | "github.com/julienschmidt/httprouter"
5 | . "github.com/lios/go-activiti/web"
6 |
7 | "log"
8 | "net/http"
9 | )
10 |
11 | func RegisterHandler() *httprouter.Router {
12 | router := httprouter.New()
13 | router.GET("/", Index)
14 | router.POST("/import", Create)
15 | return router
16 | }
17 |
18 | func main() {
19 | r := RegisterHandler()
20 | log.Println("StartIng Http.....")
21 | http.ListenAndServe(":8080", r)
22 | }
23 |
--------------------------------------------------------------------------------
/model/bytearry.go:
--------------------------------------------------------------------------------
1 | package model
2 |
3 | //流程源数据
4 | type Bytearry struct {
5 | Id int64 `gorm:"column:id"`
6 | Key string `gorm:"column:key"`
7 | Name string `gorm:"column:name"`
8 | Version int `gorm:"column:version"`
9 | Bytes string `gorm:"column:bytes"`
10 | DeploymentId int64 `gorm:"column:deployment_id"`
11 | }
12 |
13 | func (Bytearry) TableName() string {
14 | return "bytearry"
15 | }
16 |
--------------------------------------------------------------------------------
/model/deployment.go:
--------------------------------------------------------------------------------
1 | package model
2 |
3 | import "time"
4 |
5 | //部署
6 | type Deployment struct {
7 | Id int64 `gorm:"column:id"`
8 | Key string `gorm:"column:key"`
9 | Name string `gorm:"column:name"`
10 | Version int `gorm:"column:version"`
11 | TenantId string `gorm:"column:tenant_id"`
12 | DeployTime time.Time `gorm:"column:deploy_time"`
13 | }
14 |
15 | func (Deployment) TableName() string {
16 | return "deployment"
17 | }
18 |
--------------------------------------------------------------------------------
/model/historicActinst.go:
--------------------------------------------------------------------------------
1 | package model
2 |
3 | import (
4 | "time"
5 | )
6 |
7 | //流程实例
8 | type HistoricActinst struct {
9 | Id int64
10 | ProcessDefineId int64 `gorm:"column:process_define_id"`
11 | ProcessInstanceId int64 `gorm:"column:proc_inst_id"`
12 | TaskId int64 `gorm:"column:task_id"`
13 | ActId string `gorm:"column:act_id"`
14 | ActName string `gorm:"column:act_name"`
15 | ActType string `gorm:"column:act_type"`
16 | TenantId string `gorm:"column:tenant_id"`
17 | StartTime time.Time `gorm:"column:start_time"`
18 | EndTime time.Time `gorm:"column:end_time","default: null"`
19 | StartUserId string `gorm:"column:start_user_id"`
20 | Assignee string `gorm:"column:assignee"`
21 | }
22 |
23 | func (HistoricActinst) TableName() string {
24 | return "hi_actinst"
25 | }
26 |
--------------------------------------------------------------------------------
/model/historicIdentityLink.go:
--------------------------------------------------------------------------------
1 | package model
2 |
3 | type HistoricIdentityLink struct {
4 | Id int64
5 | Type string `gorm:"column:type"`
6 | TaskId int64 `gorm:"column:task_id"`
7 | ProcessInstanceId int64 `gorm:"column:proc_inst_id"`
8 | GroupId string `gorm:"column:group_id"`
9 | UserId string `gorm:"column:user_id"`
10 | }
11 |
12 | func (HistoricIdentityLink) TableName() string {
13 | return "hi_identity_link"
14 | }
15 |
--------------------------------------------------------------------------------
/model/historicProcinst.go:
--------------------------------------------------------------------------------
1 | package model
2 |
3 | import (
4 | "time"
5 | )
6 |
7 | //流程实例
8 | type HistoricProcess struct {
9 | Id int64
10 | ProcessInstanceId int64 `gorm:"column:proc_inst_id"`
11 | Key string `gorm:"column:key"`
12 | Name string `gorm:"column:name"`
13 | BusinessKey string `gorm:"column:business_key"`
14 | TenantId string `gorm:"column:tenant_id"`
15 | DeploymentId int64 `gorm:"column:deployment_id"`
16 | StartTime time.Time `gorm:"column:start_time"`
17 | EndTime time.Time `gorm:"column:end_time","default: null"`
18 | StartUserId string `gorm:"column:start_user_id"`
19 | ProcessDefineId int64 `gorm:"column:process_define_id"`
20 | }
21 |
22 | func (HistoricProcess) TableName() string {
23 | return "hi_process_instance"
24 | }
25 |
--------------------------------------------------------------------------------
/model/historicTask.go:
--------------------------------------------------------------------------------
1 | package model
2 |
3 | import (
4 | "time"
5 | )
6 |
7 | type HistoricTask struct {
8 | Id int64
9 | TaskId int64 `gorm:"column:task_id"`
10 | TaskDefineKey string `gorm:"column:task_define_key"`
11 | TaskDefineName string `gorm:"column:task_define_name"`
12 | TenantId string `gorm:"column:tenant_id"`
13 | DeploymentId int `gorm:"column:deployment_id"`
14 | StartTime time.Time `gorm:"column:start_time"`
15 | EndTime time.Time `gorm:"column:end_time","default: null"`
16 | Assignee string `gorm:"column:assignee"`
17 | ProcessInstanceId int64 `gorm:"column:proc_inst_id"`
18 | }
19 |
20 | func (HistoricTask) TableName() string {
21 | return "hi_task"
22 | }
23 |
--------------------------------------------------------------------------------
/model/identityLink.go:
--------------------------------------------------------------------------------
1 | package model
2 |
3 | type IdentityLink struct {
4 | Id int64
5 | Type string `gorm:"column:type"`
6 | TaskId int64 `gorm:"column:task_id"`
7 | ProcessInstanceId int64 `gorm:"column:proc_inst_id"`
8 | GroupId string `gorm:"column:group_id"`
9 | UserId string `gorm:"column:user_id"`
10 | }
11 |
12 | func (IdentityLink) TableName() string {
13 | return "identity_link"
14 | }
15 |
--------------------------------------------------------------------------------
/model/procinst.go:
--------------------------------------------------------------------------------
1 | package model
2 |
3 | import (
4 | "time"
5 | )
6 |
7 | //流程实例
8 | type ProcessInstance struct {
9 | Id int64
10 | Key string `gorm:"column:key"`
11 | Name string `gorm:"column:name"`
12 | BusinessKey string `gorm:"column:business_key"`
13 | TenantId string `gorm:"column:tenant_id"`
14 | DeploymentId int64 `gorm:"column:deployment_id"`
15 | StartTime time.Time `gorm:"column:start_time"`
16 | StartUserId string `gorm:"column:start_user_id"`
17 | ProcessDefineId int64 `gorm:"column:process_define_id"`
18 | }
19 |
20 | func (ProcessInstance) TableName() string {
21 | return "process_instance"
22 | }
23 |
24 | func (processInstance ProcessInstance) setBusinessKey(businessKey string) {
25 | processInstance.BusinessKey = businessKey
26 | }
27 |
--------------------------------------------------------------------------------
/model/task.go:
--------------------------------------------------------------------------------
1 | package model
2 |
3 | import (
4 | "time"
5 | )
6 |
7 | type Task struct {
8 | Id int64
9 | TaskDefineKey string `gorm:"column:task_define_key"`
10 | TaskDefineName string `gorm:"column:task_define_name"`
11 | TenantId string `gorm:"column:tenant_id"`
12 | DeploymentId int `gorm:"column:deployment_id"`
13 | StartTime time.Time `gorm:"column:start_time"`
14 | Assignee string `gorm:"column:assignee"`
15 | ProcessInstanceId int64 `gorm:"column:proc_inst_id"`
16 | }
17 |
18 | func (Task) TableName() string {
19 | return "task"
20 | }
21 |
--------------------------------------------------------------------------------
/resources/process_demo.bpmn20.xml:
--------------------------------------------------------------------------------
1 |
2 |