Parcourir la source

自定义事件类,实现状态推送

cczhang il y a 6 mois
Parent
révision
498bcd1c9b

+ 7
- 0
data/workflow/license/license.xml Voir le fichier

@@ -0,0 +1,7 @@
1
+<?xml version="1.0" encoding="UTF-8"?>
2
+
3
+<horizon-licenses>
4
+  <license-group product="workflow" version="8.2" format="1.4" release-time="DE09D72D344C43BB31F6EB5F39574FF093DFA3921B4B4EE5" run-time="DE09D72D344C43BB31F6EB5F39574FF093DFA3921B4B4EE5" timer="DE09D72D344C43BB31F6EB5F39574FF093DFA3921B4B4EE5" summary="RceD8zu+eGwsvz10+yjgYjruIuTBVYLOSCwZSbuFaLO/GOLdK4ALY/D9YdMbSym0G6v7RkvGIXOn8EKtKnhO2F0oiLQCvWyO1klLIsnl3beUEXdP3v85F7uGHGEnuqo+QsmoSuZLvZhYupqzDyqpwUW0vSE2Kr6lqCPTlx25h4s=" install="machine">
5
+    <license licensee="山信开发" expiration="2025-02-12" cpus="16" users="200" formsums="200" units="1" ip="http://localhost" port="8080" app="/horizon-workflow-boot" flow="20" work="20" tenantspace="1" concurrent="1" multi-server="1" clusters="1" simple="1" form-designer="1">53428102B36553EF2243BF1392B4946238955D312C359A8AB27C74D06CC5DDBC1EDB539407F22DA714B4598337865680006648E21D69088702C390E085C9DB67F44BEA2369CFBA3ABEEDF7D8438472F5D34928437E2E1AC8E67EDD334C00A7BC68C5EA792E08BD4E78A1D85CB931078F6032FF4B5E66E02FCE7D73EC604D979F8E43CC233F93EA90C200B84C76B2268683970B0F23312373CF4157170914DE6AB00D7562BEBC43AC34F320CA143FB54ABB5F57F3247A7D1A898DBDDD84FE6B7B7F0AC765042B9C80A52A10417635BDEDD82F89E1DB89AE5248A78B9A7F04839D36B99A20089CB5331F47CC5D3EF9E4E39E417F5BAB9D2555E0C455A6148610D72BA914C2AE78916A175312FA4FE842B0349B27D4B07C218EBD43E4BD16C0B98F98B4BA9E51248B11B1FCD6B0F8909083C3BB869599F31B8D1E86662AB9E1DF57B867ABB62B3A3CE0DB9D14DA97179E162F93F7581FBD650F9F8D08067DB683067D62016BC35BA3E9570684E0E2AFBCC1BBC6BCE6F801BBFB2C4DF6AB6E1F6364DB571E0CCF3AD8421CA2C5F61126FCE98D17AD9AB1A4E0195B396A860268DEF7FB30784878A2E4D44703AEE8D2AC51B68D07521CB81D4ECDB85C3867A696F7A6602ACB06FDBC34026384F5974B1681FCDEE941668965362C345194D4EFED6E4F8ED318EC7EA809F0DB328B5295C5EDD9B5E9D6657EF10B18C817E8E25BDCE8E4D3089C0CEE39A8340DCDEE7EBF53B72961B8841CE83DAB0DB9E9779207DD41E70E2C11CD1A188FCDAD2C216FD79E6269B1E6031DB15EFBCF078D3EF0423A8B2F8B6430345EF6351091DCDE27044BB05A60ED80CAD255700475AD5946ACA0A11BF7DA00462D89BEE30218F3703BA358FE865EA1DA3BB6FC36606B9EEF91F56D81918189A54FDD7AA72AC757EF297D22523247251DBBA08B2CB293A942892903E24B4C81668AF1CE987888F11120A2BF886C684AAA305837C4982B442A0396934B572E71D5FE470EE41B7895C4A756A4299C4EE5CCC1EB452E06FE77B7D2B383D967DE95905BE2B105288E032D2F257D4FB36EC92BB1D39E2028ED30FEF05662425CAF98622F1D91A6547A7002BBC806E9C37ED5B4343799B243F6635E687F7459B54153F162BEDFD1588E551CD12114E53C37381B4FDCA0C505F9F8E661BF19583FDD4B1B295DF47555AF4973FF542F0970CA53C94EEB04EE3EE892A1B700DC65</license>
6
+  </license-group>
7
+</horizon-licenses>

+ 95
- 0
data/workflow/properties/cache.properties Voir le fichier

@@ -0,0 +1,95 @@
1
+#流程缓存模式 redis memcached guava ehcache
2
+cache.type=guava
3
+
4
+#默认的缓存组名称
5
+default.cache.name=defaultCache
6
+#默认的缓存过期时间
7
+default.cache.time=0
8
+#开启二级缓存,缓存类型为guava时不建议开启
9
+enableLocalCache=false
10
+#开启二级缓存后,存储二级缓存的key(模糊包含)(多个用;隔开)
11
+localCacheKey=HORIZON_DEPTS;HORIZON_USERS;HORIZON_GROUPS;HORIZON_ROLES;HORIZON_POSITIONS
12
+
13
+#------------------guava缓存配置---------------
14
+guava.enable=true
15
+#瓜娃缓存数接近该值时开始移除不常用的缓存
16
+guava.maximum.size= 1000
17
+#当key在被“read/write”操作之后,空闲多久后被删除。(秒)
18
+guava.expire.after.access= 604800
19
+#当key被write(put或者reload)操作之后,空闲多久后被删除。(秒)
20
+expire.after.write=604800
21
+
22
+#----------------redis缓存配置----------------------------------------------------
23
+redis.enable=false
24
+#redis连接是否是哨兵模式
25
+redis.sentinel=false
26
+#redis的服务器地址,多个用分号";"隔开
27
+#哨兵模式下,第一个redis地址写主节点,哨兵节点写在主节点后面,用分号";"隔开
28
+redis.host=127.0.0.1
29
+#redis的服务端口,多个用分号";"隔开
30
+#哨兵模式下,第一个redis端口写主节点,哨兵节点写在主节点后面,用分号";"隔开
31
+redis.port=6379
32
+#名称,多个用分号隔开
33
+#哨兵模式下,主节点(master)节点的名称必需设置
34
+redis.name=
35
+#redis连接密码,多个用分号";"隔开
36
+#哨兵模式下,密码只需设置一个即可
37
+redis.passWord=
38
+#链接数据库
39
+#redis.default.db=0
40
+#客户端超时时间单位是毫秒
41
+redis.timeout=100000
42
+#最大连接数
43
+redis.pool.maxActive=300
44
+#最大空闲数
45
+redis.pool.maxIdle=100
46
+#最小空闲数
47
+redis.pool.minIdle=20
48
+#最大建立连接等待时间
49
+redis.pool.maxWait=10000
50
+#使用连接时,检测连接是否成功
51
+redis.pool.testOnBorrow=true
52
+#返回连接时,检测连接是否成功
53
+redis.pool.testOnReturn=false
54
+
55
+#---------------------memcached缓存配置-------------------------
56
+#启用
57
+memcache.enable=false
58
+#服务器地址
59
+memcached.servers=192.168.3.158:11211
60
+#当一个服务器请求超时是否去访问另一台
61
+memcached.failover=true
62
+#初始链接数
63
+memcached.initConn=5
64
+#最小连接数
65
+memcached.minConn=5
66
+#最大连接数
67
+memcached.maxConn=300
68
+#主线程休眠时间
69
+memcached.maintSleep=30
70
+#禁止使用nagle算法
71
+memcached.nagle=false
72
+#请求缓存超时时间
73
+memcached.socketTO=3000
74
+#检查服务器是否失效
75
+memcached.aliveCheck=true
76
+#memcached队列存放缓存时的超时期限
77
+memcached.timeOut=5
78
+#memcached内存实例超期期限
79
+memcached.expiryTime=30
80
+
81
+#---------------------ehcache缓存配置-------------------------
82
+#启用
83
+ehcache.enable=false
84
+#内存中最大缓存对象数
85
+ehcache.maxElementsInMemory=1000
86
+#是否将会对象写到磁盘中
87
+ehcache.overflowToDisk=true
88
+#对象是否永久有效
89
+ehcache.eternal=false
90
+#允许对象处于空闲状态的最长时间,以秒为单位。
91
+ehcache.timeToLiveSeconds=604800
92
+#对象允许存在于缓存中的最长时间
93
+ehcache.timeToIdleSeconds=604800
94
+#磁盘失效线程运行时间间隔
95
+ehcahce.diskExpiryThreadIntervalSeconds=120

+ 27
- 0
data/workflow/properties/dbconfig.properties Voir le fichier

@@ -0,0 +1,27 @@
1
+#Horizon Workflow DB base info
2
+horizon.identifier=system
3
+horizon.databaseType=Oracle
4
+horizon.isDefault=true
5
+horizon.lobProcessorClass=com.horizon.db.xlob.XlobProcessorImpl4Oracle
6
+horizon.lobBufferSize=1048576
7
+horizon.connectionType=jdbc
8
+horizon.jndiName=
9
+#datasource config
10
+horizon.db.driverClass=oracle.jdbc.driver.OracleDriver
11
+horizon.db.maxPoolSize=15
12
+horizon.db.minPoolSize=3
13
+horizon.db.initialPoolSize=3
14
+horizon.db.maxIdelTime=0
15
+horizon.db.jdbcUrl=jdbc:oracle:thin:@172.16.7.51:10002/pdb
16
+horizon.db.username=zksf
17
+horizon.db.password=1234
18
+#数据源类型 默认tomcat-jdbc
19
+horizon.db.datasourceType=tomcat-jdbc
20
+# 用于验证数据库连接是否可用的SQL语句,不同数据库sql语句不同
21
+# mysql,mysql8,dm,tidb;sqlserver,oscar:     SELECT 1
22
+# oracle:                                   SELECT 1 FROM DUAL
23
+# postgresql,gbase,highgo,gauss,upbase:     SELECT VERSION()
24
+# db2:                                      SELECT 1 FROM SYSIBM.SYSDUMMY1
25
+# gbase8s:                                  SELECT 1 FROM SYSUSERS
26
+# kingbase,kingbase8:                       SELECT 1 FROM SYS_STAT_ACTIVITY
27
+horizon.db.validationQuery=SELECT 1 FROM DUAL

+ 167
- 0
data/workflow/properties/horizon.properties Voir le fichier

@@ -0,0 +1,167 @@
1
+
2
+#文件根目录
3
+sys.path=/workflow
4
+
5
+#模块资源文件目录
6
+assets.path=/workflow/assets
7
+
8
+#第三方插件资源文件目录
9
+front.path=/workflow/plugins
10
+
11
+#公共页面
12
+common.path=/workflow/common
13
+
14
+#初始化安装文件目录
15
+init.path=/init
16
+
17
+#初始化安装模块
18
+init.module.path=workflow
19
+
20
+#管理端请求路径
21
+url.prefix=/horizon/workflow
22
+
23
+#URL请求后缀
24
+url.suffix=.wf
25
+
26
+#视图路径
27
+view.prefix=/workflow
28
+view.suffix=.html
29
+
30
+#布局 top/top-left/top-left-hoversubmenu/bottom-left/bottom-left-hoversubmenu/left/left-hoversubmenu
31
+layout.engine=bottom-left
32
+
33
+#默认展开框架右侧树
34
+layout.fixedModal=true
35
+
36
+#嵌入 embed
37
+embed=
38
+
39
+#允许上传文件大小
40
+maxUploadSize=10485760
41
+
42
+#允许上传普通附件的类型
43
+fileFormat=doc;txt;xls;ppt
44
+
45
+#允许上传图片的类型
46
+imgFormat=png;gif;svg;bmp
47
+
48
+#保存文件的类型,0为保存到物理机文件系统,1为保存至数据库
49
+saveType=0
50
+
51
+#附件上传路径
52
+store.path=D:/_tmp
53
+
54
+#上传文件是否需要加密
55
+file.isNeedEncode = false
56
+
57
+#产品默认初始化方式  1:租户模式  3:单利模式
58
+initFlag=3
59
+
60
+#实时记录开关,0-不记录,1记录
61
+realtimeflag=1
62
+
63
+#实时数据保留时间,单位“天”,超过三天数据将按天进行归档
64
+keeptime=1
65
+
66
+#WorkflowContextFilter过滤器不需要拦截的地址列表,中间用逗号分隔,
67
+#注意:不能换行。根据配置,除了jsp,实际请求地址类似:url.prefix+下列地址+url.suffix
68
+sessionExceptiveURL=/index.html;/index_system.html;/login/tenant;/login/system;/system/tenant/login;/workflow/module/workflow/flow.info.html;/flowchart/chartdata;/workflow/module/designer/index_1.html
69
+
70
+#流程框架页面固定右侧信息
71
+workflow.fixedModal=false
72
+
73
+#流程前端设置消息发送类型Mail;Msg;SMS;IM
74
+workflow.messageType=
75
+
76
+#流程启动是否自动到第一个任务节点
77
+workflow.autoFirstNode=true
78
+
79
+#流程无法计算出办理人时,使用默认办理人
80
+workflow.openDefAuthor=false
81
+
82
+#流程在测试是否保存业务数据:默认保存
83
+workflow.unCommitData=false
84
+
85
+#流程[退回]操作时选择办理人
86
+workflow.reject.selectAuthor=false
87
+
88
+#流程[任意退回]操作时选择办理人
89
+workflow.jumpreject.selectAuthor=false
90
+
91
+#如果设置读者,流程提交自动过滤去掉subjection
92
+workflow.replace.subjection=true
93
+
94
+#流程[自由提交]坐标设置
95
+workflow.freesubmit.axis=true
96
+
97
+#流程执行以下操作不执行表单验证֤
98
+workflow.unValidate=reject;jumpreject;innerreject;getback;save;close;move;goto;pause;stop;subflow;replace
99
+
100
+#流程框架导入页面(/module/workflow/page.import.ftl)
101
+workflow.import=
102
+ 
103
+#当前语言
104
+localeVal=zh_CN
105
+
106
+#token 过期时间(分钟)
107
+token.timeout=7200
108
+
109
+#500错误页面
110
+errorpage500=
111
+
112
+#产品分类
113
+product=workflow
114
+
115
+#develop:开发模式
116
+#product:产品模式
117
+run.mode=develop
118
+
119
+#启动定时任务默认true, 停止启动为false
120
+task.start=true
121
+#批量处理个数(用户配置数据库关键字in中的数据个数默认900最大1000.神通数据库请配置200;最大255)
122
+batch.number=200
123
+
124
+#初始化数据时是否忽略连接失败的数据源
125
+ignore.dataSource.connFail=false
126
+#是否解析主办组织机构为人员
127
+workflow.authorParsingToUser=false
128
+
129
+# 解析组织机构类型D (部门(不包含子部门)) P(岗位) G(群组) ;分隔
130
+workflow.authorParsingType=D;
131
+
132
+#启动是否加载全部组织机构信息
133
+orgData.loadAll=true
134
+
135
+#组织机构搜索框最大返回数目
136
+orgData.searchMax=100
137
+#程序应用名称
138
+server.name=workflow
139
+#程序应用监控是否打开
140
+server.monitor.open=true
141
+#程序程序运行记录频率5分钟一次
142
+server.runRecord.step=5
143
+#jvm内存运行记录频率30分钟一次
144
+server.jvmRecord.step=30
145
+#cpu占用率情况记录频率30分钟一次
146
+server.cpuRecord.step=30
147
+#磁盘空间记录频率60分钟一次
148
+server.diskRecord.step=60
149
+#接口请求响应时间间隔记录
150
+server.requestRecord.step=10
151
+#流程域数据刷新时间5分钟一次
152
+flowArea.refresh.time=5
153
+#流程实例严重超期天数限制
154
+monitor.overexceed.day=2
155
+
156
+#jar包启动时.properties配置文件和license文件生成的文件夹路径
157
+#路径为绝对路径,路径之间以 "/" 作为分隔符,例如: C:/test/conf
158
+#文件夹名不要含有特殊字符,不进行设置时默认为当前用户目录
159
+horizon.home=data
160
+
161
+#首页URl
162
+home.url=/manager/index
163
+
164
+#是否开启租户授权校验
165
+isValidateOfTenant=false
166
+
167
+#initFieldLength.varchar=4

+ 1
- 0
data/workflow/properties/version.properties Voir le fichier

@@ -0,0 +1 @@
1
+version=8.2.2

+ 15
- 10
pom.xml Voir le fichier

@@ -23,6 +23,11 @@
23 23
     </properties>
24 24
 
25 25
     <dependencies>
26
+        <dependency>
27
+            <groupId>cn.hutool</groupId>
28
+            <artifactId>hutool-all</artifactId>
29
+            <version>5.8.8</version>
30
+        </dependency>
26 31
         <!--其他需要依赖的jar包-->
27 32
         <dependency>
28 33
             <groupId>org.springframework.boot</groupId>
@@ -260,28 +265,28 @@
260 265
         <dependency>
261 266
             <groupId>com.horizon</groupId>
262 267
             <artifactId>horizon-framework</artifactId>
263
-            <version>8.2</version>
268
+            <version>8.2.2</version>
264 269
             <scope>system</scope>
265 270
             <systemPath>${basedir}/lib/horizon/horizon-framework-8.2.2.jar</systemPath>
266 271
         </dependency>
267 272
         <dependency>
268 273
             <groupId>com.horizon</groupId>
269 274
             <artifactId>horizon-language-zh_CN</artifactId>
270
-            <version>8.2</version>
275
+            <version>8.2.2</version>
271 276
             <scope>system</scope>
272 277
             <systemPath>${basedir}/lib/horizon/horizon-language-zh_CN-8.2.2.jar</systemPath>
273 278
         </dependency>
274 279
         <dependency>
275 280
             <groupId>com.horizon</groupId>
276 281
             <artifactId>horizon-language-en</artifactId>
277
-            <version>8.2</version>
282
+            <version>8.2.2</version>
278 283
             <scope>system</scope>
279 284
             <systemPath>${basedir}/lib/horizon/horizon-language-en-8.2.2.jar</systemPath>
280 285
         </dependency>
281 286
         <dependency>
282 287
             <groupId>com.horizon</groupId>
283 288
             <artifactId>horizon-language-pub</artifactId>
284
-            <version>8.2</version>
289
+            <version>8.2.2</version>
285 290
             <scope>system</scope>
286 291
             <systemPath>${basedir}/lib/horizon/horizon-language-pub-8.2.2.jar</systemPath>
287 292
         </dependency>
@@ -295,21 +300,21 @@
295 300
         <dependency>
296 301
             <groupId>com.horizon</groupId>
297 302
             <artifactId>horizon-tenant-extras</artifactId>
298
-            <version>8.2</version>
303
+            <version>8.2.2</version>
299 304
             <scope>system</scope>
300 305
             <systemPath>${basedir}/lib/horizon/horizon-tenant-extras-8.2.2.jar</systemPath>
301 306
         </dependency>
302 307
         <dependency>
303 308
             <groupId>com.horizon</groupId>
304 309
             <artifactId>horizon-workflow-conf</artifactId>
305
-            <version>8.2</version>
310
+            <version>8.2.2</version>
306 311
             <scope>system</scope>
307 312
             <systemPath>${basedir}/lib/horizon/horizon-workflow-conf-8.2.2.jar</systemPath>
308 313
         </dependency>
309 314
         <dependency>
310 315
             <groupId>com.horizon</groupId>
311 316
             <artifactId>horizon-workflow-core</artifactId>
312
-            <version>8.2</version>
317
+            <version>8.2.2</version>
313 318
             <scope>system</scope>
314 319
             <systemPath>${basedir}/lib/horizon/horizon-workflow-core-8.2.2.jar</systemPath>
315 320
         </dependency>
@@ -323,21 +328,21 @@
323 328
         <dependency>
324 329
             <groupId>com.horizon</groupId>
325 330
             <artifactId>horizon-workflow-extend</artifactId>
326
-            <version>8.2</version>
331
+            <version>8.2.2</version>
327 332
             <scope>system</scope>
328 333
             <systemPath>${basedir}/lib/horizon/horizon-workflow-extend-8.2.2.jar</systemPath>
329 334
         </dependency>
330 335
         <dependency>
331 336
             <groupId>com.horizon</groupId>
332 337
             <artifactId>horizon-workflow-pub</artifactId>
333
-            <version>8.2</version>
338
+            <version>8.2.2</version>
334 339
             <scope>system</scope>
335 340
             <systemPath>${basedir}/lib/horizon/horizon-workflow-pub-8.2.2.jar</systemPath>
336 341
         </dependency>
337 342
         <dependency>
338 343
             <groupId>com.horizon</groupId>
339 344
             <artifactId>horizon-workflow-xml</artifactId>
340
-            <version>8.2</version>
345
+            <version>8.2.2</version>
341 346
             <scope>system</scope>
342 347
             <systemPath>${basedir}/lib/horizon/horizon-workflow-xml-8.2.2.jar</systemPath>
343 348
         </dependency>

+ 14
- 0
src/main/java/com/horizon/common/constant/Constants.java Voir le fichier

@@ -0,0 +1,14 @@
1
+package com.horizon.common.constant;
2
+
3
+/**
4
+ * 流程常量信息
5
+ */
6
+public class Constants {
7
+
8
+    /**
9
+     * WF服务器URL,临时写死,后续会写到配置文件中
10
+     */
11
+    // public static final String WF_PRE_URL = "http://127.0.0.1:8003";
12
+    public static final String WF_PRE_URL = "http://172.16.7.51:10034/jlyypt";
13
+    // http://172.16.7.51:10034/jlyypt/cot/Head/approvalProccess
14
+}

+ 11
- 11
src/main/java/com/horizon/org/OrgBuilderImpl.java Voir le fichier

@@ -17,15 +17,15 @@ public class OrgBuilderImpl extends OrgBuilder {
17 17
     @Override
18 18
     public List<OrgData> depts() {
19 19
         System.out.println("当前租户标识:" + HorizonCore.TENANT_CODE.value());
20
-        String dbIdentifier = "sgiip";
20
+        String dbIdentifier = "jl_sgiip";
21 21
         Map<String, List<User>> usersDept = getUsersAndDept(dbIdentifier);//获取部门与用户的对应关系
22 22
         // id:部门id; dept_code :部门编号 ; dept_name:部门名称 ;parent_id:部门父节点id,必须存在 ; order_no 排序号,没有可默认
23 23
 //        String deptsql = "select id,dept_code,dept_name,parent_id,order_no from to_horizon_dept where  id!='root_node_id' order by order_no";
24 24
 
25 25
         String deptsql = "";
26
-        deptsql += " select d.id,d.dept_code,d.dept_name, ( select a.id from sgiip.sys_department a where a.dept_code = d.f_id ) as parent_id  ,";
26
+        deptsql += " select d.id,d.dept_code,d.dept_name, ( select a.id from JLOPAPUSER.sys_department a where a.dept_code = d.f_id ) as parent_id  ,";
27 27
         deptsql += " 'D' as type ,0 as order_no ";
28
-        deptsql += " from sgiip.sys_department d where d.cancel_flag = '0' and  d.dept_code!='D' ";
28
+        deptsql += " from JLOPAPUSER.sys_department d where d.cancel_flag = '0' and  d.dept_code!='D' ";
29 29
 
30 30
 
31 31
         List<Map<String, Object>> deptmap = Access.getMultiMap(deptsql, null, dbIdentifier);
@@ -73,9 +73,9 @@ public class OrgBuilderImpl extends OrgBuilder {
73 73
      */
74 74
     private Map<String, List<User>> getUsersAndDept(String dbIdentifier) {
75 75
 //        String usersql = "select u.id,u.login_name,u.name,tor.dept_id from to_horizon_user u,tor_horizon_user_dept tor where u.id = tor.user_id";
76
-//        String usersql = "select u.id,u.user_name as login_name,u.user_desc,tor.dept_id from sgiip.sys_user u,sgiip.sys_user_department tor where u.id = tor.user_id";
76
+//        String usersql = "select u.id,u.user_name as login_name,u.user_desc,tor.dept_id from JLOPAPUSER.sys_user u,JLOPAPUSER.sys_user_department tor where u.id = tor.user_id";
77 77
         String usersql = "";
78
-        usersql += "  SELECT u.id,u.user_name as LOGIN_NAME,u.user_desc as NAME,tor.DEPT_ID ,'' as type FROM sgiip.sys_user u,sgiip.sys_user_department tor WHERE u.ID = tor.USER_ID";
78
+        usersql += "  SELECT u.id,u.user_name as LOGIN_NAME,u.user_desc as NAME,tor.DEPT_ID ,'' as type FROM JLOPAPUSER.sys_user u,JLOPAPUSER.sys_user_department tor WHERE u.ID = tor.USER_ID";
79 79
         usersql += "  union all";
80 80
         usersql += " select '1' as id ,'admin' as login_name  ,'超级管理员' as NAME ,'0' as DEPT_ID  ,'' as type from dual";
81 81
 
@@ -114,7 +114,7 @@ public class OrgBuilderImpl extends OrgBuilder {
114 114
 
115 115
         return null;
116 116
 
117
-//        String dbIdentifier = "sgiip";
117
+//        String dbIdentifier = "jl_sgiip";
118 118
 //        Map<String,List<User>> usersAndGroup = getUsersAndGroup(dbIdentifier);
119 119
 //        // code是编号;  群组跟部门一样,支持树形结构
120 120
 //        String usersql = "select id,group_name,group_code,parent_id from to_horizon_group WHERE ID!='root_node_id'";
@@ -156,7 +156,7 @@ public class OrgBuilderImpl extends OrgBuilder {
156 156
     @Override
157 157
     public List<OrgData> positions() {
158 158
         System.out.println("当前租户标识:" + HorizonCore.TENANT_CODE.value());
159
-        String dbIdentifier = "sgiip";
159
+        String dbIdentifier = "jl_sgiip";
160 160
         Map<String, List<User>> usersDept = getUsersAndPost(dbIdentifier);//获取部门与用户的对应关系
161 161
         // id:部门id; dept_code :部门编号 ; dept_name:部门名称 ;parent_id:部门父节点id,必须存在 ; order_no 排序号,没有可默认
162 162
 //        String deptsql = "select id,dept_code,dept_name,parent_id,order_no from to_horizon_dept where  id!='root_node_id' order by order_no";
@@ -164,7 +164,7 @@ public class OrgBuilderImpl extends OrgBuilder {
164 164
         String deptsql = "";
165 165
         deptsql += " select d.id,d.post_code,d.post_name, 'position_root' as parent_id,";
166 166
         deptsql += " 'P' as type ,0 as order_no";
167
-        deptsql += " from sgiip.sys_post d where d.cancel_flag = '0'";
167
+        deptsql += " from JLOPAPUSER.sys_post d where d.cancel_flag = '0'";
168 168
 
169 169
 
170 170
         List<Map<String, Object>> deptmap = Access.getMultiMap(deptsql, null, dbIdentifier);
@@ -207,7 +207,7 @@ public class OrgBuilderImpl extends OrgBuilder {
207 207
 
208 208
 
209 209
     private Map<String, List<User>> getUsersAndPost(String dbIdentifier) {
210
-        String usersql = " SELECT u.id,u.user_name as LOGIN_NAME,u.user_desc as NAME,tor.post_ID ,'' as type FROM sgiip.sys_user u,sgiip.sys_user_post tor WHERE u.ID = tor.USER_ID ";
210
+        String usersql = " SELECT u.id,u.user_name as LOGIN_NAME,u.user_desc as NAME,tor.post_ID ,'' as type FROM JLOPAPUSER.sys_user u,JLOPAPUSER.sys_user_post tor WHERE u.ID = tor.USER_ID ";
211 211
         List<Map<String, Object>> userMap = Access.getMultiMap(usersql, null, dbIdentifier);
212 212
         Map<String, List<User>> usersAndDept = new HashMap<String, List<User>>();
213 213
         for (Map<String, Object> map : userMap) {
@@ -277,12 +277,12 @@ public class OrgBuilderImpl extends OrgBuilder {
277 277
 
278 278
     @Override
279 279
     public List<User> users() {
280
-        String dbIdentifier = "sgiip";
280
+        String dbIdentifier = "jl_sgiip";
281 281
         //id,用户唯一id;  login_name,用户登录名;   name,用户姓名;  dept_id,用户所属部门id ;
282 282
 //        String sql="SELECT u.id,u.LOGIN_NAME,'F;D' as type,u.NAME,tor.DEPT_ID FROM TO_HORIZON_USER u,TOR_HORIZON_USER_DEPT tor WHERE u.ID = tor.USER_ID";
283 283
 
284 284
         String sql = "";
285
-        sql += "  SELECT u.id,u.user_name as LOGIN_NAME,u.user_desc as NAME,tor.DEPT_ID ,'' as type FROM sgiip.sys_user u,sgiip.sys_user_department tor WHERE u.ID = tor.USER_ID";
285
+        sql += "  SELECT u.id,u.user_name as LOGIN_NAME,u.user_desc as NAME,tor.DEPT_ID ,'' as type FROM JLOPAPUSER.sys_user u,JLOPAPUSER.sys_user_department tor WHERE u.ID = tor.USER_ID";
286 286
         sql += "  union all";
287 287
         sql += " select '1' as id ,'admin' as login_name  ,'超级管理员' as NAME ,'0' as DEPT_ID  ,'' as type from dual";
288 288
 

+ 320
- 0
src/main/java/com/horizon/org/OrgBuilderImplSgiip.java Voir le fichier

@@ -0,0 +1,320 @@
1
+package com.horizon.org;
2
+
3
+import com.horizon.common.collect.Lists;
4
+import com.horizon.core.HorizonCore;
5
+import com.horizon.db.Access;
6
+import com.horizon.third.build.OrgBuilder;
7
+import com.horizon.third.entity.OrgData;
8
+import com.horizon.third.entity.User;
9
+
10
+import java.util.*;
11
+
12
+/**
13
+ * @Author: yangff update  2024-03-21
14
+ */
15
+public class OrgBuilderImplSgiip extends OrgBuilder {
16
+
17
+    @Override
18
+    public List<OrgData> depts() {
19
+        System.out.println("当前租户标识:" + HorizonCore.TENANT_CODE.value());
20
+        String dbIdentifier = "sgiip";
21
+        Map<String, List<User>> usersDept = getUsersAndDept(dbIdentifier);//获取部门与用户的对应关系
22
+        // id:部门id; dept_code :部门编号 ; dept_name:部门名称 ;parent_id:部门父节点id,必须存在 ; order_no 排序号,没有可默认
23
+//        String deptsql = "select id,dept_code,dept_name,parent_id,order_no from to_horizon_dept where  id!='root_node_id' order by order_no";
24
+
25
+        String deptsql = "";
26
+        deptsql += " select d.id,d.dept_code,d.dept_name, ( select a.id from sgiip.sys_department a where a.dept_code = d.f_id ) as parent_id  ,";
27
+        deptsql += " 'D' as type ,0 as order_no ";
28
+        deptsql += " from sgiip.sys_department d where d.cancel_flag = '0' and  d.dept_code!='D' ";
29
+
30
+
31
+        List<Map<String, Object>> deptmap = Access.getMultiMap(deptsql, null, dbIdentifier);
32
+        //部门信息封装到datas对象中,作为返回值
33
+        List<OrgData> datas = Lists.newArrayList();
34
+        //处理根部门
35
+        OrgData data_r = new OrgData();
36
+        data_r.setId("1");
37
+        data_r.setName("部门导航");
38
+        data_r.setParentId("0");
39
+        data_r.setType("D");
40
+        datas.add(data_r);
41
+        for (Map<String, Object> map : deptmap) {
42
+            String id = map.get("id") == null ? "" : map.get("id").toString();
43
+            String name = map.get("dept_name") == null ? "" : map.get("dept_name").toString();
44
+            String bmbh = map.get("dept_code") == null ? "" : map.get("dept_code").toString();
45
+            String parentId = map.get("parent_id") == null ? "" : map.get("parent_id").toString();
46
+            String sort = map.get("order_no") == null ? "" : map.get("order_no").toString();
47
+
48
+            if ("0".equals(parentId)) {
49
+                parentId = "1"; //部门导航、最顶层
50
+            }
51
+            //一个data对象封装一个部门信息
52
+            OrgData data_d = new OrgData();
53
+            data_d.setId(id);
54
+            data_d.setName(name);
55
+            data_d.setParentId(parentId);
56
+            data_d.setType("D");
57
+            data_d.setOrderNo(Integer.parseInt(sort));
58
+            data_d.setCode(bmbh);
59
+            //usermap.get(id)根据部门ID获取此部门人员,并保存到data对象中
60
+            if (usersDept.get(id) != null) {//判断通过id键获取的用户信息不为空,增加对应用户信息
61
+                data_d.setUsers(usersDept.get(id));
62
+            }
63
+            //封装部门信息的实例增加到datas对象中
64
+            datas.add(data_d);
65
+        }
66
+        return datas;
67
+    }
68
+
69
+    /**
70
+     * 获取部门下人员信息,此方法是获取用户与部门关联的信息,部门ID作为键,User对象为值
71
+     *
72
+     * @return
73
+     */
74
+    private Map<String, List<User>> getUsersAndDept(String dbIdentifier) {
75
+//        String usersql = "select u.id,u.login_name,u.name,tor.dept_id from to_horizon_user u,tor_horizon_user_dept tor where u.id = tor.user_id";
76
+//        String usersql = "select u.id,u.user_name as login_name,u.user_desc,tor.dept_id from sgiip.sys_user u,sgiip.sys_user_department tor where u.id = tor.user_id";
77
+        String usersql = "";
78
+        usersql += "  SELECT u.id,u.user_name as LOGIN_NAME,u.user_desc as NAME,tor.DEPT_ID ,'' as type FROM sgiip.sys_user u,sgiip.sys_user_department tor WHERE u.ID = tor.USER_ID";
79
+        usersql += "  union all";
80
+        usersql += " select '1' as id ,'admin' as login_name  ,'超级管理员' as NAME ,'0' as DEPT_ID  ,'' as type from dual";
81
+
82
+
83
+        List<Map<String, Object>> userMap = Access.getMultiMap(usersql, null, dbIdentifier);
84
+        Map<String, List<User>> usersAndDept = new HashMap<String, List<User>>();
85
+        for (Map<String, Object> map : userMap) {
86
+            //部门ID
87
+            String deptId = map.get("dept_id") == null ? "" : map.get("dept_id").toString();
88
+            //用户名
89
+            String userName = map.get("name") == null ? "" : map.get("name").toString();
90
+            //用户ID
91
+            String id = map.get("id") == null ? null : map.get("id").toString();
92
+            //若存在ID为null的User对象,那么在获取用户信息时,会出现空指针错误
93
+            if (id != null) {
94
+                //用户信息存入user对象中
95
+                User user = new User();
96
+                user.setId(id);
97
+                user.setUserName(userName);
98
+                List<User> users = new ArrayList<User>();
99
+                if (usersAndDept.get(deptId) == null) {//第一次存入部门与用户对应信息
100
+                    users.add(user);
101
+                    usersAndDept.put(deptId, users);
102
+                } else {//已存在该部门与用户的对应信息
103
+                    users = usersAndDept.get(deptId);
104
+                    users.add(user);
105
+                    usersAndDept.put(deptId, users);
106
+                }
107
+            }
108
+        }
109
+        return usersAndDept;
110
+    }
111
+
112
+    @Override
113
+    public List<OrgData> groups() {
114
+
115
+        return null;
116
+
117
+//        String dbIdentifier = "sgiip";
118
+//        Map<String,List<User>> usersAndGroup = getUsersAndGroup(dbIdentifier);
119
+//        // code是编号;  群组跟部门一样,支持树形结构
120
+//        String usersql = "select id,group_name,group_code,parent_id from to_horizon_group WHERE ID!='root_node_id'";
121
+//        List<Map<String,Object>> userMap = Access.getMultiMap(usersql, null, dbIdentifier);
122
+//        //群组信息封装到datas对象中,作为返回值
123
+//        List<OrgData> datas = Lists.newArrayList();
124
+//        OrgData data_r = new OrgData();//群组根数据,根数据的parentid需要为null
125
+//        data_r.setId("group_root");
126
+//        data_r.setName("角色导航");
127
+//        data_r.setParentId(null);
128
+//        data_r.setType("G");
129
+//        datas.add(data_r);
130
+//        for (Map<String, Object> map : userMap) {
131
+//            String id = map.get("id")==null?"":map.get("id").toString();
132
+//            String name = map.get("group_name")==null?"":map.get("group_name").toString();
133
+//            String code = map.get("group_code")==null?"":map.get("group_code").toString();
134
+//            String parentid = map.get("parent_id")==null?"":map.get("parent_id").toString();
135
+//
136
+//            //如果是一级群组,需要转换下根部门,根据实际情况修改名称
137
+//            if("root_node_id".equals(parentid)){
138
+//                parentid="group_root";
139
+//            }
140
+//            OrgData data_g = new OrgData();
141
+//            data_g.setId(id);
142
+//            data_g.setName(name);
143
+//            data_g.setCode(code);
144
+//            data_g.setParentId(parentid);
145
+//            if (usersAndGroup.get(id) != null){//判断通过id键获取的用户信息不为空,增加对应用户信息
146
+//                data_g.setUsers(usersAndGroup.get(id));
147
+//            }
148
+//            //必须固定
149
+//            data_g.setType("G");
150
+//            datas.add(data_g);
151
+//        }
152
+//         return datas;
153
+
154
+    }
155
+
156
+    @Override
157
+    public List<OrgData> positions() {
158
+        System.out.println("当前租户标识:" + HorizonCore.TENANT_CODE.value());
159
+        String dbIdentifier = "sgiip";
160
+        Map<String, List<User>> usersDept = getUsersAndPost(dbIdentifier);//获取部门与用户的对应关系
161
+        // id:部门id; dept_code :部门编号 ; dept_name:部门名称 ;parent_id:部门父节点id,必须存在 ; order_no 排序号,没有可默认
162
+//        String deptsql = "select id,dept_code,dept_name,parent_id,order_no from to_horizon_dept where  id!='root_node_id' order by order_no";
163
+
164
+        String deptsql = "";
165
+        deptsql += " select d.id,d.post_code,d.post_name, 'position_root' as parent_id,";
166
+        deptsql += " 'P' as type ,0 as order_no";
167
+        deptsql += " from sgiip.sys_post d where d.cancel_flag = '0'";
168
+
169
+
170
+        List<Map<String, Object>> deptmap = Access.getMultiMap(deptsql, null, dbIdentifier);
171
+        //部门信息封装到datas对象中,作为返回值
172
+        List<OrgData> datas = Lists.newArrayList();
173
+        //处理根部门
174
+        OrgData data_r = new OrgData();
175
+        data_r.setId("position_root");
176
+        data_r.setName("岗位导航");
177
+        data_r.setParentId("0");
178
+        data_r.setType("P");
179
+        datas.add(data_r);
180
+        for (Map<String, Object> map : deptmap) {
181
+            String id = map.get("id") == null ? "" : map.get("id").toString();
182
+            String name = map.get("post_name") == null ? "" : map.get("post_name").toString();
183
+            String bmbh = map.get("post_code") == null ? "" : map.get("post_code").toString();
184
+            String parentId = map.get("parent_id") == null ? "" : map.get("parent_id").toString();
185
+            String sort = map.get("order_no") == null ? "" : map.get("order_no").toString();
186
+
187
+            if ("0".equals(parentId)) {
188
+                parentId = "1"; //部门导航、最顶层
189
+            }
190
+            //一个data对象封装一个部门信息
191
+            OrgData data_d = new OrgData();
192
+            data_d.setId(id);
193
+            data_d.setName(name);
194
+            data_d.setParentId(parentId);
195
+            data_d.setType("P");
196
+            data_d.setOrderNo(Integer.parseInt(sort));
197
+            data_d.setCode(bmbh);
198
+            //usermap.get(id)根据部门ID获取此部门人员,并保存到data对象中
199
+            if (usersDept.get(id) != null) {//判断通过id键获取的用户信息不为空,增加对应用户信息
200
+                data_d.setUsers(usersDept.get(id));
201
+            }
202
+            //封装部门信息的实例增加到datas对象中
203
+            datas.add(data_d);
204
+        }
205
+        return datas;
206
+    }
207
+
208
+
209
+    private Map<String, List<User>> getUsersAndPost(String dbIdentifier) {
210
+        String usersql = " SELECT u.id,u.user_name as LOGIN_NAME,u.user_desc as NAME,tor.post_ID ,'' as type FROM sgiip.sys_user u,sgiip.sys_user_post tor WHERE u.ID = tor.USER_ID ";
211
+        List<Map<String, Object>> userMap = Access.getMultiMap(usersql, null, dbIdentifier);
212
+        Map<String, List<User>> usersAndDept = new HashMap<String, List<User>>();
213
+        for (Map<String, Object> map : userMap) {
214
+            //部门ID
215
+            String deptId = map.get("post_id") == null ? "" : map.get("post_id").toString();
216
+            //用户名
217
+            String userName = map.get("name") == null ? "" : map.get("name").toString();
218
+            //用户ID
219
+            String id = map.get("id") == null ? null : map.get("id").toString();
220
+            //若存在ID为null的User对象,那么在获取用户信息时,会出现空指针错误
221
+            if (id != null) {
222
+                //用户信息存入user对象中
223
+                User user = new User();
224
+                user.setId(id);
225
+                user.setUserName(userName);
226
+                List<User> users = new ArrayList<User>();
227
+                if (usersAndDept.get(deptId) == null) {//第一次存入部门与用户对应信息
228
+                    users.add(user);
229
+                    usersAndDept.put(deptId, users);
230
+                } else {//已存在该部门与用户的对应信息
231
+                    users = usersAndDept.get(deptId);
232
+                    users.add(user);
233
+                    usersAndDept.put(deptId, users);
234
+                }
235
+            }
236
+        }
237
+        return usersAndDept;
238
+    }
239
+
240
+
241
+    @Override
242
+    public List<OrgData> roles() {
243
+        return null;
244
+    }
245
+
246
+    //获取工作群组人员
247
+    private Map<String, List<User>> getUsersAndGroup(String dbIdentifier) {
248
+        // 需要群组id,用户id,用户name
249
+        String userSql = "select tor.workgroup_id,u.id,u.name from tor_horizon_user_group tor , to_horizon_user u where tor.user_id= u.id";
250
+        List<Map<String, Object>> userMap = Access.getMultiMap(userSql, null, dbIdentifier);
251
+        Map<String, List<User>> usersAndGroup = new HashMap<String, List<User>>();
252
+        for (Map<String, Object> map : userMap) {
253
+            List<User> users = new ArrayList<User>();
254
+            String id = map.get("id") == null ? "" : map.get("id").toString();
255
+            String userName = map.get("name") == null ? "" : map.get("name").toString();
256
+            String workGroupId = map.get("workgroup_id") == null ? "" : map.get("workgroup_id").toString();
257
+            if (id != null) {//避免出现空指针错误,如此处ID与users方法中的userid不一致也会出现空指针错误
258
+                if (usersAndGroup.get(workGroupId) == null) {//第一次操作岗位信息
259
+                    User user = new User();
260
+                    user.setId(id);
261
+                    user.setUserName(userName);
262
+                    users.add(user);
263
+                    usersAndGroup.put(workGroupId, users);
264
+                } else {//已有岗位信息,进行从新编辑
265
+                    users = usersAndGroup.get(workGroupId);
266
+                    User user = new User();
267
+                    user.setId(id);
268
+                    user.setUserName(userName);
269
+                    users.add(user);
270
+                    usersAndGroup.put(workGroupId, users);
271
+                }
272
+            }
273
+        }
274
+        return usersAndGroup;
275
+    }
276
+
277
+
278
+    @Override
279
+    public List<User> users() {
280
+        String dbIdentifier = "sgiip";
281
+        //id,用户唯一id;  login_name,用户登录名;   name,用户姓名;  dept_id,用户所属部门id ;
282
+//        String sql="SELECT u.id,u.LOGIN_NAME,'F;D' as type,u.NAME,tor.DEPT_ID FROM TO_HORIZON_USER u,TOR_HORIZON_USER_DEPT tor WHERE u.ID = tor.USER_ID";
283
+
284
+        String sql = "";
285
+        sql += "  SELECT u.id,u.user_name as LOGIN_NAME,u.user_desc as NAME,tor.DEPT_ID ,'' as type FROM sgiip.sys_user u,sgiip.sys_user_department tor WHERE u.ID = tor.USER_ID";
286
+        sql += "  union all";
287
+        sql += " select '1' as id ,'admin' as login_name  ,'超级管理员' as NAME ,'0' as DEPT_ID  ,'' as type from dual";
288
+
289
+        //从数据库获取用户信息
290
+        List<Map<String, Object>> usermap = Access.getMultiMap(sql, null, dbIdentifier);
291
+        //用户信息保存到datas集合对象中返回
292
+        List<User> datas = Lists.newArrayList();
293
+        for (Map<String, Object> map : usermap) {
294
+            String id = map.get("id") == null ? "" : map.get("id").toString();
295
+            String name = map.get("name") == null ? "" : map.get("name").toString();
296
+            String loginName = map.get("login_name") == null ? "" : map.get("login_name").toString();
297
+            String deptid = map.get("dept_id") == null ? "" : map.get("dept_id").toString();
298
+
299
+            //处理用户所属部门,可以所属多个部门
300
+            List<String> listDept = Lists.newArrayList(deptid);
301
+//            listDept.add(deptid);
302
+            //用户信息保存到User类的对象中
303
+            User u = new User();
304
+            u.setId(id);
305
+            u.setUserName(name);
306
+            u.setLoginName(loginName);
307
+            u.setPasswd("1234");//密码,一般设置默认统一的密码
308
+            u.setDepartment(listDept);
309
+            u.setOrderNo(1);//用户排序,可选
310
+
311
+            if(Objects.equals(id, "24F955A08CD8CDECE063040011AC9F7F") && listDept.contains("25855EBF0D906250E063040011ACA98F")){
312
+                u.setOperType("F");//用户类型(F:直接部门领导,C:上级主管领导,I:部门管理员,空:一般用户,可传多值,多值用;隔开)
313
+            }else {
314
+                u.setOperType("");//用户类型(F:直接部门领导,C:上级主管领导,I:部门管理员,空:一般用户,可传多值,多值用;隔开)
315
+            }
316
+            datas.add(u);
317
+        }
318
+        return datas;
319
+    }
320
+}

+ 0
- 5
src/main/java/com/horizon/org/web/OrgSysController.java Voir le fichier

@@ -1,17 +1,12 @@
1 1
 package com.horizon.org.web;
2 2
 
3
-import javax.servlet.http.HttpServletRequest;
4
-import javax.servlet.http.HttpServletResponse;
5
-
6 3
 import com.horizon.third.init.WorkflowAdapterInit;
7 4
 import org.springframework.stereotype.Controller;
8
-import org.springframework.web.bind.annotation.ModelAttribute;
9 5
 import org.springframework.web.bind.annotation.RequestMapping;
10 6
 import org.springframework.web.bind.annotation.RequestMethod;
11 7
 import org.springframework.web.bind.annotation.ResponseBody;
12 8
 
13 9
 import com.alibaba.fastjson.JSON;
14
-import com.horizon.wf.bean.WorkParaBeanBase;
15 10
 import com.horizon.workflow.rest.web.base.RestSuperController;
16 11
 
17 12
 @Controller

+ 305
- 0
src/main/java/com/horizon/wf/action/ActionGetBack.java Voir le fichier

@@ -0,0 +1,305 @@
1
+package com.horizon.wf.action;
2
+
3
+
4
+import com.horizon.wf.action.base.BaseAction;
5
+import com.horizon.wf.core.node.INextNode;
6
+import com.horizon.wf.core.node.ITaskNode;
7
+import com.horizon.wf.core.runtime.RunningData;
8
+import com.horizon.wf.core.work.ICustomAction;
9
+import com.horizon.wf.definition.pub.IFlowNode;
10
+import com.horizon.wf.definition.pub.node.INodeControl;
11
+import com.horizon.wf.definition.tools.NodeTypeEnum;
12
+import com.horizon.wf.entity.db.DBTodo;
13
+import com.horizon.wf.entity.db.DBTrack;
14
+import com.horizon.wf.entity.db.DBWorkAuth;
15
+import com.horizon.wf.global.CollectionUtil;
16
+import com.horizon.wf.global.StaticVarExtend;
17
+import com.horizon.wf.global.StringUtilExtend;
18
+import com.horizon.wf.tools.AccessUtil;
19
+
20
+import java.util.ArrayList;
21
+import java.util.LinkedHashMap;
22
+import java.util.List;
23
+import java.util.Map;
24
+
25
+/**
26
+ * 正常拿回操作实现类
27
+ * **不支持节点内部拿回
28
+ * 此类为同一路径下的节点间拿回,从分支和合并节点拿回时,系统在获取操作时,
29
+ * 自动对操作实现类进行重置为ActionGetBackForBranch和ActionGetBackForMerger
30
+ * @author liys
31
+ * @version 1.0
32
+ * @since v7.2.2
33
+ */
34
+public class ActionGetBack extends BaseAction implements ICustomAction {
35
+    private List<INextNode> nextNodes =null;
36
+    /**
37
+     * 操作调用的方法
38
+     */
39
+    public boolean execute(ITaskNode curTaskNode) {
40
+
41
+        runningdata.setFunname(StaticVarExtend.OPERATOR_FUNNAME_GETBACK);
42
+        setActionname("GetBack_Msg0001","拿回");
43
+        if(isGetBack()){
44
+            msg = pubInfo.getInfo("GetBack_Msg0002", "拿回成功");
45
+            getCurTrack().setFlowstatus(StaticVarExtend.FlowStatus_GetBack);
46
+            //将办理人设置的交互对象中,供节点进入事件使用
47
+            selectedUsers = new LinkedHashMap<String, String>();
48
+
49
+            //将当前人员放到人员列表中
50
+            selectedUsers.put(StaticVarExtend.AUTH_AUTHOR,  getCurUser().getFullName());
51
+            /**
52
+             * 20160711 liys
53
+             * 拿回分为以下几种情况:
54
+             * 1.同一路径内流转时的拿回,例如:(N1->N2->N3),N2的办理人在流转到N3节点时执行拿回
55
+             * 2.路径出现分支时,各分支未处理之前,例如:(N1->N2,N1->N3),N1的办理人在N2或者N3上执行拿回,
56
+             *   每次只能拿回一个分支,拿回后的N1其实是在分支路径上,而不是在分支之前的路径上
57
+             */
58
+            //将本来的主办人都设置为读者
59
+            List<DBWorkAuth> curAuth = runningdata
60
+                    .getListAuthLikeAuthorByTrackid(getCurTrack().getId());
61
+//			curAuth.addAll(getXAuthList(StaticVarExtend.AUTH_SECOND_AUTHOR));
62
+            for(int i=0,n=curAuth.size();i<n;i++){
63
+                DBWorkAuth a  = curAuth.get(i);
64
+                //更改其余办理人权限
65
+                a.setStatus(StaticVarExtend.AUTH_CREADER);
66
+            }
67
+
68
+            //将处理好的人员列表放回底层
69
+            runningdata.setCurAuthToMap(curAuth);
70
+            curTaskNode.backToPrevNode(nextNodeList, selectedUsers);
71
+            INextNode curNode = curTaskNode.getCurNode();
72
+            result = curNode.getInitResult();
73
+            msg = curNode.getBackMsg();
74
+            if(result == StaticVarExtend.F_STATUS_Success){
75
+                nextNodes = curTaskNode.getGNextNodes();
76
+                getCurTrack().setEnd(true);//结束当前路径
77
+                ac.dowithTimer("cancel", getCurNodeType(), runningdata, getIdentifier());//如果当前节点包含定时任务则撤销定时任务
78
+
79
+                //2024-2-19 触发进入事件,如果同时想触发进入事件和离开事件,参数传递true
80
+                doWithNextNodeResult(false);
81
+
82
+                //执行操作完成事件
83
+                if(executeEventSave()){
84
+//					selectedUsers = ac.makeAgentUser(selectedUsers, runningdata);
85
+                    runningdata.setUpdateTask(true);
86
+                    msg = pubInfo.getInfo("GetBack_Msg0002", "拿回成功");
87
+                    memoBuffer.append(msg);
88
+                }
89
+            }
90
+        }
91
+        getCurTrack().setFlowstatus(StaticVarExtend.FlowStatus_GetBack);
92
+        runningdata.setBackMsg(msg);
93
+        runningdata.setResultCode(result);
94
+        return true;
95
+    }
96
+
97
+    /**
98
+     * 判断是否允许拿回
99
+     * @return
100
+     */
101
+    protected boolean isGetBack(){
102
+        if(!isNodeGetBack()){//节点不在可拿回节点的类型范围之内
103
+            result = StaticVarExtend.F_STATUS_OtherError;
104
+            msg = pubInfo.getInfo("GetBack_Msg0003","当前节点不在可拿回的节点类型范围之内");
105
+            return false;
106
+        }else if(isDone()){//当前流程已经办理,无法拿回
107
+            result = StaticVarExtend.F_STATUS_OtherError;
108
+            msg = pubInfo.getInfo("GetBack_Msg0004","当前流程已经办理,无法拿回");
109
+            return false;
110
+        }else if(isSave()){//当前流程主办人已经暂存,无法拿回
111
+            result = StaticVarExtend.F_STATUS_OtherError;
112
+            msg = pubInfo.getInfo("GetBack_Msg0005","当前流程主办人已暂存,无法拿回");
113
+            return false;
114
+        }else if(getCurTrack().getFlowstatus() != StaticVarExtend.FlowStatus_Normal){
115
+            result = StaticVarExtend.F_STATUS_OtherError;
116
+            msg = pubInfo.getInfo("GetBack_Msg0006","当前流程状态不是正常状态,不允许拿回");
117
+            return false;
118
+        }
119
+
120
+        return true;
121
+    }
122
+
123
+
124
+    /**
125
+     * 判断当前节点类型是否允许拿回
126
+     * @return true:允许拿回
127
+     */
128
+    protected boolean isNodeGetBack(){
129
+        int nodetype = getCurNodeType();
130
+        if(nodetype == NodeTypeEnum.Node_Single
131
+                || nodetype == NodeTypeEnum.Node_Multi_Single
132
+                || nodetype == NodeTypeEnum.Node_Multi
133
+                || nodetype == NodeTypeEnum.Node_Order
134
+                || nodetype == NodeTypeEnum.Node_Progressively){
135
+            return true;
136
+        }
137
+        return false;
138
+    }
139
+
140
+    /**
141
+     * 判断当前节点是否已经暂存
142
+     * @return
143
+     */
144
+    protected boolean isSave(){
145
+
146
+        String sql="SELECT L.ACTION FROM TW_HZ_LOG L WHERE L.WORKID=? AND L.TRACKID=? ORDER BY L.ACTIONTIME DESC";
147
+        List<Object> con= new ArrayList<Object>();
148
+        con.add(getWorkid());
149
+        con.add(getCurTrackid());
150
+        List<List<Object>> workLogs= AccessUtil.getInstance().getMultiList(sql,con,getIdentifier());
151
+        if(null==workLogs || workLogs.isEmpty())return false;
152
+        if("Save".equals(workLogs.get(0).get(0).toString())){
153
+            return true;
154
+        }
155
+        return false;
156
+    }
157
+
158
+    /**
159
+     * 判断当前节点是否已经办理
160
+     * @return
161
+     */
162
+    protected boolean isDone(){
163
+        //获取会签人员和已办人员
164
+        List<DBWorkAuth> curAuth = getXAuthList(StaticVarExtend.AUTH_DONE);
165
+        curAuth.addAll(getXAuthList(StaticVarExtend.AUTH_HUIQIAN_AUTHOR));
166
+        curAuth.addAll(getXAuthList(StaticVarExtend.AUTH_START_HUIQIAN_AUTHOR));
167
+
168
+        return CollectionUtil.isListNotEmpty(curAuth);
169
+    }
170
+
171
+    /**
172
+     * 判断当前操作人是否为主办
173
+     * @return true:当前人是主办
174
+     */
175
+    private boolean isCurUserAuthor(){
176
+        List<DBWorkAuth> authors =  getXAuthList(StaticVarExtend.AUTH_AUTHOR);
177
+        for(int i=0,n=authors.size();i<n;i++){
178
+            DBWorkAuth a = authors.get(i);
179
+            if(a.equalsRunUser(getCurUser())){
180
+                return true;
181
+            }
182
+        }
183
+        return false;
184
+    }
185
+
186
+    /**
187
+     * 给task表添加数据
188
+     */
189
+    public Map<String,List<Object>>  actionForTask() {
190
+        Map<String, List<Object>> saveMap = new LinkedHashMap<String, List<Object>>();
191
+        actionForTask(saveMap);
192
+        //下一节点任务创建
193
+        for(int i=0,n=runningdata.getNextTrackList().size();i<n;i++){
194
+            DBTrack tTrack = runningdata.getNextTrackList().get(i);
195
+            createTaskObj(null,tTrack,saveMap);
196
+        }
197
+        return saveMap;
198
+    }
199
+    /**
200
+     * 取消分支时调用
201
+     */
202
+    public void cancelTrackAction(String arg0, List<DBWorkAuth> arg1) {
203
+
204
+    }
205
+
206
+    /**
207
+     * 当取消某个路径的激活状态时,对应的权限变化规则设定<br>
208
+     * (比如把待办的状态改为只读,或者是删除,或者忽略)<br>
209
+     * 如果不指定,则忽略权限变更(比如Reader不需要处理)<br>
210
+     * 主要用于合并节点提交时,如果有其他分支未到达时,对未到达的分支的参与者进行处理<br>
211
+     * @return key=修改前的权限名称(比如:办理人Author),value=修改后的权限名称(比如:只读权限CReader)
212
+     */
213
+    public Map<String,String> getCancelTrackAuthRuleMap(){
214
+        return null;
215
+    }
216
+    /**
217
+     * 保存之后的接口方法.例如:消息数据的更新
218
+     */
219
+    public void actionAfterSaveToDB() {
220
+        if(isNotSaveToDB){
221
+            return;
222
+        }
223
+        actionStartTodoThread();
224
+    }
225
+    /**
226
+     * 保存数据之前的接口方法.例如:消息数据的处理
227
+     * key=sql,value=parameter
228
+     */
229
+    public Map<String,List<Object>> actionBeforeSaveToDB() {
230
+        Map<String, List<Object>> saveMap = new LinkedHashMap<String, List<Object>>();
231
+        sendTodo();
232
+        actionBefore(saveMap);
233
+        return saveMap ;
234
+    }
235
+    /**
236
+     * 当前节点权限处理(由操作再次干预参与者的接口)<br>
237
+     * auths列表中为系统节点默认处理完毕后的当前节点的参与者列表
238
+     * 对应的消息是否需要处理,可以在这个方法中写
239
+     */
240
+    public boolean chgCurNodeAuth(List<DBWorkAuth> auths) {
241
+        if(CollectionUtil.isListNotEmpty(auths)){
242
+            makeSendInfoByCurAuthList(auths);
243
+        }
244
+
245
+        return true;
246
+    }
247
+    /**
248
+     * 重写父类待办发送方法
249
+     * 给当前办理人发送待阅
250
+     */
251
+    protected void sendTodo(){
252
+        String getbackNodeId = getGetBackNode(runningdata);
253
+        if(StringUtilExtend.isNotNull(getbackNodeId)){
254
+            if(isTrackByNodeId(getbackNodeId, StaticVarExtend.FlowStatus_Reject, getWorkid(), getIdentifier())){
255
+                runningdata.putMsgToConsole("[msg]this node have track.");
256
+                return;
257
+            }
258
+        }
259
+
260
+        String todoUser = selectedUsers.get(StaticVarExtend.AUTH_AUTHOR);
261
+        DBTodo todo = makeDefaultDBTodo();
262
+        String nodeid="";
263
+        if(nextNodes != null){
264
+            nodeid = nextNodes.get(0).getNodeid();
265
+        }
266
+        IFlowNode node = runningdata.getInstanceDefinition().getFlowinfo().getNodeById(nodeid);
267
+        DBTrack track = getTrackIdByNodeId(nodeid);
268
+        makeSendInfoForNewAuth(todo,todoUser,StaticVarExtend.AUTH_AUTHOR,StaticVarExtend.Send_Todo,
269
+                null,track,node);
270
+    }
271
+    /**
272
+     * 在指定节点是否有指定状态的track
273
+     * @param nodeid
274
+     * @param status
275
+     * @param workid
276
+     * @param identifier
277
+     */
278
+    private boolean isTrackByNodeId(String nodeid, int status, String workid, String identifier){
279
+        String sql = "SELECT id FROM " + StaticVarExtend.Table_Track +" WHERE WORKID=? AND NODEID=? AND FLOWSTATUS=?";
280
+        List<Object> conditionList = new ArrayList<Object>();
281
+        conditionList.add(workid);
282
+        conditionList.add(nodeid);
283
+        conditionList.add(status);
284
+        int count = AccessUtil.getInstance().getRsCount(sql, conditionList, identifier);
285
+        if(count == 0){
286
+            return false;
287
+        }
288
+        return true;
289
+    }
290
+    /**
291
+     * 当前节点是否为上一节点,拿回操作调用
292
+     * @return
293
+     */
294
+    private String getGetBackNode(RunningData rd){
295
+        IFlowNode node = rd.getCurFlowNode();
296
+        INodeControl control = node.getParticipantsControl(StaticVarExtend.AUTH_DONE+"_DO");
297
+        String allNodes = "";
298
+        if(null != control){
299
+            allNodes = control.getAllowGetBackNode();
300
+        }
301
+        //获取上一节点
302
+        return allNodes;
303
+    }
304
+
305
+}

+ 744
- 0
src/main/java/com/horizon/wf/action/ActionSubmit.java Voir le fichier

@@ -0,0 +1,744 @@
1
+package com.horizon.wf.action;
2
+
3
+import com.horizon.wf.action.base.BaseForTask;
4
+import com.horizon.wf.action.base.IActionForStartSubFlow;
5
+import com.horizon.wf.action.base.SubflowEnd;
6
+import com.horizon.wf.config.HZResourceBundle;
7
+import com.horizon.wf.core.node.INextNode;
8
+import com.horizon.wf.core.node.ITaskNode;
9
+import com.horizon.wf.core.runtime.RunningData;
10
+import com.horizon.wf.core.track.json.impl.ITrackJson;
11
+import com.horizon.wf.core.work.ICustomAction;
12
+import com.horizon.wf.definition.pub.IFlowInfo;
13
+import com.horizon.wf.definition.pub.IFlowNode;
14
+import com.horizon.wf.definition.pub.node.INodeControl;
15
+import com.horizon.wf.definition.pub.node.INodeForm;
16
+import com.horizon.wf.definition.pub.node.INodeRouter;
17
+import com.horizon.wf.definition.tools.NodeTypeEnum;
18
+import com.horizon.wf.entity.db.*;
19
+import com.horizon.wf.entity.user.INodeUser;
20
+import com.horizon.wf.expand.impl.IOrganizationInterface;
21
+import com.horizon.wf.global.*;
22
+import com.horizon.wf.plugins.PluginsUtil;
23
+import com.horizon.wf.rule.jsr94.IRuleEngine;
24
+
25
+import java.util.*;
26
+
27
+/**
28
+ * 提交操作实现类
29
+ *
30
+ * @author liys
31
+ * @version 1.0
32
+ * @since v7.0
33
+ */
34
+public class ActionSubmit extends BaseForTask implements ICustomAction,
35
+        IActionForStartSubFlow {
36
+    private List<INextNode> nextNodes = new ArrayList<INextNode>();
37
+    private boolean isSendTodo = true;// 是否发送待办
38
+    private boolean isMakeTaskData = true;// 是否生成task数据
39
+    private SubflowEnd subflowEnd = null;// 子流程实例结束时,主流程是否可以往下流转处理类
40
+
41
+    /**
42
+     * 本操作需要执行的内容
43
+     */
44
+    public boolean execute(ITaskNode curTaskNode) {
45
+        setFunnameToRunningdata();
46
+
47
+        // 提交到退回节点时,如果需要重新选择办理人,则把下面的赋值语句打开即可,不打开则获取退回节点的原来办理人(包含没有办理的人)
48
+        if (runningdata.getCurTrack().getFlowstatus() == StaticVarExtend.FlowStatus_Reject) {
49
+            runningdata.getCurTrack().setFlowstatus(
50
+                    StaticVarExtend.FlowStatus_Normal);
51
+        }
52
+        normalSubmit(curTaskNode);
53
+        // 执行操作完成事件
54
+        if (StaticVarExtend.F_STATUS_Success == result && executeEventSave()) {
55
+            handleFirstStart();// 处理第一次操作的 权限
56
+            if (actionSuccess(resultBean.getNextNodes())) {
57
+                runningdata.setUpdateTask(true);
58
+                if("Start".equals(curTaskNode.getNodeid()) && !HZResourceBundle.getInstance().isSaveToDBWhenStartInstance()){
59
+                    // 开始节点只有没有业务表单
60
+                    String[] formids={"FlowTrack"};
61
+                    runningdata.getInitData().setFormids(formids);
62
+                }else{
63
+                    // 获取当前人有权限的表单
64
+                    runningdata.getInitData().setFormids(
65
+                            ac.setFormIdsByRunningdata(getCurFlowNode(),
66
+                                    getCurUser()));
67
+                }
68
+
69
+            } else {
70
+                result = StaticVarExtend.F_STATUS_OtherError;
71
+            }
72
+        }
73
+
74
+        runningdata.setBackMsg(msg);
75
+        runningdata.setResultCode(result);
76
+        return true;
77
+    }
78
+
79
+    protected void setFunnameToRunningdata() {
80
+        runningdata.setFunname(StaticVarExtend.OPERATOR_FUNNAME_SUBMIT);
81
+        setActionname("Submit_Msg0001", "提交");
82
+    }
83
+
84
+    /**
85
+     * 处理第一次操作
86
+     */
87
+    private void handleFirstStart() {
88
+        List<DBWorkAuth> auths = new ArrayList<DBWorkAuth>();
89
+        DBTrack track = runningdata.getCurTrack();
90
+        IFlowNode curNode = runningdata.getCurFlowNode();
91
+        // 是否第一次操作
92
+        if (isnewdoc < 2) {
93
+            isNewDoc("2");
94
+            // 全局读者
95
+            String flowreaders = changeReaderList(runningdata);
96
+            if (StringUtilExtend.isNotNull(flowreaders)) {
97
+                auths.add(makeAuthByAuthId(flowreaders,
98
+                        StaticVarExtend.AUTH_READER, ""));
99
+
100
+                // 增加发送消息
101
+                DBTodo frTodo = makeDefaultDBTodo();
102
+                frTodo.setAuthId(flowreaders);
103
+                frTodo.setTrackactive(String.valueOf(track.getActive()));
104
+                frTodo.setTrackid(track.getId());
105
+                frTodo.setTrackstatus(String.valueOf(track.getFlowstatus()));
106
+                frTodo.setNodeid(getCurNodeid());
107
+                frTodo.setNodename(track.getNodename());
108
+                frTodo.setWorkver((track.getVersion() + 1));
109
+
110
+                IFlowInfo flowInfo = runningdata.getInstanceDefinition()
111
+                        .getFlowinfo();
112
+                String msgType = flowInfo.getReaderMsg();
113
+
114
+                String dMsg = StaticVarExtend.Send_Read;
115
+                // 20150727 liys 修改为默认发送待阅消息,不管定义是否勾选
116
+                DBTodo nTodo = frTodo.copy();
117
+                nTodo.setTitle(ac.getTodoTitle(track.getId(), curNode,
118
+                        runningdata, dMsg, StaticVarExtend.AUTH_READER));
119
+                nTodo.setStatus(StaticVarExtend.AUTH_READER);
120
+                todoLst.add(nTodo);
121
+
122
+                String[] msgSendTypes = msgType
123
+                        .split(StaticVarExtend.StrSplitChar);
124
+                for (String str : msgSendTypes) {
125
+                    if (null == str || "".equals(str)
126
+                            || str.equalsIgnoreCase(dMsg)) {
127
+                        continue;
128
+                    }
129
+                    DBTodo oTodo = frTodo.copy();
130
+                    oTodo.setTitle(ac.getTodoTitle(track.getId(), curNode,
131
+                            runningdata, str, StaticVarExtend.AUTH_READER));
132
+                    oTodo.setStatus("");
133
+                    oTodo._setOtherstatus(str);
134
+                    todoLst.add(oTodo);
135
+                }
136
+
137
+            }
138
+
139
+            if (isnewdoc == 0) {
140
+                String doneId = getCurUser().getFullName();
141
+                // 增加创建者权限
142
+                DBWorkAuth creator = makeAuthByAuthId(doneId,
143
+                        StaticVarExtend.AUTH_CREATOR, "");
144
+                creator.setAuthType(StaticVarExtend.UserFix);
145
+                auths.add(creator);
146
+            }
147
+
148
+        }
149
+        if (!auths.isEmpty()) {
150
+            runningdata.setCurAuthToMap(auths);
151
+        }
152
+    }
153
+
154
+    /**
155
+     * 将全局读者的list转换成string
156
+     * @return 转换后的字符串
157
+     */
158
+    private String changeReaderList(RunningData rd) {
159
+        StringBuilder readers = new StringBuilder("");
160
+        String dataIdentifier = rd.getInitData().getDataIdentifier();
161
+        List<String> readersList = rd.getInstanceDefinition().getFlowinfo()
162
+                .getReader();
163
+        IOrganizationInterface organization = PluginsUtil.getMultiInstance().getOrganization(rd.getInitData().getTenantid());
164
+        if (CollectionUtil.isListNotEmpty(readersList)) {
165
+            // 个人,无前缀
166
+            if (StringUtilExtend.isNotNull(readersList.get(0))) {
167
+                String[] persons = readersList.get(0).split(
168
+                        StaticVarExtend.UserSplitChar);
169
+                for (String s : persons) {
170
+                    if(!s.startsWith(StaticVarExtend.UserFix+StaticVarExtend.Mark_Fix)){
171
+                        readers.append(StaticVarExtend.UserFix).append(StaticVarExtend.Mark_Fix);
172
+                    }
173
+                    readers.append(s).append(StaticVarExtend.UserSplitChar);
174
+                }
175
+            }
176
+            // 部门,有前缀
177
+            if (StringUtilExtend.isNotNull(readersList.get(1))) {
178
+                String[] depts = readersList.get(1).split(
179
+                        StaticVarExtend.UserSplitChar);
180
+                for (String s : depts) {
181
+                    if(!(s.startsWith(StaticVarExtend.DeptFix+StaticVarExtend.Mark_Fix)
182
+                            || s.startsWith(StaticVarExtend.DeptSubFix+StaticVarExtend.Mark_Fix))){
183
+                        if(s.startsWith("DF_") || s.startsWith("DL_") || s.startsWith("DJ_")) {
184
+                            String deptType = s.substring(0, 2);
185
+                            String deptId = s.substring(3);
186
+                            String type = null;
187
+                            if ("DJ".equals(deptType)){
188
+                                type = "I";
189
+                            }else if ("DL".equals(deptType)){
190
+                                type = "C";
191
+                            }else if ("DF".equals(deptType)){
192
+                                type = "F";
193
+                            }
194
+                            String userId = organization.getDeptSpecialUser(deptId, type, dataIdentifier);
195
+                            if (StringUtilExtend.isNotNull(userId)) {
196
+                                readers.append(StaticVarExtend.UserFix).append(StaticVarExtend.Mark_Fix).append(userId);
197
+                            }
198
+                            readers.append(StaticVarExtend.SubjectionFix);
199
+                            readers.append(StaticVarExtend.DeptFix).append(StaticVarExtend.Mark_Fix).append(deptId).append(StaticVarExtend.UserSplitChar);
200
+                        }else{
201
+                            readers.append(StaticVarExtend.SubjectionFix);
202
+                            readers.append(StaticVarExtend.DeptFix).append(StaticVarExtend.Mark_Fix).append(s).append(StaticVarExtend.UserSplitChar);;
203
+                        }
204
+                    }else {
205
+                        readers.append(StaticVarExtend.SubjectionFix).append(s).append(StaticVarExtend.UserSplitChar);
206
+                    }
207
+                }
208
+            }
209
+            // 群组,无前缀
210
+            if (StringUtilExtend.isNotNull(readersList.get(2))) {
211
+                String[] groups = readersList.get(2).split(
212
+                        StaticVarExtend.UserSplitChar);
213
+                for (String s : groups) {
214
+                    readers.append(StaticVarExtend.SubjectionFix);
215
+                    if(!s.startsWith(StaticVarExtend.GroupFix+StaticVarExtend.Mark_Fix)){
216
+                        readers.append(StaticVarExtend.GroupFix).append(StaticVarExtend.Mark_Fix);
217
+                    }
218
+                    readers.append(s).append(StaticVarExtend.UserSplitChar);
219
+                }
220
+            }
221
+            // 角色,无前缀
222
+            if (StringUtilExtend.isNotNull(readersList.get(3))) {
223
+                String[] roles = readersList.get(3).split(
224
+                        StaticVarExtend.UserSplitChar);
225
+                for (String s : roles) {
226
+                    readers.append(StaticVarExtend.SubjectionFix);
227
+                    if(!s.startsWith(StaticVarExtend.RoleFix+StaticVarExtend.Mark_Fix)){
228
+                        readers.append(StaticVarExtend.RoleFix).append(StaticVarExtend.Mark_Fix);
229
+                    }
230
+                    readers.append(s).append(StaticVarExtend.UserSplitChar);
231
+                }
232
+            }
233
+            // 岗位,无前缀
234
+            if (StringUtilExtend.isNotNull(readersList.get(4))) {
235
+                String[] positions = readersList.get(4).split(
236
+                        StaticVarExtend.UserSplitChar);
237
+                for (String s : positions) {
238
+                    readers.append(StaticVarExtend.SubjectionFix);
239
+                    if(!s.startsWith(StaticVarExtend.PosFix+StaticVarExtend.Mark_Fix)){
240
+                        readers.append(StaticVarExtend.PosFix).append(StaticVarExtend.Mark_Fix);
241
+                    }
242
+                    readers.append(s).append(StaticVarExtend.UserSplitChar);
243
+                }
244
+            }
245
+        }
246
+
247
+        String readerScript = rd.getInstanceDefinition().getFlowinfo()
248
+                .getReaderRuleScript();
249
+        if (StringUtilExtend.isNotNull(readerScript)) {
250
+            try {
251
+                IRuleEngine du = PluginsUtil.getMultiInstance().getRuleEngine();
252
+                du.setPara("RunningData", rd);
253
+
254
+                Object rs = du.exctu(readerScript);
255
+                if (null != rs) {
256
+                    readers.append(String.valueOf(rs));
257
+                }
258
+            } catch (Exception e) {
259
+                rd.putMsgToConsole("[err]get readerScript error!");
260
+            }
261
+        }
262
+        return readers.toString();
263
+    }
264
+
265
+    /**
266
+     * 根据authId生成auth对象
267
+     *
268
+     * @param authId
269
+     * @return
270
+     */
271
+    private DBWorkAuth makeAuthByAuthId(String authId, String status,
272
+                                        String oldStatus) {
273
+        DBWorkAuth a = new DBWorkAuth();
274
+        a.setAuthId(authId);
275
+        a.setAuthNo(0);
276
+        a.setNodeid(getCurNodeid());
277
+        a.setNodenum(0);
278
+        a.setStatus(status);
279
+        a.setOldStatus(oldStatus);
280
+
281
+        a.setTrackid(getCurTrackid());
282
+        a.setVersion(0);
283
+        a.setWorkid(getWorkid());
284
+        return a;
285
+    }
286
+
287
+    /**
288
+     * 正常提交(准备离开当前节点的提交)
289
+     *
290
+     * @param curTaskNode
291
+     */
292
+    private void normalSubmit(ITaskNode curTaskNode) {
293
+        runningdata.putMsgToConsole("[msg]docurNode start.");
294
+        boolean curResult = curTaskNode.doCurNode();
295
+        runningdata.putMsgToConsole("[msg]docurNode end.reulst:" + result);
296
+        // 前台参数
297
+        if (curResult) {// false时为当前节点不允许离开 如多人处理
298
+            leaveThisNode(curTaskNode, false);
299
+        } else {// 不离开当前节点
300
+            result = curTaskNode.getCurNode().getInitResult();
301
+            if (StaticVarExtend.F_STATUS_Success == result) {
302
+                msg = pubInfo.getInfo("Action_Msg0004", "提交成功");
303
+
304
+                int curNodeType = getCurNodeType();
305
+                // 当前节点是顺签和逐级办理的时候将办理人置于selectUsers用来发送待办
306
+                if (curNodeType == NodeTypeEnum.Node_Order
307
+                        || curNodeType == NodeTypeEnum.Node_Progressively) {
308
+                    List<INodeUser> nodeUserList = curTaskNode.getCurNode()
309
+                            .getListUserByNodeInit();
310
+                    for (int i = 0, n = nodeUserList.size(); i < n; i++) {
311
+                        INodeUser nu = nodeUserList.get(i);
312
+                        String key = curTaskNode.getCurNode().getKeyid()
313
+                                + StaticVarExtend.MARK_NODE_USER
314
+                                + nu.getAuthType();
315
+                        selectedUsers.put(key, nu.getNowid());
316
+                    }
317
+                    if (curNodeType == NodeTypeEnum.Node_Order) {
318
+                        memoBuffer.append(pubInfo.getInfo("Submit_Msg0006",
319
+                                "顺签办理"));
320
+                    } else {
321
+                        memoBuffer.append(pubInfo.getInfo("Submit_Msg0007",
322
+                                "逐级审批"));
323
+                    }
324
+                    doMemoFromSelected(curTaskNode.getCurNode());
325
+                } else if (curNodeType == NodeTypeEnum.Node_Merger) {
326
+                    result = StaticVarExtend.F_STATUS_UnitSubmit;
327
+                    msg = pubInfo.getInfo("Submit_Msg0002", "不符合离开规则,不能离开当前节点");
328
+                } else if (curNodeType == NodeTypeEnum.Node_Multi) {// 多人处理时将剩余办理人置于selectedUsers供前台显示
329
+                    isSendTodo = false;
330
+                    // 并行处理,等待其他人办理
331
+                    memoBuffer.append(pubInfo.getInfo("Submit_Msg0008",
332
+                            "多人处理,等待其他人办理"));
333
+                }
334
+                isMakeTaskData = false;// 不离开当前节点,不执行task表写入
335
+            }
336
+            // else if(StaticVarExtend.F_STATUS_SelectAuthor == result){
337
+            // //只有内部循环节点才会出现
338
+            //
339
+            // }
340
+            // else if(StaticVarExtend.F_STATUS_SelectNode == result){
341
+            // //只有内部循环节点才会出现
342
+            // leaveThisNode(curTaskNode,true);
343
+            // }
344
+            else {
345
+                msg = curTaskNode.getCurNode().getBackMsg();
346
+            }
347
+
348
+        }
349
+    }
350
+
351
+    /**
352
+     * 离开当前节点 addCurNode,是否增加当前节点到选择列表中
353
+     */
354
+    private void leaveThisNode(ITaskNode curTaskNode, boolean addCurNode) {
355
+        // 获取传入的下一节点和办理人信息
356
+        initNextNodePara();
357
+        leaveByRouter(curTaskNode);
358
+        if (result == StaticVarExtend.F_STATUS_Success) {
359
+            if (CollectionUtil.isListEmpty(nextNodes)) {
360
+                result = runningdata.getResultCode();
361
+                msg = runningdata.getBackMsg();
362
+                return;
363
+            }
364
+            doWithNextNodeResult(true);
365
+        }
366
+
367
+        // 20150513增加下一节点按路由序号排序
368
+        sortNextNodes();
369
+
370
+        resultBean.setNextNodes(nextNodes);// (curTaskNode.getGNextNodes());
371
+        StringBuilder sb = new StringBuilder(1000);
372
+        memoBuffer.append(pubInfo.getInfo("Submit_Msg0009", "提交到节点"));
373
+        for (int i = 0, m = nextNodes.size(); i < m; i++) {
374
+            INextNode n = nextNodes.get(i);
375
+            if (n.isSelected()) {
376
+                sb.append(StaticVarExtend.MARK_NODE_SPLIT).append(
377
+                        n.getSelectedIdStr());
378
+                doMemoFromSelected(n);
379
+            }
380
+        }
381
+        if (sb.length() > 0) {
382
+            sb.deleteCharAt(0);
383
+            nextNodeId = sb.toString();
384
+
385
+        }
386
+    }
387
+
388
+    private void leaveByRouter(ITaskNode curTaskNode) {
389
+        runningdata.putMsgToConsole("[msg]leaveByRouter start.");
390
+        // 没有传入选择节点内容时,系统默认根据定义查找下一节点
391
+        // 前台选择人员设置格式:key=节点id_参与者类型(Author,reader),value=userid(多个使用分号|)
392
+        // 此处传入的参数在节点进入规则接口中使用
393
+        if (checkForFree()) {
394
+            return;
395
+        }
396
+        curTaskNode.leaveByRouter(nextNodeList, selectedUsers);
397
+        result = curTaskNode.getCurNode().getInitResult();
398
+        int initResult = runningdata.getResultCode();
399
+        if (initResult != StaticVarExtend.F_STATUS_Success) {
400
+            initResult = runningdata.getResultCode();
401
+            msg = runningdata.getBackMsg();
402
+            return;
403
+        }
404
+        msg = curTaskNode.getCurNode().getBackMsg();
405
+        nextNodes = curTaskNode.getGNextNodes();// 获取符合条件的节点列表
406
+        runningdata.putMsgToConsole("[msg]leaveByRouter end.result:"
407
+                + initResult + ";msg:" + msg);
408
+    }
409
+
410
+    /**
411
+     * 自由提交时,用于检查节点是否有需要增加节点的处理 返回true表示终止程序
412
+     *
413
+     * @return
414
+     */
415
+    protected boolean checkForFree() {
416
+        return false;
417
+    }
418
+
419
+    /**
420
+     * 拿回状态,提交时直接给拿回之前的节点 下一节点进行处理
421
+     */
422
+    void doForGetBack(ITaskNode curTaskNode) {
423
+        DBTrack track = getCurTrack();
424
+        if (track.getFlowstatus() == StaticVarExtend.FlowStatus_GetBack) {
425
+            runningdata.putMsgToConsole("[msg]flowstatus = getback");
426
+            ITrackJson xmlTrack = track._getTrackJson();
427
+            String doneNodeID = xmlTrack.getTrueRecord();
428
+            String[] nodes = doneNodeID.split(StaticVar.StrSplitChar);
429
+            // 获取拿回前的节点
430
+            if (nodes.length > 1) {
431
+                List<INodeRouter> routers = curTaskNode.getFlowNode()
432
+                        .getAllToRouters();
433
+                String nodeid = nodes[nodes.length - 2];
434
+                for (int i = 0, n = routers.size(); i < n; i++) {
435
+                    INodeRouter router = routers.get(i);
436
+                    if (nodeid.equals(router.getNodeid())) {
437
+                        nextNodeId = router.getRouterid() + "~" + nodeid;
438
+                        break;
439
+                    }
440
+                }
441
+                if (StringUtilExtend.isNull(nextNodeId)) {
442
+                    // 拿回之前的节点跟当前节点无路由连接
443
+                    runningdata.putMsgToConsole("[msg]get back from jump node");
444
+                } else {
445
+                    // 重新初始化下一节点列表
446
+                    runningdata.putMsgToConsole("[msg]re init nextnodes");
447
+                    initNextNodePara();
448
+                }
449
+            }
450
+        }
451
+    }
452
+
453
+    private void sortNextNodes() {
454
+        List<INextNode> nodes = nextNodes;
455
+        List<INextNode> sortNodes = new ArrayList<INextNode>();
456
+        List<INextNode> tmpNode = new ArrayList<INextNode>();
457
+
458
+        for (int i = 0, n = nodes.size(); i < n; i++) {
459
+            INextNode node = nodes.get(i);
460
+            // 排序准备
461
+            INodeRouter tmpRouter = node.getFromXmlRouter();
462
+            if (tmpRouter == null) {
463
+                sortNodes.add(node);
464
+            } else {
465
+                tmpNode.add(node);
466
+            }
467
+        }
468
+        Collections.sort(tmpNode, new Comparator<INextNode>() {
469
+            public int compare(INextNode o1, INextNode o2) {
470
+                return o1.getFromXmlRouter().getSortnum()
471
+                        - o2.getFromXmlRouter().getSortnum();
472
+            }
473
+        });
474
+        sortNodes.addAll(tmpNode);
475
+
476
+        nextNodes = sortNodes;
477
+    }
478
+
479
+    // =================================================================================
480
+    /**
481
+     * 提交成功后执行 用于子流程结束时,对主流程的修改
482
+     *
483
+     * @param nextNodes2
484
+     */
485
+    private boolean actionSuccess(List<INextNode> nextNodes2) {
486
+        // 下一节点列表为空直接返回
487
+        if (CollectionUtil.isListEmpty(nextNodes2) || isNotSaveToDB) {
488
+            return true;
489
+        }
490
+        for (int i = 0, n = nextNodes2.size(); i < n; i++) {
491
+            INextNode nextNode = nextNodes2.get(i);
492
+            int nextNodeType = nextNode.getFlowNode().getNodetype();
493
+            if (ac.isEndNode(nextNodeType)) {
494
+                // 2016-03-17 liys 实例结束的情况下,对其他活动分支进行关闭
495
+                if (ac.isEndInstanceNode(nextNodeType)) {
496
+                    if(nextNodes2.size()>1){
497
+                        msg=pubInfo.getInfo("Action_Msg0014", "下节点路由包含实例结束节点不允许多选");
498
+                        return false;
499
+                    }
500
+                    runningdata.cancelOtherTrackForEndInstance(getCurTrackid());
501
+                }
502
+            } else if (nextNodeType == NodeTypeEnum.Node_Mutual) {
503
+                // 引擎交互节点,
504
+                if (!doWithMutualNode(nextNode)) {
505
+                    return false;
506
+                }
507
+            } else if (nextNodeType == NodeTypeEnum.Node_Sub) {
508
+                // 子流程节点,内嵌子流程时的处理
509
+                if (!doWithInnerSubFlow(nextNode)) {
510
+                    return false;
511
+                }
512
+            }
513
+        }
514
+        return true;
515
+    }
516
+
517
+    /**
518
+     * 引擎交互节点时,处理数据和相关任务
519
+     *
520
+     * @param node
521
+     * @return
522
+     */
523
+    private boolean doWithMutualNode(INextNode node) {
524
+        // 放到ActionExtraData.doWithNextNodesExtraData(RunningData,
525
+        // List<Object>)中处理
526
+        // 此处无法获确定trackid
527
+        return true;
528
+    }
529
+
530
+    /**
531
+     * 内嵌子流程启动处理
532
+     *
533
+     * @param node
534
+     * @return
535
+     */
536
+    private boolean doWithInnerSubFlow(INextNode node) {
537
+        // 放到ActionExtraData.doWithNextNodesExtraData(RunningData,
538
+        // List<Object>)中处理
539
+        return true;
540
+    }
541
+
542
+    /**
543
+     * 给task表添加数据
544
+     */
545
+    public Map<String, List<Object>> actionForTask() {
546
+        runningdata.putMsgToConsole("[msg]actionForTask start.");
547
+        Map<String, List<Object>> saveMap = new LinkedHashMap<String, List<Object>>();
548
+        if (!isMakeTaskData) {// 不执行task表的写入
549
+            return saveMap;
550
+        }
551
+        if (isNotSaveToDB
552
+                || paraBean.getFunname().equals(
553
+                StaticVarExtend.OPERATOR_FUNNAME_URGE)) {
554
+            return saveMap;
555
+        }
556
+        // 流程结束,无论是否配置删除版本,task都需要清理
557
+        if (runningdata.isFlowEnd()) {
558
+            // 20161122 liys 子流程结束时,对主流程的处理,由actionSuccess方法中移动到此处
559
+            // 可以避免子流程只是分支结束时,也对主流程的处理
560
+            subflowEnd = new SubflowEnd(this);
561
+            if (!subflowEnd.doWithSubFlowEnd()) {
562
+                // 结束节点时的额外处理
563
+                runningdata.setResultCode(StaticVarExtend.F_STATUS_OtherError);
564
+                return null;
565
+            }
566
+
567
+//			List<Object> para = new ArrayList<Object>(1);
568
+//			para.add(runningdata.getInitData().getWorkid());
569
+//			List<Object> lst = new ArrayList<Object>();
570
+//			lst.add(para);
571
+//			saveMap.put(
572
+//					("DELETE FROM " + StaticVarExtend.Table_Task + " WHERE WORKID=? "),
573
+//					lst);
574
+            DBTask.delSQLByWorkid(saveMap, runningdata.getResultJson(), runningdata.getWork().getId());
575
+            return saveMap;
576
+        }
577
+        actionForTask(saveMap);
578
+        // 下一节点任务创建
579
+        for (int i = 0, n = runningdata.getNextTrackList().size(); i < n; i++) {
580
+            DBTrack tTrack = runningdata.getNextTrackList().get(i);
581
+            createTaskObj(null, tTrack, saveMap);
582
+        }
583
+        runningdata.putMsgToConsole("[msg]actionForTask end.");
584
+        return saveMap;
585
+    }
586
+
587
+    // =================================================================================
588
+    /**
589
+     * 取消分支时调用
590
+     */
591
+    public void cancelTrackAction(String cancelTrackids, List<DBWorkAuth> auths) {
592
+        if (isNotSaveToDB) {
593
+            return;
594
+        }
595
+        makeSendInfoByCurAuthList(auths);
596
+    }
597
+
598
+    /**
599
+     * 当取消某个路径的激活状态时,对应的权限变化规则设定<br>
600
+     * (比如把待办的状态改为只读,或者是删除,或者忽略)<br>
601
+     * 如果不指定,则忽略权限变更(比如Reader不需要处理)<br>
602
+     * 主要用于合并节点提交时,如果有其他分支未到达时,对未到达的分支的参与者进行处理<br>
603
+     *
604
+     * @return key=修改前的权限名称(比如:办理人Author),value=修改后的权限名称(比如:只读权限CReader)
605
+     */
606
+    public Map<String, String> getCancelTrackAuthRuleMap() {
607
+        Map<String, String> map = new HashMap<String, String>();
608
+        if (!isNotSaveToDB) {
609
+            // 取消其他分支时,哪些权限需要变更,在map中设置即可
610
+            map.put(StaticVarExtend.AUTH_AUTHOR, StaticVarExtend.AUTH_CREADER);
611
+            map.put(StaticVarExtend.AUTH_SECOND_AUTHOR,
612
+                    StaticVarExtend.AUTH_CREADER);
613
+            map.put(StaticVarExtend.AUTH_START_HUIQIAN_AUTHOR,
614
+                    StaticVarExtend.AUTH_CREADER);
615
+            map.put(StaticVarExtend.AUTH_HUIQIAN_AUTHOR,
616
+                    StaticVarExtend.AUTH_CREADER);
617
+            map.put(StaticVarExtend.AUTH_SUBFLOW_AUTHOR,
618
+                    StaticVarExtend.AUTH_CREADER);
619
+        }
620
+        return map;
621
+    }
622
+
623
+    /**
624
+     * 当前节点权限处理(由操作再次干预参与者的接口)<br>
625
+     * auths列表中为系统节点默认处理完毕后的当前节点的参与者列表 对应的消息是否需要处理,可以在这个方法中写
626
+     */
627
+    public boolean chgCurNodeAuth(List<DBWorkAuth> auths) {
628
+        if (CollectionUtil.isListNotEmpty(auths)) {
629
+            makeSendInfoByCurAuthList(auths);
630
+        }
631
+        // 20160719 liys 从execute方法中移动此处,解决异步拿回后再次提交时,出现新的分支问题
632
+        runningdata.getCurTrack().setFlowstatus(
633
+                StaticVarExtend.FlowStatus_Normal);
634
+        return true;
635
+    }
636
+
637
+    /**
638
+     * 保存数据之前的接口方法.例如:消息数据的处理 key=sql,value=parameter
639
+     */
640
+    public Map<String, List<Object>> actionBeforeSaveToDB() {
641
+        Map<String, List<Object>> saveMap = new LinkedHashMap<String, List<Object>>();
642
+        if (!StaticFunExtend.getActionExtraData()
643
+                .doWithNextNodesExtraData(this)) {
644
+            return null;
645
+        }
646
+        if (subflowEnd != null) {
647
+            if (!subflowEnd.mainInstanceContinue(saveMap, getTaskLists())) {
648
+                return null;
649
+            }
650
+        }
651
+        // 20180312 liys 增加记录:当前节点的已办权限设置的表单信息
652
+        // 用于满足不同节点的主办提交后变成已办时能显示跟主办节点相关的表单信息
653
+        // 用于在打开实例时,如果是已办从这个记录中获取之前主办节点时的设置信息
654
+        if (HZResourceBundle.getInstance().isDoneAuthFormAuthorNode()) {
655
+            recodeDoneAuthForCurUserInCurNode(saveMap);
656
+        }
657
+
658
+        if (isSendTodo) {
659
+            sendTodo();
660
+        }
661
+        actionBefore(saveMap);
662
+
663
+        actionBeforeForSubFlow(saveMap);
664
+
665
+        return saveMap;
666
+    }
667
+
668
+    private void recodeDoneAuthForCurUserInCurNode(
669
+            Map<String, List<Object>> saveMap) {
670
+        if ("Start".equals(getCurNodeid())) {
671
+            return;
672
+        }
673
+        // 获取已办权限信息
674
+        IFlowNode curNodeXml = getCurFlowNode();
675
+        INodeControl doneControl = curNodeXml
676
+                .getParticipantsControl(StaticVarExtend.AUTH_DONE + "_DO");
677
+        if (doneControl == null) {
678
+            return;
679
+        }
680
+        List<INodeForm> doneForms = doneControl.getAllNodeForms();
681
+        boolean isHaveTrack = false;
682
+        boolean isAgent = StringUtilExtend.isNotNull(getCurUser().getAgentUser());
683
+        for (INodeForm form : doneForms) {
684
+            String formId = form.getFormid();
685
+            if ("FlowTrack".equals(formId)) {
686
+                isHaveTrack = true;
687
+                continue;
688
+            }
689
+
690
+            // 记录当前节点,当前人,权限
691
+            makeDone(form, saveMap, isAgent);
692
+        }
693
+        if (isHaveTrack) {
694
+            makeDone(null, saveMap, isAgent);
695
+        }
696
+    }
697
+
698
+    private void makeDone(INodeForm form, Map<String, List<Object>> saveMap,
699
+                          boolean isAgent) {
700
+        DBDone done = new DBDone();
701
+        done.setId(StaticFunExtend.getUnid());
702
+        done.setWorkid(getWorkid());
703
+        done.setNodeid(getCurNodeid());
704
+        done.setUserid(getCurUserid());
705
+        done.setFormid(form == null ? "FlowTrack" : form.getFormid());
706
+        done.setFormbutton(form == null ? "" : form.getFormButton());
707
+        done.setFieldauthid(form == null ? "" : form.getRealFormid());
708
+        done.getSQL(saveMap,runningdata.getResultJson());
709
+
710
+        if (isAgent) {
711
+            done.setId(StaticFunExtend.getUnid());
712
+            done.setUserid(getCurUser().getAgentUser());
713
+            done.getSQL(saveMap,runningdata.getResultJson());
714
+        }
715
+    }
716
+
717
+    /**
718
+     * 保存之后的接口方法.例如:消息数据的更新
719
+     */
720
+    public void actionAfterSaveToDB() {
721
+        if (isNotSaveToDB) {
722
+            return;
723
+        }
724
+        // 处理多人并行节点,没有离开节点的情况下,不触发“待办变已办”方法的问题;
725
+        // https://www.huizhengsoft.com/hznetwork/support/know/jump.html?pageId=HZ2881ea7b9f1fde017b9f4333b702c7&formDataId=HZ28831d934da6a4019370bdf42d331a
726
+        actionStartTodoThread();
727
+//         if (isSendTodo) {
728
+//             actionStartTodoThread();
729
+//         }
730
+        actionAfterForSubFlow();
731
+        // 发送定时任务
732
+        super.actionAfterSaveToDB();
733
+        //操作执行完毕后的事件执行
734
+        executeEventAfterToDB();
735
+    }
736
+
737
+    /**
738
+     * 发送待办(可继承重写)
739
+     */
740
+    protected void sendTodo() {
741
+        sendTodoForSelectedUsers();
742
+    }
743
+
744
+}

+ 1689
- 0
src/main/java/com/horizon/wf/action/base/BaseAction.java
Fichier diff supprimé car celui-ci est trop grand
Voir le fichier


+ 95
- 0
src/main/java/com/horizon/wf/core/rule/CotRule.java Voir le fichier

@@ -0,0 +1,95 @@
1
+package com.horizon.wf.core.rule;
2
+
3
+import cn.hutool.http.HttpUtil;
4
+import com.horizon.common.constant.Constants;
5
+import com.horizon.wf.bean.WorkParaBean;
6
+import com.horizon.wf.core.runtime.RunningData;
7
+import com.horizon.wf.definition.pub.IFlowNode;
8
+import com.horizon.wf.entity.db.DBTrack;
9
+import com.horizon.wf.entity.db.DBWork;
10
+import com.horizon.wf.entity.user.IRunUser;
11
+import com.horizon.wf.global.StaticVarExtend;
12
+
13
+import java.util.HashMap;
14
+import java.util.List;
15
+import java.util.Map;
16
+
17
+/**
18
+ * 合同业务相关的事件触发器
19
+ * 用于更新合同状态
20
+ */
21
+public class CotRule extends BaseRuleImpl implements IBaseRule {
22
+
23
+    /**
24
+     * 具体的实现,参考下面方法中的说明,所有的实现都差不多结构,
25
+     * 只有自定义的异常处理接口实现中是没有传入 runningdata的.
26
+     * 不同的接口 仅仅是额外传入的参数有些差异,额外的参数多数都是可以从runningdata中获取的
27
+     * 系统为了方便接口的实现,额外传入了一些认为会用到的参数
28
+     * @return
29
+     */
30
+    @Override
31
+    public boolean executeRule() {
32
+        // 从引擎获取到核心数据对象(如果接口没有额外传入需要的数据时,可以从此对象中获取)
33
+        RunningData runningdata = getRunningdata();
34
+        //事件处理类额外传入参数
35
+        // 1.执行事件的节点对象
36
+        IFlowNode eventNode = (IFlowNode) getParameter(StaticVarExtend.Parameter_IFlowNode);
37
+
38
+        // 2.当前节点对象
39
+        IFlowNode curNode = (IFlowNode)getParameter(StaticVarExtend.Parameter_Current_IFlowNode);
40
+        // 3.引擎调用时,传入的参数对象
41
+        WorkParaBean paraBean = (WorkParaBean)getParameter(StaticVarExtend.Parameter_WorkParaBean);
42
+        Map<String, String> varMap = paraBean.getFlowVarMap();
43
+        String action = paraBean.getActionname();
44
+        // 4.当前实例对象
45
+        DBWork work = (DBWork)getParameter(StaticVarExtend.Parameter_DBWork);
46
+        // 5.当前执行人对象
47
+        IRunUser user = (IRunUser) getParameter(StaticVarExtend.Parameter_RunUser);
48
+        // 6.当前路径对象
49
+        DBTrack track = (DBTrack)getParameter(StaticVarExtend.Parameter_DBTrack);
50
+        int status = track.getFlowstatus();
51
+        String nodeId = track.getNodeid();
52
+        String statusName = track.getFunname();
53
+        String nodeName = track.getNodename();
54
+        // 7.需要保存的SQL数据如果需要引擎来保存,请放入此 map中(key=SQL,value=List为SQL中对应的参数)
55
+        Map<String, List<Object>> dataMap = (Map<String, List<Object>>) getParameter(StaticVarExtend.Parameter_SaveMap);
56
+        // 8.事件类型
57
+        String eventType = (String)getParameter("eventType");
58
+        // 9.事件实际执行内容
59
+        // 10.返回 true 表示执行成功,引擎从第7步中的dataMap里获取需要保存的数据,引擎继续往下执行,
60
+        // 返回 false表示执行失败, 引擎会根据事件类型,确定是否继续往下执行
61
+
62
+        System.err.println(
63
+                ",status:" + status +
64
+                ",nodeId:" + nodeId +
65
+                ",nodeName:" + nodeName +
66
+                ",statusName:" + statusName +
67
+                ",action:" + action +
68
+                ",eventNodeId:" + eventNode.getNodeid() +
69
+                ",eventNodeName:" + eventNode.getNodename());
70
+
71
+         if(eventNode.getNodeid().contains("End")){
72
+             status = 170;
73
+         }else if(eventNode.getNodeid().equals("Node1")){
74
+             if(statusName.equals("JumpReject") || statusName.equals("Reject")){
75
+                 status = 130;
76
+             }else if(statusName.equals("Getback")){
77
+                 status = 190;
78
+             }else if(statusName.equals("autofirst")){
79
+                 status = 110;
80
+             }
81
+        }else {
82
+             status = 110;
83
+         }
84
+        String url = Constants.WF_PRE_URL + "/cot/Head/horizonApprovalProcess";
85
+        // String url = Constants.WF_PRE_URL + "/framework/Schedule/horizonApprovalProcess";
86
+        String id = varMap.get("id");
87
+        Map<String, Object> params = new HashMap<>();
88
+        params.put("id", id);
89
+        params.put("processInstanceStatus", status);
90
+        String result = HttpUtil.post(url, params);
91
+        return true;
92
+    }
93
+}
94
+
95
+

+ 340
- 0
src/main/java/com/horizon/wf/core/rule/ExampleRule.java Voir le fichier

@@ -0,0 +1,340 @@
1
+package com.horizon.wf.core.rule;
2
+
3
+import com.horizon.wf.bean.WorkParaBean;
4
+import com.horizon.wf.core.runtime.RunningData;
5
+import com.horizon.wf.core.track.json.impl.ITrackJson;
6
+import com.horizon.wf.definition.pub.IFlowNode;
7
+import com.horizon.wf.definition.pub.node.INodeException;
8
+import com.horizon.wf.definition.pub.node.INodePara;
9
+import com.horizon.wf.definition.pub.node.INodeRouter;
10
+import com.horizon.wf.entity.db.DBTrack;
11
+import com.horizon.wf.entity.db.DBWork;
12
+import com.horizon.wf.entity.user.IRunUser;
13
+import com.horizon.wf.global.StaticVar;
14
+import com.horizon.wf.global.StaticVarExtend;
15
+import com.horizon.wf.tools.CStrUtil;
16
+
17
+import java.util.List;
18
+import java.util.Map;
19
+
20
+/**
21
+ * 接口实现类的说明示例
22
+ * 必须继承已有的类 com.horizon.wf.core.rule.BaseRuleImpl
23
+ */
24
+public class ExampleRule extends BaseRuleImpl implements IBaseRule {
25
+
26
+    /**
27
+     * 具体的实现,参考下面方法中的说明,所有的实现都差不多结构,
28
+     * 只有自定义的异常处理接口实现中是没有传入 runningdata的.
29
+     * 不同的接口 仅仅是额外传入的参数有些差异,额外的参数多数都是可以从runningdata中获取的
30
+     * 系统为了方便接口的实现,额外传入了一些认为会用到的参数
31
+     * @return
32
+     */
33
+    @Override
34
+    public boolean executeRule() {
35
+        // 从引擎获取到核心数据对象(如果接口没有额外传入需要的数据时,可以从此对象中获取)
36
+        RunningData runningdata = getRunningdata();
37
+        //事件处理类额外传入参数
38
+        // 1.执行事件的节点对象
39
+        IFlowNode eventNode = (IFlowNode) getParameter(StaticVarExtend.Parameter_IFlowNode);
40
+        // 2.当前节点对象
41
+        IFlowNode curNode = (IFlowNode)getParameter(StaticVarExtend.Parameter_Current_IFlowNode);
42
+        // 3.引擎调用时,传入的参数对象
43
+        WorkParaBean paraBean = (WorkParaBean)getParameter(StaticVarExtend.Parameter_WorkParaBean);
44
+        Map<String, String> varMap = paraBean.getFlowVarMap();
45
+        // 4.当前实例对象
46
+        DBWork work = (DBWork)getParameter(StaticVarExtend.Parameter_DBWork);
47
+        // 5.当前执行人对象
48
+        IRunUser user = (IRunUser) getParameter(StaticVarExtend.Parameter_RunUser);
49
+        // 6.当前路径对象
50
+        DBTrack track = (DBTrack)getParameter(StaticVarExtend.Parameter_DBTrack);
51
+        int status = track.getFlowstatus();
52
+        String nodeId = track.getNodeid();
53
+        String statusName = track.getFunname();
54
+        String nodeName = track.getNodename();
55
+        // 7.需要保存的SQL数据如果需要引擎来保存,请放入此 map中(key=SQL,value=List为SQL中对应的参数)
56
+        Map<String, List<Object>> dataMap = (Map<String, List<Object>>) getParameter(StaticVarExtend.Parameter_SaveMap);
57
+        // 8.事件类型
58
+        String eventType = (String)getParameter("eventType");
59
+        // 9.事件实际执行内容
60
+        // System.err.println("zcc");
61
+        // System.err.println(paraBean.toString());
62
+        // 10.返回 true 表示执行成功,引擎从第7步中的dataMap里获取需要保存的数据,引擎继续往下执行,
63
+        // 返回 false表示执行失败, 引擎会根据事件类型,确定是否继续往下执行
64
+        return true;
65
+    }
66
+
67
+    /**
68
+     * 内部循环节点
69
+     * 如果前台没有传入办理人,则判断是否有接口类
70
+     * @return
71
+     */
72
+    private boolean doProgressively(){
73
+        // 从引擎获取到核心数据对象(如果接口没有额外传入需要的数据时,可以从此对象中获取)
74
+        RunningData runningdata = getRunningdata();
75
+        DBWork work = (DBWork)getParameter(StaticVarExtend.Parameter_DBWork);// runningdata.getWork());
76
+        WorkParaBean paraBean =(WorkParaBean)getParameter(StaticVarExtend.Parameter_WorkParaBean);// 设置前后台对象到接口
77
+        IFlowNode curNode = (IFlowNode)getParameter(StaticVarExtend.Parameter_Current_IFlowNode);// 逐级审批节点
78
+        IRunUser user = (IRunUser) getParameter(StaticVarExtend.Parameter_RunUser);// 当前操作者
79
+        String userid = (String)getParameter(StaticVarExtend.Parameter_Progressive_Userid);// 提交到逐级审批节点的人员id
80
+
81
+        // 通过setResult("")方法把下一个办理人的id返回给引擎
82
+
83
+        // 返回ture,引擎从返回结果中获取办理人,false则忽略
84
+        return true;
85
+    }
86
+
87
+    /**
88
+     * 合并网关 合并处理
89
+     * @return
90
+     */
91
+    private boolean doGatewayMerger(){
92
+        // 从引擎获取到核心数据对象(如果接口没有额外传入需要的数据时,可以从此对象中获取)
93
+        RunningData runningdata = getRunningdata();
94
+
95
+        WorkParaBean paraBean = (WorkParaBean)getParameter(StaticVarExtend.Parameter_WorkParaBean);
96
+        IFlowNode curNode = (IFlowNode)getParameter(StaticVarExtend.Parameter_GateWay_IFlowNode);// 当前节点
97
+        // 所有需要到达合并网关的分支列表
98
+        List<ITrackJson> lstTrack = (List<ITrackJson>) getParameter(StaticVarExtend.Parameter_GateWay_Alltracks);// 设置所有分支路径信息到接口rd.getAllTrackNeedToGateway(this)
99
+        DBTrack track = (DBTrack)getParameter(StaticVarExtend.Parameter_DBTrack);// rd.getCurTrack());
100
+        DBWork work = (DBWork)getParameter(StaticVarExtend.Parameter_DBWork);// rd.getWork());
101
+        IRunUser user = (IRunUser)getParameter(StaticVarExtend.Parameter_RunUser);// rd.getCurUser());
102
+
103
+        // 如果有需要撤销的分支,请使用setResult("")方法把需要撤销的分支路径id返回给引擎
104
+
105
+        // 返回是否允许离开 true 允许离开 false 不允许离开
106
+        return true;
107
+    }
108
+
109
+    /**
110
+     * 多人并行节点离开规则中的自定义
111
+     * 调用入口 com.horizon.wf.expand.node.NodeMultiImpl#doNormal
112
+     * @return
113
+     */
114
+    private boolean doNodeMultilLeave(){
115
+        // 从引擎获取到核心数据对象(如果接口没有额外传入需要的数据时,可以从此对象中获取)
116
+        RunningData runningdata = getRunningdata();
117
+
118
+        WorkParaBean paraBean = (WorkParaBean)getParameter(StaticVarExtend.Parameter_WorkParaBean);
119
+        IFlowNode curNode = (IFlowNode)getParameter(StaticVarExtend.Parameter_Current_IFlowNode);// 当前节点
120
+
121
+        // 返回是否允许离开 true 允许离开 false 不允许离开
122
+        return true;
123
+    }
124
+
125
+    /**
126
+     * 合并节点激活方式中的定义实现
127
+     *
128
+     * @return
129
+     */
130
+    private boolean doMergerEntryType(){
131
+        // 从引擎获取到核心数据对象(如果接口没有额外传入需要的数据时,可以从此对象中获取)
132
+        RunningData runningdata = getRunningdata();
133
+
134
+        WorkParaBean paraBean = (WorkParaBean)getParameter(StaticVarExtend.Parameter_WorkParaBean);
135
+        IFlowNode curNode = (IFlowNode)getParameter(StaticVarExtend.Parameter_Current_IFlowNode);// 当前节点
136
+        IFlowNode mergerNode = (IFlowNode)getParameter(StaticVarExtend.Parameter_Merger_IFlowNode);// 进入的节点
137
+
138
+        int allTrackNum = (Integer)getParameter("AllTrackNum"); // 所有需要到达的分支数
139
+        int reachedNum = (Integer)getParameter("ReachedTrackNum"); // 已经到达的分支数
140
+
141
+
142
+        // 返回是否允许离开 true 允许离开 false 不允许离开
143
+        return true;
144
+    }
145
+    /**
146
+     * 合并节点的离开方式中的自定义实现
147
+     * 调用入口 com.horizon.wf.expand.node.NodeMergerImpl#checkMergerNodeLeaveRule
148
+     * @return
149
+     */
150
+    private boolean doMergerLeaveType(){
151
+        // 从引擎获取到核心数据对象(如果接口没有额外传入需要的数据时,可以从此对象中获取)
152
+        RunningData runningdata = getRunningdata();
153
+
154
+        WorkParaBean paraBean = (WorkParaBean)getParameter(StaticVarExtend.Parameter_WorkParaBean);
155
+        IFlowNode curNode = (IFlowNode)getParameter(StaticVarExtend.Parameter_Current_IFlowNode); // 当前节点
156
+        IFlowNode mergerNode = (IFlowNode)getParameter(StaticVarExtend.Parameter_Merger_IFlowNode);
157
+
158
+
159
+        // 返回是否允许离开 true 允许离开 false 不允许离开
160
+        return true;
161
+    }
162
+
163
+
164
+    /**
165
+     * 异常处理接口实现示范代码
166
+     * 调用入口 com.horizon.wf.action.common.ActionCommon#dealException
167
+     * @return
168
+     */
169
+    private boolean doException(){
170
+        // 1.引擎调用时,传入的参数对象
171
+        WorkParaBean paraBean = (WorkParaBean) getParameter(StaticVarExtend.Parameter_WorkParaBean);
172
+        // 2.当前实例对象
173
+        DBWork work = (DBWork) getParameter(StaticVarExtend.Parameter_DBWork);
174
+        // 3.当前路径对象
175
+        DBTrack track = (DBTrack) getParameter(StaticVarExtend.Parameter_DBTrack);
176
+        // 4.当前异常定义对象
177
+        INodeException e = (INodeException) getParameter(StaticVarExtend.Parameter_Exception_INodeException);
178
+
179
+        // 5.异常处理内容
180
+
181
+        // 返回true,异常执行结束,
182
+        // 如果返回 false,可以使用setResult指定一个系统默认处理的方式: setResult("2"); 也可以不设置跟返回true一样
183
+        // 2 = 跳转 ,3= 挂起,4=终止,其他值系统忽略处理
184
+        return true;
185
+    }
186
+
187
+    /**
188
+     * 节点进入的扩展实现示例代码(只有在其少数情况下才会用到)
189
+     * 调用入口 com.horizon.wf.rule.defa.core.EntryRuleDefault#actionInterface
190
+     * @return
191
+     */
192
+    private boolean doNodeEntry(){
193
+        // 从引擎获取到核心数据对象(如果接口没有额外传入需要的数据时,可以从此对象中获取)
194
+        RunningData runningdata = getRunningdata();
195
+        // 要进入的节点对象
196
+        IFlowNode entryNode = (IFlowNode) getParameter(StaticVar.Para_EntryRules_IXmlNode);
197
+        // 指向要进入的节点的路由
198
+        INodeRouter fromRouter =(INodeRouter) getParameter(StaticVar.Para_EntryRules_IXmlRouter);
199
+        // 节点进入的方式,1按路由方向进入,2=退回的方式进入,3=跳转的方式进入
200
+        int leaveType = (Integer)getParameter(StaticVar.Para_EntryRules_LeaveType);
201
+        // 退回时使用的参数,一般是要退回的节点原来所在的路径id
202
+        String oldTrackid =(String)getParameter(StaticVar.Para_EntryRules_OldTrackidForReject);
203
+
204
+        //需要执行的代码
205
+
206
+        // 返回true 表示节点允许进入,false表示不允许进入
207
+        return true;
208
+    }
209
+    /**
210
+     * 节点离开的扩展实现示例代码(只有在其少数情况下才会用到)
211
+     * 调用入口 com.horizon.wf.rule.defa.core.LeaveRuleDefault
212
+     * @return
213
+     */
214
+    private boolean doNodeLeave(){
215
+        // 从引擎获取到核心数据对象(如果接口没有额外传入需要的数据时,可以从此对象中获取)
216
+        RunningData runningdata = getRunningdata();
217
+        // 当前节点对象(离开只有当前节点才会有)
218
+        IFlowNode curNode = (IFlowNode) getParameter(StaticVar.Para_LeaveRules_IXmlNode);
219
+
220
+        // 需要执行的代码
221
+        // 比如要实现在节点离开时想要对节点参数进行修改的功能如下:
222
+        List<INodePara> paraList = runningdata.getCurFlowNode().getAllNodePara();
223
+        INodePara para = paraList.get(0);
224
+
225
+        String initValue = para.getInitialValue();
226
+        // 获取当前节点参数的数据
227
+        String oldValue = runningdata.getThisNodeParaValue(para.getParaId());
228
+        int tmp = 0;
229
+        if(CStrUtil.isNull(oldValue)){
230
+            tmp = Integer.parseInt(initValue);
231
+        }
232
+        else{
233
+            tmp = Integer.parseInt(oldValue);
234
+        }
235
+        tmp += 1;
236
+        // 给当前节点参数赋值
237
+        runningdata.setThisNodeParaValue(para.getParaId(),""+tmp);
238
+        // -----上面的代码,仅供参考----------
239
+
240
+        // 返回true 表示节点允许离开,false表示不允许离开
241
+        return true;
242
+    }
243
+
244
+    /**
245
+     * 节点事件处理实现类的示范代码
246
+     * 调用入口 com.horizon.wf.rule.event.EventUtil#excuteEvents
247
+     * @return
248
+     */
249
+    private boolean doNodeEvent(){
250
+        // 从引擎获取到核心数据对象(如果接口没有额外传入需要的数据时,可以从此对象中获取)
251
+        RunningData runningdata = getRunningdata();
252
+        //事件处理类额外传入参数
253
+        // 1.执行事件的节点对象
254
+        IFlowNode eventNode = (IFlowNode) getParameter(StaticVarExtend.Parameter_IFlowNode);
255
+        // 2.当前节点对象
256
+        IFlowNode curNode = (IFlowNode)getParameter(StaticVarExtend.Parameter_Current_IFlowNode);
257
+        // 3.引擎调用时,传入的参数对象
258
+        WorkParaBean paraBean = (WorkParaBean)getParameter(StaticVarExtend.Parameter_WorkParaBean);
259
+        // 4.当前实例对象
260
+        DBWork work = (DBWork)getParameter(StaticVarExtend.Parameter_DBWork);
261
+        // 5.当前执行人对象
262
+        IRunUser user = (IRunUser) getParameter(StaticVarExtend.Parameter_RunUser);
263
+        // 6.当前路径对象
264
+        DBTrack track = (DBTrack)getParameter(StaticVarExtend.Parameter_DBTrack);
265
+        // 7.需要保存的SQL数据如果需要引擎来保存,请放入此 map中(key=SQL,value=List为SQL中对应的参数)
266
+        Map<String, List<Object>> dataMap = (Map<String, List<Object>>) getParameter(StaticVarExtend.Parameter_SaveMap);
267
+        // 8.事件类型
268
+        String eventType = (String)getParameter("eventType");
269
+        // 9.事件实际执行内容
270
+
271
+        // 10.返回 true 表示执行成功,引擎从第7步中的dataMap里获取需要保存的数据,引擎继续往下执行,
272
+        // 返回 false表示执行失败, 引擎会根据事件类型,确定是否继续往下执行
273
+        return true;
274
+    }
275
+
276
+    /**
277
+     * 事件节点的进入扩展类
278
+     * @return
279
+     */
280
+    private boolean doEventNodeEntry(){
281
+        // 从引擎获取到核心数据对象(如果接口没有额外传入需要的数据时,可以从此对象中获取)
282
+        RunningData runningdata = getRunningdata();
283
+
284
+        WorkParaBean paraBean = (WorkParaBean)getParameter(StaticVarExtend.Parameter_WorkParaBean);// 设置前后台对象到接口
285
+        DBWork work = (DBWork) getParameter(StaticVarExtend.Parameter_DBWork);
286
+        IRunUser user = (IRunUser)getParameter(StaticVarExtend.Parameter_RunUser);
287
+        DBTrack track = (DBTrack)getParameter(StaticVarExtend.Parameter_DBTrack);
288
+        // 如果需要引擎保存数据,则放入savemap中,引擎会从中获取到
289
+        Map<String, List<Object>> saveMap = (Map<String,List<Object>>)getParameter(StaticVarExtend.Parameter_SaveMap);
290
+
291
+        // 返回true,允许事件节点进入,false 不允许
292
+        return true;
293
+    }
294
+
295
+    /**
296
+     * 自定义接口实现 获取办理人的示范代码
297
+     * 调用入口 com.horizon.wf.rule.defa.core.EntryRuleDefault#getUserFromCustom
298
+     * @return
299
+     */
300
+    private boolean doCustomUser(){
301
+        // 从引擎获取到核心数据对象(如果接口没有额外传入需要的数据时,可以从此对象中获取)
302
+        RunningData runningdata = getRunningdata();
303
+        // 下面参数为获取办理人时,额外传入的对象
304
+        // 1.引擎调用时,传入的参数对象
305
+        WorkParaBean paraBean = (WorkParaBean)getParameter(StaticVarExtend.Parameter_WorkParaBean);
306
+        // 2.流程定义中用来获取自定义办理人时设置的数据
307
+        String customer = (String)getParameter(StaticVarExtend.Parameter_CustomeUser_Para);
308
+        // 3.获取办理人的节点定义对象
309
+        IFlowNode flowNode = (IFlowNode) getParameter(StaticVarExtend.Parameter_CustomeUser_IFlowNode);
310
+        // 4.获取到的办理人ID
311
+        String userId = "";
312
+        // 5.获取的办理人返回
313
+        setResult(userId);
314
+        // 6.返回
315
+        // true表示获取成功,引擎会从 第5步设置的返回值中获取结果  false,引擎忽略获取结果
316
+        return true;
317
+    }
318
+
319
+
320
+    /**
321
+     * 路由条件判断接口实现的示范代码
322
+     * @return
323
+     */
324
+    private boolean doRouter(){
325
+        // 从引擎获取到核心数据对象(如果接口没有额外传入需要的数据时,可以从此对象中获取)
326
+        RunningData runningdata = getRunningdata();
327
+        // 下面两个参数是此接口类被调用时,引擎额外传入的对象供以当前接口实现类使用
328
+        // 1.获取路由定义对象 ,通过router可以获取到在流程定义中定义的数据
329
+        INodeRouter router = (INodeRouter)getParameter(StaticVarExtend.Para_RouterRules_Router);
330
+        // 2.获取引擎执行时路由判断时的默认结果 ture or false( true表示此路由可以通过,false表示不能通过)
331
+        boolean isPass = (Boolean) getParameter(StaticVarExtend.Para_RouterRules_IsPass);
332
+        // 3.自行处理判断内容
333
+
334
+        // 4. 最终返回 此路由是否允许通过
335
+        // true 允许通过  flase 不允许通过
336
+        return true;
337
+    }
338
+}
339
+
340
+

+ 65
- 0
src/main/java/com/horizon/wf/third/hz/todo/TodoImpl.java Voir le fichier

@@ -0,0 +1,65 @@
1
+package com.horizon.wf.third.hz.todo;
2
+
3
+import java.util.Map;
4
+
5
+import com.horizon.wf.expand.impl.ITodoInterface;
6
+
7
+/**
8
+ * 作者:李勇 创建日期:2008-09-19 跟待办相关的实现类
9
+ * workflow-pub.xml
10
+ * @author Administrator
11
+ * 
12
+ */
13
+@SuppressWarnings({"rawtypes"})
14
+public class TodoImpl implements ITodoInterface {
15
+	public void setTenantid(String tenantid){
16
+		
17
+	}
18
+	/**
19
+	 * 发送邮件,未实现
20
+	 */
21
+	public boolean sendMail(Map lhm){
22
+		return true;
23
+//		return MailUtil.sendMail(lhm, "0");
24
+	}
25
+	
26
+	/**
27
+	 * 发送系统提醒消息,未实现
28
+	 * @param lhm
29
+	 * @return
30
+	 */
31
+	public boolean sendMsg(Map lhm){
32
+		return true;
33
+//		return AlertUtil.saveAlert(lhm);
34
+	}
35
+	
36
+	/**
37
+	 * 发送短信,未实现
38
+	 * @param lhm
39
+	 * @return
40
+	 */
41
+	public boolean sendNode(Map lhm){
42
+//		System.out.println("短信发送");
43
+		return true;
44
+	}
45
+	
46
+	/**
47
+	 * 发送RTF,未实现
48
+	 * @param lhm
49
+	 * @return
50
+	 */
51
+	public boolean sendRTF(Map lhm){
52
+		return true;
53
+	}
54
+	
55
+	/**
56
+	 * 发送其他消息,未实现
57
+	 * @param lhm
58
+	 * @return
59
+	 */
60
+	public boolean sendOther(Map lhm){
61
+		return true;
62
+	}
63
+
64
+	
65
+}

+ 251
- 0
src/main/java/com/horizon/wf/util/PushWorkflowToPortal.java Voir le fichier

@@ -0,0 +1,251 @@
1
+package com.horizon.wf.util;
2
+
3
+import cn.hutool.http.HttpRequest;
4
+import cn.hutool.http.HttpResponse;
5
+import cn.hutool.http.HttpUtil;
6
+import com.alibaba.fastjson.JSONArray;
7
+import com.alibaba.fastjson.JSONObject;
8
+import com.horizon.cache.api.HCacheClient;
9
+import com.horizon.common.collect.Lists;
10
+import com.horizon.common.collect.Maps;
11
+import com.horizon.common.constant.Constants;
12
+import com.horizon.core.HorizonCore;
13
+import com.horizon.db.Access;
14
+import com.horizon.third.adapter.OrganizationAdapter;
15
+import com.horizon.wf.bean.WorkParaBean;
16
+
17
+import java.sql.SQLOutput;
18
+import java.util.HashMap;
19
+import java.util.List;
20
+import java.util.Map;
21
+
22
+
23
+public class PushWorkflowToPortal {
24
+
25
+    private static String cacheGroup = "SendMsgToHall";
26
+    /**
27
+     * 如果需要往第三方数据写入待办相关数据
28
+     * tmpJson JSON格式的数组
29
+     *
30
+     * SqlType=INSERT时
31
+     * InsertFields = 已经拼好的要插入的字段,字符串
32
+     * InsertPara = 插入时对应的值,数组
33
+     *
34
+     * SqlType=UPDATE或者DELETE时
35
+     * WhereCondition = 已经拼好的查询条件字段,字符串
36
+     * WhereFields = 查询条件字段列表,数组
37
+     * WherePara = 查询条件对应的参数值,数组
38
+     *
39
+     * SqlType=UPDATE时
40
+     * SetStr = 已经拼好的需要更新的字段,字符串
41
+     * SetFields = 更新字段列表,数组
42
+     * SetPara = 更新字段对应的参数值,数组
43
+     */
44
+    public static void sendTodoData(String type, JSONArray tmpJson, WorkParaBean paraBean, String workid) {
45
+        if(type.equals("dataToSend")){
46
+            //待办、待阅数据
47
+            Map<String, Map<String, String>> insertSaveMap = Maps.newHashMap();
48
+            //待办变已办、待阅变已阅、待办变可阅数据
49
+            Map<String, Map<String, String>> updateSaveMap = Maps.newHashMap();
50
+            sendTodoData(tmpJson, paraBean, insertSaveMap, updateSaveMap, workid);
51
+            // System.out.println("+=============================");
52
+            //在这里调用门户的接口
53
+            if(!insertSaveMap.isEmpty()){
54
+                // select creator from tw_hz_instance where id = 'workid'
55
+                // HorizonCore.USER_ID.value()
56
+                String creator = "";
57
+                if(workid != null && !workid.isEmpty()){
58
+                    String sql = "select creator from tw_hz_instance where id = ?";
59
+                    List<String> list = Lists.newArrayList();
60
+                    list.add(workid);
61
+                    //单条数据查询
62
+                    //返回第一条数据,list
63
+                    //返回第一条数据,map,key=小写字段名,value=值
64
+                    Map resmap = Access.getSingleMap(sql, list);
65
+                    // System.err.println(resmap);
66
+                    creator = (String) resmap.get("creator");
67
+                }else{
68
+                    creator = HorizonCore.USER_ID.value();
69
+                }
70
+
71
+                for(Map.Entry<String, Map<String, String>> entry : insertSaveMap.entrySet()){
72
+                    String scheduleId = entry.getKey();
73
+                    Map<String, String> value = entry.getValue();
74
+
75
+                    String subjectionId = value.get("subjectionId");
76
+                    String workId = value.get("workId");
77
+                    String trackId = value.get("trackId");
78
+                    String flowId = value.get("flowId");
79
+                    String nodeId = value.get("nodeId");
80
+                    String flowName = value.get("flowName");
81
+
82
+                    String title = value.get("title");
83
+
84
+                    String startTime = value.get("sendTime");
85
+                    String nextUserId = value.get("authId");
86
+
87
+                    // String businessParam = value.get("title");
88
+
89
+                    JSONObject jsonObject = new JSONObject();
90
+                    jsonObject.put("scheduleId", scheduleId);
91
+                    jsonObject.put("title", title);
92
+                    jsonObject.put("startUserId", creator);
93
+                    jsonObject.put("startTime", startTime);
94
+                    jsonObject.put("nextUserId", nextUserId);
95
+                    jsonObject.put("toWebPath", "/workflow/detail");
96
+
97
+                    JSONObject businessParam = new JSONObject();
98
+                    businessParam.put("flowId", flowId);
99
+                    businessParam.put("flowName", flowName);
100
+                    businessParam.put("workId", workId);
101
+                    businessParam.put("trackId", trackId);
102
+                    businessParam.put("subjectionId", subjectionId);
103
+                    businessParam.put("nodeId", nodeId);
104
+                    businessParam.put("type", "3");
105
+                    jsonObject.put("businessParam", businessParam.toJSONString());
106
+
107
+                    String url = Constants.WF_PRE_URL + "/framework/Schedule/horizonAdd";
108
+                    Map<String, Object> params = new HashMap<>();
109
+                    params.put("json", jsonObject.toJSONString());
110
+
111
+                    String result = HttpUtil.post(url, params);
112
+                    // System.out.println("INSERT: "+result);
113
+                }
114
+            }
115
+            if(!updateSaveMap.isEmpty()){
116
+                // System.err.println(updateSaveMap);
117
+                for(Map.Entry<String, Map<String, String>> entry : updateSaveMap.entrySet()){
118
+                    String scheduleId = entry.getKey();
119
+                    Map<String, String> value = entry.getValue();
120
+                    String url = Constants.WF_PRE_URL + "/framework/Schedule/horizonUpdateDealFlag";
121
+                    Map<String, Object> params = new HashMap<>();
122
+                    params.put("scheduleId", scheduleId);
123
+
124
+                    String result = HttpUtil.post(url, params);
125
+                    // System.out.println("UPDATE: "+result);
126
+                }
127
+            }
128
+        }
129
+    }
130
+
131
+    private static void sendTodoData(JSONArray dataToSend, WorkParaBean paraBean,
132
+                                     Map<String, Map<String, String>> insertSaveMap, Map<String, Map<String, String>> updateSaveMap, String workid){
133
+        OrganizationAdapter organizationAdapter = new OrganizationAdapter();
134
+        if(dataToSend == null || dataToSend.size() <= 0){
135
+            return;
136
+        }
137
+
138
+        //2022-06-29 新增
139
+        //判断是不是创建流程,如果只有一条,并且是insert,则表示是创建流程
140
+        if(dataToSend.size()==1 && "INSERT".equals(dataToSend.getJSONObject(0).getString("SqlType"))) {
141
+            //将流程的实例信息放到session中
142
+            HCacheClient.put(cacheGroup,"TODO"+workid,dataToSend.getJSONObject(0), 0L);
143
+            return;
144
+        }
145
+
146
+        //2022-06-29 end
147
+        for(int i = 0; i < dataToSend.size(); i++){
148
+            JSONObject currentItem = dataToSend.getJSONObject(i);
149
+
150
+            //2022-06-29 新增 如果是更新,在缓存中查找是否有workid,有的就是新流程暂存,加入insert
151
+            if(currentItem.getString("SqlType").equals("UPDATE")){
152
+                JSONObject cacheTodo = HCacheClient.get(cacheGroup,"TODO"+paraBean.getWorkId());
153
+                if(cacheTodo!=null && cacheTodo.size()>0){
154
+                    currentItem = cacheTodo;
155
+                    HCacheClient.remove(cacheGroup,"TODO"+paraBean.getWorkId());
156
+                }
157
+            }
158
+            //2022-06-29 end
159
+            String sqlType = currentItem.getString("SqlType");
160
+            String flag = currentItem.getString("FLAG");
161
+            if(sqlType.equals("INSERT")){ //待办
162
+                String[] insertFields = currentItem.getString("InsertFields").split(",");
163
+                if(insertFields.length == 0){
164
+                    continue;
165
+                }
166
+                JSONArray insertParas = currentItem.getJSONArray("InsertPara");
167
+                Map<String,String> insertTodo = Maps.newHashMap();
168
+                for(int index = 0; index < insertFields.length; index++){
169
+                    insertTodo.put(insertFields[index], insertParas.getString(index));
170
+                }
171
+                String status = insertTodo.get("STATUS"); //Author主办
172
+                String statusNo = insertTodo.get("STATUS_NO"); //Author主办
173
+                String authId = insertTodo.get("AUTH_ID"); //办理人id
174
+                // String agentId = insertTodo.get("AGENT_ID"); //代办人id
175
+                Map<String, String> author = organizationAdapter.getUserById(authId, paraBean.getFlowIdentifier());
176
+                String authName = author.get("name"); //办理人姓名
177
+                String authLoginName = author.get("login_name"); //办理人账号
178
+                // Map<String, String> agentor = organizationAdapter.getUserById(agentId, paraBean.getFlowIdentifier());
179
+                // String agentName = agentor.get("name"); //代办人姓名
180
+                // String agentLoginName = agentor.get("login_name"); //代办人账号
181
+                String workId = insertTodo.get("WORKID");
182
+                String trackId = insertTodo.get("TRACKID");
183
+                String flowId = insertTodo.get("FLOWID");
184
+                String flowName = insertTodo.get("FLOWNAME");
185
+                String nodeId = insertTodo.get("NODEID");
186
+                String title = insertTodo.get("TITLE");
187
+                String sendTime = insertTodo.get("SENDTIME"); //sendtime
188
+                String subjectionType = insertTodo.get("SUBJECTION_TYPE"); //办理人所属组织type D部门 G群组 P岗位
189
+                String subjectionId = insertTodo.get("SUBJECTION_ID"); //办理人所属组织id
190
+                String id = insertTodo.get("ID"); //待办数据的唯一标识
191
+                Map<String, String> map = insertSaveMap.get(id);
192
+                if(null==map || map.isEmpty()){
193
+                    map = Maps.newHashMap();
194
+                    map.put("flowId", flowId);
195
+                    map.put("workId", workId);
196
+                    map.put("trackId", trackId);
197
+                    map.put("title", title);
198
+                    map.put("flowName", flowName);
199
+                    map.put("nodeId", nodeId);
200
+                }
201
+                map.put("authId", authId);
202
+                map.put("authName", authName);
203
+                map.put("authLoginName", authLoginName);
204
+                // map.put("agentId", agentId);
205
+                // map.put("agentName", agentName);
206
+                // map.put("agentLoginName", agentLoginName);
207
+                map.put("sendTime", sendTime);
208
+                map.put("subjectionType", subjectionType);
209
+                map.put("subjectionId", subjectionId);
210
+                map.put("status", status);
211
+                map.put("statusNo", statusNo);
212
+                map.put("id", id);
213
+                insertSaveMap.put(id, map);
214
+
215
+            } else if(sqlType.equals("UPDATE")&&flag.equals("DONE")){ //待办变已办
216
+                JSONArray todoIds = currentItem.getJSONArray("WherePara");
217
+                String workId = paraBean.getWorkId(); //workid
218
+                String[] setFields = currentItem.getString("SetFields").substring(1, currentItem.getString("SetFields").length()-1).split(",");
219
+                if(setFields.length == 0){
220
+                    continue;
221
+                }
222
+                JSONArray setParas = currentItem.getJSONArray("SetPara");
223
+                Map<String,String> updateTodo = Maps.newHashMap();
224
+                for(int index = 0; index < setFields.length; index++){
225
+                    updateTodo.put(setFields[index].trim(), setParas.getString(index));
226
+                }
227
+                String dotime = updateTodo.get("dotime"); //办理时间
228
+                String status = updateTodo.get("status"); //状态
229
+                String statusNo = updateTodo.get("statusNo"); //状态编号
230
+                String title = updateTodo.get("title"); //title
231
+                String id = todoIds.getString(0);
232
+                Map<String, String> map = updateSaveMap.get(id);
233
+                if(null==map || map.isEmpty()){
234
+                    map = Maps.newHashMap();
235
+                    map.put("dotime", dotime);
236
+                    map.put("statusNo", statusNo);
237
+                    map.put("status", status);
238
+                    map.put("workId", workId);
239
+                    map.put("title", title);
240
+                } else {
241
+                    map.put("dotime", dotime);
242
+                    map.put("statusNo", statusNo);
243
+                    map.put("status", status);
244
+                }
245
+                map.put("id", id);
246
+                updateSaveMap.put(id, map);
247
+            }
248
+        }
249
+    }
250
+}
251
+

+ 1
- 1
src/main/resources/workflow-conf/workflow-web.xml Voir le fichier

@@ -10,7 +10,7 @@
10 10
 
11 11
     <context:property-placeholder ignore-unresolvable="true" location="classpath:workflow-conf/properties/horizon.properties" />
12 12
     <!-- 开启spring注解支持 需要配置 -->
13
-    <context:component-scan base-package="com.horizon.**.org,com.horizon.**.web" use-default-filters="false">
13
+    <context:component-scan base-package="com.horizon.**.web" use-default-filters="false">
14 14
         <context:include-filter type="annotation" expression="org.springframework.stereotype.Controller"/>
15 15
     </context:component-scan>
16 16
     <mvc:default-servlet-handler/>

Loading…
Annuler
Enregistrer