Commit 69b93ca75a66a706d05d014f82a2dbee74609649

Authored by 芋道源码
Committed by Gitee
2 parents f3e0ca27 6489047a

!88 工作流新增 Flowable 实现

Merge pull request !88 from 芋道源码/feature/flowable
Showing 104 changed files with 5354 additions and 195 deletions
README.md
... ... @@ -21,10 +21,10 @@
21 21 * 集成微信小程序、微信公众号、企业微信、钉钉等三方登陆,集成支付宝、微信等支付与退款。
22 22 * 集成阿里云、腾讯云、云片等短信渠道,集成阿里云、腾讯云、七牛云等云存储服务。
23 23  
24   -| 项目名 | 说明 | 传说门 |
25   -| ---- | ---- | ---- |
26   -| `ruoyi-vue-pro` | Spring Boot 版本 | **[Gitee](https://gitee.com/zhijiantianya/ruoyi-vue-pro)**     [Github](https://github.com/YunaiV/ruoyi-vue-pro) |
27   -| `ruoyi-vue-cloud` | Spring Cloud 版本 | **[Gitee](https://gitee.com/zhijiantianya/ruoyi-vue-cloud)**     [Github](https://github.com/YunaiV/onemall) |
  24 +| 项目名 | 说明 | 传说门 |
  25 +| ---- |------------------------| ---- |
  26 +| `ruoyi-vue-pro` | Spring Boot 多模块 | **[Gitee](https://gitee.com/zhijiantianya/ruoyi-vue-pro)**     [Github](https://github.com/YunaiV/ruoyi-vue-pro) |
  27 +| `ruoyi-vue-cloud` | Spring Cloud 微服务 | **[Gitee](https://gitee.com/zhijiantianya/ruoyi-vue-cloud)**     [Github](https://github.com/YunaiV/onemall) |
28 28 | `Spring-Boot-Labs` | Spring Boot & Cloud 入门 | **[Gitee](https://gitee.com/zhijiantianya/SpringBoot-Labs)**     [Github](https://github.com/YunaiV/SpringBoot-Labs) |
29 29  
30 30 ## 🐶 在线体验
... ...
sql/activiti.sql renamed to sql/bpm-activiti.sql
sql/bpm-flowable.sql 0 → 100644
  1 +/*
  2 + Navicat Premium Data Transfer
  3 +
  4 + Source Server : 127.0.0.1
  5 + Source Server Type : MySQL
  6 + Source Server Version : 80026
  7 + Source Host : localhost:3306
  8 + Source Schema : ruoyi-vue-pro-flowable
  9 +
  10 + Target Server Type : MySQL
  11 + Target Server Version : 80026
  12 + File Encoding : 65001
  13 +
  14 + Date: 28/02/2022 00:57:25
  15 +*/
  16 +
  17 +SET NAMES utf8mb4;
  18 +SET FOREIGN_KEY_CHECKS = 0;
  19 +
  20 +-- ----------------------------
  21 +-- Table structure for ACT_EVT_LOG
  22 +-- ----------------------------
  23 +DROP TABLE IF EXISTS `ACT_EVT_LOG`;
  24 +CREATE TABLE `ACT_EVT_LOG` (
  25 + `LOG_NR_` bigint NOT NULL AUTO_INCREMENT,
  26 + `TYPE_` varchar(64) COLLATE utf8_bin DEFAULT NULL,
  27 + `PROC_DEF_ID_` varchar(64) COLLATE utf8_bin DEFAULT NULL,
  28 + `PROC_INST_ID_` varchar(64) COLLATE utf8_bin DEFAULT NULL,
  29 + `EXECUTION_ID_` varchar(64) COLLATE utf8_bin DEFAULT NULL,
  30 + `TASK_ID_` varchar(64) COLLATE utf8_bin DEFAULT NULL,
  31 + `TIME_STAMP_` timestamp(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3),
  32 + `USER_ID_` varchar(255) COLLATE utf8_bin DEFAULT NULL,
  33 + `DATA_` longblob,
  34 + `LOCK_OWNER_` varchar(255) COLLATE utf8_bin DEFAULT NULL,
  35 + `LOCK_TIME_` timestamp(3) NULL DEFAULT NULL,
  36 + `IS_PROCESSED_` tinyint DEFAULT '0',
  37 + PRIMARY KEY (`LOG_NR_`)
  38 +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb3 COLLATE=utf8_bin;
  39 +
  40 +-- ----------------------------
  41 +-- Records of ACT_EVT_LOG
  42 +-- ----------------------------
  43 +BEGIN;
  44 +COMMIT;
  45 +
  46 +-- ----------------------------
  47 +-- Table structure for ACT_GE_BYTEARRAY
  48 +-- ----------------------------
  49 +DROP TABLE IF EXISTS `ACT_GE_BYTEARRAY`;
  50 +CREATE TABLE `ACT_GE_BYTEARRAY` (
  51 + `ID_` varchar(64) COLLATE utf8_bin NOT NULL,
  52 + `REV_` int DEFAULT NULL,
  53 + `NAME_` varchar(255) COLLATE utf8_bin DEFAULT NULL,
  54 + `DEPLOYMENT_ID_` varchar(64) COLLATE utf8_bin DEFAULT NULL,
  55 + `BYTES_` longblob,
  56 + `GENERATED_` tinyint DEFAULT NULL,
  57 + PRIMARY KEY (`ID_`),
  58 + KEY `ACT_FK_BYTEARR_DEPL` (`DEPLOYMENT_ID_`),
  59 + CONSTRAINT `ACT_FK_BYTEARR_DEPL` FOREIGN KEY (`DEPLOYMENT_ID_`) REFERENCES `ACT_RE_DEPLOYMENT` (`ID_`)
  60 +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb3 COLLATE=utf8_bin;
  61 +
  62 +-- ----------------------------
  63 +-- Records of ACT_GE_BYTEARRAY
  64 +-- ----------------------------
  65 +BEGIN;
  66 +INSERT INTO `ACT_GE_BYTEARRAY` VALUES ('7bac85f2-97ed-11ec-a2b9-862bc1a4a054', 2, 'source', NULL, 0x3C3F786D6C2076657273696F6E3D22312E302220656E636F64696E673D225554462D38223F3E0A3C62706D6E323A646566696E6974696F6E7320786D6C6E733A7873693D22687474703A2F2F7777772E77332E6F72672F323030312F584D4C536368656D612D696E7374616E63652220786D6C6E733A62706D6E323D22687474703A2F2F7777772E6F6D672E6F72672F737065632F42504D4E2F32303130303532342F4D4F44454C2220786D6C6E733A62706D6E64693D22687474703A2F2F7777772E6F6D672E6F72672F737065632F42504D4E2F32303130303532342F44492220786D6C6E733A64633D22687474703A2F2F7777772E6F6D672E6F72672F737065632F44442F32303130303532342F44432220786D6C6E733A64693D22687474703A2F2F7777772E6F6D672E6F72672F737065632F44442F32303130303532342F4449222069643D226469616772616D5F50726F636573735F3136343539383036353033313122207461726765744E616D6573706163653D22687474703A2F2F61637469766974692E6F72672F62706D6E223E3C62706D6E323A70726F636573732069643D22666C6F7761626C655F303122206E616D653D22666C6F7761626C65E6B58BE8AF952220697345786563757461626C653D2274727565223E3C62706D6E323A73746172744576656E742069643D224576656E745F3169727578696D223E3C62706D6E323A6F7574676F696E673E466C6F775F30383034676D6F3C2F62706D6E323A6F7574676F696E673E3C2F62706D6E323A73746172744576656E743E3C62706D6E323A757365725461736B2069643D227461736B303122206E616D653D227461736B3031223E3C62706D6E323A696E636F6D696E673E466C6F775F30383034676D6F3C2F62706D6E323A696E636F6D696E673E3C62706D6E323A6F7574676F696E673E466C6F775F306378343739783C2F62706D6E323A6F7574676F696E673E3C2F62706D6E323A757365725461736B3E3C62706D6E323A73657175656E6365466C6F772069643D22466C6F775F30383034676D6F2220736F757263655265663D224576656E745F3169727578696D22207461726765745265663D227461736B303122202F3E3C62706D6E323A656E644576656E742069643D224576656E745F316D647363637A223E3C62706D6E323A696E636F6D696E673E466C6F775F306378343739783C2F62706D6E323A696E636F6D696E673E3C2F62706D6E323A656E644576656E743E3C62706D6E323A73657175656E6365466C6F772069643D22466C6F775F306378343739782220736F757263655265663D227461736B303122207461726765745265663D224576656E745F316D647363637A22202F3E3C2F62706D6E323A70726F636573733E3C62706D6E64693A42504D4E4469616772616D2069643D2242504D4E4469616772616D5F31223E3C62706D6E64693A42504D4E506C616E652069643D22666C6F7761626C655F30315F6469222062706D6E456C656D656E743D22666C6F7761626C655F3031223E3C62706D6E64693A42504D4E456467652069643D22466C6F775F306378343739785F6469222062706D6E456C656D656E743D22466C6F775F30637834373978223E3C64693A776179706F696E7420783D223434302220793D2233353022202F3E3C64693A776179706F696E7420783D223439322220793D2233353022202F3E3C2F62706D6E64693A42504D4E456467653E3C62706D6E64693A42504D4E456467652069643D22466C6F775F30383034676D6F5F6469222062706D6E456C656D656E743D22466C6F775F30383034676D6F223E3C64693A776179706F696E7420783D223238382220793D2233353022202F3E3C64693A776179706F696E7420783D223334302220793D2233353022202F3E3C2F62706D6E64693A42504D4E456467653E3C62706D6E64693A42504D4E53686170652069643D224576656E745F3169727578696D5F6469222062706D6E456C656D656E743D224576656E745F3169727578696D223E3C64633A426F756E647320783D223235322220793D22333332222077696474683D22333622206865696768743D22333622202F3E3C2F62706D6E64693A42504D4E53686170653E3C62706D6E64693A42504D4E53686170652069643D227461736B30315F6469222062706D6E456C656D656E743D227461736B3031223E3C64633A426F756E647320783D223334302220793D22333130222077696474683D2231303022206865696768743D22383022202F3E3C2F62706D6E64693A42504D4E53686170653E3C62706D6E64693A42504D4E53686170652069643D224576656E745F316D647363637A5F6469222062706D6E456C656D656E743D224576656E745F316D647363637A223E3C64633A426F756E647320783D223439322220793D22333332222077696474683D22333622206865696768743D22333622202F3E3C2F62706D6E64693A42504D4E53686170653E3C2F62706D6E64693A42504D4E506C616E653E3C2F62706D6E64693A42504D4E4469616772616D3E3C2F62706D6E323A646566696E6974696F6E733E, NULL);
  67 +INSERT INTO `ACT_GE_BYTEARRAY` VALUES ('bfb4c0a4-97ed-11ec-a2b9-862bc1a4a054', 1, 'flowable_01.bpmn', 'bfb4c0a3-97ed-11ec-a2b9-862bc1a4a054', 0x3C3F786D6C2076657273696F6E3D22312E302220656E636F64696E673D225554462D38223F3E0A3C62706D6E323A646566696E6974696F6E7320786D6C6E733A7873693D22687474703A2F2F7777772E77332E6F72672F323030312F584D4C536368656D612D696E7374616E63652220786D6C6E733A62706D6E323D22687474703A2F2F7777772E6F6D672E6F72672F737065632F42504D4E2F32303130303532342F4D4F44454C2220786D6C6E733A62706D6E64693D22687474703A2F2F7777772E6F6D672E6F72672F737065632F42504D4E2F32303130303532342F44492220786D6C6E733A64633D22687474703A2F2F7777772E6F6D672E6F72672F737065632F44442F32303130303532342F44432220786D6C6E733A64693D22687474703A2F2F7777772E6F6D672E6F72672F737065632F44442F32303130303532342F4449222069643D226469616772616D5F50726F636573735F3136343539383036353033313122207461726765744E616D6573706163653D22687474703A2F2F61637469766974692E6F72672F62706D6E223E3C62706D6E323A70726F636573732069643D22666C6F7761626C655F303122206E616D653D22666C6F7761626C65E6B58BE8AF952220697345786563757461626C653D2274727565223E3C62706D6E323A73746172744576656E742069643D224576656E745F3169727578696D223E3C62706D6E323A6F7574676F696E673E466C6F775F30383034676D6F3C2F62706D6E323A6F7574676F696E673E3C2F62706D6E323A73746172744576656E743E3C62706D6E323A757365725461736B2069643D227461736B303122206E616D653D227461736B3031223E3C62706D6E323A696E636F6D696E673E466C6F775F30383034676D6F3C2F62706D6E323A696E636F6D696E673E3C62706D6E323A6F7574676F696E673E466C6F775F306378343739783C2F62706D6E323A6F7574676F696E673E3C2F62706D6E323A757365725461736B3E3C62706D6E323A73657175656E6365466C6F772069643D22466C6F775F30383034676D6F2220736F757263655265663D224576656E745F3169727578696D22207461726765745265663D227461736B303122202F3E3C62706D6E323A656E644576656E742069643D224576656E745F316D647363637A223E3C62706D6E323A696E636F6D696E673E466C6F775F306378343739783C2F62706D6E323A696E636F6D696E673E3C2F62706D6E323A656E644576656E743E3C62706D6E323A73657175656E6365466C6F772069643D22466C6F775F306378343739782220736F757263655265663D227461736B303122207461726765745265663D224576656E745F316D647363637A22202F3E3C2F62706D6E323A70726F636573733E3C62706D6E64693A42504D4E4469616772616D2069643D2242504D4E4469616772616D5F31223E3C62706D6E64693A42504D4E506C616E652069643D22666C6F7761626C655F30315F6469222062706D6E456C656D656E743D22666C6F7761626C655F3031223E3C62706D6E64693A42504D4E456467652069643D22466C6F775F306378343739785F6469222062706D6E456C656D656E743D22466C6F775F30637834373978223E3C64693A776179706F696E7420783D223434302220793D2233353022202F3E3C64693A776179706F696E7420783D223439322220793D2233353022202F3E3C2F62706D6E64693A42504D4E456467653E3C62706D6E64693A42504D4E456467652069643D22466C6F775F30383034676D6F5F6469222062706D6E456C656D656E743D22466C6F775F30383034676D6F223E3C64693A776179706F696E7420783D223238382220793D2233353022202F3E3C64693A776179706F696E7420783D223334302220793D2233353022202F3E3C2F62706D6E64693A42504D4E456467653E3C62706D6E64693A42504D4E53686170652069643D224576656E745F3169727578696D5F6469222062706D6E456C656D656E743D224576656E745F3169727578696D223E3C64633A426F756E647320783D223235322220793D22333332222077696474683D22333622206865696768743D22333622202F3E3C2F62706D6E64693A42504D4E53686170653E3C62706D6E64693A42504D4E53686170652069643D227461736B30315F6469222062706D6E456C656D656E743D227461736B3031223E3C64633A426F756E647320783D223334302220793D22333130222077696474683D2231303022206865696768743D22383022202F3E3C2F62706D6E64693A42504D4E53686170653E3C62706D6E64693A42504D4E53686170652069643D224576656E745F316D647363637A5F6469222062706D6E456C656D656E743D224576656E745F316D647363637A223E3C64633A426F756E647320783D223439322220793D22333332222077696474683D22333622206865696768743D22333622202F3E3C2F62706D6E64693A42504D4E53686170653E3C2F62706D6E64693A42504D4E506C616E653E3C2F62706D6E64693A42504D4E4469616772616D3E3C2F62706D6E323A646566696E6974696F6E733E, 0);
  68 +INSERT INTO `ACT_GE_BYTEARRAY` VALUES ('c0bae605-97ed-11ec-a2b9-862bc1a4a054', 1, 'flowable_01.flowable_01.png', 'bfb4c0a3-97ed-11ec-a2b9-862bc1a4a054', 0x89504E470D0A1A0A0000000D494844520000021A000001900806000000E87AC905000010174944415478DAEDDD0B8896F59E07F0531854D8952516929038D021160A3AD0424B146C6450ED093273D4AC316D2D1BEDA25D305BCDAE6BB638854442EDD9A2C432375BCE76BCA4633A8A5D5C2F15999D2E8EB38EBA9AE6F136F5ECF37B9877781C9D1C67E6BDCCF8F9C01FDF79DF77DE9197E7F93FDFE77FFDCD6F0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003A2549923EDF7CF3CD9C952B57FEBC68D1A264C182054A89CBC2850B93BABABAED6919EA8804A0578990B16CD9B2A4A9A9293970E08052A6B26DDBB664E9D2A53FA6A1E366472500BD46B46408191513360E2C58B0E00B472500BD467497B8C8574E4983C621472500BD468C117081AFA8A091382A0138E182C64FBB1A936F56BF9A6C5838252BF1389E130E040D00E852D0D8B3B32159FFC163C9FFFCD7F8C34A3C17AF0908820600743A68FCB0E1BD234246A16CDE305F40103400A0F341E38B0F9F6D3768C46B0282A001009D0E1AEB17FC4BBB41235E1310040D001034040D00A8BCA011B34CDA0B1AF19A8020680040A783C6C6E52FB61B34E2350141D000804E078D1D0D6B93F57F7EFCC86E93F4B9784D40103400A0D34123CA5F3EFEE31141239E130E040D00E85AD0D8BF3FD9B862E691DD26E973F19A8020680040A78246ACFCF9D5F2DA76C768C46B5607153400E0F882C6FEFD49E3C6C5C9BAFF7EB4DD905128F19E78AFD60D4103008E19348ED58AA17543D000804E078D8EB462FC5AEB86C020680040BB41A3B321A3500406410300DA0D1A8AA0512EB7DF7EFBD9B7DE7AEBCD69A94D4B7D5A1AD392E44AFC5C3F68D0A057060F1E3C342D7FE32C064A6AF3E6CD97BCFBEEBBFFF6D24B2FAD9F3871E29E3163C6FC3C64C890D68A6AE4C891071F78E0811D93274FAE9B366DDA3FA715DBA982860BBCA0515E6970B83E3D3FE7A7C1A1B94DB03866497F67415AFE70D55557F5510302459124499FFAFAFA093366CC684C8344F2F4D34F2773E7CE4DD6AC599334343424CDCDCD49C18E1D3B92B56BD726F3E6CD4B5E7CF1C5240D1ACDE3C78F5F515D5D7D89A0A1081AA5950685DFA72161E5F1868B76CAEAF4B306A811816EB574E9D2EA175E7861CFDD77DF9DCC993327696C6C4C8EC7CE9D3BB3CAFD9E7BEE39545353B33CADACFA0B1A8AA0515CD1FA908682A78FD682F1D0430F65E7F2F2E5CB93EFBFFF3ED9B76F5F76AE1E3C7830FB79E5CA95D98DC4638F3DD65EE0A83DD15B2A816E6AC5983D7BF6BAEAEAEAE4CD37DF6CAD8C3A2B5A3DA29563D8B06187468C18F190A0A1081AC53164C8907E6D5B31D2F32E79F5D5578FFB46E1DB6FBF4D66CD9A152D936DC3C6BAF83B6A4AA053D2CAA87F6D6D6DD3B871E3B28AA63BC5E7DD77DF7DFB468E1CF9FA8970572468081AA594068CDF5555556DC98782E8EA6C6A6AEAD2791B5DA253A64C691B367E38D15A28816E0A19D15512CDA6D1ED510CD13AF2E4934FEE1D3162C49F7AFB00334143D028654B463E64442BC692254B0E1B43D555CB962DCB3E57D8003A25BA4BA22523424657BB4A3AD2953275EAD4DD69A5354BD050048DAE691993D1DA5D1233C1BEFCF2CBA29CBB3186A34D57CABA810307F6558302C7146332A2BB64F7EEDD49294498A9A9A9D99D568A13040D45D0E8BC18F8996FC92856C8C8878DFCB4F61820AA06057E555D5DDDC818F8D9DD63323A326623ADB0F6A57744BF15341441E3F8B54C616D9D5D12DD25A510DD286DD6DB30F51538BAE83279FEF9E77F8AD925E53077EEDC5D69D8982B68288246A75A3356E6077E76E7988C6369334074B545BD80A38AC5B8629D8C628FCBF8B5F11AD5D5D55BABAAAA2E15341441A3E35A56FC6CED32E9EAEC92CECC46C98FD7881544D5A8C011A64F9FDE180BF894D3FCF9F363F4FA7F081A8AA0D171B1AC78E1221FEB6494C3EBAFBF7ED872E56A54E030B177492C2B7EBC0BF974B7984A5B5555F57FBD6D6D0D4143D02896D8202D3F36A35CE770B4A2E40786DA880D384C6C90F6DC73CF2595E091471E591D4DC13DE17B6BD968EA1F040D41A35CC757CB2EACADCB8A97537EB9F2D8F555CD0AB49A3163C686D8D7A012BCF6DA6BEB7ACA34B97C53711A8EFE5ED010344A7D7CB56CF59EBDAFDC5D9F518714FE2FB1C5BC9A1568155BBDC72EAC95E0D34F3FDD985654F53DE942902B7F3ADA1DA8A0216814EBF88A73A5F07A6C90564EB1AE46EEFF5AAF66055A8D1933E6E7728FCF28D8BE7DFB4F6925D5D8432F04AD77A0F90B82A0216814EBF88A73A5F07CECBA5A4E0D0D0DF9FF67A39A15681583B84A39EFFE58A2A2EAC91782FC1D6834790B1A8246B18EAFFCCFB1C57B39C5DFCFFF7FD4ACC061155A25E94005DBA38AA05159A5B71D5F855269E7AE9A15A8D4168D3DBDA045239B39535821F1440A1AFBF7EF3FEAF33FFEF863B6189C168DEE3DBEF2CF976BB13D2D1AC0318D1E3DFA40A58CD1D8BA75EBFA1E3C46E3B080515029412342C0AC59B39237DE78A353BFFFD65B6FC5C52379E79D778E786DEAD4A9C959679D959C79E699D934C7FC6BB18854FCDECC9933058D6E3EBEF263344ABD4791311A40874D9830E17F2B65D6497D7DFD921E38EBA43E965D6E6F8F874A091A2B56ACC82EF8D3A64DEB52D078FBEDB70F7B3E8E9D934E3A29B9EEBAEB921B6EB8217B4FCC40D8B3674FF2ECB3CF26A79F7EBAA051A4E3CBAC13A047983265CA9F2B651D8DE9D3A7CFEF41EB681CB505A35283C6A5975E9A5DF0CF3DF7DCA4B6B6366B6ABFF3CE3B93F3CF3F3F39F5D45393ABAFBE3ABB2B8DD6ADE84E3BEFBCF392BE7DFB66FB58446B483E68BCF2CA2B49FFFEFD93B163C726CF3CF34CF67C0499CF3EFB2C7BFCF8E38F27AB56ADCA3EF7C61B6F14348A747CE5D7D1983D7BB6753480CA94DE75DE91DEE5FE520941E3AEBBEE9ADF535606EDA84A091AE3C78FCF2EF8D1F250575797BCF7DE7B5957C7A44993927BEFBD377B2D02C4C48913B3C7D1CD128F2FBEF8E2ECFD85A0317AF4E8E494534E49AEBCF2CA6CEC454D4D4DF6FCC68D1B93CD9B37678F478D1A956CD9B225F9EAABAF92850B170A1AC50B235606052A5FEC2D525D5D7D3076612CF31A1A313E639BBD4E4AD775B278F1E264C28409C965975D96BD165B7EBFFFFEFBD9E3E8F2B8E69A6BB280B077EFDED6A051281F7DF451F61963C68CC97EFEFAEBAF5B8346B49414FE86A051D473F7ECF49C3954B8C06FDAB4A96C7B9D545555FD62AF13A05DE9DDD087F3E7CF2F6BD0A8ADADFD77BBB7962E6844EB45A185235A35E2F1134F3CD13A80F3A69B6ECA5A3CE2F9E86A29048D0B2FBC3039EDB4D3926BAFBD367B6FFC4E3C1F5D256BD7AECD1EE707840A1A456FD568DDBDF5E5975FB67B2B5099AAABAB2F19356A5473B9A6C8353737FF9056505FA77745970A1AC5291F7FFC7176C14FBFE3E4934F3EC9BA37E2E70F3EF82079F4D147B3C7D155124DF0E79C734E12C133C663C4F3E3C68D6B0D1A3116E0E1871FCE1E47F74B74ABC4E341830625B7DD765BF6385A4A048DD288AEC6C2457ED8B06159EB4229454BE8F0E1C3F3AD197F50A302473576ECD8A5E51A14FAD4534FBD965652737AE3F75A294163E7CE9D49BF7EFDB28BFE830F3E18337C920B2EB820FBF9F2CB2F4FCE38E38CAC15E3BBEFBE4BAEB8E28AA44F9F3E59CBC5800103B22E91FCF4D6EDDBB76783452FBAE8A26C5069749F9C7CF2C9D9EC937CB789A051B2568DD6D927D1FD55CA7571E2EFE5A7E01E6B703470021B3870E0DFDE71C71D074A3D1FFFF3CF3F5F9A56507BD2BFFF5B41A3B825C65A4468C8AFAD11334D8EF6DEB853DDB56B57873F3BDEBF6DDB364B9097C12DB7DCF28FF93537962C5952927377D9B2656DF76119A026057E55555555CDB871E3FE5AAA2E94F4C2B721FD9B1BD24AEAC1DEFA9D5A825CD02851ABC6BF162EF8313D394240B1D7CD183A74E82FB9A051AB06053A64C488117F9C3C7972D1C3467373F3B7D5D5D58BD30A6A666FFE3E050D41A3145A9624AFCF878D622DE2152163F8F0E13FE742C6BA810307F6557B021DAEB0D200F09F93264DDA5DACB0112D1969A0F930C665F4B6E9AC8286A0512E69B8E8979E531BF36123BA51BA73CC46B494B469C9F8212DFDD59CC071878DAAAAAA976B6A6A7677F7988D1893D1D25D32B3B7870C4143D028B5B8E8E7C3466180685767A3C4189C36033F850CA0EB060D1A3426BD2BFA69F6ECD93B6377C6AE4E616D995DB2A7378FC91034048D0A69D9A8CF878298FA1AEBA31CEF068A1150629D8CFC14D64277899001748B988D3278F0E0B7D38A66D79C397336A57736878E77C5CF588C2BFD8C2FA3AB24FDF77727D2F72768081AE56A954C6F145E38DA56F3B16E4AAC87126338A2C5B2701311FFC62CA41883316FDEBC6CE1B5FC8A9FF9819FC66400C568DDF8BBD82C29AD7876DF7FFFFD6B66CD9AB566D5AA559BB66CD9B237972BF644B0885D586383B4D8BB2496154FC3C59BBD71312E4143D0A8742D535FEB8F16383A51569BC20A145D8CAB68A9BC623A5D0CE8FC4B7EBF85B434B6546CB5B16AE189300E43D010347AC08DC2F52DCB951F3ADE8011CB8AB7B7553D0082862268E46F14CE4E43C7AD2D5BCCD7B7DC18246D6F14A2F53276618DAE53673180A0A1081A00081A8AA001008286A0010082862268002068B8C00B1A002068081A00206828820600081A820600081A820600081A8AA001008286A001008286A00100828622680080A021680080A021680080A0A1081A002068081A00502E8B162D7281AF9CB22F0D1A871C9500F41A7575758D4D4D4D2EF215501A1A1ADE4A83C6178E4A007A8DC58B17FFD392254B766DDDBAF5AF2EF6E56BC98890B170E1C2EFD272B3A312805E25BDB85D9FDE49AF8E66FB1823A094BCC4F7FE859001000000000000000000000000000000000000F408FF0FC85213564CA9202B0000000049454E44AE426082, 1);
  69 +INSERT INTO `ACT_GE_BYTEARRAY` VALUES ('c969093d-97ed-11ec-a2b9-862bc1a4a054', 1, 'hist.var-field122', NULL, 0xACED0005737200136A6176612E7574696C2E41727261794C6973747881D21D99C7619D03000149000473697A65787000000001770400000001737200116A6176612E6C616E672E496E746567657212E2A0A4F781873802000149000576616C7565787200106A6176612E6C616E672E4E756D62657286AC951D0B94E08B02000078700000000178, NULL);
  70 +INSERT INTO `ACT_GE_BYTEARRAY` VALUES ('c969304e-97ed-11ec-a2b9-862bc1a4a054', 1, 'hist.detail.var-field122', NULL, 0xACED0005737200136A6176612E7574696C2E41727261794C6973747881D21D99C7619D03000149000473697A65787000000001770400000001737200116A6176612E6C616E672E496E746567657212E2A0A4F781873802000149000576616C7565787200106A6176612E6C616E672E4E756D62657286AC951D0B94E08B02000078700000000178, NULL);
  71 +COMMIT;
  72 +
  73 +-- ----------------------------
  74 +-- Table structure for ACT_GE_PROPERTY
  75 +-- ----------------------------
  76 +DROP TABLE IF EXISTS `ACT_GE_PROPERTY`;
  77 +CREATE TABLE `ACT_GE_PROPERTY` (
  78 + `NAME_` varchar(64) COLLATE utf8_bin NOT NULL,
  79 + `VALUE_` varchar(300) COLLATE utf8_bin DEFAULT NULL,
  80 + `REV_` int DEFAULT NULL,
  81 + PRIMARY KEY (`NAME_`)
  82 +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb3 COLLATE=utf8_bin;
  83 +
  84 +-- ----------------------------
  85 +-- Records of ACT_GE_PROPERTY
  86 +-- ----------------------------
  87 +BEGIN;
  88 +INSERT INTO `ACT_GE_PROPERTY` VALUES ('batch.schema.version', '6.7.0.0', 1);
  89 +INSERT INTO `ACT_GE_PROPERTY` VALUES ('cfg.execution-related-entities-count', 'true', 1);
  90 +INSERT INTO `ACT_GE_PROPERTY` VALUES ('cfg.task-related-entities-count', 'true', 1);
  91 +INSERT INTO `ACT_GE_PROPERTY` VALUES ('common.schema.version', '6.7.0.0', 1);
  92 +INSERT INTO `ACT_GE_PROPERTY` VALUES ('entitylink.schema.version', '6.7.0.0', 1);
  93 +INSERT INTO `ACT_GE_PROPERTY` VALUES ('eventsubscription.schema.version', '6.7.0.0', 1);
  94 +INSERT INTO `ACT_GE_PROPERTY` VALUES ('identitylink.schema.version', '6.7.0.0', 1);
  95 +INSERT INTO `ACT_GE_PROPERTY` VALUES ('job.schema.version', '6.7.0.0', 1);
  96 +INSERT INTO `ACT_GE_PROPERTY` VALUES ('next.dbid', '1', 1);
  97 +INSERT INTO `ACT_GE_PROPERTY` VALUES ('schema.history', 'create(6.7.0.0)', 1);
  98 +INSERT INTO `ACT_GE_PROPERTY` VALUES ('schema.version', '6.7.0.0', 1);
  99 +INSERT INTO `ACT_GE_PROPERTY` VALUES ('task.schema.version', '6.7.0.0', 1);
  100 +INSERT INTO `ACT_GE_PROPERTY` VALUES ('variable.schema.version', '6.7.0.0', 1);
  101 +COMMIT;
  102 +
  103 +-- ----------------------------
  104 +-- Table structure for ACT_HI_ACTINST
  105 +-- ----------------------------
  106 +DROP TABLE IF EXISTS `ACT_HI_ACTINST`;
  107 +CREATE TABLE `ACT_HI_ACTINST` (
  108 + `ID_` varchar(64) COLLATE utf8_bin NOT NULL,
  109 + `REV_` int DEFAULT '1',
  110 + `PROC_DEF_ID_` varchar(64) COLLATE utf8_bin NOT NULL,
  111 + `PROC_INST_ID_` varchar(64) COLLATE utf8_bin NOT NULL,
  112 + `EXECUTION_ID_` varchar(64) COLLATE utf8_bin NOT NULL,
  113 + `ACT_ID_` varchar(255) COLLATE utf8_bin NOT NULL,
  114 + `TASK_ID_` varchar(64) COLLATE utf8_bin DEFAULT NULL,
  115 + `CALL_PROC_INST_ID_` varchar(64) COLLATE utf8_bin DEFAULT NULL,
  116 + `ACT_NAME_` varchar(255) COLLATE utf8_bin DEFAULT NULL,
  117 + `ACT_TYPE_` varchar(255) COLLATE utf8_bin NOT NULL,
  118 + `ASSIGNEE_` varchar(255) COLLATE utf8_bin DEFAULT NULL,
  119 + `START_TIME_` datetime(3) NOT NULL,
  120 + `END_TIME_` datetime(3) DEFAULT NULL,
  121 + `TRANSACTION_ORDER_` int DEFAULT NULL,
  122 + `DURATION_` bigint DEFAULT NULL,
  123 + `DELETE_REASON_` varchar(4000) COLLATE utf8_bin DEFAULT NULL,
  124 + `TENANT_ID_` varchar(255) COLLATE utf8_bin DEFAULT '',
  125 + PRIMARY KEY (`ID_`),
  126 + KEY `ACT_IDX_HI_ACT_INST_START` (`START_TIME_`),
  127 + KEY `ACT_IDX_HI_ACT_INST_END` (`END_TIME_`),
  128 + KEY `ACT_IDX_HI_ACT_INST_PROCINST` (`PROC_INST_ID_`,`ACT_ID_`),
  129 + KEY `ACT_IDX_HI_ACT_INST_EXEC` (`EXECUTION_ID_`,`ACT_ID_`)
  130 +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb3 COLLATE=utf8_bin;
  131 +
  132 +-- ----------------------------
  133 +-- Records of ACT_HI_ACTINST
  134 +-- ----------------------------
  135 +BEGIN;
  136 +INSERT INTO `ACT_HI_ACTINST` VALUES ('c9695761-97ed-11ec-a2b9-862bc1a4a054', 1, 'flowable_01:1:c0bb5b36-97ed-11ec-a2b9-862bc1a4a054', 'c964c377-97ed-11ec-a2b9-862bc1a4a054', 'c9695760-97ed-11ec-a2b9-862bc1a4a054', 'Event_1iruxim', NULL, NULL, NULL, 'startEvent', NULL, '2022-02-28 00:53:28.382', '2022-02-28 00:53:28.388', 1, 6, NULL, '');
  137 +INSERT INTO `ACT_HI_ACTINST` VALUES ('c96b0512-97ed-11ec-a2b9-862bc1a4a054', 1, 'flowable_01:1:c0bb5b36-97ed-11ec-a2b9-862bc1a4a054', 'c964c377-97ed-11ec-a2b9-862bc1a4a054', 'c9695760-97ed-11ec-a2b9-862bc1a4a054', 'Flow_0804gmo', NULL, NULL, NULL, 'sequenceFlow', NULL, '2022-02-28 00:53:28.392', '2022-02-28 00:53:28.392', 2, 0, NULL, '');
  138 +INSERT INTO `ACT_HI_ACTINST` VALUES ('c96b0513-97ed-11ec-a2b9-862bc1a4a054', 2, 'flowable_01:1:c0bb5b36-97ed-11ec-a2b9-862bc1a4a054', 'c964c377-97ed-11ec-a2b9-862bc1a4a054', 'c9695760-97ed-11ec-a2b9-862bc1a4a054', 'task01', 'c97146a4-97ed-11ec-a2b9-862bc1a4a054', NULL, 'task01', 'userTask', '1', '2022-02-28 00:53:28.392', '2022-02-28 00:53:34.789', 3, 6397, NULL, '');
  139 +INSERT INTO `ACT_HI_ACTINST` VALUES ('cd3b6e08-97ed-11ec-a2b9-862bc1a4a054', 1, 'flowable_01:1:c0bb5b36-97ed-11ec-a2b9-862bc1a4a054', 'c964c377-97ed-11ec-a2b9-862bc1a4a054', 'c9695760-97ed-11ec-a2b9-862bc1a4a054', 'Flow_0cx479x', NULL, NULL, NULL, 'sequenceFlow', NULL, '2022-02-28 00:53:34.792', '2022-02-28 00:53:34.792', 1, 0, NULL, '');
  140 +INSERT INTO `ACT_HI_ACTINST` VALUES ('cd3be339-97ed-11ec-a2b9-862bc1a4a054', 1, 'flowable_01:1:c0bb5b36-97ed-11ec-a2b9-862bc1a4a054', 'c964c377-97ed-11ec-a2b9-862bc1a4a054', 'c9695760-97ed-11ec-a2b9-862bc1a4a054', 'Event_1mdsccz', NULL, NULL, NULL, 'endEvent', NULL, '2022-02-28 00:53:34.794', '2022-02-28 00:53:34.796', 2, 2, NULL, '');
  141 +COMMIT;
  142 +
  143 +-- ----------------------------
  144 +-- Table structure for ACT_HI_ATTACHMENT
  145 +-- ----------------------------
  146 +DROP TABLE IF EXISTS `ACT_HI_ATTACHMENT`;
  147 +CREATE TABLE `ACT_HI_ATTACHMENT` (
  148 + `ID_` varchar(64) COLLATE utf8_bin NOT NULL,
  149 + `REV_` int DEFAULT NULL,
  150 + `USER_ID_` varchar(255) COLLATE utf8_bin DEFAULT NULL,
  151 + `NAME_` varchar(255) COLLATE utf8_bin DEFAULT NULL,
  152 + `DESCRIPTION_` varchar(4000) COLLATE utf8_bin DEFAULT NULL,
  153 + `TYPE_` varchar(255) COLLATE utf8_bin DEFAULT NULL,
  154 + `TASK_ID_` varchar(64) COLLATE utf8_bin DEFAULT NULL,
  155 + `PROC_INST_ID_` varchar(64) COLLATE utf8_bin DEFAULT NULL,
  156 + `URL_` varchar(4000) COLLATE utf8_bin DEFAULT NULL,
  157 + `CONTENT_ID_` varchar(64) COLLATE utf8_bin DEFAULT NULL,
  158 + `TIME_` datetime(3) DEFAULT NULL,
  159 + PRIMARY KEY (`ID_`)
  160 +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb3 COLLATE=utf8_bin;
  161 +
  162 +-- ----------------------------
  163 +-- Records of ACT_HI_ATTACHMENT
  164 +-- ----------------------------
  165 +BEGIN;
  166 +COMMIT;
  167 +
  168 +-- ----------------------------
  169 +-- Table structure for ACT_HI_COMMENT
  170 +-- ----------------------------
  171 +DROP TABLE IF EXISTS `ACT_HI_COMMENT`;
  172 +CREATE TABLE `ACT_HI_COMMENT` (
  173 + `ID_` varchar(64) COLLATE utf8_bin NOT NULL,
  174 + `TYPE_` varchar(255) COLLATE utf8_bin DEFAULT NULL,
  175 + `TIME_` datetime(3) NOT NULL,
  176 + `USER_ID_` varchar(255) COLLATE utf8_bin DEFAULT NULL,
  177 + `TASK_ID_` varchar(64) COLLATE utf8_bin DEFAULT NULL,
  178 + `PROC_INST_ID_` varchar(64) COLLATE utf8_bin DEFAULT NULL,
  179 + `ACTION_` varchar(255) COLLATE utf8_bin DEFAULT NULL,
  180 + `MESSAGE_` varchar(4000) COLLATE utf8_bin DEFAULT NULL,
  181 + `FULL_MSG_` longblob,
  182 + PRIMARY KEY (`ID_`)
  183 +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb3 COLLATE=utf8_bin;
  184 +
  185 +-- ----------------------------
  186 +-- Records of ACT_HI_COMMENT
  187 +-- ----------------------------
  188 +BEGIN;
  189 +COMMIT;
  190 +
  191 +-- ----------------------------
  192 +-- Table structure for ACT_HI_DETAIL
  193 +-- ----------------------------
  194 +DROP TABLE IF EXISTS `ACT_HI_DETAIL`;
  195 +CREATE TABLE `ACT_HI_DETAIL` (
  196 + `ID_` varchar(64) COLLATE utf8_bin NOT NULL,
  197 + `TYPE_` varchar(255) COLLATE utf8_bin NOT NULL,
  198 + `PROC_INST_ID_` varchar(64) COLLATE utf8_bin DEFAULT NULL,
  199 + `EXECUTION_ID_` varchar(64) COLLATE utf8_bin DEFAULT NULL,
  200 + `TASK_ID_` varchar(64) COLLATE utf8_bin DEFAULT NULL,
  201 + `ACT_INST_ID_` varchar(64) COLLATE utf8_bin DEFAULT NULL,
  202 + `NAME_` varchar(255) COLLATE utf8_bin NOT NULL,
  203 + `VAR_TYPE_` varchar(255) COLLATE utf8_bin DEFAULT NULL,
  204 + `REV_` int DEFAULT NULL,
  205 + `TIME_` datetime(3) NOT NULL,
  206 + `BYTEARRAY_ID_` varchar(64) COLLATE utf8_bin DEFAULT NULL,
  207 + `DOUBLE_` double DEFAULT NULL,
  208 + `LONG_` bigint DEFAULT NULL,
  209 + `TEXT_` varchar(4000) COLLATE utf8_bin DEFAULT NULL,
  210 + `TEXT2_` varchar(4000) COLLATE utf8_bin DEFAULT NULL,
  211 + PRIMARY KEY (`ID_`),
  212 + KEY `ACT_IDX_HI_DETAIL_PROC_INST` (`PROC_INST_ID_`),
  213 + KEY `ACT_IDX_HI_DETAIL_ACT_INST` (`ACT_INST_ID_`),
  214 + KEY `ACT_IDX_HI_DETAIL_TIME` (`TIME_`),
  215 + KEY `ACT_IDX_HI_DETAIL_NAME` (`NAME_`),
  216 + KEY `ACT_IDX_HI_DETAIL_TASK_ID` (`TASK_ID_`)
  217 +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb3 COLLATE=utf8_bin;
  218 +
  219 +-- ----------------------------
  220 +-- Records of ACT_HI_DETAIL
  221 +-- ----------------------------
  222 +BEGIN;
  223 +INSERT INTO `ACT_HI_DETAIL` VALUES ('c9681eda-97ed-11ec-a2b9-862bc1a4a054', 'VariableUpdate', 'c964c377-97ed-11ec-a2b9-862bc1a4a054', 'c964c377-97ed-11ec-a2b9-862bc1a4a054', NULL, NULL, 'field121', 'string', 0, '2022-02-28 00:53:28.373', NULL, NULL, NULL, 'AAA', NULL);
  224 +INSERT INTO `ACT_HI_DETAIL` VALUES ('c969304f-97ed-11ec-a2b9-862bc1a4a054', 'VariableUpdate', 'c964c377-97ed-11ec-a2b9-862bc1a4a054', 'c964c377-97ed-11ec-a2b9-862bc1a4a054', NULL, NULL, 'field122', 'serializable', 0, '2022-02-28 00:53:28.379', 'c969304e-97ed-11ec-a2b9-862bc1a4a054', NULL, NULL, NULL, NULL);
  225 +COMMIT;
  226 +
  227 +-- ----------------------------
  228 +-- Table structure for ACT_HI_ENTITYLINK
  229 +-- ----------------------------
  230 +DROP TABLE IF EXISTS `ACT_HI_ENTITYLINK`;
  231 +CREATE TABLE `ACT_HI_ENTITYLINK` (
  232 + `ID_` varchar(64) COLLATE utf8_bin NOT NULL,
  233 + `LINK_TYPE_` varchar(255) COLLATE utf8_bin DEFAULT NULL,
  234 + `CREATE_TIME_` datetime(3) DEFAULT NULL,
  235 + `SCOPE_ID_` varchar(255) COLLATE utf8_bin DEFAULT NULL,
  236 + `SUB_SCOPE_ID_` varchar(255) COLLATE utf8_bin DEFAULT NULL,
  237 + `SCOPE_TYPE_` varchar(255) COLLATE utf8_bin DEFAULT NULL,
  238 + `SCOPE_DEFINITION_ID_` varchar(255) COLLATE utf8_bin DEFAULT NULL,
  239 + `PARENT_ELEMENT_ID_` varchar(255) COLLATE utf8_bin DEFAULT NULL,
  240 + `REF_SCOPE_ID_` varchar(255) COLLATE utf8_bin DEFAULT NULL,
  241 + `REF_SCOPE_TYPE_` varchar(255) COLLATE utf8_bin DEFAULT NULL,
  242 + `REF_SCOPE_DEFINITION_ID_` varchar(255) COLLATE utf8_bin DEFAULT NULL,
  243 + `ROOT_SCOPE_ID_` varchar(255) COLLATE utf8_bin DEFAULT NULL,
  244 + `ROOT_SCOPE_TYPE_` varchar(255) COLLATE utf8_bin DEFAULT NULL,
  245 + `HIERARCHY_TYPE_` varchar(255) COLLATE utf8_bin DEFAULT NULL,
  246 + PRIMARY KEY (`ID_`),
  247 + KEY `ACT_IDX_HI_ENT_LNK_SCOPE` (`SCOPE_ID_`,`SCOPE_TYPE_`,`LINK_TYPE_`),
  248 + KEY `ACT_IDX_HI_ENT_LNK_REF_SCOPE` (`REF_SCOPE_ID_`,`REF_SCOPE_TYPE_`,`LINK_TYPE_`),
  249 + KEY `ACT_IDX_HI_ENT_LNK_ROOT_SCOPE` (`ROOT_SCOPE_ID_`,`ROOT_SCOPE_TYPE_`,`LINK_TYPE_`),
  250 + KEY `ACT_IDX_HI_ENT_LNK_SCOPE_DEF` (`SCOPE_DEFINITION_ID_`,`SCOPE_TYPE_`,`LINK_TYPE_`)
  251 +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb3 COLLATE=utf8_bin;
  252 +
  253 +-- ----------------------------
  254 +-- Records of ACT_HI_ENTITYLINK
  255 +-- ----------------------------
  256 +BEGIN;
  257 +COMMIT;
  258 +
  259 +-- ----------------------------
  260 +-- Table structure for ACT_HI_IDENTITYLINK
  261 +-- ----------------------------
  262 +DROP TABLE IF EXISTS `ACT_HI_IDENTITYLINK`;
  263 +CREATE TABLE `ACT_HI_IDENTITYLINK` (
  264 + `ID_` varchar(64) COLLATE utf8_bin NOT NULL,
  265 + `GROUP_ID_` varchar(255) COLLATE utf8_bin DEFAULT NULL,
  266 + `TYPE_` varchar(255) COLLATE utf8_bin DEFAULT NULL,
  267 + `USER_ID_` varchar(255) COLLATE utf8_bin DEFAULT NULL,
  268 + `TASK_ID_` varchar(64) COLLATE utf8_bin DEFAULT NULL,
  269 + `CREATE_TIME_` datetime(3) DEFAULT NULL,
  270 + `PROC_INST_ID_` varchar(64) COLLATE utf8_bin DEFAULT NULL,
  271 + `SCOPE_ID_` varchar(255) COLLATE utf8_bin DEFAULT NULL,
  272 + `SUB_SCOPE_ID_` varchar(255) COLLATE utf8_bin DEFAULT NULL,
  273 + `SCOPE_TYPE_` varchar(255) COLLATE utf8_bin DEFAULT NULL,
  274 + `SCOPE_DEFINITION_ID_` varchar(255) COLLATE utf8_bin DEFAULT NULL,
  275 + PRIMARY KEY (`ID_`),
  276 + KEY `ACT_IDX_HI_IDENT_LNK_USER` (`USER_ID_`),
  277 + KEY `ACT_IDX_HI_IDENT_LNK_SCOPE` (`SCOPE_ID_`,`SCOPE_TYPE_`),
  278 + KEY `ACT_IDX_HI_IDENT_LNK_SUB_SCOPE` (`SUB_SCOPE_ID_`,`SCOPE_TYPE_`),
  279 + KEY `ACT_IDX_HI_IDENT_LNK_SCOPE_DEF` (`SCOPE_DEFINITION_ID_`,`SCOPE_TYPE_`),
  280 + KEY `ACT_IDX_HI_IDENT_LNK_TASK` (`TASK_ID_`),
  281 + KEY `ACT_IDX_HI_IDENT_LNK_PROCINST` (`PROC_INST_ID_`)
  282 +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb3 COLLATE=utf8_bin;
  283 +
  284 +-- ----------------------------
  285 +-- Records of ACT_HI_IDENTITYLINK
  286 +-- ----------------------------
  287 +BEGIN;
  288 +INSERT INTO `ACT_HI_IDENTITYLINK` VALUES ('c9651198-97ed-11ec-a2b9-862bc1a4a054', NULL, 'starter', '1', NULL, '2022-02-28 00:53:28.353', 'c964c377-97ed-11ec-a2b9-862bc1a4a054', NULL, NULL, NULL, NULL);
  289 +INSERT INTO `ACT_HI_IDENTITYLINK` VALUES ('c9769dd5-97ed-11ec-a2b9-862bc1a4a054', NULL, 'assignee', '1', 'c97146a4-97ed-11ec-a2b9-862bc1a4a054', '2022-02-28 00:53:28.468', NULL, NULL, NULL, NULL, NULL);
  290 +INSERT INTO `ACT_HI_IDENTITYLINK` VALUES ('c978e7c6-97ed-11ec-a2b9-862bc1a4a054', NULL, 'participant', '1', NULL, '2022-02-28 00:53:28.483', 'c964c377-97ed-11ec-a2b9-862bc1a4a054', NULL, NULL, NULL, NULL);
  291 +INSERT INTO `ACT_HI_IDENTITYLINK` VALUES ('cd377667-97ed-11ec-a2b9-862bc1a4a054', NULL, 'participant', '1', NULL, '2022-02-28 00:53:34.765', 'c964c377-97ed-11ec-a2b9-862bc1a4a054', NULL, NULL, NULL, NULL);
  292 +COMMIT;
  293 +
  294 +-- ----------------------------
  295 +-- Table structure for ACT_HI_PROCINST
  296 +-- ----------------------------
  297 +DROP TABLE IF EXISTS `ACT_HI_PROCINST`;
  298 +CREATE TABLE `ACT_HI_PROCINST` (
  299 + `ID_` varchar(64) COLLATE utf8_bin NOT NULL,
  300 + `REV_` int DEFAULT '1',
  301 + `PROC_INST_ID_` varchar(64) COLLATE utf8_bin NOT NULL,
  302 + `BUSINESS_KEY_` varchar(255) COLLATE utf8_bin DEFAULT NULL,
  303 + `PROC_DEF_ID_` varchar(64) COLLATE utf8_bin NOT NULL,
  304 + `START_TIME_` datetime(3) NOT NULL,
  305 + `END_TIME_` datetime(3) DEFAULT NULL,
  306 + `DURATION_` bigint DEFAULT NULL,
  307 + `START_USER_ID_` varchar(255) COLLATE utf8_bin DEFAULT NULL,
  308 + `START_ACT_ID_` varchar(255) COLLATE utf8_bin DEFAULT NULL,
  309 + `END_ACT_ID_` varchar(255) COLLATE utf8_bin DEFAULT NULL,
  310 + `SUPER_PROCESS_INSTANCE_ID_` varchar(64) COLLATE utf8_bin DEFAULT NULL,
  311 + `DELETE_REASON_` varchar(4000) COLLATE utf8_bin DEFAULT NULL,
  312 + `TENANT_ID_` varchar(255) COLLATE utf8_bin DEFAULT '',
  313 + `NAME_` varchar(255) COLLATE utf8_bin DEFAULT NULL,
  314 + `CALLBACK_ID_` varchar(255) COLLATE utf8_bin DEFAULT NULL,
  315 + `CALLBACK_TYPE_` varchar(255) COLLATE utf8_bin DEFAULT NULL,
  316 + `REFERENCE_ID_` varchar(255) COLLATE utf8_bin DEFAULT NULL,
  317 + `REFERENCE_TYPE_` varchar(255) COLLATE utf8_bin DEFAULT NULL,
  318 + `PROPAGATED_STAGE_INST_ID_` varchar(255) COLLATE utf8_bin DEFAULT NULL,
  319 + PRIMARY KEY (`ID_`),
  320 + UNIQUE KEY `PROC_INST_ID_` (`PROC_INST_ID_`),
  321 + KEY `ACT_IDX_HI_PRO_INST_END` (`END_TIME_`),
  322 + KEY `ACT_IDX_HI_PRO_I_BUSKEY` (`BUSINESS_KEY_`)
  323 +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb3 COLLATE=utf8_bin;
  324 +
  325 +-- ----------------------------
  326 +-- Records of ACT_HI_PROCINST
  327 +-- ----------------------------
  328 +BEGIN;
  329 +INSERT INTO `ACT_HI_PROCINST` VALUES ('c964c377-97ed-11ec-a2b9-862bc1a4a054', 3, 'c964c377-97ed-11ec-a2b9-862bc1a4a054', NULL, 'flowable_01:1:c0bb5b36-97ed-11ec-a2b9-862bc1a4a054', '2022-02-28 00:53:28.351', '2022-02-28 00:53:34.899', 6548, '1', 'Event_1iruxim', 'Event_1mdsccz', NULL, NULL, '', 'flowable测试', NULL, NULL, NULL, NULL, NULL);
  330 +COMMIT;
  331 +
  332 +-- ----------------------------
  333 +-- Table structure for ACT_HI_TASKINST
  334 +-- ----------------------------
  335 +DROP TABLE IF EXISTS `ACT_HI_TASKINST`;
  336 +CREATE TABLE `ACT_HI_TASKINST` (
  337 + `ID_` varchar(64) COLLATE utf8_bin NOT NULL,
  338 + `REV_` int DEFAULT '1',
  339 + `PROC_DEF_ID_` varchar(64) COLLATE utf8_bin DEFAULT NULL,
  340 + `TASK_DEF_ID_` varchar(64) COLLATE utf8_bin DEFAULT NULL,
  341 + `TASK_DEF_KEY_` varchar(255) COLLATE utf8_bin DEFAULT NULL,
  342 + `PROC_INST_ID_` varchar(64) COLLATE utf8_bin DEFAULT NULL,
  343 + `EXECUTION_ID_` varchar(64) COLLATE utf8_bin DEFAULT NULL,
  344 + `SCOPE_ID_` varchar(255) COLLATE utf8_bin DEFAULT NULL,
  345 + `SUB_SCOPE_ID_` varchar(255) COLLATE utf8_bin DEFAULT NULL,
  346 + `SCOPE_TYPE_` varchar(255) COLLATE utf8_bin DEFAULT NULL,
  347 + `SCOPE_DEFINITION_ID_` varchar(255) COLLATE utf8_bin DEFAULT NULL,
  348 + `PROPAGATED_STAGE_INST_ID_` varchar(255) COLLATE utf8_bin DEFAULT NULL,
  349 + `NAME_` varchar(255) COLLATE utf8_bin DEFAULT NULL,
  350 + `PARENT_TASK_ID_` varchar(64) COLLATE utf8_bin DEFAULT NULL,
  351 + `DESCRIPTION_` varchar(4000) COLLATE utf8_bin DEFAULT NULL,
  352 + `OWNER_` varchar(255) COLLATE utf8_bin DEFAULT NULL,
  353 + `ASSIGNEE_` varchar(255) COLLATE utf8_bin DEFAULT NULL,
  354 + `START_TIME_` datetime(3) NOT NULL,
  355 + `CLAIM_TIME_` datetime(3) DEFAULT NULL,
  356 + `END_TIME_` datetime(3) DEFAULT NULL,
  357 + `DURATION_` bigint DEFAULT NULL,
  358 + `DELETE_REASON_` varchar(4000) COLLATE utf8_bin DEFAULT NULL,
  359 + `PRIORITY_` int DEFAULT NULL,
  360 + `DUE_DATE_` datetime(3) DEFAULT NULL,
  361 + `FORM_KEY_` varchar(255) COLLATE utf8_bin DEFAULT NULL,
  362 + `CATEGORY_` varchar(255) COLLATE utf8_bin DEFAULT NULL,
  363 + `TENANT_ID_` varchar(255) COLLATE utf8_bin DEFAULT '',
  364 + `LAST_UPDATED_TIME_` datetime(3) DEFAULT NULL,
  365 + PRIMARY KEY (`ID_`),
  366 + KEY `ACT_IDX_HI_TASK_SCOPE` (`SCOPE_ID_`,`SCOPE_TYPE_`),
  367 + KEY `ACT_IDX_HI_TASK_SUB_SCOPE` (`SUB_SCOPE_ID_`,`SCOPE_TYPE_`),
  368 + KEY `ACT_IDX_HI_TASK_SCOPE_DEF` (`SCOPE_DEFINITION_ID_`,`SCOPE_TYPE_`),
  369 + KEY `ACT_IDX_HI_TASK_INST_PROCINST` (`PROC_INST_ID_`)
  370 +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb3 COLLATE=utf8_bin;
  371 +
  372 +-- ----------------------------
  373 +-- Records of ACT_HI_TASKINST
  374 +-- ----------------------------
  375 +BEGIN;
  376 +INSERT INTO `ACT_HI_TASKINST` VALUES ('c97146a4-97ed-11ec-a2b9-862bc1a4a054', 2, 'flowable_01:1:c0bb5b36-97ed-11ec-a2b9-862bc1a4a054', NULL, 'task01', 'c964c377-97ed-11ec-a2b9-862bc1a4a054', 'c9695760-97ed-11ec-a2b9-862bc1a4a054', NULL, NULL, NULL, NULL, NULL, 'task01', NULL, NULL, NULL, '1', '2022-02-28 00:53:28.392', NULL, '2022-02-28 00:53:34.779', 6387, NULL, 50, NULL, NULL, NULL, '', '2022-02-28 00:53:34.779');
  377 +COMMIT;
  378 +
  379 +-- ----------------------------
  380 +-- Table structure for ACT_HI_TSK_LOG
  381 +-- ----------------------------
  382 +DROP TABLE IF EXISTS `ACT_HI_TSK_LOG`;
  383 +CREATE TABLE `ACT_HI_TSK_LOG` (
  384 + `ID_` bigint NOT NULL AUTO_INCREMENT,
  385 + `TYPE_` varchar(64) COLLATE utf8_bin DEFAULT NULL,
  386 + `TASK_ID_` varchar(64) COLLATE utf8_bin NOT NULL,
  387 + `TIME_STAMP_` timestamp(3) NOT NULL,
  388 + `USER_ID_` varchar(255) COLLATE utf8_bin DEFAULT NULL,
  389 + `DATA_` varchar(4000) COLLATE utf8_bin DEFAULT NULL,
  390 + `EXECUTION_ID_` varchar(64) COLLATE utf8_bin DEFAULT NULL,
  391 + `PROC_INST_ID_` varchar(64) COLLATE utf8_bin DEFAULT NULL,
  392 + `PROC_DEF_ID_` varchar(64) COLLATE utf8_bin DEFAULT NULL,
  393 + `SCOPE_ID_` varchar(255) COLLATE utf8_bin DEFAULT NULL,
  394 + `SCOPE_DEFINITION_ID_` varchar(255) COLLATE utf8_bin DEFAULT NULL,
  395 + `SUB_SCOPE_ID_` varchar(255) COLLATE utf8_bin DEFAULT NULL,
  396 + `SCOPE_TYPE_` varchar(255) COLLATE utf8_bin DEFAULT NULL,
  397 + `TENANT_ID_` varchar(255) COLLATE utf8_bin DEFAULT '',
  398 + PRIMARY KEY (`ID_`)
  399 +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb3 COLLATE=utf8_bin;
  400 +
  401 +-- ----------------------------
  402 +-- Records of ACT_HI_TSK_LOG
  403 +-- ----------------------------
  404 +BEGIN;
  405 +COMMIT;
  406 +
  407 +-- ----------------------------
  408 +-- Table structure for ACT_HI_VARINST
  409 +-- ----------------------------
  410 +DROP TABLE IF EXISTS `ACT_HI_VARINST`;
  411 +CREATE TABLE `ACT_HI_VARINST` (
  412 + `ID_` varchar(64) COLLATE utf8_bin NOT NULL,
  413 + `REV_` int DEFAULT '1',
  414 + `PROC_INST_ID_` varchar(64) COLLATE utf8_bin DEFAULT NULL,
  415 + `EXECUTION_ID_` varchar(64) COLLATE utf8_bin DEFAULT NULL,
  416 + `TASK_ID_` varchar(64) COLLATE utf8_bin DEFAULT NULL,
  417 + `NAME_` varchar(255) COLLATE utf8_bin NOT NULL,
  418 + `VAR_TYPE_` varchar(100) COLLATE utf8_bin DEFAULT NULL,
  419 + `SCOPE_ID_` varchar(255) COLLATE utf8_bin DEFAULT NULL,
  420 + `SUB_SCOPE_ID_` varchar(255) COLLATE utf8_bin DEFAULT NULL,
  421 + `SCOPE_TYPE_` varchar(255) COLLATE utf8_bin DEFAULT NULL,
  422 + `BYTEARRAY_ID_` varchar(64) COLLATE utf8_bin DEFAULT NULL,
  423 + `DOUBLE_` double DEFAULT NULL,
  424 + `LONG_` bigint DEFAULT NULL,
  425 + `TEXT_` varchar(4000) COLLATE utf8_bin DEFAULT NULL,
  426 + `TEXT2_` varchar(4000) COLLATE utf8_bin DEFAULT NULL,
  427 + `CREATE_TIME_` datetime(3) DEFAULT NULL,
  428 + `LAST_UPDATED_TIME_` datetime(3) DEFAULT NULL,
  429 + PRIMARY KEY (`ID_`),
  430 + KEY `ACT_IDX_HI_PROCVAR_NAME_TYPE` (`NAME_`,`VAR_TYPE_`),
  431 + KEY `ACT_IDX_HI_VAR_SCOPE_ID_TYPE` (`SCOPE_ID_`,`SCOPE_TYPE_`),
  432 + KEY `ACT_IDX_HI_VAR_SUB_ID_TYPE` (`SUB_SCOPE_ID_`,`SCOPE_TYPE_`),
  433 + KEY `ACT_IDX_HI_PROCVAR_PROC_INST` (`PROC_INST_ID_`),
  434 + KEY `ACT_IDX_HI_PROCVAR_TASK_ID` (`TASK_ID_`),
  435 + KEY `ACT_IDX_HI_PROCVAR_EXE` (`EXECUTION_ID_`)
  436 +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb3 COLLATE=utf8_bin;
  437 +
  438 +-- ----------------------------
  439 +-- Records of ACT_HI_VARINST
  440 +-- ----------------------------
  441 +BEGIN;
  442 +INSERT INTO `ACT_HI_VARINST` VALUES ('c9678299-97ed-11ec-a2b9-862bc1a4a054', 0, 'c964c377-97ed-11ec-a2b9-862bc1a4a054', 'c964c377-97ed-11ec-a2b9-862bc1a4a054', NULL, 'field121', 'string', NULL, NULL, NULL, NULL, NULL, NULL, 'AAA', NULL, '2022-02-28 00:53:28.373', '2022-02-28 00:53:28.373');
  443 +INSERT INTO `ACT_HI_VARINST` VALUES ('c969093c-97ed-11ec-a2b9-862bc1a4a054', 0, 'c964c377-97ed-11ec-a2b9-862bc1a4a054', 'c964c377-97ed-11ec-a2b9-862bc1a4a054', NULL, 'field122', 'serializable', NULL, NULL, NULL, 'c969093d-97ed-11ec-a2b9-862bc1a4a054', NULL, NULL, NULL, NULL, '2022-02-28 00:53:28.379', '2022-02-28 00:53:28.379');
  444 +COMMIT;
  445 +
  446 +-- ----------------------------
  447 +-- Table structure for ACT_ID_BYTEARRAY
  448 +-- ----------------------------
  449 +DROP TABLE IF EXISTS `ACT_ID_BYTEARRAY`;
  450 +CREATE TABLE `ACT_ID_BYTEARRAY` (
  451 + `ID_` varchar(64) COLLATE utf8_bin NOT NULL,
  452 + `REV_` int DEFAULT NULL,
  453 + `NAME_` varchar(255) COLLATE utf8_bin DEFAULT NULL,
  454 + `BYTES_` longblob,
  455 + PRIMARY KEY (`ID_`)
  456 +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb3 COLLATE=utf8_bin;
  457 +
  458 +-- ----------------------------
  459 +-- Records of ACT_ID_BYTEARRAY
  460 +-- ----------------------------
  461 +BEGIN;
  462 +COMMIT;
  463 +
  464 +-- ----------------------------
  465 +-- Table structure for ACT_ID_GROUP
  466 +-- ----------------------------
  467 +DROP TABLE IF EXISTS `ACT_ID_GROUP`;
  468 +CREATE TABLE `ACT_ID_GROUP` (
  469 + `ID_` varchar(64) COLLATE utf8_bin NOT NULL,
  470 + `REV_` int DEFAULT NULL,
  471 + `NAME_` varchar(255) COLLATE utf8_bin DEFAULT NULL,
  472 + `TYPE_` varchar(255) COLLATE utf8_bin DEFAULT NULL,
  473 + PRIMARY KEY (`ID_`)
  474 +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb3 COLLATE=utf8_bin;
  475 +
  476 +-- ----------------------------
  477 +-- Records of ACT_ID_GROUP
  478 +-- ----------------------------
  479 +BEGIN;
  480 +COMMIT;
  481 +
  482 +-- ----------------------------
  483 +-- Table structure for ACT_ID_INFO
  484 +-- ----------------------------
  485 +DROP TABLE IF EXISTS `ACT_ID_INFO`;
  486 +CREATE TABLE `ACT_ID_INFO` (
  487 + `ID_` varchar(64) COLLATE utf8_bin NOT NULL,
  488 + `REV_` int DEFAULT NULL,
  489 + `USER_ID_` varchar(64) COLLATE utf8_bin DEFAULT NULL,
  490 + `TYPE_` varchar(64) COLLATE utf8_bin DEFAULT NULL,
  491 + `KEY_` varchar(255) COLLATE utf8_bin DEFAULT NULL,
  492 + `VALUE_` varchar(255) COLLATE utf8_bin DEFAULT NULL,
  493 + `PASSWORD_` longblob,
  494 + `PARENT_ID_` varchar(255) COLLATE utf8_bin DEFAULT NULL,
  495 + PRIMARY KEY (`ID_`)
  496 +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb3 COLLATE=utf8_bin;
  497 +
  498 +-- ----------------------------
  499 +-- Records of ACT_ID_INFO
  500 +-- ----------------------------
  501 +BEGIN;
  502 +COMMIT;
  503 +
  504 +-- ----------------------------
  505 +-- Table structure for ACT_ID_MEMBERSHIP
  506 +-- ----------------------------
  507 +DROP TABLE IF EXISTS `ACT_ID_MEMBERSHIP`;
  508 +CREATE TABLE `ACT_ID_MEMBERSHIP` (
  509 + `USER_ID_` varchar(64) COLLATE utf8_bin NOT NULL,
  510 + `GROUP_ID_` varchar(64) COLLATE utf8_bin NOT NULL,
  511 + PRIMARY KEY (`USER_ID_`,`GROUP_ID_`),
  512 + KEY `ACT_FK_MEMB_GROUP` (`GROUP_ID_`),
  513 + CONSTRAINT `ACT_FK_MEMB_GROUP` FOREIGN KEY (`GROUP_ID_`) REFERENCES `ACT_ID_GROUP` (`ID_`),
  514 + CONSTRAINT `ACT_FK_MEMB_USER` FOREIGN KEY (`USER_ID_`) REFERENCES `ACT_ID_USER` (`ID_`)
  515 +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb3 COLLATE=utf8_bin;
  516 +
  517 +-- ----------------------------
  518 +-- Records of ACT_ID_MEMBERSHIP
  519 +-- ----------------------------
  520 +BEGIN;
  521 +COMMIT;
  522 +
  523 +-- ----------------------------
  524 +-- Table structure for ACT_ID_PRIV
  525 +-- ----------------------------
  526 +DROP TABLE IF EXISTS `ACT_ID_PRIV`;
  527 +CREATE TABLE `ACT_ID_PRIV` (
  528 + `ID_` varchar(64) COLLATE utf8_bin NOT NULL,
  529 + `NAME_` varchar(255) COLLATE utf8_bin NOT NULL,
  530 + PRIMARY KEY (`ID_`),
  531 + UNIQUE KEY `ACT_UNIQ_PRIV_NAME` (`NAME_`)
  532 +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb3 COLLATE=utf8_bin;
  533 +
  534 +-- ----------------------------
  535 +-- Records of ACT_ID_PRIV
  536 +-- ----------------------------
  537 +BEGIN;
  538 +COMMIT;
  539 +
  540 +-- ----------------------------
  541 +-- Table structure for ACT_ID_PRIV_MAPPING
  542 +-- ----------------------------
  543 +DROP TABLE IF EXISTS `ACT_ID_PRIV_MAPPING`;
  544 +CREATE TABLE `ACT_ID_PRIV_MAPPING` (
  545 + `ID_` varchar(64) COLLATE utf8_bin NOT NULL,
  546 + `PRIV_ID_` varchar(64) COLLATE utf8_bin NOT NULL,
  547 + `USER_ID_` varchar(255) COLLATE utf8_bin DEFAULT NULL,
  548 + `GROUP_ID_` varchar(255) COLLATE utf8_bin DEFAULT NULL,
  549 + PRIMARY KEY (`ID_`),
  550 + KEY `ACT_FK_PRIV_MAPPING` (`PRIV_ID_`),
  551 + KEY `ACT_IDX_PRIV_USER` (`USER_ID_`),
  552 + KEY `ACT_IDX_PRIV_GROUP` (`GROUP_ID_`),
  553 + CONSTRAINT `ACT_FK_PRIV_MAPPING` FOREIGN KEY (`PRIV_ID_`) REFERENCES `ACT_ID_PRIV` (`ID_`)
  554 +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb3 COLLATE=utf8_bin;
  555 +
  556 +-- ----------------------------
  557 +-- Records of ACT_ID_PRIV_MAPPING
  558 +-- ----------------------------
  559 +BEGIN;
  560 +COMMIT;
  561 +
  562 +-- ----------------------------
  563 +-- Table structure for ACT_ID_PROPERTY
  564 +-- ----------------------------
  565 +DROP TABLE IF EXISTS `ACT_ID_PROPERTY`;
  566 +CREATE TABLE `ACT_ID_PROPERTY` (
  567 + `NAME_` varchar(64) COLLATE utf8_bin NOT NULL,
  568 + `VALUE_` varchar(300) COLLATE utf8_bin DEFAULT NULL,
  569 + `REV_` int DEFAULT NULL,
  570 + PRIMARY KEY (`NAME_`)
  571 +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb3 COLLATE=utf8_bin;
  572 +
  573 +-- ----------------------------
  574 +-- Records of ACT_ID_PROPERTY
  575 +-- ----------------------------
  576 +BEGIN;
  577 +INSERT INTO `ACT_ID_PROPERTY` VALUES ('schema.version', '6.7.0.0', 1);
  578 +COMMIT;
  579 +
  580 +-- ----------------------------
  581 +-- Table structure for ACT_ID_TOKEN
  582 +-- ----------------------------
  583 +DROP TABLE IF EXISTS `ACT_ID_TOKEN`;
  584 +CREATE TABLE `ACT_ID_TOKEN` (
  585 + `ID_` varchar(64) COLLATE utf8_bin NOT NULL,
  586 + `REV_` int DEFAULT NULL,
  587 + `TOKEN_VALUE_` varchar(255) COLLATE utf8_bin DEFAULT NULL,
  588 + `TOKEN_DATE_` timestamp(3) NULL DEFAULT NULL,
  589 + `IP_ADDRESS_` varchar(255) COLLATE utf8_bin DEFAULT NULL,
  590 + `USER_AGENT_` varchar(255) COLLATE utf8_bin DEFAULT NULL,
  591 + `USER_ID_` varchar(255) COLLATE utf8_bin DEFAULT NULL,
  592 + `TOKEN_DATA_` varchar(2000) COLLATE utf8_bin DEFAULT NULL,
  593 + PRIMARY KEY (`ID_`)
  594 +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb3 COLLATE=utf8_bin;
  595 +
  596 +-- ----------------------------
  597 +-- Records of ACT_ID_TOKEN
  598 +-- ----------------------------
  599 +BEGIN;
  600 +COMMIT;
  601 +
  602 +-- ----------------------------
  603 +-- Table structure for ACT_ID_USER
  604 +-- ----------------------------
  605 +DROP TABLE IF EXISTS `ACT_ID_USER`;
  606 +CREATE TABLE `ACT_ID_USER` (
  607 + `ID_` varchar(64) COLLATE utf8_bin NOT NULL,
  608 + `REV_` int DEFAULT NULL,
  609 + `FIRST_` varchar(255) COLLATE utf8_bin DEFAULT NULL,
  610 + `LAST_` varchar(255) COLLATE utf8_bin DEFAULT NULL,
  611 + `DISPLAY_NAME_` varchar(255) COLLATE utf8_bin DEFAULT NULL,
  612 + `EMAIL_` varchar(255) COLLATE utf8_bin DEFAULT NULL,
  613 + `PWD_` varchar(255) COLLATE utf8_bin DEFAULT NULL,
  614 + `PICTURE_ID_` varchar(64) COLLATE utf8_bin DEFAULT NULL,
  615 + `TENANT_ID_` varchar(255) COLLATE utf8_bin DEFAULT '',
  616 + PRIMARY KEY (`ID_`)
  617 +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb3 COLLATE=utf8_bin;
  618 +
  619 +-- ----------------------------
  620 +-- Records of ACT_ID_USER
  621 +-- ----------------------------
  622 +BEGIN;
  623 +COMMIT;
  624 +
  625 +-- ----------------------------
  626 +-- Table structure for ACT_PROCDEF_INFO
  627 +-- ----------------------------
  628 +DROP TABLE IF EXISTS `ACT_PROCDEF_INFO`;
  629 +CREATE TABLE `ACT_PROCDEF_INFO` (
  630 + `ID_` varchar(64) COLLATE utf8_bin NOT NULL,
  631 + `PROC_DEF_ID_` varchar(64) COLLATE utf8_bin NOT NULL,
  632 + `REV_` int DEFAULT NULL,
  633 + `INFO_JSON_ID_` varchar(64) COLLATE utf8_bin DEFAULT NULL,
  634 + PRIMARY KEY (`ID_`),
  635 + UNIQUE KEY `ACT_UNIQ_INFO_PROCDEF` (`PROC_DEF_ID_`),
  636 + KEY `ACT_IDX_INFO_PROCDEF` (`PROC_DEF_ID_`),
  637 + KEY `ACT_FK_INFO_JSON_BA` (`INFO_JSON_ID_`),
  638 + CONSTRAINT `ACT_FK_INFO_JSON_BA` FOREIGN KEY (`INFO_JSON_ID_`) REFERENCES `ACT_GE_BYTEARRAY` (`ID_`),
  639 + CONSTRAINT `ACT_FK_INFO_PROCDEF` FOREIGN KEY (`PROC_DEF_ID_`) REFERENCES `ACT_RE_PROCDEF` (`ID_`)
  640 +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb3 COLLATE=utf8_bin;
  641 +
  642 +-- ----------------------------
  643 +-- Records of ACT_PROCDEF_INFO
  644 +-- ----------------------------
  645 +BEGIN;
  646 +COMMIT;
  647 +
  648 +-- ----------------------------
  649 +-- Table structure for ACT_RE_DEPLOYMENT
  650 +-- ----------------------------
  651 +DROP TABLE IF EXISTS `ACT_RE_DEPLOYMENT`;
  652 +CREATE TABLE `ACT_RE_DEPLOYMENT` (
  653 + `ID_` varchar(64) COLLATE utf8_bin NOT NULL,
  654 + `NAME_` varchar(255) COLLATE utf8_bin DEFAULT NULL,
  655 + `CATEGORY_` varchar(255) COLLATE utf8_bin DEFAULT NULL,
  656 + `KEY_` varchar(255) COLLATE utf8_bin DEFAULT NULL,
  657 + `TENANT_ID_` varchar(255) COLLATE utf8_bin DEFAULT '',
  658 + `DEPLOY_TIME_` timestamp(3) NULL DEFAULT NULL,
  659 + `DERIVED_FROM_` varchar(64) COLLATE utf8_bin DEFAULT NULL,
  660 + `DERIVED_FROM_ROOT_` varchar(64) COLLATE utf8_bin DEFAULT NULL,
  661 + `PARENT_DEPLOYMENT_ID_` varchar(255) COLLATE utf8_bin DEFAULT NULL,
  662 + `ENGINE_VERSION_` varchar(255) COLLATE utf8_bin DEFAULT NULL,
  663 + PRIMARY KEY (`ID_`)
  664 +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb3 COLLATE=utf8_bin;
  665 +
  666 +-- ----------------------------
  667 +-- Records of ACT_RE_DEPLOYMENT
  668 +-- ----------------------------
  669 +BEGIN;
  670 +INSERT INTO `ACT_RE_DEPLOYMENT` VALUES ('bfb4c0a3-97ed-11ec-a2b9-862bc1a4a054', 'flowable测试', '1', 'flowable_01', '', '2022-02-28 00:53:12.098', NULL, NULL, 'bfb4c0a3-97ed-11ec-a2b9-862bc1a4a054', NULL);
  671 +COMMIT;
  672 +
  673 +-- ----------------------------
  674 +-- Table structure for ACT_RE_MODEL
  675 +-- ----------------------------
  676 +DROP TABLE IF EXISTS `ACT_RE_MODEL`;
  677 +CREATE TABLE `ACT_RE_MODEL` (
  678 + `ID_` varchar(64) COLLATE utf8_bin NOT NULL,
  679 + `REV_` int DEFAULT NULL,
  680 + `NAME_` varchar(255) COLLATE utf8_bin DEFAULT NULL,
  681 + `KEY_` varchar(255) COLLATE utf8_bin DEFAULT NULL,
  682 + `CATEGORY_` varchar(255) COLLATE utf8_bin DEFAULT NULL,
  683 + `CREATE_TIME_` timestamp(3) NULL DEFAULT NULL,
  684 + `LAST_UPDATE_TIME_` timestamp(3) NULL DEFAULT NULL,
  685 + `VERSION_` int DEFAULT NULL,
  686 + `META_INFO_` varchar(4000) COLLATE utf8_bin DEFAULT NULL,
  687 + `DEPLOYMENT_ID_` varchar(64) COLLATE utf8_bin DEFAULT NULL,
  688 + `EDITOR_SOURCE_VALUE_ID_` varchar(64) COLLATE utf8_bin DEFAULT NULL,
  689 + `EDITOR_SOURCE_EXTRA_VALUE_ID_` varchar(64) COLLATE utf8_bin DEFAULT NULL,
  690 + `TENANT_ID_` varchar(255) COLLATE utf8_bin DEFAULT '',
  691 + PRIMARY KEY (`ID_`),
  692 + KEY `ACT_FK_MODEL_SOURCE` (`EDITOR_SOURCE_VALUE_ID_`),
  693 + KEY `ACT_FK_MODEL_SOURCE_EXTRA` (`EDITOR_SOURCE_EXTRA_VALUE_ID_`),
  694 + KEY `ACT_FK_MODEL_DEPLOYMENT` (`DEPLOYMENT_ID_`),
  695 + CONSTRAINT `ACT_FK_MODEL_DEPLOYMENT` FOREIGN KEY (`DEPLOYMENT_ID_`) REFERENCES `ACT_RE_DEPLOYMENT` (`ID_`),
  696 + CONSTRAINT `ACT_FK_MODEL_SOURCE` FOREIGN KEY (`EDITOR_SOURCE_VALUE_ID_`) REFERENCES `ACT_GE_BYTEARRAY` (`ID_`),
  697 + CONSTRAINT `ACT_FK_MODEL_SOURCE_EXTRA` FOREIGN KEY (`EDITOR_SOURCE_EXTRA_VALUE_ID_`) REFERENCES `ACT_GE_BYTEARRAY` (`ID_`)
  698 +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb3 COLLATE=utf8_bin;
  699 +
  700 +-- ----------------------------
  701 +-- Records of ACT_RE_MODEL
  702 +-- ----------------------------
  703 +BEGIN;
  704 +INSERT INTO `ACT_RE_MODEL` VALUES ('4b4909d8-97e7-11ec-8e20-862bc1a4a054', 6, 'flowable测试', 'flowable_01', '1', '2022-02-28 00:06:59.795', '2022-02-28 00:53:13.893', 1, '{\"description\":\"ooxx\",\"formType\":10,\"formId\":11,\"formCustomCreatePath\":null,\"formCustomViewPath\":null}', 'bfb4c0a3-97ed-11ec-a2b9-862bc1a4a054', '7bac85f2-97ed-11ec-a2b9-862bc1a4a054', NULL, '');
  705 +COMMIT;
  706 +
  707 +-- ----------------------------
  708 +-- Table structure for ACT_RE_PROCDEF
  709 +-- ----------------------------
  710 +DROP TABLE IF EXISTS `ACT_RE_PROCDEF`;
  711 +CREATE TABLE `ACT_RE_PROCDEF` (
  712 + `ID_` varchar(64) COLLATE utf8_bin NOT NULL,
  713 + `REV_` int DEFAULT NULL,
  714 + `CATEGORY_` varchar(255) COLLATE utf8_bin DEFAULT NULL,
  715 + `NAME_` varchar(255) COLLATE utf8_bin DEFAULT NULL,
  716 + `KEY_` varchar(255) COLLATE utf8_bin NOT NULL,
  717 + `VERSION_` int NOT NULL,
  718 + `DEPLOYMENT_ID_` varchar(64) COLLATE utf8_bin DEFAULT NULL,
  719 + `RESOURCE_NAME_` varchar(4000) COLLATE utf8_bin DEFAULT NULL,
  720 + `DGRM_RESOURCE_NAME_` varchar(4000) COLLATE utf8_bin DEFAULT NULL,
  721 + `DESCRIPTION_` varchar(4000) COLLATE utf8_bin DEFAULT NULL,
  722 + `HAS_START_FORM_KEY_` tinyint DEFAULT NULL,
  723 + `HAS_GRAPHICAL_NOTATION_` tinyint DEFAULT NULL,
  724 + `SUSPENSION_STATE_` int DEFAULT NULL,
  725 + `TENANT_ID_` varchar(255) COLLATE utf8_bin DEFAULT '',
  726 + `ENGINE_VERSION_` varchar(255) COLLATE utf8_bin DEFAULT NULL,
  727 + `DERIVED_FROM_` varchar(64) COLLATE utf8_bin DEFAULT NULL,
  728 + `DERIVED_FROM_ROOT_` varchar(64) COLLATE utf8_bin DEFAULT NULL,
  729 + `DERIVED_VERSION_` int NOT NULL DEFAULT '0',
  730 + PRIMARY KEY (`ID_`),
  731 + UNIQUE KEY `ACT_UNIQ_PROCDEF` (`KEY_`,`VERSION_`,`DERIVED_VERSION_`,`TENANT_ID_`)
  732 +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb3 COLLATE=utf8_bin;
  733 +
  734 +-- ----------------------------
  735 +-- Records of ACT_RE_PROCDEF
  736 +-- ----------------------------
  737 +BEGIN;
  738 +INSERT INTO `ACT_RE_PROCDEF` VALUES ('flowable_01:1:c0bb5b36-97ed-11ec-a2b9-862bc1a4a054', 2, '1', 'flowable测试', 'flowable_01', 1, 'bfb4c0a3-97ed-11ec-a2b9-862bc1a4a054', 'flowable_01.bpmn', 'flowable_01.flowable_01.png', NULL, 0, 1, 1, '', NULL, NULL, NULL, 0);
  739 +COMMIT;
  740 +
  741 +-- ----------------------------
  742 +-- Table structure for ACT_RU_ACTINST
  743 +-- ----------------------------
  744 +DROP TABLE IF EXISTS `ACT_RU_ACTINST`;
  745 +CREATE TABLE `ACT_RU_ACTINST` (
  746 + `ID_` varchar(64) COLLATE utf8_bin NOT NULL,
  747 + `REV_` int DEFAULT '1',
  748 + `PROC_DEF_ID_` varchar(64) COLLATE utf8_bin NOT NULL,
  749 + `PROC_INST_ID_` varchar(64) COLLATE utf8_bin NOT NULL,
  750 + `EXECUTION_ID_` varchar(64) COLLATE utf8_bin NOT NULL,
  751 + `ACT_ID_` varchar(255) COLLATE utf8_bin NOT NULL,
  752 + `TASK_ID_` varchar(64) COLLATE utf8_bin DEFAULT NULL,
  753 + `CALL_PROC_INST_ID_` varchar(64) COLLATE utf8_bin DEFAULT NULL,
  754 + `ACT_NAME_` varchar(255) COLLATE utf8_bin DEFAULT NULL,
  755 + `ACT_TYPE_` varchar(255) COLLATE utf8_bin NOT NULL,
  756 + `ASSIGNEE_` varchar(255) COLLATE utf8_bin DEFAULT NULL,
  757 + `START_TIME_` datetime(3) NOT NULL,
  758 + `END_TIME_` datetime(3) DEFAULT NULL,
  759 + `DURATION_` bigint DEFAULT NULL,
  760 + `TRANSACTION_ORDER_` int DEFAULT NULL,
  761 + `DELETE_REASON_` varchar(4000) COLLATE utf8_bin DEFAULT NULL,
  762 + `TENANT_ID_` varchar(255) COLLATE utf8_bin DEFAULT '',
  763 + PRIMARY KEY (`ID_`),
  764 + KEY `ACT_IDX_RU_ACTI_START` (`START_TIME_`),
  765 + KEY `ACT_IDX_RU_ACTI_END` (`END_TIME_`),
  766 + KEY `ACT_IDX_RU_ACTI_PROC` (`PROC_INST_ID_`),
  767 + KEY `ACT_IDX_RU_ACTI_PROC_ACT` (`PROC_INST_ID_`,`ACT_ID_`),
  768 + KEY `ACT_IDX_RU_ACTI_EXEC` (`EXECUTION_ID_`),
  769 + KEY `ACT_IDX_RU_ACTI_EXEC_ACT` (`EXECUTION_ID_`,`ACT_ID_`),
  770 + KEY `ACT_IDX_RU_ACTI_TASK` (`TASK_ID_`)
  771 +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb3 COLLATE=utf8_bin;
  772 +
  773 +-- ----------------------------
  774 +-- Records of ACT_RU_ACTINST
  775 +-- ----------------------------
  776 +BEGIN;
  777 +COMMIT;
  778 +
  779 +-- ----------------------------
  780 +-- Table structure for ACT_RU_DEADLETTER_JOB
  781 +-- ----------------------------
  782 +DROP TABLE IF EXISTS `ACT_RU_DEADLETTER_JOB`;
  783 +CREATE TABLE `ACT_RU_DEADLETTER_JOB` (
  784 + `ID_` varchar(64) COLLATE utf8_bin NOT NULL,
  785 + `REV_` int DEFAULT NULL,
  786 + `CATEGORY_` varchar(255) COLLATE utf8_bin DEFAULT NULL,
  787 + `TYPE_` varchar(255) COLLATE utf8_bin NOT NULL,
  788 + `EXCLUSIVE_` tinyint(1) DEFAULT NULL,
  789 + `EXECUTION_ID_` varchar(64) COLLATE utf8_bin DEFAULT NULL,
  790 + `PROCESS_INSTANCE_ID_` varchar(64) COLLATE utf8_bin DEFAULT NULL,
  791 + `PROC_DEF_ID_` varchar(64) COLLATE utf8_bin DEFAULT NULL,
  792 + `ELEMENT_ID_` varchar(255) COLLATE utf8_bin DEFAULT NULL,
  793 + `ELEMENT_NAME_` varchar(255) COLLATE utf8_bin DEFAULT NULL,
  794 + `SCOPE_ID_` varchar(255) COLLATE utf8_bin DEFAULT NULL,
  795 + `SUB_SCOPE_ID_` varchar(255) COLLATE utf8_bin DEFAULT NULL,
  796 + `SCOPE_TYPE_` varchar(255) COLLATE utf8_bin DEFAULT NULL,
  797 + `SCOPE_DEFINITION_ID_` varchar(255) COLLATE utf8_bin DEFAULT NULL,
  798 + `CORRELATION_ID_` varchar(255) COLLATE utf8_bin DEFAULT NULL,
  799 + `EXCEPTION_STACK_ID_` varchar(64) COLLATE utf8_bin DEFAULT NULL,
  800 + `EXCEPTION_MSG_` varchar(4000) COLLATE utf8_bin DEFAULT NULL,
  801 + `DUEDATE_` timestamp(3) NULL DEFAULT NULL,
  802 + `REPEAT_` varchar(255) COLLATE utf8_bin DEFAULT NULL,
  803 + `HANDLER_TYPE_` varchar(255) COLLATE utf8_bin DEFAULT NULL,
  804 + `HANDLER_CFG_` varchar(4000) COLLATE utf8_bin DEFAULT NULL,
  805 + `CUSTOM_VALUES_ID_` varchar(64) COLLATE utf8_bin DEFAULT NULL,
  806 + `CREATE_TIME_` timestamp(3) NULL DEFAULT NULL,
  807 + `TENANT_ID_` varchar(255) COLLATE utf8_bin DEFAULT '',
  808 + PRIMARY KEY (`ID_`),
  809 + KEY `ACT_IDX_DEADLETTER_JOB_EXCEPTION_STACK_ID` (`EXCEPTION_STACK_ID_`),
  810 + KEY `ACT_IDX_DEADLETTER_JOB_CUSTOM_VALUES_ID` (`CUSTOM_VALUES_ID_`),
  811 + KEY `ACT_IDX_DEADLETTER_JOB_CORRELATION_ID` (`CORRELATION_ID_`),
  812 + KEY `ACT_IDX_DJOB_SCOPE` (`SCOPE_ID_`,`SCOPE_TYPE_`),
  813 + KEY `ACT_IDX_DJOB_SUB_SCOPE` (`SUB_SCOPE_ID_`,`SCOPE_TYPE_`),
  814 + KEY `ACT_IDX_DJOB_SCOPE_DEF` (`SCOPE_DEFINITION_ID_`,`SCOPE_TYPE_`),
  815 + KEY `ACT_FK_DEADLETTER_JOB_EXECUTION` (`EXECUTION_ID_`),
  816 + KEY `ACT_FK_DEADLETTER_JOB_PROCESS_INSTANCE` (`PROCESS_INSTANCE_ID_`),
  817 + KEY `ACT_FK_DEADLETTER_JOB_PROC_DEF` (`PROC_DEF_ID_`),
  818 + CONSTRAINT `ACT_FK_DEADLETTER_JOB_CUSTOM_VALUES` FOREIGN KEY (`CUSTOM_VALUES_ID_`) REFERENCES `ACT_GE_BYTEARRAY` (`ID_`),
  819 + CONSTRAINT `ACT_FK_DEADLETTER_JOB_EXCEPTION` FOREIGN KEY (`EXCEPTION_STACK_ID_`) REFERENCES `ACT_GE_BYTEARRAY` (`ID_`),
  820 + CONSTRAINT `ACT_FK_DEADLETTER_JOB_EXECUTION` FOREIGN KEY (`EXECUTION_ID_`) REFERENCES `ACT_RU_EXECUTION` (`ID_`),
  821 + CONSTRAINT `ACT_FK_DEADLETTER_JOB_PROC_DEF` FOREIGN KEY (`PROC_DEF_ID_`) REFERENCES `ACT_RE_PROCDEF` (`ID_`),
  822 + CONSTRAINT `ACT_FK_DEADLETTER_JOB_PROCESS_INSTANCE` FOREIGN KEY (`PROCESS_INSTANCE_ID_`) REFERENCES `ACT_RU_EXECUTION` (`ID_`)
  823 +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb3 COLLATE=utf8_bin;
  824 +
  825 +-- ----------------------------
  826 +-- Records of ACT_RU_DEADLETTER_JOB
  827 +-- ----------------------------
  828 +BEGIN;
  829 +COMMIT;
  830 +
  831 +-- ----------------------------
  832 +-- Table structure for ACT_RU_ENTITYLINK
  833 +-- ----------------------------
  834 +DROP TABLE IF EXISTS `ACT_RU_ENTITYLINK`;
  835 +CREATE TABLE `ACT_RU_ENTITYLINK` (
  836 + `ID_` varchar(64) COLLATE utf8_bin NOT NULL,
  837 + `REV_` int DEFAULT NULL,
  838 + `CREATE_TIME_` datetime(3) DEFAULT NULL,
  839 + `LINK_TYPE_` varchar(255) COLLATE utf8_bin DEFAULT NULL,
  840 + `SCOPE_ID_` varchar(255) COLLATE utf8_bin DEFAULT NULL,
  841 + `SUB_SCOPE_ID_` varchar(255) COLLATE utf8_bin DEFAULT NULL,
  842 + `SCOPE_TYPE_` varchar(255) COLLATE utf8_bin DEFAULT NULL,
  843 + `SCOPE_DEFINITION_ID_` varchar(255) COLLATE utf8_bin DEFAULT NULL,
  844 + `PARENT_ELEMENT_ID_` varchar(255) COLLATE utf8_bin DEFAULT NULL,
  845 + `REF_SCOPE_ID_` varchar(255) COLLATE utf8_bin DEFAULT NULL,
  846 + `REF_SCOPE_TYPE_` varchar(255) COLLATE utf8_bin DEFAULT NULL,
  847 + `REF_SCOPE_DEFINITION_ID_` varchar(255) COLLATE utf8_bin DEFAULT NULL,
  848 + `ROOT_SCOPE_ID_` varchar(255) COLLATE utf8_bin DEFAULT NULL,
  849 + `ROOT_SCOPE_TYPE_` varchar(255) COLLATE utf8_bin DEFAULT NULL,
  850 + `HIERARCHY_TYPE_` varchar(255) COLLATE utf8_bin DEFAULT NULL,
  851 + PRIMARY KEY (`ID_`),
  852 + KEY `ACT_IDX_ENT_LNK_SCOPE` (`SCOPE_ID_`,`SCOPE_TYPE_`,`LINK_TYPE_`),
  853 + KEY `ACT_IDX_ENT_LNK_REF_SCOPE` (`REF_SCOPE_ID_`,`REF_SCOPE_TYPE_`,`LINK_TYPE_`),
  854 + KEY `ACT_IDX_ENT_LNK_ROOT_SCOPE` (`ROOT_SCOPE_ID_`,`ROOT_SCOPE_TYPE_`,`LINK_TYPE_`),
  855 + KEY `ACT_IDX_ENT_LNK_SCOPE_DEF` (`SCOPE_DEFINITION_ID_`,`SCOPE_TYPE_`,`LINK_TYPE_`)
  856 +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb3 COLLATE=utf8_bin;
  857 +
  858 +-- ----------------------------
  859 +-- Records of ACT_RU_ENTITYLINK
  860 +-- ----------------------------
  861 +BEGIN;
  862 +COMMIT;
  863 +
  864 +-- ----------------------------
  865 +-- Table structure for ACT_RU_EVENT_SUBSCR
  866 +-- ----------------------------
  867 +DROP TABLE IF EXISTS `ACT_RU_EVENT_SUBSCR`;
  868 +CREATE TABLE `ACT_RU_EVENT_SUBSCR` (
  869 + `ID_` varchar(64) COLLATE utf8_bin NOT NULL,
  870 + `REV_` int DEFAULT NULL,
  871 + `EVENT_TYPE_` varchar(255) COLLATE utf8_bin NOT NULL,
  872 + `EVENT_NAME_` varchar(255) COLLATE utf8_bin DEFAULT NULL,
  873 + `EXECUTION_ID_` varchar(64) COLLATE utf8_bin DEFAULT NULL,
  874 + `PROC_INST_ID_` varchar(64) COLLATE utf8_bin DEFAULT NULL,
  875 + `ACTIVITY_ID_` varchar(64) COLLATE utf8_bin DEFAULT NULL,
  876 + `CONFIGURATION_` varchar(255) COLLATE utf8_bin DEFAULT NULL,
  877 + `CREATED_` timestamp(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3),
  878 + `PROC_DEF_ID_` varchar(64) COLLATE utf8_bin DEFAULT NULL,
  879 + `SUB_SCOPE_ID_` varchar(64) COLLATE utf8_bin DEFAULT NULL,
  880 + `SCOPE_ID_` varchar(64) COLLATE utf8_bin DEFAULT NULL,
  881 + `SCOPE_DEFINITION_ID_` varchar(64) COLLATE utf8_bin DEFAULT NULL,
  882 + `SCOPE_TYPE_` varchar(64) COLLATE utf8_bin DEFAULT NULL,
  883 + `TENANT_ID_` varchar(255) COLLATE utf8_bin DEFAULT '',
  884 + PRIMARY KEY (`ID_`),
  885 + KEY `ACT_IDX_EVENT_SUBSCR_CONFIG_` (`CONFIGURATION_`),
  886 + KEY `ACT_FK_EVENT_EXEC` (`EXECUTION_ID_`),
  887 + CONSTRAINT `ACT_FK_EVENT_EXEC` FOREIGN KEY (`EXECUTION_ID_`) REFERENCES `ACT_RU_EXECUTION` (`ID_`)
  888 +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb3 COLLATE=utf8_bin;
  889 +
  890 +-- ----------------------------
  891 +-- Records of ACT_RU_EVENT_SUBSCR
  892 +-- ----------------------------
  893 +BEGIN;
  894 +COMMIT;
  895 +
  896 +-- ----------------------------
  897 +-- Table structure for ACT_RU_EXECUTION
  898 +-- ----------------------------
  899 +DROP TABLE IF EXISTS `ACT_RU_EXECUTION`;
  900 +CREATE TABLE `ACT_RU_EXECUTION` (
  901 + `ID_` varchar(64) COLLATE utf8_bin NOT NULL,
  902 + `REV_` int DEFAULT NULL,
  903 + `PROC_INST_ID_` varchar(64) COLLATE utf8_bin DEFAULT NULL,
  904 + `BUSINESS_KEY_` varchar(255) COLLATE utf8_bin DEFAULT NULL,
  905 + `PARENT_ID_` varchar(64) COLLATE utf8_bin DEFAULT NULL,
  906 + `PROC_DEF_ID_` varchar(64) COLLATE utf8_bin DEFAULT NULL,
  907 + `SUPER_EXEC_` varchar(64) COLLATE utf8_bin DEFAULT NULL,
  908 + `ROOT_PROC_INST_ID_` varchar(64) COLLATE utf8_bin DEFAULT NULL,
  909 + `ACT_ID_` varchar(255) COLLATE utf8_bin DEFAULT NULL,
  910 + `IS_ACTIVE_` tinyint DEFAULT NULL,
  911 + `IS_CONCURRENT_` tinyint DEFAULT NULL,
  912 + `IS_SCOPE_` tinyint DEFAULT NULL,
  913 + `IS_EVENT_SCOPE_` tinyint DEFAULT NULL,
  914 + `IS_MI_ROOT_` tinyint DEFAULT NULL,
  915 + `SUSPENSION_STATE_` int DEFAULT NULL,
  916 + `CACHED_ENT_STATE_` int DEFAULT NULL,
  917 + `TENANT_ID_` varchar(255) COLLATE utf8_bin DEFAULT '',
  918 + `NAME_` varchar(255) COLLATE utf8_bin DEFAULT NULL,
  919 + `START_ACT_ID_` varchar(255) COLLATE utf8_bin DEFAULT NULL,
  920 + `START_TIME_` datetime(3) DEFAULT NULL,
  921 + `START_USER_ID_` varchar(255) COLLATE utf8_bin DEFAULT NULL,
  922 + `LOCK_TIME_` timestamp(3) NULL DEFAULT NULL,
  923 + `LOCK_OWNER_` varchar(255) COLLATE utf8_bin DEFAULT NULL,
  924 + `IS_COUNT_ENABLED_` tinyint DEFAULT NULL,
  925 + `EVT_SUBSCR_COUNT_` int DEFAULT NULL,
  926 + `TASK_COUNT_` int DEFAULT NULL,
  927 + `JOB_COUNT_` int DEFAULT NULL,
  928 + `TIMER_JOB_COUNT_` int DEFAULT NULL,
  929 + `SUSP_JOB_COUNT_` int DEFAULT NULL,
  930 + `DEADLETTER_JOB_COUNT_` int DEFAULT NULL,
  931 + `EXTERNAL_WORKER_JOB_COUNT_` int DEFAULT NULL,
  932 + `VAR_COUNT_` int DEFAULT NULL,
  933 + `ID_LINK_COUNT_` int DEFAULT NULL,
  934 + `CALLBACK_ID_` varchar(255) COLLATE utf8_bin DEFAULT NULL,
  935 + `CALLBACK_TYPE_` varchar(255) COLLATE utf8_bin DEFAULT NULL,
  936 + `REFERENCE_ID_` varchar(255) COLLATE utf8_bin DEFAULT NULL,
  937 + `REFERENCE_TYPE_` varchar(255) COLLATE utf8_bin DEFAULT NULL,
  938 + `PROPAGATED_STAGE_INST_ID_` varchar(255) COLLATE utf8_bin DEFAULT NULL,
  939 + PRIMARY KEY (`ID_`),
  940 + KEY `ACT_IDX_EXEC_BUSKEY` (`BUSINESS_KEY_`),
  941 + KEY `ACT_IDC_EXEC_ROOT` (`ROOT_PROC_INST_ID_`),
  942 + KEY `ACT_IDX_EXEC_REF_ID_` (`REFERENCE_ID_`),
  943 + KEY `ACT_FK_EXE_PROCINST` (`PROC_INST_ID_`),
  944 + KEY `ACT_FK_EXE_PARENT` (`PARENT_ID_`),
  945 + KEY `ACT_FK_EXE_SUPER` (`SUPER_EXEC_`),
  946 + KEY `ACT_FK_EXE_PROCDEF` (`PROC_DEF_ID_`),
  947 + CONSTRAINT `ACT_FK_EXE_PARENT` FOREIGN KEY (`PARENT_ID_`) REFERENCES `ACT_RU_EXECUTION` (`ID_`) ON DELETE CASCADE,
  948 + CONSTRAINT `ACT_FK_EXE_PROCDEF` FOREIGN KEY (`PROC_DEF_ID_`) REFERENCES `ACT_RE_PROCDEF` (`ID_`),
  949 + CONSTRAINT `ACT_FK_EXE_PROCINST` FOREIGN KEY (`PROC_INST_ID_`) REFERENCES `ACT_RU_EXECUTION` (`ID_`) ON DELETE CASCADE ON UPDATE CASCADE,
  950 + CONSTRAINT `ACT_FK_EXE_SUPER` FOREIGN KEY (`SUPER_EXEC_`) REFERENCES `ACT_RU_EXECUTION` (`ID_`) ON DELETE CASCADE
  951 +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb3 COLLATE=utf8_bin;
  952 +
  953 +-- ----------------------------
  954 +-- Records of ACT_RU_EXECUTION
  955 +-- ----------------------------
  956 +BEGIN;
  957 +COMMIT;
  958 +
  959 +-- ----------------------------
  960 +-- Table structure for ACT_RU_EXTERNAL_JOB
  961 +-- ----------------------------
  962 +DROP TABLE IF EXISTS `ACT_RU_EXTERNAL_JOB`;
  963 +CREATE TABLE `ACT_RU_EXTERNAL_JOB` (
  964 + `ID_` varchar(64) COLLATE utf8_bin NOT NULL,
  965 + `REV_` int DEFAULT NULL,
  966 + `CATEGORY_` varchar(255) COLLATE utf8_bin DEFAULT NULL,
  967 + `TYPE_` varchar(255) COLLATE utf8_bin NOT NULL,
  968 + `LOCK_EXP_TIME_` timestamp(3) NULL DEFAULT NULL,
  969 + `LOCK_OWNER_` varchar(255) COLLATE utf8_bin DEFAULT NULL,
  970 + `EXCLUSIVE_` tinyint(1) DEFAULT NULL,
  971 + `EXECUTION_ID_` varchar(64) COLLATE utf8_bin DEFAULT NULL,
  972 + `PROCESS_INSTANCE_ID_` varchar(64) COLLATE utf8_bin DEFAULT NULL,
  973 + `PROC_DEF_ID_` varchar(64) COLLATE utf8_bin DEFAULT NULL,
  974 + `ELEMENT_ID_` varchar(255) COLLATE utf8_bin DEFAULT NULL,
  975 + `ELEMENT_NAME_` varchar(255) COLLATE utf8_bin DEFAULT NULL,
  976 + `SCOPE_ID_` varchar(255) COLLATE utf8_bin DEFAULT NULL,
  977 + `SUB_SCOPE_ID_` varchar(255) COLLATE utf8_bin DEFAULT NULL,
  978 + `SCOPE_TYPE_` varchar(255) COLLATE utf8_bin DEFAULT NULL,
  979 + `SCOPE_DEFINITION_ID_` varchar(255) COLLATE utf8_bin DEFAULT NULL,
  980 + `CORRELATION_ID_` varchar(255) COLLATE utf8_bin DEFAULT NULL,
  981 + `RETRIES_` int DEFAULT NULL,
  982 + `EXCEPTION_STACK_ID_` varchar(64) COLLATE utf8_bin DEFAULT NULL,
  983 + `EXCEPTION_MSG_` varchar(4000) COLLATE utf8_bin DEFAULT NULL,
  984 + `DUEDATE_` timestamp(3) NULL DEFAULT NULL,
  985 + `REPEAT_` varchar(255) COLLATE utf8_bin DEFAULT NULL,
  986 + `HANDLER_TYPE_` varchar(255) COLLATE utf8_bin DEFAULT NULL,
  987 + `HANDLER_CFG_` varchar(4000) COLLATE utf8_bin DEFAULT NULL,
  988 + `CUSTOM_VALUES_ID_` varchar(64) COLLATE utf8_bin DEFAULT NULL,
  989 + `CREATE_TIME_` timestamp(3) NULL DEFAULT NULL,
  990 + `TENANT_ID_` varchar(255) COLLATE utf8_bin DEFAULT '',
  991 + PRIMARY KEY (`ID_`),
  992 + KEY `ACT_IDX_EXTERNAL_JOB_EXCEPTION_STACK_ID` (`EXCEPTION_STACK_ID_`),
  993 + KEY `ACT_IDX_EXTERNAL_JOB_CUSTOM_VALUES_ID` (`CUSTOM_VALUES_ID_`),
  994 + KEY `ACT_IDX_EXTERNAL_JOB_CORRELATION_ID` (`CORRELATION_ID_`),
  995 + KEY `ACT_IDX_EJOB_SCOPE` (`SCOPE_ID_`,`SCOPE_TYPE_`),
  996 + KEY `ACT_IDX_EJOB_SUB_SCOPE` (`SUB_SCOPE_ID_`,`SCOPE_TYPE_`),
  997 + KEY `ACT_IDX_EJOB_SCOPE_DEF` (`SCOPE_DEFINITION_ID_`,`SCOPE_TYPE_`),
  998 + CONSTRAINT `ACT_FK_EXTERNAL_JOB_CUSTOM_VALUES` FOREIGN KEY (`CUSTOM_VALUES_ID_`) REFERENCES `ACT_GE_BYTEARRAY` (`ID_`),
  999 + CONSTRAINT `ACT_FK_EXTERNAL_JOB_EXCEPTION` FOREIGN KEY (`EXCEPTION_STACK_ID_`) REFERENCES `ACT_GE_BYTEARRAY` (`ID_`)
  1000 +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb3 COLLATE=utf8_bin;
  1001 +
  1002 +-- ----------------------------
  1003 +-- Records of ACT_RU_EXTERNAL_JOB
  1004 +-- ----------------------------
  1005 +BEGIN;
  1006 +COMMIT;
  1007 +
  1008 +-- ----------------------------
  1009 +-- Table structure for ACT_RU_HISTORY_JOB
  1010 +-- ----------------------------
  1011 +DROP TABLE IF EXISTS `ACT_RU_HISTORY_JOB`;
  1012 +CREATE TABLE `ACT_RU_HISTORY_JOB` (
  1013 + `ID_` varchar(64) COLLATE utf8_bin NOT NULL,
  1014 + `REV_` int DEFAULT NULL,
  1015 + `LOCK_EXP_TIME_` timestamp(3) NULL DEFAULT NULL,
  1016 + `LOCK_OWNER_` varchar(255) COLLATE utf8_bin DEFAULT NULL,
  1017 + `RETRIES_` int DEFAULT NULL,
  1018 + `EXCEPTION_STACK_ID_` varchar(64) COLLATE utf8_bin DEFAULT NULL,
  1019 + `EXCEPTION_MSG_` varchar(4000) COLLATE utf8_bin DEFAULT NULL,
  1020 + `HANDLER_TYPE_` varchar(255) COLLATE utf8_bin DEFAULT NULL,
  1021 + `HANDLER_CFG_` varchar(4000) COLLATE utf8_bin DEFAULT NULL,
  1022 + `CUSTOM_VALUES_ID_` varchar(64) COLLATE utf8_bin DEFAULT NULL,
  1023 + `ADV_HANDLER_CFG_ID_` varchar(64) COLLATE utf8_bin DEFAULT NULL,
  1024 + `CREATE_TIME_` timestamp(3) NULL DEFAULT NULL,
  1025 + `SCOPE_TYPE_` varchar(255) COLLATE utf8_bin DEFAULT NULL,
  1026 + `TENANT_ID_` varchar(255) COLLATE utf8_bin DEFAULT '',
  1027 + PRIMARY KEY (`ID_`)
  1028 +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb3 COLLATE=utf8_bin;
  1029 +
  1030 +-- ----------------------------
  1031 +-- Records of ACT_RU_HISTORY_JOB
  1032 +-- ----------------------------
  1033 +BEGIN;
  1034 +COMMIT;
  1035 +
  1036 +-- ----------------------------
  1037 +-- Table structure for ACT_RU_IDENTITYLINK
  1038 +-- ----------------------------
  1039 +DROP TABLE IF EXISTS `ACT_RU_IDENTITYLINK`;
  1040 +CREATE TABLE `ACT_RU_IDENTITYLINK` (
  1041 + `ID_` varchar(64) COLLATE utf8_bin NOT NULL,
  1042 + `REV_` int DEFAULT NULL,
  1043 + `GROUP_ID_` varchar(255) COLLATE utf8_bin DEFAULT NULL,
  1044 + `TYPE_` varchar(255) COLLATE utf8_bin DEFAULT NULL,
  1045 + `USER_ID_` varchar(255) COLLATE utf8_bin DEFAULT NULL,
  1046 + `TASK_ID_` varchar(64) COLLATE utf8_bin DEFAULT NULL,
  1047 + `PROC_INST_ID_` varchar(64) COLLATE utf8_bin DEFAULT NULL,
  1048 + `PROC_DEF_ID_` varchar(64) COLLATE utf8_bin DEFAULT NULL,
  1049 + `SCOPE_ID_` varchar(255) COLLATE utf8_bin DEFAULT NULL,
  1050 + `SUB_SCOPE_ID_` varchar(255) COLLATE utf8_bin DEFAULT NULL,
  1051 + `SCOPE_TYPE_` varchar(255) COLLATE utf8_bin DEFAULT NULL,
  1052 + `SCOPE_DEFINITION_ID_` varchar(255) COLLATE utf8_bin DEFAULT NULL,
  1053 + PRIMARY KEY (`ID_`),
  1054 + KEY `ACT_IDX_IDENT_LNK_USER` (`USER_ID_`),
  1055 + KEY `ACT_IDX_IDENT_LNK_GROUP` (`GROUP_ID_`),
  1056 + KEY `ACT_IDX_IDENT_LNK_SCOPE` (`SCOPE_ID_`,`SCOPE_TYPE_`),
  1057 + KEY `ACT_IDX_IDENT_LNK_SUB_SCOPE` (`SUB_SCOPE_ID_`,`SCOPE_TYPE_`),
  1058 + KEY `ACT_IDX_IDENT_LNK_SCOPE_DEF` (`SCOPE_DEFINITION_ID_`,`SCOPE_TYPE_`),
  1059 + KEY `ACT_IDX_ATHRZ_PROCEDEF` (`PROC_DEF_ID_`),
  1060 + KEY `ACT_FK_TSKASS_TASK` (`TASK_ID_`),
  1061 + KEY `ACT_FK_IDL_PROCINST` (`PROC_INST_ID_`),
  1062 + CONSTRAINT `ACT_FK_ATHRZ_PROCEDEF` FOREIGN KEY (`PROC_DEF_ID_`) REFERENCES `ACT_RE_PROCDEF` (`ID_`),
  1063 + CONSTRAINT `ACT_FK_IDL_PROCINST` FOREIGN KEY (`PROC_INST_ID_`) REFERENCES `ACT_RU_EXECUTION` (`ID_`),
  1064 + CONSTRAINT `ACT_FK_TSKASS_TASK` FOREIGN KEY (`TASK_ID_`) REFERENCES `ACT_RU_TASK` (`ID_`)
  1065 +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb3 COLLATE=utf8_bin;
  1066 +
  1067 +-- ----------------------------
  1068 +-- Records of ACT_RU_IDENTITYLINK
  1069 +-- ----------------------------
  1070 +BEGIN;
  1071 +COMMIT;
  1072 +
  1073 +-- ----------------------------
  1074 +-- Table structure for ACT_RU_JOB
  1075 +-- ----------------------------
  1076 +DROP TABLE IF EXISTS `ACT_RU_JOB`;
  1077 +CREATE TABLE `ACT_RU_JOB` (
  1078 + `ID_` varchar(64) COLLATE utf8_bin NOT NULL,
  1079 + `REV_` int DEFAULT NULL,
  1080 + `CATEGORY_` varchar(255) COLLATE utf8_bin DEFAULT NULL,
  1081 + `TYPE_` varchar(255) COLLATE utf8_bin NOT NULL,
  1082 + `LOCK_EXP_TIME_` timestamp(3) NULL DEFAULT NULL,
  1083 + `LOCK_OWNER_` varchar(255) COLLATE utf8_bin DEFAULT NULL,
  1084 + `EXCLUSIVE_` tinyint(1) DEFAULT NULL,
  1085 + `EXECUTION_ID_` varchar(64) COLLATE utf8_bin DEFAULT NULL,
  1086 + `PROCESS_INSTANCE_ID_` varchar(64) COLLATE utf8_bin DEFAULT NULL,
  1087 + `PROC_DEF_ID_` varchar(64) COLLATE utf8_bin DEFAULT NULL,
  1088 + `ELEMENT_ID_` varchar(255) COLLATE utf8_bin DEFAULT NULL,
  1089 + `ELEMENT_NAME_` varchar(255) COLLATE utf8_bin DEFAULT NULL,
  1090 + `SCOPE_ID_` varchar(255) COLLATE utf8_bin DEFAULT NULL,
  1091 + `SUB_SCOPE_ID_` varchar(255) COLLATE utf8_bin DEFAULT NULL,
  1092 + `SCOPE_TYPE_` varchar(255) COLLATE utf8_bin DEFAULT NULL,
  1093 + `SCOPE_DEFINITION_ID_` varchar(255) COLLATE utf8_bin DEFAULT NULL,
  1094 + `CORRELATION_ID_` varchar(255) COLLATE utf8_bin DEFAULT NULL,
  1095 + `RETRIES_` int DEFAULT NULL,
  1096 + `EXCEPTION_STACK_ID_` varchar(64) COLLATE utf8_bin DEFAULT NULL,
  1097 + `EXCEPTION_MSG_` varchar(4000) COLLATE utf8_bin DEFAULT NULL,
  1098 + `DUEDATE_` timestamp(3) NULL DEFAULT NULL,
  1099 + `REPEAT_` varchar(255) COLLATE utf8_bin DEFAULT NULL,
  1100 + `HANDLER_TYPE_` varchar(255) COLLATE utf8_bin DEFAULT NULL,
  1101 + `HANDLER_CFG_` varchar(4000) COLLATE utf8_bin DEFAULT NULL,
  1102 + `CUSTOM_VALUES_ID_` varchar(64) COLLATE utf8_bin DEFAULT NULL,
  1103 + `CREATE_TIME_` timestamp(3) NULL DEFAULT NULL,
  1104 + `TENANT_ID_` varchar(255) COLLATE utf8_bin DEFAULT '',
  1105 + PRIMARY KEY (`ID_`),
  1106 + KEY `ACT_IDX_JOB_EXCEPTION_STACK_ID` (`EXCEPTION_STACK_ID_`),
  1107 + KEY `ACT_IDX_JOB_CUSTOM_VALUES_ID` (`CUSTOM_VALUES_ID_`),
  1108 + KEY `ACT_IDX_JOB_CORRELATION_ID` (`CORRELATION_ID_`),
  1109 + KEY `ACT_IDX_JOB_SCOPE` (`SCOPE_ID_`,`SCOPE_TYPE_`),
  1110 + KEY `ACT_IDX_JOB_SUB_SCOPE` (`SUB_SCOPE_ID_`,`SCOPE_TYPE_`),
  1111 + KEY `ACT_IDX_JOB_SCOPE_DEF` (`SCOPE_DEFINITION_ID_`,`SCOPE_TYPE_`),
  1112 + KEY `ACT_FK_JOB_EXECUTION` (`EXECUTION_ID_`),
  1113 + KEY `ACT_FK_JOB_PROCESS_INSTANCE` (`PROCESS_INSTANCE_ID_`),
  1114 + KEY `ACT_FK_JOB_PROC_DEF` (`PROC_DEF_ID_`),
  1115 + CONSTRAINT `ACT_FK_JOB_CUSTOM_VALUES` FOREIGN KEY (`CUSTOM_VALUES_ID_`) REFERENCES `ACT_GE_BYTEARRAY` (`ID_`),
  1116 + CONSTRAINT `ACT_FK_JOB_EXCEPTION` FOREIGN KEY (`EXCEPTION_STACK_ID_`) REFERENCES `ACT_GE_BYTEARRAY` (`ID_`),
  1117 + CONSTRAINT `ACT_FK_JOB_EXECUTION` FOREIGN KEY (`EXECUTION_ID_`) REFERENCES `ACT_RU_EXECUTION` (`ID_`),
  1118 + CONSTRAINT `ACT_FK_JOB_PROC_DEF` FOREIGN KEY (`PROC_DEF_ID_`) REFERENCES `ACT_RE_PROCDEF` (`ID_`),
  1119 + CONSTRAINT `ACT_FK_JOB_PROCESS_INSTANCE` FOREIGN KEY (`PROCESS_INSTANCE_ID_`) REFERENCES `ACT_RU_EXECUTION` (`ID_`)
  1120 +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb3 COLLATE=utf8_bin;
  1121 +
  1122 +-- ----------------------------
  1123 +-- Records of ACT_RU_JOB
  1124 +-- ----------------------------
  1125 +BEGIN;
  1126 +COMMIT;
  1127 +
  1128 +-- ----------------------------
  1129 +-- Table structure for ACT_RU_SUSPENDED_JOB
  1130 +-- ----------------------------
  1131 +DROP TABLE IF EXISTS `ACT_RU_SUSPENDED_JOB`;
  1132 +CREATE TABLE `ACT_RU_SUSPENDED_JOB` (
  1133 + `ID_` varchar(64) COLLATE utf8_bin NOT NULL,
  1134 + `REV_` int DEFAULT NULL,
  1135 + `CATEGORY_` varchar(255) COLLATE utf8_bin DEFAULT NULL,
  1136 + `TYPE_` varchar(255) COLLATE utf8_bin NOT NULL,
  1137 + `EXCLUSIVE_` tinyint(1) DEFAULT NULL,
  1138 + `EXECUTION_ID_` varchar(64) COLLATE utf8_bin DEFAULT NULL,
  1139 + `PROCESS_INSTANCE_ID_` varchar(64) COLLATE utf8_bin DEFAULT NULL,
  1140 + `PROC_DEF_ID_` varchar(64) COLLATE utf8_bin DEFAULT NULL,
  1141 + `ELEMENT_ID_` varchar(255) COLLATE utf8_bin DEFAULT NULL,
  1142 + `ELEMENT_NAME_` varchar(255) COLLATE utf8_bin DEFAULT NULL,
  1143 + `SCOPE_ID_` varchar(255) COLLATE utf8_bin DEFAULT NULL,
  1144 + `SUB_SCOPE_ID_` varchar(255) COLLATE utf8_bin DEFAULT NULL,
  1145 + `SCOPE_TYPE_` varchar(255) COLLATE utf8_bin DEFAULT NULL,
  1146 + `SCOPE_DEFINITION_ID_` varchar(255) COLLATE utf8_bin DEFAULT NULL,
  1147 + `CORRELATION_ID_` varchar(255) COLLATE utf8_bin DEFAULT NULL,
  1148 + `RETRIES_` int DEFAULT NULL,
  1149 + `EXCEPTION_STACK_ID_` varchar(64) COLLATE utf8_bin DEFAULT NULL,
  1150 + `EXCEPTION_MSG_` varchar(4000) COLLATE utf8_bin DEFAULT NULL,
  1151 + `DUEDATE_` timestamp(3) NULL DEFAULT NULL,
  1152 + `REPEAT_` varchar(255) COLLATE utf8_bin DEFAULT NULL,
  1153 + `HANDLER_TYPE_` varchar(255) COLLATE utf8_bin DEFAULT NULL,
  1154 + `HANDLER_CFG_` varchar(4000) COLLATE utf8_bin DEFAULT NULL,
  1155 + `CUSTOM_VALUES_ID_` varchar(64) COLLATE utf8_bin DEFAULT NULL,
  1156 + `CREATE_TIME_` timestamp(3) NULL DEFAULT NULL,
  1157 + `TENANT_ID_` varchar(255) COLLATE utf8_bin DEFAULT '',
  1158 + PRIMARY KEY (`ID_`),
  1159 + KEY `ACT_IDX_SUSPENDED_JOB_EXCEPTION_STACK_ID` (`EXCEPTION_STACK_ID_`),
  1160 + KEY `ACT_IDX_SUSPENDED_JOB_CUSTOM_VALUES_ID` (`CUSTOM_VALUES_ID_`),
  1161 + KEY `ACT_IDX_SUSPENDED_JOB_CORRELATION_ID` (`CORRELATION_ID_`),
  1162 + KEY `ACT_IDX_SJOB_SCOPE` (`SCOPE_ID_`,`SCOPE_TYPE_`),
  1163 + KEY `ACT_IDX_SJOB_SUB_SCOPE` (`SUB_SCOPE_ID_`,`SCOPE_TYPE_`),
  1164 + KEY `ACT_IDX_SJOB_SCOPE_DEF` (`SCOPE_DEFINITION_ID_`,`SCOPE_TYPE_`),
  1165 + KEY `ACT_FK_SUSPENDED_JOB_EXECUTION` (`EXECUTION_ID_`),
  1166 + KEY `ACT_FK_SUSPENDED_JOB_PROCESS_INSTANCE` (`PROCESS_INSTANCE_ID_`),
  1167 + KEY `ACT_FK_SUSPENDED_JOB_PROC_DEF` (`PROC_DEF_ID_`),
  1168 + CONSTRAINT `ACT_FK_SUSPENDED_JOB_CUSTOM_VALUES` FOREIGN KEY (`CUSTOM_VALUES_ID_`) REFERENCES `ACT_GE_BYTEARRAY` (`ID_`),
  1169 + CONSTRAINT `ACT_FK_SUSPENDED_JOB_EXCEPTION` FOREIGN KEY (`EXCEPTION_STACK_ID_`) REFERENCES `ACT_GE_BYTEARRAY` (`ID_`),
  1170 + CONSTRAINT `ACT_FK_SUSPENDED_JOB_EXECUTION` FOREIGN KEY (`EXECUTION_ID_`) REFERENCES `ACT_RU_EXECUTION` (`ID_`),
  1171 + CONSTRAINT `ACT_FK_SUSPENDED_JOB_PROC_DEF` FOREIGN KEY (`PROC_DEF_ID_`) REFERENCES `ACT_RE_PROCDEF` (`ID_`),
  1172 + CONSTRAINT `ACT_FK_SUSPENDED_JOB_PROCESS_INSTANCE` FOREIGN KEY (`PROCESS_INSTANCE_ID_`) REFERENCES `ACT_RU_EXECUTION` (`ID_`)
  1173 +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb3 COLLATE=utf8_bin;
  1174 +
  1175 +-- ----------------------------
  1176 +-- Records of ACT_RU_SUSPENDED_JOB
  1177 +-- ----------------------------
  1178 +BEGIN;
  1179 +COMMIT;
  1180 +
  1181 +-- ----------------------------
  1182 +-- Table structure for ACT_RU_TASK
  1183 +-- ----------------------------
  1184 +DROP TABLE IF EXISTS `ACT_RU_TASK`;
  1185 +CREATE TABLE `ACT_RU_TASK` (
  1186 + `ID_` varchar(64) COLLATE utf8_bin NOT NULL,
  1187 + `REV_` int DEFAULT NULL,
  1188 + `EXECUTION_ID_` varchar(64) COLLATE utf8_bin DEFAULT NULL,
  1189 + `PROC_INST_ID_` varchar(64) COLLATE utf8_bin DEFAULT NULL,
  1190 + `PROC_DEF_ID_` varchar(64) COLLATE utf8_bin DEFAULT NULL,
  1191 + `TASK_DEF_ID_` varchar(64) COLLATE utf8_bin DEFAULT NULL,
  1192 + `SCOPE_ID_` varchar(255) COLLATE utf8_bin DEFAULT NULL,
  1193 + `SUB_SCOPE_ID_` varchar(255) COLLATE utf8_bin DEFAULT NULL,
  1194 + `SCOPE_TYPE_` varchar(255) COLLATE utf8_bin DEFAULT NULL,
  1195 + `SCOPE_DEFINITION_ID_` varchar(255) COLLATE utf8_bin DEFAULT NULL,
  1196 + `PROPAGATED_STAGE_INST_ID_` varchar(255) COLLATE utf8_bin DEFAULT NULL,
  1197 + `NAME_` varchar(255) COLLATE utf8_bin DEFAULT NULL,
  1198 + `PARENT_TASK_ID_` varchar(64) COLLATE utf8_bin DEFAULT NULL,
  1199 + `DESCRIPTION_` varchar(4000) COLLATE utf8_bin DEFAULT NULL,
  1200 + `TASK_DEF_KEY_` varchar(255) COLLATE utf8_bin DEFAULT NULL,
  1201 + `OWNER_` varchar(255) COLLATE utf8_bin DEFAULT NULL,
  1202 + `ASSIGNEE_` varchar(255) COLLATE utf8_bin DEFAULT NULL,
  1203 + `DELEGATION_` varchar(64) COLLATE utf8_bin DEFAULT NULL,
  1204 + `PRIORITY_` int DEFAULT NULL,
  1205 + `CREATE_TIME_` timestamp(3) NULL DEFAULT NULL,
  1206 + `DUE_DATE_` datetime(3) DEFAULT NULL,
  1207 + `CATEGORY_` varchar(255) COLLATE utf8_bin DEFAULT NULL,
  1208 + `SUSPENSION_STATE_` int DEFAULT NULL,
  1209 + `TENANT_ID_` varchar(255) COLLATE utf8_bin DEFAULT '',
  1210 + `FORM_KEY_` varchar(255) COLLATE utf8_bin DEFAULT NULL,
  1211 + `CLAIM_TIME_` datetime(3) DEFAULT NULL,
  1212 + `IS_COUNT_ENABLED_` tinyint DEFAULT NULL,
  1213 + `VAR_COUNT_` int DEFAULT NULL,
  1214 + `ID_LINK_COUNT_` int DEFAULT NULL,
  1215 + `SUB_TASK_COUNT_` int DEFAULT NULL,
  1216 + PRIMARY KEY (`ID_`),
  1217 + KEY `ACT_IDX_TASK_CREATE` (`CREATE_TIME_`),
  1218 + KEY `ACT_IDX_TASK_SCOPE` (`SCOPE_ID_`,`SCOPE_TYPE_`),
  1219 + KEY `ACT_IDX_TASK_SUB_SCOPE` (`SUB_SCOPE_ID_`,`SCOPE_TYPE_`),
  1220 + KEY `ACT_IDX_TASK_SCOPE_DEF` (`SCOPE_DEFINITION_ID_`,`SCOPE_TYPE_`),
  1221 + KEY `ACT_FK_TASK_EXE` (`EXECUTION_ID_`),
  1222 + KEY `ACT_FK_TASK_PROCINST` (`PROC_INST_ID_`),
  1223 + KEY `ACT_FK_TASK_PROCDEF` (`PROC_DEF_ID_`),
  1224 + CONSTRAINT `ACT_FK_TASK_EXE` FOREIGN KEY (`EXECUTION_ID_`) REFERENCES `ACT_RU_EXECUTION` (`ID_`),
  1225 + CONSTRAINT `ACT_FK_TASK_PROCDEF` FOREIGN KEY (`PROC_DEF_ID_`) REFERENCES `ACT_RE_PROCDEF` (`ID_`),
  1226 + CONSTRAINT `ACT_FK_TASK_PROCINST` FOREIGN KEY (`PROC_INST_ID_`) REFERENCES `ACT_RU_EXECUTION` (`ID_`)
  1227 +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb3 COLLATE=utf8_bin;
  1228 +
  1229 +-- ----------------------------
  1230 +-- Records of ACT_RU_TASK
  1231 +-- ----------------------------
  1232 +BEGIN;
  1233 +COMMIT;
  1234 +
  1235 +-- ----------------------------
  1236 +-- Table structure for ACT_RU_TIMER_JOB
  1237 +-- ----------------------------
  1238 +DROP TABLE IF EXISTS `ACT_RU_TIMER_JOB`;
  1239 +CREATE TABLE `ACT_RU_TIMER_JOB` (
  1240 + `ID_` varchar(64) COLLATE utf8_bin NOT NULL,
  1241 + `REV_` int DEFAULT NULL,
  1242 + `CATEGORY_` varchar(255) COLLATE utf8_bin DEFAULT NULL,
  1243 + `TYPE_` varchar(255) COLLATE utf8_bin NOT NULL,
  1244 + `LOCK_EXP_TIME_` timestamp(3) NULL DEFAULT NULL,
  1245 + `LOCK_OWNER_` varchar(255) COLLATE utf8_bin DEFAULT NULL,
  1246 + `EXCLUSIVE_` tinyint(1) DEFAULT NULL,
  1247 + `EXECUTION_ID_` varchar(64) COLLATE utf8_bin DEFAULT NULL,
  1248 + `PROCESS_INSTANCE_ID_` varchar(64) COLLATE utf8_bin DEFAULT NULL,
  1249 + `PROC_DEF_ID_` varchar(64) COLLATE utf8_bin DEFAULT NULL,
  1250 + `ELEMENT_ID_` varchar(255) COLLATE utf8_bin DEFAULT NULL,
  1251 + `ELEMENT_NAME_` varchar(255) COLLATE utf8_bin DEFAULT NULL,
  1252 + `SCOPE_ID_` varchar(255) COLLATE utf8_bin DEFAULT NULL,
  1253 + `SUB_SCOPE_ID_` varchar(255) COLLATE utf8_bin DEFAULT NULL,
  1254 + `SCOPE_TYPE_` varchar(255) COLLATE utf8_bin DEFAULT NULL,
  1255 + `SCOPE_DEFINITION_ID_` varchar(255) COLLATE utf8_bin DEFAULT NULL,
  1256 + `CORRELATION_ID_` varchar(255) COLLATE utf8_bin DEFAULT NULL,
  1257 + `RETRIES_` int DEFAULT NULL,
  1258 + `EXCEPTION_STACK_ID_` varchar(64) COLLATE utf8_bin DEFAULT NULL,
  1259 + `EXCEPTION_MSG_` varchar(4000) COLLATE utf8_bin DEFAULT NULL,
  1260 + `DUEDATE_` timestamp(3) NULL DEFAULT NULL,
  1261 + `REPEAT_` varchar(255) COLLATE utf8_bin DEFAULT NULL,
  1262 + `HANDLER_TYPE_` varchar(255) COLLATE utf8_bin DEFAULT NULL,
  1263 + `HANDLER_CFG_` varchar(4000) COLLATE utf8_bin DEFAULT NULL,
  1264 + `CUSTOM_VALUES_ID_` varchar(64) COLLATE utf8_bin DEFAULT NULL,
  1265 + `CREATE_TIME_` timestamp(3) NULL DEFAULT NULL,
  1266 + `TENANT_ID_` varchar(255) COLLATE utf8_bin DEFAULT '',
  1267 + PRIMARY KEY (`ID_`),
  1268 + KEY `ACT_IDX_TIMER_JOB_EXCEPTION_STACK_ID` (`EXCEPTION_STACK_ID_`),
  1269 + KEY `ACT_IDX_TIMER_JOB_CUSTOM_VALUES_ID` (`CUSTOM_VALUES_ID_`),
  1270 + KEY `ACT_IDX_TIMER_JOB_CORRELATION_ID` (`CORRELATION_ID_`),
  1271 + KEY `ACT_IDX_TIMER_JOB_DUEDATE` (`DUEDATE_`),
  1272 + KEY `ACT_IDX_TJOB_SCOPE` (`SCOPE_ID_`,`SCOPE_TYPE_`),
  1273 + KEY `ACT_IDX_TJOB_SUB_SCOPE` (`SUB_SCOPE_ID_`,`SCOPE_TYPE_`),
  1274 + KEY `ACT_IDX_TJOB_SCOPE_DEF` (`SCOPE_DEFINITION_ID_`,`SCOPE_TYPE_`),
  1275 + KEY `ACT_FK_TIMER_JOB_EXECUTION` (`EXECUTION_ID_`),
  1276 + KEY `ACT_FK_TIMER_JOB_PROCESS_INSTANCE` (`PROCESS_INSTANCE_ID_`),
  1277 + KEY `ACT_FK_TIMER_JOB_PROC_DEF` (`PROC_DEF_ID_`),
  1278 + CONSTRAINT `ACT_FK_TIMER_JOB_CUSTOM_VALUES` FOREIGN KEY (`CUSTOM_VALUES_ID_`) REFERENCES `ACT_GE_BYTEARRAY` (`ID_`),
  1279 + CONSTRAINT `ACT_FK_TIMER_JOB_EXCEPTION` FOREIGN KEY (`EXCEPTION_STACK_ID_`) REFERENCES `ACT_GE_BYTEARRAY` (`ID_`),
  1280 + CONSTRAINT `ACT_FK_TIMER_JOB_EXECUTION` FOREIGN KEY (`EXECUTION_ID_`) REFERENCES `ACT_RU_EXECUTION` (`ID_`),
  1281 + CONSTRAINT `ACT_FK_TIMER_JOB_PROC_DEF` FOREIGN KEY (`PROC_DEF_ID_`) REFERENCES `ACT_RE_PROCDEF` (`ID_`),
  1282 + CONSTRAINT `ACT_FK_TIMER_JOB_PROCESS_INSTANCE` FOREIGN KEY (`PROCESS_INSTANCE_ID_`) REFERENCES `ACT_RU_EXECUTION` (`ID_`)
  1283 +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb3 COLLATE=utf8_bin;
  1284 +
  1285 +-- ----------------------------
  1286 +-- Records of ACT_RU_TIMER_JOB
  1287 +-- ----------------------------
  1288 +BEGIN;
  1289 +COMMIT;
  1290 +
  1291 +-- ----------------------------
  1292 +-- Table structure for ACT_RU_VARIABLE
  1293 +-- ----------------------------
  1294 +DROP TABLE IF EXISTS `ACT_RU_VARIABLE`;
  1295 +CREATE TABLE `ACT_RU_VARIABLE` (
  1296 + `ID_` varchar(64) COLLATE utf8_bin NOT NULL,
  1297 + `REV_` int DEFAULT NULL,
  1298 + `TYPE_` varchar(255) COLLATE utf8_bin NOT NULL,
  1299 + `NAME_` varchar(255) COLLATE utf8_bin NOT NULL,
  1300 + `EXECUTION_ID_` varchar(64) COLLATE utf8_bin DEFAULT NULL,
  1301 + `PROC_INST_ID_` varchar(64) COLLATE utf8_bin DEFAULT NULL,
  1302 + `TASK_ID_` varchar(64) COLLATE utf8_bin DEFAULT NULL,
  1303 + `SCOPE_ID_` varchar(255) COLLATE utf8_bin DEFAULT NULL,
  1304 + `SUB_SCOPE_ID_` varchar(255) COLLATE utf8_bin DEFAULT NULL,
  1305 + `SCOPE_TYPE_` varchar(255) COLLATE utf8_bin DEFAULT NULL,
  1306 + `BYTEARRAY_ID_` varchar(64) COLLATE utf8_bin DEFAULT NULL,
  1307 + `DOUBLE_` double DEFAULT NULL,
  1308 + `LONG_` bigint DEFAULT NULL,
  1309 + `TEXT_` varchar(4000) COLLATE utf8_bin DEFAULT NULL,
  1310 + `TEXT2_` varchar(4000) COLLATE utf8_bin DEFAULT NULL,
  1311 + PRIMARY KEY (`ID_`),
  1312 + KEY `ACT_IDX_RU_VAR_SCOPE_ID_TYPE` (`SCOPE_ID_`,`SCOPE_TYPE_`),
  1313 + KEY `ACT_IDX_RU_VAR_SUB_ID_TYPE` (`SUB_SCOPE_ID_`,`SCOPE_TYPE_`),
  1314 + KEY `ACT_FK_VAR_BYTEARRAY` (`BYTEARRAY_ID_`),
  1315 + KEY `ACT_IDX_VARIABLE_TASK_ID` (`TASK_ID_`),
  1316 + KEY `ACT_FK_VAR_EXE` (`EXECUTION_ID_`),
  1317 + KEY `ACT_FK_VAR_PROCINST` (`PROC_INST_ID_`),
  1318 + CONSTRAINT `ACT_FK_VAR_BYTEARRAY` FOREIGN KEY (`BYTEARRAY_ID_`) REFERENCES `ACT_GE_BYTEARRAY` (`ID_`),
  1319 + CONSTRAINT `ACT_FK_VAR_EXE` FOREIGN KEY (`EXECUTION_ID_`) REFERENCES `ACT_RU_EXECUTION` (`ID_`),
  1320 + CONSTRAINT `ACT_FK_VAR_PROCINST` FOREIGN KEY (`PROC_INST_ID_`) REFERENCES `ACT_RU_EXECUTION` (`ID_`)
  1321 +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb3 COLLATE=utf8_bin;
  1322 +
  1323 +-- ----------------------------
  1324 +-- Records of ACT_RU_VARIABLE
  1325 +-- ----------------------------
  1326 +BEGIN;
  1327 +COMMIT;
  1328 +
  1329 +SET FOREIGN_KEY_CHECKS = 1;
... ...
yudao-dependencies/pom.xml
... ... @@ -400,6 +400,11 @@
400 400 </dependency>
401 401 <!-- 工作流相关 flowable -->
402 402 <dependency>
  403 + <groupId>cn.iocoder.boot</groupId>
  404 + <artifactId>yudao-spring-boot-starter-flowable</artifactId>
  405 + <version>${revision}</version>
  406 + </dependency>
  407 + <dependency>
403 408 <groupId>org.flowable</groupId>
404 409 <artifactId>flowable-spring-boot-starter-basic</artifactId>
405 410 <version>${flowable.version}</version>
... ...
yudao-framework/pom.xml
... ... @@ -35,12 +35,13 @@
35 35 <module>yudao-spring-boot-starter-biz-social</module>
36 36 <module>yudao-spring-boot-starter-biz-tenant</module>
37 37 <module>yudao-spring-boot-starter-biz-data-permission</module>
  38 + <module>yudao-spring-boot-starter-flowable</module>
38 39 </modules>
39 40  
40 41 <artifactId>yudao-framework</artifactId>
41 42 <description>
42 43 该包是技术组件,每个子包,代表一个组件。每个组件包括两部分:
43   - 1. core 包:是该组件的核心分装
  44 + 1. core 包:是该组件的核心封装
44 45 2. config 包:是该组件基于 Spring 的配置
45 46  
46 47 技术组件,也分成两类:
... ...
yudao-framework/yudao-common/src/main/java/cn/iocoder/yudao/framework/common/enums/WebFilterOrderEnum.java
... ... @@ -29,6 +29,8 @@ public interface WebFilterOrderEnum {
29 29  
30 30 int ACTIVITI_FILTER = -98; // 需要保证在 Spring Security 过滤后面
31 31  
  32 + int FLOWABLE_FILTER = -98; // 需要保证在 Spring Security 过滤后面
  33 +
32 34 int DEMO_FILTER = Integer.MAX_VALUE;
33 35  
34 36 }
... ...
yudao-framework/yudao-spring-boot-starter-flowable/pom.xml 0 → 100644
  1 +<?xml version="1.0" encoding="UTF-8"?>
  2 +<project xmlns="http://maven.apache.org/POM/4.0.0"
  3 + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  4 + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
  5 + <parent>
  6 + <artifactId>yudao-framework</artifactId>
  7 + <groupId>cn.iocoder.boot</groupId>
  8 + <version>${revision}</version>
  9 + </parent>
  10 + <modelVersion>4.0.0</modelVersion>
  11 +
  12 + <artifactId>yudao-spring-boot-starter-flowable</artifactId>
  13 +
  14 + <dependencies>
  15 + <dependency>
  16 + <groupId>cn.iocoder.boot</groupId>
  17 + <artifactId>yudao-common</artifactId>
  18 + </dependency>
  19 +
  20 + <!-- Web 相关 -->
  21 + <dependency>
  22 + <groupId>cn.iocoder.boot</groupId>
  23 + <artifactId>yudao-spring-boot-starter-security</artifactId>
  24 + </dependency>
  25 +
  26 + <!-- flowable 工作流相关 -->
  27 + <dependency>
  28 + <groupId>org.flowable</groupId>
  29 + <artifactId>flowable-spring-boot-starter-basic</artifactId>
  30 + </dependency>
  31 + <dependency>
  32 + <groupId>org.flowable</groupId>
  33 + <artifactId>flowable-spring-boot-starter-actuator</artifactId>
  34 + </dependency>
  35 + </dependencies>
  36 +
  37 +</project>
... ...
yudao-framework/yudao-spring-boot-starter-flowable/src/main/java/cn/iocoder/yudao/framework/flowable/config/YudaoFlowableConfiguration.java 0 → 100644
  1 +package cn.iocoder.yudao.framework.flowable.config;
  2 +
  3 +import cn.iocoder.yudao.framework.common.enums.WebFilterOrderEnum;
  4 +import cn.iocoder.yudao.framework.flowable.core.web.FlowableWebFilter;
  5 +import org.springframework.boot.web.servlet.FilterRegistrationBean;
  6 +import org.springframework.context.annotation.Bean;
  7 +import org.springframework.context.annotation.Configuration;
  8 +
  9 +@Configuration
  10 +public class YudaoFlowableConfiguration {
  11 +
  12 + /**
  13 + * 配置 flowable Web 过滤器
  14 + */
  15 + @Bean
  16 + public FilterRegistrationBean<FlowableWebFilter> flowableWebFilter() {
  17 + FilterRegistrationBean<FlowableWebFilter> registrationBean = new FilterRegistrationBean<>();
  18 + registrationBean.setFilter(new FlowableWebFilter());
  19 + registrationBean.setOrder(WebFilterOrderEnum.FLOWABLE_FILTER);
  20 + return registrationBean;
  21 + }
  22 +}
... ...
yudao-framework/yudao-spring-boot-starter-flowable/src/main/java/cn/iocoder/yudao/framework/flowable/core/package-info.java 0 → 100644
  1 +package cn.iocoder.yudao.framework.flowable.core;
... ...
yudao-framework/yudao-spring-boot-starter-flowable/src/main/java/cn/iocoder/yudao/framework/flowable/core/util/FlowableUtils.java 0 → 100644
  1 +package cn.iocoder.yudao.framework.flowable.core.util;
  2 +
  3 +import org.flowable.bpmn.converter.BpmnXMLConverter;
  4 +import org.flowable.bpmn.model.BpmnModel;
  5 +import org.flowable.bpmn.model.FlowElement;
  6 +import org.flowable.common.engine.impl.identity.Authentication;
  7 +
  8 +import java.util.ArrayList;
  9 +import java.util.Arrays;
  10 +import java.util.List;
  11 +
  12 +public class FlowableUtils {
  13 +
  14 + public static void setAuthenticatedUserId(Long userId) {
  15 + Authentication.setAuthenticatedUserId(String.valueOf(userId));
  16 + }
  17 +
  18 + public static void clearAuthenticatedUserId() {
  19 + Authentication.setAuthenticatedUserId(null);
  20 + }
  21 +
  22 + /**
  23 + * 获得 BPMN 流程中,指定的元素们
  24 + *
  25 + * @param model
  26 + * @param clazz 指定元素。例如说,{@link org.flowable.bpmn.model.UserTask}、{@link org.flowable.bpmn.model.Gateway} 等等
  27 + * @return 元素们
  28 + */
  29 + public static <T extends FlowElement> List<T> getBpmnModelElements(BpmnModel model, Class<T> clazz) {
  30 + List<T> result = new ArrayList<>();
  31 + model.getProcesses().forEach(process -> {
  32 + process.getFlowElements().forEach(flowElement -> {
  33 + if (flowElement.getClass().isAssignableFrom(clazz)) {
  34 + result.add((T) flowElement);
  35 + }
  36 + });
  37 + });
  38 + return result;
  39 + }
  40 +
  41 + /**
  42 + * 比较 两个bpmnModel 是否相同
  43 + * @param oldModel 老的bpmn model
  44 + * @param newModel 新的bpmn model
  45 + */
  46 + public static boolean equals(BpmnModel oldModel, BpmnModel newModel) {
  47 + // 由于 BpmnModel 未提供 equals 方法,所以只能转成字节数组,进行比较
  48 + return Arrays.equals(getBpmnBytes(oldModel), getBpmnBytes(newModel));
  49 + }
  50 +
  51 + /**
  52 + * 把 bpmnModel 转换成 byte[]
  53 + * @param model bpmnModel
  54 + */
  55 + public static byte[] getBpmnBytes(BpmnModel model) {
  56 + if (model == null) {
  57 + return new byte[0];
  58 + }
  59 + BpmnXMLConverter converter = new BpmnXMLConverter();
  60 + return converter.convertToXML(model);
  61 + }
  62 +}
... ...
yudao-framework/yudao-spring-boot-starter-flowable/src/main/java/cn/iocoder/yudao/framework/flowable/core/web/FlowableWebFilter.java 0 → 100644
  1 +package cn.iocoder.yudao.framework.flowable.core.web;
  2 +
  3 +import cn.iocoder.yudao.framework.flowable.core.util.FlowableUtils;
  4 +import cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils;
  5 +import org.springframework.web.filter.OncePerRequestFilter;
  6 +
  7 +import javax.servlet.FilterChain;
  8 +import javax.servlet.ServletException;
  9 +import javax.servlet.http.HttpServletRequest;
  10 +import javax.servlet.http.HttpServletResponse;
  11 +import java.io.IOException;
  12 +/**
  13 + * flowable Web 过滤器,将 userId 设置到 {@link org.flowable.common.engine.impl.identity.Authentication} 中
  14 + *
  15 + * @author jason
  16 + */
  17 +public class FlowableWebFilter extends OncePerRequestFilter {
  18 +
  19 + @Override
  20 + protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain chain)
  21 + throws ServletException, IOException {
  22 + try {
  23 + // 设置工作流的用户
  24 + Long userId = SecurityFrameworkUtils.getLoginUserId();
  25 + if (userId != null) {
  26 + FlowableUtils.setAuthenticatedUserId(userId);
  27 + }
  28 + // 过滤
  29 + chain.doFilter(request, response);
  30 + } finally {
  31 + // 清理
  32 + FlowableUtils.clearAuthenticatedUserId();
  33 + }
  34 + }
  35 +}
... ...
yudao-framework/yudao-spring-boot-starter-flowable/src/main/java/cn/iocoder/yudao/framework/flowable/package-info.java 0 → 100644
  1 +package cn.iocoder.yudao.framework.flowable;
... ...
yudao-framework/yudao-spring-boot-starter-flowable/src/main/resources/META-INF/spring.factories 0 → 100644
  1 +org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
  2 + cn.iocoder.yudao.framework.flowable.config.YudaoFlowableConfiguration
... ...
yudao-framework/yudao-spring-boot-starter-web/pom.xml
... ... @@ -12,7 +12,7 @@
12 12 <packaging>jar</packaging>
13 13  
14 14 <name>${project.artifactId}</name>
15   - <description>用户的认证、权限的校验</description>
  15 + <description>Web 框架,全局异常、API 日志等</description>
16 16 <url>https://github.com/YunaiV/ruoyi-vue-pro</url>
17 17  
18 18 <dependencies>
... ...
yudao-module-bpm/yudao-module-bpm-base/pom.xml
... ... @@ -32,6 +32,10 @@
32 32 <groupId>cn.iocoder.boot</groupId>
33 33 <artifactId>yudao-spring-boot-starter-biz-operatelog</artifactId>
34 34 </dependency>
  35 + <dependency>
  36 + <groupId>cn.iocoder.boot</groupId>
  37 + <artifactId>yudao-spring-boot-starter-biz-data-permission</artifactId>
  38 + </dependency>
35 39  
36 40 <!-- Web 相关 -->
37 41 <dependency>
... ...
yudao-module-bpm/yudao-module-bpm-base/src/main/java/cn/iocoder/yudao/module/bpm/service/definition/BpmFormService.java
... ... @@ -88,4 +88,12 @@ public interface BpmFormService {
88 88 */
89 89 PageResult<BpmFormDO> getFormPage(BpmFormPageReqVO pageReqVO);
90 90  
  91 + /**
  92 + * 校验流程表单已配置
  93 + *
  94 + * @param configStr configStr 字段
  95 + * @return 流程表单
  96 + */
  97 + BpmFormDO checkFormConfig(String configStr);
  98 +
91 99 }
... ...
yudao-module-bpm/yudao-module-bpm-base/src/main/java/cn/iocoder/yudao/module/bpm/service/definition/BpmFormServiceImpl.java
1 1 package cn.iocoder.yudao.module.bpm.service.definition;
2 2  
3 3 import cn.hutool.core.lang.Assert;
  4 +import cn.iocoder.yudao.framework.common.util.validation.ValidationUtils;
4 5 import cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.form.BpmFormCreateReqVO;
5 6 import cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.form.BpmFormPageReqVO;
6 7 import cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.form.BpmFormUpdateReqVO;
... ... @@ -8,18 +9,20 @@ import cn.iocoder.yudao.module.bpm.convert.definition.BpmFormConvert;
8 9 import cn.iocoder.yudao.module.bpm.dal.dataobject.definition.BpmFormDO;
9 10 import cn.iocoder.yudao.module.bpm.dal.mysql.definition.BpmFormMapper;
10 11 import cn.iocoder.yudao.module.bpm.enums.ErrorCodeConstants;
  12 +import cn.iocoder.yudao.module.bpm.enums.definition.BpmModelFormTypeEnum;
11 13 import cn.iocoder.yudao.module.bpm.service.definition.dto.BpmFormFieldRespDTO;
12 14 import cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil;
13 15 import cn.iocoder.yudao.framework.common.pojo.PageResult;
14 16 import cn.iocoder.yudao.framework.common.util.json.JsonUtils;
  17 +import cn.iocoder.yudao.module.bpm.service.definition.dto.BpmModelMetaInfoRespDTO;
15 18 import org.springframework.stereotype.Service;
16 19 import org.springframework.validation.annotation.Validated;
17 20  
18 21 import javax.annotation.Resource;
19   -import java.util.Collection;
20   -import java.util.HashMap;
21   -import java.util.List;
22   -import java.util.Map;
  22 +import java.util.*;
  23 +
  24 +import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
  25 +import static cn.iocoder.yudao.module.bpm.enums.ErrorCodeConstants.*;
23 26  
24 27 /**
25 28 * 动态表单 Service 实现类
... ... @@ -87,6 +90,29 @@ public class BpmFormServiceImpl implements BpmFormService {
87 90 return formMapper.selectPage(pageReqVO);
88 91 }
89 92  
  93 +
  94 + @Override
  95 + public BpmFormDO checkFormConfig(String configStr) {
  96 + BpmModelMetaInfoRespDTO metaInfo = JsonUtils.parseObject(configStr, BpmModelMetaInfoRespDTO.class);
  97 + if (metaInfo == null || metaInfo.getFormType() == null) {
  98 + throw exception(MODEL_DEPLOY_FAIL_FORM_NOT_CONFIG);
  99 + }
  100 + // 校验表单存在
  101 + if (Objects.equals(metaInfo.getFormType(), BpmModelFormTypeEnum.NORMAL.getType())) {
  102 + BpmFormDO form = getForm(metaInfo.getFormId());
  103 + if (form == null) {
  104 + throw exception(FORM_NOT_EXISTS);
  105 + }
  106 + return form;
  107 + }
  108 + return null;
  109 + }
  110 +
  111 + private void checkKeyNCName(String key) {
  112 + if (!ValidationUtils.isXmlNCName(key)) {
  113 + throw exception(MODEL_KEY_VALID);
  114 + }
  115 + }
90 116 /**
91 117 * 校验 Field,避免 field 重复
92 118 *
... ...
yudao-module-bpm/yudao-module-bpm-impl-activiti/src/main/java/cn/iocoder/yudao/module/bpm/service/definition/dto/BpmModelMetaInfoRespDTO.java renamed to yudao-module-bpm/yudao-module-bpm-base/src/main/java/cn/iocoder/yudao/module/bpm/service/definition/dto/BpmModelMetaInfoRespDTO.java
... ... @@ -5,7 +5,7 @@ import lombok.Data;
5 5  
6 6 /**
7 7 * BPM 流程 MetaInfo Response DTO
8   - * 主要用于 {@link org.activiti.engine.repository.Model#setMetaInfo(String)} 的存储
  8 + * 主要用于 { Model#setMetaInfo(String)} 的存储
9 9 *
10 10 * @author 芋道源码
11 11 */
... ...
yudao-module-bpm/yudao-module-bpm-impl-activiti/src/main/java/cn/iocoder/yudao/module/bpm/service/definition/dto/BpmProcessDefinitionCreateReqDTO.java renamed to yudao-module-bpm/yudao-module-bpm-base/src/main/java/cn/iocoder/yudao/module/bpm/service/definition/dto/BpmProcessDefinitionCreateReqDTO.java
yudao-module-bpm/yudao-module-bpm-impl-activiti/src/main/java/cn/iocoder/yudao/module/bpm/api/task/BpmProcessInstanceApiImpl.java
... ... @@ -8,7 +8,7 @@ import org.springframework.validation.annotation.Validated;
8 8 import javax.annotation.Resource;
9 9  
10 10 /**
11   - * 流程实例 Api 实现类
  11 + * Activiti 流程实例 Api 实现类
12 12 *
13 13 * @author 芋道源码
14 14 */
... ...
yudao-module-bpm/yudao-module-bpm-impl-activiti/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/definition/BpmModelController.java
... ... @@ -93,5 +93,4 @@ public class BpmModelController {
93 93 bpmModelService.updateModelState(reqVO.getId(), reqVO.getState());
94 94 return success(true);
95 95 }
96   -
97 96 }
... ...
yudao-module-bpm/yudao-module-bpm-impl-activiti/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/definition/BpmTaskAssignRuleController.java
1 1 package cn.iocoder.yudao.module.bpm.controller.admin.definition;
2 2  
  3 +import cn.iocoder.yudao.framework.common.pojo.CommonResult;
3 4 import cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.rule.BpmTaskAssignRuleCreateReqVO;
4 5 import cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.rule.BpmTaskAssignRuleRespVO;
5 6 import cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.rule.BpmTaskAssignRuleUpdateReqVO;
6 7 import cn.iocoder.yudao.module.bpm.service.definition.BpmTaskAssignRuleService;
7   -import cn.iocoder.yudao.framework.common.pojo.CommonResult;
8 8 import io.swagger.annotations.Api;
9 9 import io.swagger.annotations.ApiImplicitParam;
10 10 import io.swagger.annotations.ApiImplicitParams;
... ... @@ -32,7 +32,7 @@ public class BpmTaskAssignRuleController {
32 32 @ApiOperation(value = "获得任务分配规则列表")
33 33 @ApiImplicitParams({
34 34 @ApiImplicitParam(name = "modelId", value = "模型编号", example = "1024", dataTypeClass = String.class),
35   - @ApiImplicitParam(name = "processDefinitionId", value = "刘晨定义的编号", example = "2048", dataTypeClass = String.class)
  35 + @ApiImplicitParam(name = "processDefinitionId", value = "流程定义的编号", example = "2048", dataTypeClass = String.class)
36 36 })
37 37 @PreAuthorize("@ss.hasPermission('bpm:task-assign-rule:query')")
38 38 public CommonResult<List<BpmTaskAssignRuleRespVO>> getTaskAssignRuleList(
... ...
yudao-module-bpm/yudao-module-bpm-impl-activiti/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/task/BpmTaskController.java
... ... @@ -37,7 +37,7 @@ public class BpmTaskController {
37 37 @GetMapping("done-page")
38 38 @ApiOperation("获取 Done 已办任务分页")
39 39 @PreAuthorize("@ss.hasPermission('bpm:task:query')")
40   - public CommonResult<PageResult<BpmTaskDonePageItemRespVO>> getTodoTaskPage(@Valid BpmTaskDonePageReqVO pageVO) {
  40 + public CommonResult<PageResult<BpmTaskDonePageItemRespVO>> getDoneTaskPage(@Valid BpmTaskDonePageReqVO pageVO) {
41 41 return success(taskService.getDoneTaskPage(getLoginUserId(), pageVO));
42 42 }
43 43  
... ...
yudao-module-bpm/yudao-module-bpm-impl-activiti/src/main/java/cn/iocoder/yudao/module/bpm/convert/definition/BpmModelConvert.java
... ... @@ -2,11 +2,11 @@ package cn.iocoder.yudao.module.bpm.convert.definition;
2 2  
3 3 import cn.hutool.core.util.StrUtil;
4 4 import cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.model.*;
5   -import cn.iocoder.yudao.module.bpm.service.definition.dto.BpmModelMetaInfoRespDTO;
6   -import cn.iocoder.yudao.module.bpm.service.definition.dto.BpmProcessDefinitionCreateReqDTO;
7 5 import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils;
8 6 import cn.iocoder.yudao.framework.common.util.json.JsonUtils;
9 7 import cn.iocoder.yudao.module.bpm.dal.dataobject.definition.BpmFormDO;
  8 +import cn.iocoder.yudao.module.bpm.service.definition.dto.BpmModelMetaInfoRespDTO;
  9 +import cn.iocoder.yudao.module.bpm.service.definition.dto.BpmProcessDefinitionCreateReqDTO;
10 10 import org.activiti.engine.impl.persistence.entity.SuspensionState;
11 11 import org.activiti.engine.repository.Deployment;
12 12 import org.activiti.engine.repository.Model;
... ...
yudao-module-bpm/yudao-module-bpm-impl-activiti/src/main/java/cn/iocoder/yudao/module/bpm/convert/definition/BpmProcessDefinitionConvert.java
1 1 package cn.iocoder.yudao.module.bpm.convert.definition;
2 2  
  3 +import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils;
3 4 import cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.process.BpmProcessDefinitionPageItemRespVO;
4 5 import cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.process.BpmProcessDefinitionRespVO;
5 6 import cn.iocoder.yudao.module.bpm.dal.dataobject.definition.BpmFormDO;
6 7 import cn.iocoder.yudao.module.bpm.dal.dataobject.definition.BpmProcessDefinitionExtDO;
7 8 import cn.iocoder.yudao.module.bpm.service.definition.dto.BpmProcessDefinitionCreateReqDTO;
8   -import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils;
9 9 import org.activiti.engine.impl.persistence.entity.SuspensionState;
10 10 import org.activiti.engine.repository.Deployment;
11 11 import org.activiti.engine.repository.ProcessDefinition;
... ...
yudao-module-bpm/yudao-module-bpm-impl-activiti/src/main/java/cn/iocoder/yudao/module/bpm/framework/activiti/core/behavior/BpmActivityBehaviorFactory.java
... ... @@ -44,7 +44,7 @@ public class BpmActivityBehaviorFactory extends DefaultActivityBehaviorFactory {
44 44  
45 45 @Override
46 46 public UserTaskActivityBehavior createUserTaskActivityBehavior(UserTask userTask) {
47   - BpmUserTaskActivitiBehavior userTaskActivityBehavior = new BpmUserTaskActivitiBehavior(userTask);
  47 + BpmUserTaskActivityBehavior userTaskActivityBehavior = new BpmUserTaskActivityBehavior(userTask);
48 48 userTaskActivityBehavior.setBpmTaskRuleService(bpmTaskRuleService);
49 49 userTaskActivityBehavior.setPermissionApi(permissionApi);
50 50 userTaskActivityBehavior.setDeptApi(deptApi);
... ...
yudao-module-bpm/yudao-module-bpm-impl-activiti/src/main/java/cn/iocoder/yudao/module/bpm/framework/activiti/core/behavior/BpmUserTaskActivitiBehavior.java renamed to yudao-module-bpm/yudao-module-bpm-impl-activiti/src/main/java/cn/iocoder/yudao/module/bpm/framework/activiti/core/behavior/BpmUserTaskActivityBehavior.java
... ... @@ -44,7 +44,7 @@ import static cn.iocoder.yudao.module.bpm.enums.ErrorCodeConstants.TASK_CREATE_F
44 44 * @author 芋道源码
45 45 */
46 46 @Slf4j
47   -public class BpmUserTaskActivitiBehavior extends UserTaskActivityBehavior {
  47 +public class BpmUserTaskActivityBehavior extends UserTaskActivityBehavior {
48 48  
49 49 @Setter
50 50 private BpmTaskAssignRuleService bpmTaskRuleService;
... ... @@ -64,7 +64,7 @@ public class BpmUserTaskActivitiBehavior extends UserTaskActivityBehavior {
64 64 */
65 65 private Map<Long, BpmTaskAssignScript> scriptMap = Collections.emptyMap();
66 66  
67   - public BpmUserTaskActivitiBehavior(UserTask userTask) {
  67 + public BpmUserTaskActivityBehavior(UserTask userTask) {
68 68 super(userTask);
69 69 }
70 70  
... ...
yudao-module-bpm/yudao-module-bpm-impl-activiti/src/main/java/cn/iocoder/yudao/module/bpm/framework/activiti/core/behavior/script/impl/BpmTaskAssignLeaderX1Script.java
1 1 package cn.iocoder.yudao.module.bpm.framework.activiti.core.behavior.script.impl;
2 2  
  3 +import cn.iocoder.yudao.framework.datapermission.core.annotation.DataPermission;
3 4 import cn.iocoder.yudao.module.bpm.enums.definition.BpmTaskRuleScriptEnum;
4 5 import org.activiti.engine.impl.persistence.entity.TaskEntity;
5 6 import org.springframework.stereotype.Component;
... ... @@ -15,6 +16,7 @@ import java.util.Set;
15 16 public class BpmTaskAssignLeaderX1Script extends BpmTaskAssignLeaderAbstractScript {
16 17  
17 18 @Override
  19 + @DataPermission(enable = false) // 不需要处理数据权限, 不然会有问题,查询不到数据
18 20 public Set<Long> calculateTaskCandidateUsers(TaskEntity task) {
19 21 return calculateTaskCandidateUsers(task, 1);
20 22 }
... ...
yudao-module-bpm/yudao-module-bpm-impl-activiti/src/main/java/cn/iocoder/yudao/module/bpm/framework/activiti/core/behavior/script/impl/BpmTaskAssignLeaderX2Script.java
1 1 package cn.iocoder.yudao.module.bpm.framework.activiti.core.behavior.script.impl;
2 2  
  3 +import cn.iocoder.yudao.framework.datapermission.core.annotation.DataPermission;
3 4 import cn.iocoder.yudao.module.bpm.enums.definition.BpmTaskRuleScriptEnum;
4 5 import org.activiti.engine.impl.persistence.entity.TaskEntity;
5 6 import org.springframework.stereotype.Component;
... ... @@ -15,6 +16,7 @@ import java.util.Set;
15 16 public class BpmTaskAssignLeaderX2Script extends BpmTaskAssignLeaderAbstractScript {
16 17  
17 18 @Override
  19 + @DataPermission(enable = false) // 不需要处理数据权限, 不然会有问题,查询不到数据
18 20 public Set<Long> calculateTaskCandidateUsers(TaskEntity task) {
19 21 return calculateTaskCandidateUsers(task, 2);
20 22 }
... ...
yudao-module-bpm/yudao-module-bpm-impl-activiti/src/main/java/cn/iocoder/yudao/module/bpm/service/definition/BpmModelService.java
... ... @@ -12,7 +12,6 @@ import javax.validation.Valid;
12 12 * @author yunlongn
13 13 */
14 14 public interface BpmModelService {
15   -
16 15 /**
17 16 * 获得流程模型分页
18 17 *
... ... @@ -22,14 +21,6 @@ public interface BpmModelService {
22 21 PageResult<BpmModelPageItemRespVO> getModelPage(BpmModelPageReqVO pageVO);
23 22  
24 23 /**
25   - * 获得流程模块
26   - *
27   - * @param id 编号
28   - * @return 流程模型
29   - */
30   - BpmModelRespVO getModel(String id);
31   -
32   - /**
33 24 * 创建流程模型
34 25 *
35 26 * @param modelVO 创建信息
... ... @@ -39,6 +30,14 @@ public interface BpmModelService {
39 30 String createModel(@Valid BpmModelCreateReqVO modelVO, String bpmnXml);
40 31  
41 32 /**
  33 + * 获得流程模块
  34 + *
  35 + * @param id 编号
  36 + * @return 流程模型
  37 + */
  38 + BpmModelRespVO getModel(String id);
  39 +
  40 + /**
42 41 * 修改流程模型
43 42 *
44 43 * @param updateReqVO 更新信息
... ... @@ -63,7 +62,7 @@ public interface BpmModelService {
63 62 * 修改模型的状态,实际更新的部署的流程定义的状态
64 63 *
65 64 * @param id 编号
66   - * @param state 状态 {@link org.activiti.engine.impl.persistence.entity.SuspensionState}
  65 + * @param state 状态
67 66 */
68 67 void updateModelState(String id, Integer state);
69 68  
... ...
yudao-module-bpm/yudao-module-bpm-impl-activiti/src/main/java/cn/iocoder/yudao/module/bpm/service/definition/BpmModelServiceImpl.java
... ... @@ -3,19 +3,19 @@ package cn.iocoder.yudao.module.bpm.service.definition;
3 3 import cn.hutool.core.collection.CollUtil;
4 4 import cn.hutool.core.util.ArrayUtil;
5 5 import cn.hutool.core.util.StrUtil;
  6 +import cn.iocoder.yudao.framework.common.util.validation.ValidationUtils;
6 7 import cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.model.*;
7 8 import cn.iocoder.yudao.module.bpm.convert.definition.BpmModelConvert;
  9 +import cn.iocoder.yudao.module.bpm.enums.definition.BpmModelFormTypeEnum;
8 10 import cn.iocoder.yudao.module.bpm.service.definition.dto.BpmModelMetaInfoRespDTO;
9   -import cn.iocoder.yudao.module.bpm.service.definition.dto.BpmProcessDefinitionCreateReqDTO;
10 11 import cn.iocoder.yudao.framework.activiti.core.util.ActivitiUtils;
11 12 import cn.iocoder.yudao.framework.common.pojo.PageResult;
12 13 import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils;
13 14 import cn.iocoder.yudao.framework.common.util.json.JsonUtils;
14 15 import cn.iocoder.yudao.framework.common.util.object.PageUtils;
15   -import cn.iocoder.yudao.framework.common.util.validation.ValidationUtils;
16 16 import cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.rule.BpmTaskAssignRuleRespVO;
17 17 import cn.iocoder.yudao.module.bpm.dal.dataobject.definition.BpmFormDO;
18   -import cn.iocoder.yudao.module.bpm.enums.definition.BpmModelFormTypeEnum;
  18 +import cn.iocoder.yudao.module.bpm.service.definition.dto.BpmProcessDefinitionCreateReqDTO;
19 19 import lombok.extern.slf4j.Slf4j;
20 20 import org.activiti.bpmn.model.BpmnModel;
21 21 import org.activiti.engine.RepositoryService;
... ... @@ -47,16 +47,15 @@ import static cn.iocoder.yudao.module.bpm.enums.ErrorCodeConstants.*;
47 47 @Service
48 48 @Validated
49 49 @Slf4j
50   -public class BpmModelServiceImpl implements BpmModelService {
  50 +public class BpmModelServiceImpl implements BpmModelService {
51 51  
52 52 @Resource
53 53 private RepositoryService repositoryService;
54 54 @Resource
55   - private BpmFormService bpmFormService;
56   - @Resource
57 55 private BpmProcessDefinitionService processDefinitionService;
58 56 @Resource
59   - @Lazy // 解决循环依赖
  57 + private BpmFormService bpmFormService;
  58 + @Resource
60 59 private BpmTaskAssignRuleService taskAssignRuleService;
61 60  
62 61 @Override
... ... @@ -167,9 +166,9 @@ public class BpmModelServiceImpl implements BpmModelService {
167 166 }
168 167 // TODO 芋艿:校验流程图的有效性;例如说,是否有开始的元素,是否有结束的元素;
169 168 // 校验表单已配
170   - BpmFormDO form = checkFormConfig(model);
  169 + BpmFormDO form = checkFormConfig(model.getMetaInfo());
171 170 // 校验任务分配规则已配置
172   - checkTaskAssignRuleAllConfig(id);
  171 + taskAssignRuleService.checkTaskAssignRuleAllConfig(id);
173 172  
174 173 // 校验模型是否发生修改。如果未修改,则不允许创建
175 174 BpmProcessDefinitionCreateReqDTO definitionCreateReqDTO = BpmModelConvert.INSTANCE.convert2(model, form).setBpmnBytes(bpmnBytes);
... ... @@ -194,48 +193,6 @@ public class BpmModelServiceImpl implements BpmModelService {
194 193 taskAssignRuleService.copyTaskAssignRules(id, definition.getId());
195 194 }
196 195  
197   - /**
198   - * 校验流程模型的任务分配规则全部都配置了
199   - * 目的:如果有规则未配置,会导致流程任务找不到负责人,进而流程无法进行下去!
200   - *
201   - * @param id 流程模型编号
202   - */
203   - private void checkTaskAssignRuleAllConfig(String id) {
204   - // 一个用户任务都没配置,所以无需配置规则
205   - List<BpmTaskAssignRuleRespVO> taskAssignRules = taskAssignRuleService.getTaskAssignRuleList(id, null);
206   - if (CollUtil.isEmpty(taskAssignRules)) {
207   - return;
208   - }
209   - // 校验未配置规则的任务
210   - taskAssignRules.forEach(rule -> {
211   - if (CollUtil.isEmpty(rule.getOptions())) {
212   - throw exception(MODEL_DEPLOY_FAIL_TASK_ASSIGN_RULE_NOT_CONFIG, rule.getTaskDefinitionName());
213   - }
214   - });
215   - }
216   -
217   - /**
218   - * 校验流程表单已配置
219   - *
220   - * @param model 流程模型
221   - * @return 流程表单
222   - */
223   - private BpmFormDO checkFormConfig(Model model) {
224   - BpmModelMetaInfoRespDTO metaInfo = JsonUtils.parseObject(model.getMetaInfo(), BpmModelMetaInfoRespDTO.class);
225   - if (metaInfo == null || metaInfo.getFormType() == null) {
226   - throw exception(MODEL_DEPLOY_FAIL_FORM_NOT_CONFIG);
227   - }
228   - // 校验表单存在
229   - if (Objects.equals(metaInfo.getFormType(), BpmModelFormTypeEnum.NORMAL.getType())) {
230   - BpmFormDO form = bpmFormService.getForm(metaInfo.getFormId());
231   - if (form == null) {
232   - throw exception(FORM_NOT_EXISTS);
233   - }
234   - return form;
235   - }
236   - return null;
237   - }
238   -
239 196 @Override
240 197 @Transactional(rollbackFor = Exception.class)
241 198 public void deleteModel(String id) {
... ... @@ -297,4 +254,26 @@ public class BpmModelServiceImpl implements BpmModelService {
297 254 }
298 255 }
299 256  
  257 + /**
  258 + * 校验流程表单已配置
  259 + *
  260 + * @param metaInfoStr 流程模型 metaInfo 字段
  261 + * @return 流程表单
  262 + */
  263 + private BpmFormDO checkFormConfig(String metaInfoStr) {
  264 + BpmModelMetaInfoRespDTO metaInfo = JsonUtils.parseObject(metaInfoStr, BpmModelMetaInfoRespDTO.class);
  265 + if (metaInfo == null || metaInfo.getFormType() == null) {
  266 + throw exception(MODEL_DEPLOY_FAIL_FORM_NOT_CONFIG);
  267 + }
  268 + // 校验表单存在
  269 + if (Objects.equals(metaInfo.getFormType(), BpmModelFormTypeEnum.NORMAL.getType())) {
  270 + BpmFormDO form = bpmFormService.getForm(metaInfo.getFormId());
  271 + if (form == null) {
  272 + throw exception(FORM_NOT_EXISTS);
  273 + }
  274 + return form;
  275 + }
  276 + return null;
  277 + }
  278 +
300 279 }
... ...
yudao-module-bpm/yudao-module-bpm-impl-activiti/src/main/java/cn/iocoder/yudao/module/bpm/service/definition/BpmProcessDefinitionService.java
... ... @@ -5,9 +5,9 @@ import cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.process.BpmPro
5 5 import cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.process.BpmProcessDefinitionPageReqVO;
6 6 import cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.process.BpmProcessDefinitionRespVO;
7 7 import cn.iocoder.yudao.module.bpm.dal.dataobject.definition.BpmProcessDefinitionExtDO;
8   -import cn.iocoder.yudao.module.bpm.service.definition.dto.BpmProcessDefinitionCreateReqDTO;
9 8 import cn.iocoder.yudao.framework.common.pojo.PageResult;
10 9 import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils;
  10 +import cn.iocoder.yudao.module.bpm.service.definition.dto.BpmProcessDefinitionCreateReqDTO;
11 11 import org.activiti.bpmn.model.BpmnModel;
12 12 import org.activiti.engine.repository.Deployment;
13 13 import org.activiti.engine.repository.ProcessDefinition;
... ... @@ -35,12 +35,20 @@ public interface BpmProcessDefinitionService {
35 35 PageResult<BpmProcessDefinitionPageItemRespVO> getProcessDefinitionPage(BpmProcessDefinitionPageReqVO pageReqVO);
36 36  
37 37 /**
38   - * 获得流程定义列表
  38 + * 创建流程定义
39 39 *
40   - * @param listReqVO 列表入参
41   - * @return 流程定义列表
  40 + * @param createReqDTO 创建信息
  41 + * @return 流程编号
42 42 */
43   - List<BpmProcessDefinitionRespVO> getProcessDefinitionList(BpmProcessDefinitionListReqVO listReqVO);
  43 + String createProcessDefinition(@Valid BpmProcessDefinitionCreateReqDTO createReqDTO);
  44 +
  45 + /**
  46 + * 更新流程定义状态
  47 + *
  48 + * @param id 流程定义的编号
  49 + * @param state 状态
  50 + */
  51 + void updateProcessDefinitionState(String id, Integer state);
44 52  
45 53 /**
46 54 * 获得流程定义对应的 BPMN XML
... ... @@ -51,6 +59,30 @@ public interface BpmProcessDefinitionService {
51 59 String getProcessDefinitionBpmnXML(String id);
52 60  
53 61 /**
  62 + * 获得需要创建的流程定义,是否和当前激活的流程定义相等
  63 + *
  64 + * @param createReqDTO 创建信息
  65 + * @return 是否相等
  66 + */
  67 + boolean isProcessDefinitionEquals(@Valid BpmProcessDefinitionCreateReqDTO createReqDTO);
  68 +
  69 + /**
  70 + * 获得编号对应的 BpmProcessDefinitionExtDO
  71 + *
  72 + * @param id 编号
  73 + * @return 流程定义拓展
  74 + */
  75 + BpmProcessDefinitionExtDO getProcessDefinitionExt(String id);
  76 +
  77 + /**
  78 + * 获得流程定义列表
  79 + *
  80 + * @param listReqVO 列表入参
  81 + * @return 流程定义列表
  82 + */
  83 + List<BpmProcessDefinitionRespVO> getProcessDefinitionList(BpmProcessDefinitionListReqVO listReqVO);
  84 +
  85 + /**
54 86 * 获得 Bpmn 模型
55 87 *
56 88 * @param processDefinitionId 流程定义的编号
... ... @@ -85,14 +117,6 @@ public interface BpmProcessDefinitionService {
85 117 ProcessDefinition getActiveProcessDefinition(String key);
86 118  
87 119 /**
88   - * 获得编号对应的 BpmProcessDefinitionExtDO
89   - *
90   - * @param id 编号
91   - * @return 流程定义拓展
92   - */
93   - BpmProcessDefinitionExtDO getProcessDefinitionExt(String id);
94   -
95   - /**
96 120 * 获得 id 对应的 Deployment
97 121 *
98 122 * @param id 部署编号
... ... @@ -134,28 +158,4 @@ public interface BpmProcessDefinitionService {
134 158 */
135 159 List<ProcessDefinition> getProcessDefinitionListByDeploymentIds(Set<String> deploymentIds);
136 160  
137   - /**
138   - * 获得需要创建的流程定义,是否和当前激活的流程定义相等
139   - *
140   - * @param createReqDTO 创建信息
141   - * @return 是否相等
142   - */
143   - boolean isProcessDefinitionEquals(@Valid BpmProcessDefinitionCreateReqDTO createReqDTO);
144   -
145   - /**
146   - * 创建流程定义
147   - *
148   - * @param createReqDTO 创建信息
149   - * @return 流程编号
150   - */
151   - String createProcessDefinition(@Valid BpmProcessDefinitionCreateReqDTO createReqDTO);
152   -
153   - /**
154   - * 更新流程定义的挂起状态
155   - *
156   - * @param id 流程定义的编号
157   - * @param state 挂起状态 {@link org.activiti.engine.impl.persistence.entity.SuspensionState}
158   - */
159   - void updateProcessDefinitionState(String id, Integer state);
160   -
161 161 }
... ...
yudao-module-bpm/yudao-module-bpm-impl-activiti/src/main/java/cn/iocoder/yudao/module/bpm/service/definition/BpmProcessDefinitionServiceImpl.java
... ... @@ -4,7 +4,6 @@ import cn.hutool.core.collection.CollUtil;
4 4 import cn.hutool.core.util.ObjectUtil;
5 5 import cn.hutool.core.util.StrUtil;
6 6 import cn.iocoder.yudao.module.bpm.convert.definition.BpmProcessDefinitionConvert;
7   -import cn.iocoder.yudao.module.bpm.service.definition.dto.BpmProcessDefinitionCreateReqDTO;
8 7 import cn.iocoder.yudao.framework.activiti.core.util.ActivitiUtils;
9 8 import cn.iocoder.yudao.framework.common.pojo.PageResult;
10 9 import cn.iocoder.yudao.framework.common.util.object.PageUtils;
... ... @@ -15,6 +14,7 @@ import cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.process.BpmPro
15 14 import cn.iocoder.yudao.module.bpm.dal.dataobject.definition.BpmFormDO;
16 15 import cn.iocoder.yudao.module.bpm.dal.dataobject.definition.BpmProcessDefinitionExtDO;
17 16 import cn.iocoder.yudao.module.bpm.dal.mysql.definition.BpmProcessDefinitionExtMapper;
  17 +import cn.iocoder.yudao.module.bpm.service.definition.dto.BpmProcessDefinitionCreateReqDTO;
18 18 import lombok.extern.slf4j.Slf4j;
19 19 import org.activiti.bpmn.model.BpmnModel;
20 20 import org.activiti.engine.RepositoryService;
... ...
yudao-module-bpm/yudao-module-bpm-impl-activiti/src/main/java/cn/iocoder/yudao/module/bpm/service/definition/BpmTaskAssignRuleService.java
... ... @@ -76,4 +76,12 @@ public interface BpmTaskAssignRuleService {
76 76 */
77 77 void copyTaskAssignRules(String fromModelId, String toProcessDefinitionId);
78 78  
  79 + /**
  80 + * 校验流程模型的任务分配规则全部都配置了
  81 + * 目的:如果有规则未配置,会导致流程任务找不到负责人,进而流程无法进行下去!
  82 + *
  83 + * @param id 流程模型编号
  84 + */
  85 + void checkTaskAssignRuleAllConfig(String id);
  86 +
79 87 }
... ...
yudao-module-bpm/yudao-module-bpm-impl-activiti/src/main/java/cn/iocoder/yudao/module/bpm/service/definition/BpmTaskAssignRuleServiceImpl.java
... ... @@ -173,6 +173,21 @@ public class BpmTaskAssignRuleServiceImpl implements BpmTaskAssignRuleService {
173 173 taskRuleMapper.insertBatch(newRules);
174 174 }
175 175  
  176 + @Override
  177 + public void checkTaskAssignRuleAllConfig(String id) {
  178 + // 一个用户任务都没配置,所以无需配置规则
  179 + List<BpmTaskAssignRuleRespVO> taskAssignRules = getTaskAssignRuleList(id, null);
  180 + if (CollUtil.isEmpty(taskAssignRules)) {
  181 + return;
  182 + }
  183 + // 校验未配置规则的任务
  184 + taskAssignRules.forEach(rule -> {
  185 + if (CollUtil.isEmpty(rule.getOptions())) {
  186 + throw exception(MODEL_DEPLOY_FAIL_TASK_ASSIGN_RULE_NOT_CONFIG, rule.getTaskDefinitionName());
  187 + }
  188 + });
  189 + }
  190 +
176 191 private void validTaskAssignRuleOptions(Integer type, Set<Long> options) {
177 192 if (Objects.equals(type, BpmTaskAssignRuleTypeEnum.ROLE.getType())) {
178 193 roleApi.validRoles(options);
... ...
yudao-module-bpm/yudao-module-bpm-impl-activiti/src/test/java/cn/iocoder/yudao/module/bpm/framework/activiti/core/behavior/BpmUserTaskActivitiBehaviorTest.java renamed to yudao-module-bpm/yudao-module-bpm-impl-activiti/src/test/java/cn/iocoder/yudao/module/bpm/framework/activiti/core/behavior/BpmUserTaskActivityBehaviorTest.java
... ... @@ -33,10 +33,10 @@ import static org.junit.jupiter.api.Assertions.assertEquals;
33 33 import static org.mockito.ArgumentMatchers.eq;
34 34 import static org.mockito.Mockito.when;
35 35  
36   -public class BpmUserTaskActivitiBehaviorTest extends BaseMockitoUnitTest {
  36 +public class BpmUserTaskActivityBehaviorTest extends BaseMockitoUnitTest {
37 37  
38 38 @InjectMocks
39   - private BpmUserTaskActivitiBehavior behavior;
  39 + private BpmUserTaskActivityBehavior behavior;
40 40 @Mock
41 41 private BpmTaskAssignRuleService bpmTaskRuleService;
42 42 @Mock
... ...
yudao-module-bpm/yudao-module-bpm-impl-flowable/pom.xml
... ... @@ -16,14 +16,23 @@
16 16 </description>
17 17  
18 18 <dependencies>
  19 + <dependency>
  20 + <groupId>cn.iocoder.boot</groupId>
  21 + <artifactId>yudao-module-bpm-base</artifactId>
  22 + <version>${revision}</version>
  23 + </dependency>
  24 +
19 25 <!-- 工作流相关 -->
20 26 <dependency>
21   - <groupId>org.flowable</groupId>
22   - <artifactId>flowable-spring-boot-starter-basic</artifactId>
  27 + <groupId>cn.iocoder.boot</groupId>
  28 + <artifactId>yudao-spring-boot-starter-flowable</artifactId>
23 29 </dependency>
  30 +
  31 + <!-- Test 测试相关 -->
24 32 <dependency>
25   - <groupId>org.flowable</groupId>
26   - <artifactId>flowable-spring-boot-starter-actuator</artifactId>
  33 + <groupId>cn.iocoder.boot</groupId>
  34 + <artifactId>yudao-spring-boot-starter-test</artifactId>
  35 + <scope>test</scope>
27 36 </dependency>
28 37 </dependencies>
29 38  
... ...
yudao-module-bpm/yudao-module-bpm-impl-flowable/src/main/java/cn/iocoder/yudao/module/bpm/api/package-info.java 0 → 100644
  1 +/**
  2 + * bpm API 实现类,定义暴露给其它模块的 API
  3 + */
  4 +package cn.iocoder.yudao.module.bpm.api;
... ...
yudao-module-bpm/yudao-module-bpm-impl-flowable/src/main/java/cn/iocoder/yudao/module/bpm/api/task/BpmProcessInstanceApiImpl.java 0 → 100644
  1 +package cn.iocoder.yudao.module.bpm.api.task;
  2 +
  3 +import cn.iocoder.yudao.module.bpm.api.task.dto.BpmProcessInstanceCreateReqDTO;
  4 +import cn.iocoder.yudao.module.bpm.service.task.BpmProcessInstanceService;
  5 +import org.springframework.stereotype.Service;
  6 +import org.springframework.validation.annotation.Validated;
  7 +
  8 +import javax.annotation.Resource;
  9 +import javax.validation.Valid;
  10 +
  11 +/**
  12 + * Flowable 流程实例 Api 实现类
  13 + *
  14 + * @author 芋道源码
  15 + * @author jason
  16 + */
  17 +@Service
  18 +@Validated
  19 +public class BpmProcessInstanceApiImpl implements BpmProcessInstanceApi {
  20 +
  21 + @Resource
  22 + private BpmProcessInstanceService processInstanceService;
  23 +
  24 + @Override
  25 + public String createProcessInstance(Long userId, @Valid BpmProcessInstanceCreateReqDTO reqDTO) {
  26 + return processInstanceService.createProcessInstance(userId, reqDTO);
  27 + }
  28 +}
... ...
yudao-module-bpm/yudao-module-bpm-impl-flowable/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/definition/BpmModelController.java 0 → 100644
  1 +package cn.iocoder.yudao.module.bpm.controller.admin.definition;
  2 +
  3 +import cn.iocoder.yudao.framework.common.pojo.CommonResult;
  4 +import cn.iocoder.yudao.framework.common.pojo.PageResult;
  5 +import cn.iocoder.yudao.framework.common.util.io.IoUtils;
  6 +import cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.model.*;
  7 +import cn.iocoder.yudao.module.bpm.convert.definition.BpmModelConvert;
  8 +import cn.iocoder.yudao.module.bpm.service.definition.BpmModelService;
  9 +import io.swagger.annotations.Api;
  10 +import io.swagger.annotations.ApiImplicitParam;
  11 +import io.swagger.annotations.ApiOperation;
  12 +import org.springframework.security.access.prepost.PreAuthorize;
  13 +import org.springframework.validation.annotation.Validated;
  14 +import org.springframework.web.bind.annotation.*;
  15 +
  16 +import javax.annotation.Resource;
  17 +import javax.validation.Valid;
  18 +
  19 +import java.io.IOException;
  20 +
  21 +import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
  22 +
  23 +@Api(tags = "管理后台 - 流程模型")
  24 +@RestController
  25 +@RequestMapping("/bpm/model")
  26 +@Validated
  27 +public class BpmModelController {
  28 +
  29 + @Resource
  30 + private BpmModelService modelService;
  31 +
  32 + @GetMapping("/page")
  33 + @ApiOperation(value = "获得模型分页")
  34 + public CommonResult<PageResult<BpmModelPageItemRespVO>> getModelPage(BpmModelPageReqVO pageVO) {
  35 + return success(modelService.getModelPage(pageVO));
  36 + }
  37 +
  38 + @GetMapping("/get")
  39 + @ApiOperation("获得模型")
  40 + @ApiImplicitParam(name = "id", value = "编号", required = true, example = "1024", dataTypeClass = String.class)
  41 + @PreAuthorize("@ss.hasPermission('bpm:model:query')")
  42 + public CommonResult<BpmModelRespVO> getModel(@RequestParam("id") String id) {
  43 + BpmModelRespVO model = modelService.getModel(id);
  44 + return success(model);
  45 + }
  46 +
  47 + @PostMapping("/create")
  48 + @ApiOperation(value = "新建模型")
  49 + @PreAuthorize("@ss.hasPermission('bpm:model:create')")
  50 + public CommonResult<String> createModel(@Valid @RequestBody BpmModelCreateReqVO createRetVO) {
  51 + return success(modelService.createModel(createRetVO, null));
  52 + }
  53 +
  54 + @PutMapping("/update")
  55 + @ApiOperation(value = "修改模型")
  56 + @PreAuthorize("@ss.hasPermission('bpm:model:update')")
  57 + public CommonResult<Boolean> updateModel(@Valid @RequestBody BpmModelUpdateReqVO modelVO) {
  58 + modelService.updateModel(modelVO);
  59 + return success(true);
  60 + }
  61 +
  62 + @PostMapping("/import")
  63 + @ApiOperation(value = "导入模型")
  64 + @PreAuthorize("@ss.hasPermission('bpm:model:import')")
  65 + public CommonResult<String> importModel(@Valid BpmModeImportReqVO importReqVO) throws IOException {
  66 + BpmModelCreateReqVO createReqVO = BpmModelConvert.INSTANCE.convert(importReqVO);
  67 + // 读取文件
  68 + String bpmnXml = IoUtils.readUtf8(importReqVO.getBpmnFile().getInputStream(), false);
  69 + return success(modelService.createModel(createReqVO, bpmnXml));
  70 + }
  71 +
  72 + @PostMapping("/deploy")
  73 + @ApiOperation(value = "部署模型")
  74 + @ApiImplicitParam(name = "id", value = "编号", required = true, example = "1024", dataTypeClass = String.class)
  75 + @PreAuthorize("@ss.hasPermission('bpm:model:deploy')")
  76 + public CommonResult<Boolean> deployModel(@RequestParam("id") String id) {
  77 + modelService.deployModel(id);
  78 + return success(true);
  79 + }
  80 +
  81 + @PutMapping("/update-state")
  82 + @ApiOperation(value = "修改模型的状态", notes = "实际更新的部署的流程定义的状态")
  83 + @PreAuthorize("@ss.hasPermission('bpm:model:update')")
  84 + public CommonResult<Boolean> updateModelState(@Valid @RequestBody BpmModelUpdateStateReqVO reqVO) {
  85 + modelService.updateModelState(reqVO.getId(), reqVO.getState());
  86 + return success(true);
  87 + }
  88 +
  89 + @DeleteMapping("/delete")
  90 + @ApiOperation("删除模型")
  91 + @ApiImplicitParam(name = "id", value = "编号", required = true, example = "1024", dataTypeClass = String.class)
  92 + @PreAuthorize("@ss.hasPermission('bpm:model:delete')")
  93 + public CommonResult<Boolean> deleteModel(@RequestParam("id") String id) {
  94 + modelService.deleteModel(id);
  95 + return success(true);
  96 + }
  97 +}
... ...
yudao-module-bpm/yudao-module-bpm-impl-flowable/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/definition/BpmProcessDefinitionController.java 0 → 100644
  1 +package cn.iocoder.yudao.module.bpm.controller.admin.definition;
  2 +
  3 +import cn.iocoder.yudao.framework.common.pojo.CommonResult;
  4 +import cn.iocoder.yudao.framework.common.pojo.PageResult;
  5 +import cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.process.BpmProcessDefinitionListReqVO;
  6 +import cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.process.BpmProcessDefinitionPageItemRespVO;
  7 +import cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.process.BpmProcessDefinitionPageReqVO;
  8 +import cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.process.BpmProcessDefinitionRespVO;
  9 +import cn.iocoder.yudao.module.bpm.service.definition.BpmProcessDefinitionService;
  10 +import io.swagger.annotations.Api;
  11 +import io.swagger.annotations.ApiImplicitParam;
  12 +import io.swagger.annotations.ApiOperation;
  13 +import org.springframework.security.access.prepost.PreAuthorize;
  14 +import org.springframework.validation.annotation.Validated;
  15 +import org.springframework.web.bind.annotation.GetMapping;
  16 +import org.springframework.web.bind.annotation.RequestMapping;
  17 +import org.springframework.web.bind.annotation.RequestParam;
  18 +import org.springframework.web.bind.annotation.RestController;
  19 +
  20 +import javax.annotation.Resource;
  21 +
  22 +import java.util.List;
  23 +
  24 +import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
  25 +
  26 +@Api(tags = "管理后台 - 流程定义")
  27 +@RestController
  28 +@RequestMapping("/bpm/process-definition")
  29 +@Validated
  30 +public class BpmProcessDefinitionController {
  31 +
  32 + @Resource
  33 + private BpmProcessDefinitionService bpmDefinitionService;
  34 +
  35 + @GetMapping("/page")
  36 + @ApiOperation(value = "获得流程定义分页")
  37 + @PreAuthorize("@ss.hasPermission('bpm:process-definition:query')")
  38 + public CommonResult<PageResult<BpmProcessDefinitionPageItemRespVO>> getProcessDefinitionPage(
  39 + BpmProcessDefinitionPageReqVO pageReqVO) {
  40 + return success(bpmDefinitionService.getProcessDefinitionPage(pageReqVO));
  41 + }
  42 +
  43 + @GetMapping ("/list")
  44 + @ApiOperation(value = "获得流程定义列表")
  45 + @PreAuthorize("@ss.hasPermission('bpm:process-definition:query')")
  46 + public CommonResult<List<BpmProcessDefinitionRespVO>> getProcessDefinitionList(
  47 + BpmProcessDefinitionListReqVO listReqVO) {
  48 + return success(bpmDefinitionService.getProcessDefinitionList(listReqVO));
  49 + }
  50 +
  51 + @GetMapping ("/get-bpmn-xml")
  52 + @ApiOperation(value = "获得流程定义的 BPMN XML")
  53 + @ApiImplicitParam(name = "id", value = "编号", required = true, example = "1024", dataTypeClass = String.class)
  54 + @PreAuthorize("@ss.hasPermission('bpm:process-definition:query')")
  55 + public CommonResult<String> getProcessDefinitionBpmnXML(@RequestParam("id") String id) {
  56 + String bpmnXML = bpmDefinitionService.getProcessDefinitionBpmnXML(id);
  57 + return success(bpmnXML);
  58 + }
  59 +}
... ...
yudao-module-bpm/yudao-module-bpm-impl-flowable/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/definition/BpmTaskAssignRuleController.java 0 → 100644
  1 +package cn.iocoder.yudao.module.bpm.controller.admin.definition;
  2 +
  3 +import cn.iocoder.yudao.framework.common.pojo.CommonResult;
  4 +import cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.rule.BpmTaskAssignRuleCreateReqVO;
  5 +import cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.rule.BpmTaskAssignRuleRespVO;
  6 +import cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.rule.BpmTaskAssignRuleUpdateReqVO;
  7 +import cn.iocoder.yudao.module.bpm.service.definition.BpmTaskAssignRuleService;
  8 +import io.swagger.annotations.Api;
  9 +import io.swagger.annotations.ApiImplicitParam;
  10 +import io.swagger.annotations.ApiImplicitParams;
  11 +import io.swagger.annotations.ApiOperation;
  12 +import org.springframework.security.access.prepost.PreAuthorize;
  13 +import org.springframework.validation.annotation.Validated;
  14 +import org.springframework.web.bind.annotation.*;
  15 +
  16 +import javax.annotation.Resource;
  17 +import javax.validation.Valid;
  18 +import java.util.List;
  19 +
  20 +import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
  21 +
  22 +@Api(tags = "管理后台 - 任务分配规则")
  23 +@RestController
  24 +@RequestMapping("/bpm/task-assign-rule")
  25 +@Validated
  26 +public class BpmTaskAssignRuleController {
  27 +
  28 + @Resource
  29 + private BpmTaskAssignRuleService taskAssignRuleService;
  30 +
  31 + @GetMapping("/list")
  32 + @ApiOperation(value = "获得任务分配规则列表")
  33 + @ApiImplicitParams({
  34 + @ApiImplicitParam(name = "modelId", value = "模型编号", example = "1024", dataTypeClass = String.class),
  35 + @ApiImplicitParam(name = "processDefinitionId", value = "流程定义的编号", example = "2048", dataTypeClass = String.class)
  36 + })
  37 + @PreAuthorize("@ss.hasPermission('bpm:task-assign-rule:query')")
  38 + public CommonResult<List<BpmTaskAssignRuleRespVO>> getTaskAssignRuleList(
  39 + @RequestParam(value = "modelId", required = false) String modelId,
  40 + @RequestParam(value = "processDefinitionId", required = false) String processDefinitionId) {
  41 + return success(taskAssignRuleService.getTaskAssignRuleList(modelId, processDefinitionId));
  42 + }
  43 +
  44 + @PostMapping("/create")
  45 + @ApiOperation(value = "创建任务分配规则")
  46 + @PreAuthorize("@ss.hasPermission('bpm:task-assign-rule:create')")
  47 + public CommonResult<Long> createTaskAssignRule(@Valid @RequestBody BpmTaskAssignRuleCreateReqVO reqVO) {
  48 + return success(taskAssignRuleService.createTaskAssignRule(reqVO));
  49 + }
  50 +
  51 + @PutMapping("/update")
  52 + @ApiOperation(value = "更新任务分配规则")
  53 + @PreAuthorize("@ss.hasPermission('bpm:task-assign-rule:update')")
  54 + public CommonResult<Boolean> updateTaskAssignRule(@Valid @RequestBody BpmTaskAssignRuleUpdateReqVO reqVO) {
  55 + taskAssignRuleService.updateTaskAssignRule(reqVO);
  56 + return success(true);
  57 + }
  58 +}
... ...
yudao-module-bpm/yudao-module-bpm-impl-flowable/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/task/BpmActivityController.java 0 → 100644
  1 +package cn.iocoder.yudao.module.bpm.controller.admin.task;
  2 +
  3 +import cn.iocoder.yudao.framework.common.pojo.CommonResult;
  4 +import cn.iocoder.yudao.module.bpm.controller.admin.task.vo.activity.BpmActivityRespVO;
  5 +import cn.iocoder.yudao.module.bpm.service.task.BpmActivityService;
  6 +import io.swagger.annotations.Api;
  7 +import io.swagger.annotations.ApiImplicitParam;
  8 +import io.swagger.annotations.ApiOperation;
  9 +import org.springframework.security.access.prepost.PreAuthorize;
  10 +import org.springframework.validation.annotation.Validated;
  11 +import org.springframework.web.bind.annotation.GetMapping;
  12 +import org.springframework.web.bind.annotation.RequestMapping;
  13 +import org.springframework.web.bind.annotation.RequestParam;
  14 +import org.springframework.web.bind.annotation.RestController;
  15 +
  16 +import javax.annotation.Resource;
  17 +import java.util.List;
  18 +
  19 +import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
  20 +
  21 +@Api(tags = "管理后台 - 流程活动实例")
  22 +@RestController
  23 +@RequestMapping("/bpm/activity")
  24 +@Validated
  25 +public class BpmActivityController {
  26 +
  27 + @Resource
  28 + private BpmActivityService activityService;
  29 +
  30 + @GetMapping("/list")
  31 + @ApiOperation(value = "生成指定流程实例的高亮流程图",
  32 + notes = "只高亮进行中的任务。不过要注意,该接口暂时没用,通过前端的 ProcessViewer.vue 界面的 highlightDiagram 方法生成")
  33 + @ApiImplicitParam(name = "processInstanceId", value = "流程实例的编号", required = true, dataTypeClass = String.class)
  34 + @PreAuthorize("@ss.hasPermission('bpm:task:query')")
  35 + public CommonResult<List<BpmActivityRespVO>> getActivityList(
  36 + @RequestParam("processInstanceId") String processInstanceId) {
  37 + return success(activityService.getActivityListByProcessInstanceId(processInstanceId));
  38 + }
  39 +}
... ...
yudao-module-bpm/yudao-module-bpm-impl-flowable/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/task/BpmProcessInstanceController.java 0 → 100644
  1 +package cn.iocoder.yudao.module.bpm.controller.admin.task;
  2 +
  3 +import cn.iocoder.yudao.framework.common.pojo.CommonResult;
  4 +import cn.iocoder.yudao.framework.common.pojo.PageResult;
  5 +import cn.iocoder.yudao.module.bpm.controller.admin.task.vo.instance.*;
  6 +import cn.iocoder.yudao.module.bpm.service.task.BpmProcessInstanceService;
  7 +import io.swagger.annotations.Api;
  8 +import io.swagger.annotations.ApiImplicitParam;
  9 +import io.swagger.annotations.ApiOperation;
  10 +import org.springframework.security.access.prepost.PreAuthorize;
  11 +import org.springframework.validation.annotation.Validated;
  12 +import org.springframework.web.bind.annotation.*;
  13 +
  14 +import javax.annotation.Resource;
  15 +import javax.validation.Valid;
  16 +
  17 +import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
  18 +import static cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils.getLoginUserId;
  19 +
  20 +@Api(tags = "管理后台 - 流程实例") // 流程实例,通过流程定义创建的一次“申请”
  21 +@RestController
  22 +@RequestMapping("/bpm/process-instance")
  23 +@Validated
  24 +public class BpmProcessInstanceController {
  25 + @Resource
  26 + private BpmProcessInstanceService processInstanceService;
  27 +
  28 + @GetMapping("/my-page")
  29 + @ApiOperation(value = "获得我的实例分页列表", notes = "在【我的流程】菜单中,进行调用")
  30 + @PreAuthorize("@ss.hasPermission('bpm:process-instance:query')")
  31 + public CommonResult<PageResult<BpmProcessInstancePageItemRespVO>> getMyProcessInstancePage(
  32 + @Valid BpmProcessInstanceMyPageReqVO pageReqVO) {
  33 + return success(processInstanceService.getMyProcessInstancePage(getLoginUserId(), pageReqVO));
  34 + }
  35 +
  36 + @PostMapping("/create")
  37 + @ApiOperation("新建流程实例")
  38 + @PreAuthorize("@ss.hasPermission('bpm:process-instance:query')")
  39 + public CommonResult<String> createProcessInstance(@Valid @RequestBody BpmProcessInstanceCreateReqVO createReqVO) {
  40 + return success(processInstanceService.createProcessInstance(getLoginUserId(), createReqVO));
  41 + }
  42 +
  43 + @GetMapping("/get")
  44 + @ApiOperation(value = "获得指定流程实例", notes = "在【流程详细】界面中,进行调用")
  45 + @ApiImplicitParam(name = "id", value = "流程实例的编号", required = true, dataTypeClass = String.class)
  46 + @PreAuthorize("@ss.hasPermission('bpm:process-instance:query')")
  47 + public CommonResult<BpmProcessInstanceRespVO> getProcessInstance(@RequestParam("id") String id) {
  48 + return success(processInstanceService.getProcessInstanceVO(id));
  49 + }
  50 +
  51 + @DeleteMapping("/cancel")
  52 + @ApiOperation(value = "取消流程实例", notes = "撤回发起的流程")
  53 + @PreAuthorize("@ss.hasPermission('bpm:process-instance:cancel')")
  54 + public CommonResult<Boolean> cancelProcessInstance(@Valid @RequestBody BpmProcessInstanceCancelReqVO cancelReqVO) {
  55 + processInstanceService.cancelProcessInstance(getLoginUserId(), cancelReqVO);
  56 + return success(true);
  57 + }
  58 +}
... ...
yudao-module-bpm/yudao-module-bpm-impl-flowable/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/task/BpmTaskController.java 0 → 100644
  1 +package cn.iocoder.yudao.module.bpm.controller.admin.task;
  2 +
  3 +import cn.iocoder.yudao.framework.common.pojo.CommonResult;
  4 +import cn.iocoder.yudao.framework.common.pojo.PageResult;
  5 +import cn.iocoder.yudao.module.bpm.controller.admin.task.vo.task.*;
  6 +import cn.iocoder.yudao.module.bpm.service.task.BpmTaskService;
  7 +import io.swagger.annotations.Api;
  8 +import io.swagger.annotations.ApiImplicitParam;
  9 +import io.swagger.annotations.ApiOperation;
  10 +import org.flowable.bpmn.model.BpmnModel;
  11 +import org.flowable.engine.TaskService;
  12 +import org.springframework.security.access.prepost.PreAuthorize;
  13 +import org.springframework.validation.annotation.Validated;
  14 +import org.springframework.web.bind.annotation.*;
  15 +
  16 +import javax.annotation.Resource;
  17 +import javax.validation.Valid;
  18 +
  19 +import java.util.List;
  20 +
  21 +import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
  22 +import static cn.iocoder.yudao.framework.web.core.util.WebFrameworkUtils.getLoginUserId;
  23 +
  24 +@Api(tags = "管理后台 - 流程任务实例")
  25 +@RestController
  26 +@RequestMapping("/bpm/task")
  27 +@Validated
  28 +public class BpmTaskController {
  29 +
  30 + @Resource
  31 + private BpmTaskService taskService;
  32 +
  33 + @GetMapping("todo-page")
  34 + @ApiOperation("获取 Todo 待办任务分页")
  35 + @PreAuthorize("@ss.hasPermission('bpm:task:query')")
  36 + public CommonResult<PageResult<BpmTaskTodoPageItemRespVO>> getTodoTaskPage(@Valid BpmTaskTodoPageReqVO pageVO) {
  37 + return success(taskService.getTodoTaskPage(getLoginUserId(), pageVO));
  38 + }
  39 +
  40 + @GetMapping("done-page")
  41 + @ApiOperation("获取 Done 已办任务分页")
  42 + @PreAuthorize("@ss.hasPermission('bpm:task:query')")
  43 + public CommonResult<PageResult<BpmTaskDonePageItemRespVO>> getDoneTaskPage(@Valid BpmTaskDonePageReqVO pageVO) {
  44 + return success(taskService.getDoneTaskPage(getLoginUserId(), pageVO));
  45 + }
  46 +
  47 + @GetMapping("/list-by-process-instance-id")
  48 + @ApiOperation(value = "获得指定流程实例的任务列表", notes = "包括完成的、未完成的")
  49 + @ApiImplicitParam(name = "processInstanceId", value = "流程实例的编号", required = true, dataTypeClass = String.class)
  50 + @PreAuthorize("@ss.hasPermission('bpm:task:query')")
  51 + public CommonResult<List<BpmTaskRespVO>> getTaskListByProcessInstanceId(
  52 + @RequestParam("processInstanceId") String processInstanceId) {
  53 + return success(taskService.getTaskListByProcessInstanceId(processInstanceId));
  54 + }
  55 +
  56 + @PutMapping("/approve")
  57 + @ApiOperation("通过任务")
  58 + @PreAuthorize("@ss.hasPermission('bpm:task:update')")
  59 + public CommonResult<Boolean> approveTask(@Valid @RequestBody BpmTaskApproveReqVO reqVO) {
  60 + taskService.approveTask(getLoginUserId(), reqVO);
  61 + return success(true);
  62 + }
  63 +
  64 + @PutMapping("/reject")
  65 + @ApiOperation("不通过任务")
  66 + @PreAuthorize("@ss.hasPermission('bpm:task:update')")
  67 + public CommonResult<Boolean> rejectTask(@Valid @RequestBody BpmTaskRejectReqVO reqVO) {
  68 + taskService.rejectTask(getLoginUserId(), reqVO);
  69 + return success(true);
  70 + }
  71 +
  72 + @PutMapping("/update-assignee")
  73 + @ApiOperation(value = "更新任务的负责人", notes = "用于【流程详情】的【转派】按钮")
  74 + @PreAuthorize("@ss.hasPermission('bpm:task:update')")
  75 + public CommonResult<Boolean> updateTaskAssignee(@Valid @RequestBody BpmTaskUpdateAssigneeReqVO reqVO) {
  76 + taskService.updateTaskAssignee(getLoginUserId(), reqVO);
  77 + return success(true);
  78 + }
  79 +}
... ...
yudao-module-bpm/yudao-module-bpm-impl-flowable/src/main/java/cn/iocoder/yudao/module/bpm/controller/app/package-info.java 0 → 100644
  1 +/**
  2 + * 占位
  3 + */
  4 +package cn.iocoder.yudao.module.bpm.controller.app;
... ...
yudao-module-bpm/yudao-module-bpm-impl-flowable/src/main/java/cn/iocoder/yudao/module/bpm/controller/package-info.java 0 → 100644
  1 +/**
  2 + * 提供 RESTful API 给前端:
  3 + * 1. admin 包:提供给管理后台 yudao-ui-admin 前端项目
  4 + * 2. app 包:提供给用户 APP yudao-ui-app 前端项目,它的 Controller 和 VO 都要添加 App 前缀,用于和管理后台进行区分
  5 + */
  6 +package cn.iocoder.yudao.module.bpm.controller;
... ...
yudao-module-bpm/yudao-module-bpm-impl-flowable/src/main/java/cn/iocoder/yudao/module/bpm/convert/definition/BpmModelConvert.java 0 → 100644
  1 +package cn.iocoder.yudao.module.bpm.convert.definition;
  2 +
  3 +import cn.hutool.core.util.StrUtil;
  4 +import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils;
  5 +import cn.iocoder.yudao.framework.common.util.json.JsonUtils;
  6 +import cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.model.*;
  7 +import cn.iocoder.yudao.module.bpm.dal.dataobject.definition.BpmFormDO;
  8 +import cn.iocoder.yudao.module.bpm.service.definition.dto.BpmModelMetaInfoRespDTO;
  9 +import cn.iocoder.yudao.module.bpm.service.definition.dto.BpmProcessDefinitionCreateReqDTO;
  10 +import org.flowable.common.engine.impl.db.SuspensionState;
  11 +import org.flowable.engine.repository.Deployment;
  12 +import org.flowable.engine.repository.Model;
  13 +import org.flowable.engine.repository.ProcessDefinition;
  14 +import org.mapstruct.Mapper;
  15 +import org.mapstruct.MappingTarget;
  16 +import org.mapstruct.factory.Mappers;
  17 +
  18 +import java.util.List;
  19 +import java.util.Map;
  20 +import java.util.Objects;
  21 +
  22 +/**
  23 + * 流程模型 Convert
  24 + *
  25 + * @author yunlongn
  26 + */
  27 +@Mapper
  28 +public interface BpmModelConvert {
  29 +
  30 + BpmModelConvert INSTANCE = Mappers.getMapper(BpmModelConvert.class);
  31 +
  32 + default List<BpmModelPageItemRespVO> convertList(List<Model> list, Map<Long, BpmFormDO> formMap,
  33 + Map<String, Deployment> deploymentMap,
  34 + Map<String, ProcessDefinition> processDefinitionMap) {
  35 + return CollectionUtils.convertList(list, model -> {
  36 + BpmModelMetaInfoRespDTO metaInfo = JsonUtils.parseObject(model.getMetaInfo(), BpmModelMetaInfoRespDTO.class);
  37 + BpmFormDO form = metaInfo != null ? formMap.get(metaInfo.getFormId()) : null;
  38 + Deployment deployment = model.getDeploymentId() != null ? deploymentMap.get(model.getDeploymentId()) : null;
  39 + ProcessDefinition processDefinition = model.getDeploymentId() != null ? processDefinitionMap.get(model.getDeploymentId()) : null;
  40 + return convert(model, form, deployment, processDefinition);
  41 + });
  42 + }
  43 +
  44 + default BpmModelPageItemRespVO convert(Model model, BpmFormDO form, Deployment deployment, ProcessDefinition processDefinition) {
  45 + BpmModelPageItemRespVO modelRespVO = new BpmModelPageItemRespVO();
  46 + modelRespVO.setId(model.getId());
  47 + modelRespVO.setCreateTime(model.getCreateTime());
  48 + // 通用 copy
  49 + copyTo(model, modelRespVO);
  50 + // Form
  51 + if (form != null) {
  52 + modelRespVO.setFormId(form.getId());
  53 + modelRespVO.setFormName(form.getName());
  54 + }
  55 + // ProcessDefinition
  56 + modelRespVO.setProcessDefinition(this.convert(processDefinition));
  57 + if (modelRespVO.getProcessDefinition() != null) {
  58 + modelRespVO.getProcessDefinition().setSuspensionState(processDefinition.isSuspended() ?
  59 + SuspensionState.SUSPENDED.getStateCode() : SuspensionState.ACTIVE.getStateCode());
  60 + modelRespVO.getProcessDefinition().setDeploymentTime(deployment.getDeploymentTime());
  61 + }
  62 + return modelRespVO;
  63 + }
  64 +
  65 + default BpmModelRespVO convert(Model model) {
  66 + BpmModelRespVO modelRespVO = new BpmModelRespVO();
  67 + modelRespVO.setId(model.getId());
  68 + modelRespVO.setCreateTime(model.getCreateTime());
  69 + // 通用 copy
  70 + copyTo(model, modelRespVO);
  71 + return modelRespVO;
  72 + }
  73 +
  74 + default void copyTo(Model model, BpmModelBaseVO to) {
  75 + to.setName(model.getName());
  76 + to.setKey(model.getKey());
  77 + to.setCategory(model.getCategory());
  78 + // metaInfo
  79 + BpmModelMetaInfoRespDTO metaInfo = JsonUtils.parseObject(model.getMetaInfo(), BpmModelMetaInfoRespDTO.class);
  80 + copyTo(metaInfo, to);
  81 + }
  82 +
  83 + BpmModelCreateReqVO convert(BpmModeImportReqVO bean);
  84 +
  85 + default BpmProcessDefinitionCreateReqDTO convert2(Model model, BpmFormDO form) {
  86 + BpmProcessDefinitionCreateReqDTO createReqDTO = new BpmProcessDefinitionCreateReqDTO();
  87 + createReqDTO.setModelId(model.getId());
  88 + createReqDTO.setName(model.getName());
  89 + createReqDTO.setKey(model.getKey());
  90 + createReqDTO.setCategory(model.getCategory());
  91 + BpmModelMetaInfoRespDTO metaInfo = JsonUtils.parseObject(model.getMetaInfo(), BpmModelMetaInfoRespDTO.class);
  92 + // metaInfo
  93 + copyTo(metaInfo, createReqDTO);
  94 + // form
  95 + if (form != null) {
  96 + createReqDTO.setFormConf(form.getConf());
  97 + createReqDTO.setFormFields(form.getFields());
  98 + }
  99 + return createReqDTO;
  100 + }
  101 +
  102 + void copyTo(BpmModelMetaInfoRespDTO from, @MappingTarget BpmProcessDefinitionCreateReqDTO to);
  103 +
  104 + void copyTo(BpmModelMetaInfoRespDTO from, @MappingTarget BpmModelBaseVO to);
  105 +
  106 + BpmModelPageItemRespVO.ProcessDefinition convert(ProcessDefinition bean);
  107 +
  108 + default void copy(Model model, BpmModelCreateReqVO bean) {
  109 + model.setName(bean.getName());
  110 + model.setKey(bean.getKey());
  111 + model.setMetaInfo(buildMetaInfoStr(null, bean.getDescription(), null, null,
  112 + null, null));
  113 + }
  114 +
  115 + default void copy(Model model, BpmModelUpdateReqVO bean) {
  116 + model.setName(bean.getName());
  117 + model.setCategory(bean.getCategory());
  118 + model.setMetaInfo(buildMetaInfoStr(JsonUtils.parseObject(model.getMetaInfo(), BpmModelMetaInfoRespDTO.class),
  119 + bean.getDescription(), bean.getFormType(), bean.getFormId(),
  120 + bean.getFormCustomCreatePath(), bean.getFormCustomViewPath()));
  121 + }
  122 +
  123 + default String buildMetaInfoStr(BpmModelMetaInfoRespDTO metaInfo, String description, Integer formType,
  124 + Long formId, String formCustomCreatePath, String formCustomViewPath) {
  125 + if (metaInfo == null) {
  126 + metaInfo = new BpmModelMetaInfoRespDTO();
  127 + }
  128 + // 只有非空,才进行设置,避免更新时的覆盖
  129 + if (StrUtil.isNotEmpty(description)) {
  130 + metaInfo.setDescription(description);
  131 + }
  132 + if (Objects.nonNull(formType)) {
  133 + metaInfo.setFormType(formType);
  134 + metaInfo.setFormId(formId);
  135 + metaInfo.setFormCustomCreatePath(formCustomCreatePath);
  136 + metaInfo.setFormCustomViewPath(formCustomViewPath);
  137 + }
  138 + return JsonUtils.toJsonString(metaInfo);
  139 + }
  140 +}
... ...
yudao-module-bpm/yudao-module-bpm-impl-flowable/src/main/java/cn/iocoder/yudao/module/bpm/convert/definition/BpmProcessDefinitionConvert.java 0 → 100644
  1 +package cn.iocoder.yudao.module.bpm.convert.definition;
  2 +
  3 +import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils;
  4 +import cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.process.BpmProcessDefinitionPageItemRespVO;
  5 +import cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.process.BpmProcessDefinitionRespVO;
  6 +import cn.iocoder.yudao.module.bpm.dal.dataobject.definition.BpmFormDO;
  7 +import cn.iocoder.yudao.module.bpm.dal.dataobject.definition.BpmProcessDefinitionExtDO;
  8 +import cn.iocoder.yudao.module.bpm.service.definition.dto.BpmProcessDefinitionCreateReqDTO;
  9 +import org.flowable.common.engine.impl.db.SuspensionState;
  10 +import org.flowable.engine.repository.Deployment;
  11 +import org.flowable.engine.repository.ProcessDefinition;
  12 +import org.mapstruct.Mapper;
  13 +import org.mapstruct.Mapping;
  14 +import org.mapstruct.MappingTarget;
  15 +import org.mapstruct.Named;
  16 +import org.mapstruct.factory.Mappers;
  17 +
  18 +import java.util.List;
  19 +import java.util.Map;
  20 +
  21 +/**
  22 + * Bpm 流程定义的 Convert
  23 + *
  24 + * @author yunlong.li
  25 + */
  26 +@Mapper
  27 +public interface BpmProcessDefinitionConvert {
  28 +
  29 + BpmProcessDefinitionConvert INSTANCE = Mappers.getMapper(BpmProcessDefinitionConvert.class);
  30 +
  31 + BpmProcessDefinitionPageItemRespVO convert(ProcessDefinition bean);
  32 +
  33 + BpmProcessDefinitionExtDO convert2(BpmProcessDefinitionCreateReqDTO bean);
  34 +
  35 + default List<BpmProcessDefinitionPageItemRespVO> convertList(List<ProcessDefinition> list, Map<String, Deployment> deploymentMap,
  36 + Map<String, BpmProcessDefinitionExtDO> processDefinitionDOMap, Map<Long, BpmFormDO> formMap) {
  37 + return CollectionUtils.convertList(list, definition -> {
  38 + Deployment deployment = definition.getDeploymentId() != null ? deploymentMap.get(definition.getDeploymentId()) : null;
  39 + BpmProcessDefinitionExtDO definitionDO = processDefinitionDOMap.get(definition.getId());
  40 + BpmFormDO form = definitionDO != null ? formMap.get(definitionDO.getFormId()) : null;
  41 + return convert(definition, deployment, definitionDO, form);
  42 + });
  43 + }
  44 +
  45 + default List<BpmProcessDefinitionRespVO> convertList3(List<ProcessDefinition> list,
  46 + Map<String, BpmProcessDefinitionExtDO> processDefinitionDOMap) {
  47 + return CollectionUtils.convertList(list, processDefinition -> {
  48 + BpmProcessDefinitionRespVO respVO = convert3(processDefinition);
  49 + BpmProcessDefinitionExtDO processDefinitionExtDO = processDefinitionDOMap.get(processDefinition.getId());
  50 + // 复制通用属性
  51 + copyTo(processDefinitionExtDO, respVO);
  52 + return respVO;
  53 + });
  54 + }
  55 +
  56 + @Mapping(source = "suspended", target = "suspensionState", qualifiedByName = "convertSuspendedToSuspensionState")
  57 + BpmProcessDefinitionRespVO convert3(ProcessDefinition bean);
  58 +
  59 + @Named("convertSuspendedToSuspensionState")
  60 + default Integer convertSuspendedToSuspensionState(boolean suspended) {
  61 + return suspended ? SuspensionState.SUSPENDED.getStateCode() :
  62 + SuspensionState.ACTIVE.getStateCode();
  63 + }
  64 +
  65 + default BpmProcessDefinitionPageItemRespVO convert(ProcessDefinition bean, Deployment deployment,
  66 + BpmProcessDefinitionExtDO processDefinitionExtDO, BpmFormDO form) {
  67 + BpmProcessDefinitionPageItemRespVO respVO = convert(bean);
  68 + respVO.setSuspensionState(bean.isSuspended() ? SuspensionState.SUSPENDED.getStateCode() : SuspensionState.ACTIVE.getStateCode());
  69 + if (deployment != null) {
  70 + respVO.setDeploymentTime(deployment.getDeploymentTime());
  71 + }
  72 + if (form != null) {
  73 + respVO.setFormName(form.getName());
  74 + }
  75 + // 复制通用属性
  76 + copyTo(processDefinitionExtDO, respVO);
  77 + return respVO;
  78 + }
  79 +
  80 + @Mapping(source = "from.id", target = "to.id", ignore = true)
  81 + void copyTo(BpmProcessDefinitionExtDO from, @MappingTarget BpmProcessDefinitionRespVO to);
  82 +}
... ...
yudao-module-bpm/yudao-module-bpm-impl-flowable/src/main/java/cn/iocoder/yudao/module/bpm/convert/definition/BpmTaskAssignRuleConvert.java 0 → 100644
  1 +package cn.iocoder.yudao.module.bpm.convert.definition;
  2 +
  3 +import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils;
  4 +import cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.rule.BpmTaskAssignRuleCreateReqVO;
  5 +import cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.rule.BpmTaskAssignRuleRespVO;
  6 +import cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.rule.BpmTaskAssignRuleUpdateReqVO;
  7 +import cn.iocoder.yudao.module.bpm.dal.dataobject.definition.BpmTaskAssignRuleDO;
  8 +import org.flowable.bpmn.model.UserTask;
  9 +import org.mapstruct.Mapper;
  10 +import org.mapstruct.factory.Mappers;
  11 +
  12 +import java.util.List;
  13 +import java.util.Map;
  14 +
  15 +@Mapper
  16 +public interface BpmTaskAssignRuleConvert {
  17 + BpmTaskAssignRuleConvert INSTANCE = Mappers.getMapper(BpmTaskAssignRuleConvert.class);
  18 +
  19 + default List<BpmTaskAssignRuleRespVO> convertList(List<UserTask> tasks, List<BpmTaskAssignRuleDO> rules) {
  20 + Map<String, BpmTaskAssignRuleDO> ruleMap = CollectionUtils.convertMap(rules, BpmTaskAssignRuleDO::getTaskDefinitionKey);
  21 + // 以 UserTask 为主维度,原因是:流程图编辑后,一些规则实际就没用了。
  22 + return CollectionUtils.convertList(tasks, task -> {
  23 + BpmTaskAssignRuleRespVO respVO = convert(ruleMap.get(task.getId()));
  24 + if (respVO == null) {
  25 + respVO = new BpmTaskAssignRuleRespVO();
  26 + respVO.setTaskDefinitionKey(task.getId());
  27 + }
  28 + respVO.setTaskDefinitionName(task.getName());
  29 + return respVO;
  30 + });
  31 + }
  32 +
  33 + BpmTaskAssignRuleRespVO convert(BpmTaskAssignRuleDO bean);
  34 +
  35 + BpmTaskAssignRuleDO convert(BpmTaskAssignRuleCreateReqVO bean);
  36 +
  37 + BpmTaskAssignRuleDO convert(BpmTaskAssignRuleUpdateReqVO bean);
  38 +
  39 + List<BpmTaskAssignRuleDO> convertList2(List<BpmTaskAssignRuleRespVO> list);
  40 +}
... ...
yudao-module-bpm/yudao-module-bpm-impl-flowable/src/main/java/cn/iocoder/yudao/module/bpm/convert/package-info.java 0 → 100644
  1 +/**
  2 + * 提供 POJO 类的实体转换
  3 + *
  4 + * 目前使用 MapStruct 框架
  5 + */
  6 +package cn.iocoder.yudao.module.bpm.convert;
... ...
yudao-module-bpm/yudao-module-bpm-impl-flowable/src/main/java/cn/iocoder/yudao/module/bpm/convert/task/BpmActivityConvert.java 0 → 100644
  1 +package cn.iocoder.yudao.module.bpm.convert.task;
  2 +
  3 +import cn.iocoder.yudao.module.bpm.controller.admin.task.vo.activity.BpmActivityRespVO;
  4 +import org.flowable.engine.history.HistoricActivityInstance;
  5 +import org.mapstruct.Mapper;
  6 +import org.mapstruct.Mapping;
  7 +import org.mapstruct.Mappings;
  8 +import org.mapstruct.factory.Mappers;
  9 +
  10 +import java.util.List;
  11 +
  12 +/**
  13 + * BPM 活动 Convert
  14 + *
  15 + * @author 芋道源码
  16 + */
  17 +@Mapper
  18 +public interface BpmActivityConvert {
  19 +
  20 + BpmActivityConvert INSTANCE = Mappers.getMapper(BpmActivityConvert.class);
  21 +
  22 + List<BpmActivityRespVO> convertList(List<HistoricActivityInstance> list);
  23 +
  24 + @Mappings({
  25 + @Mapping(source = "activityId", target = "key"),
  26 + @Mapping(source = "activityType", target = "type")
  27 + })
  28 + BpmActivityRespVO convert(HistoricActivityInstance bean);
  29 +}
... ...
yudao-module-bpm/yudao-module-bpm-impl-flowable/src/main/java/cn/iocoder/yudao/module/bpm/convert/task/BpmProcessInstanceConvert.java 0 → 100644
  1 +package cn.iocoder.yudao.module.bpm.convert.task;
  2 +
  3 +import cn.iocoder.yudao.framework.common.pojo.PageResult;
  4 +import cn.iocoder.yudao.framework.common.util.number.NumberUtils;
  5 +import cn.iocoder.yudao.module.bpm.controller.admin.task.vo.instance.BpmProcessInstancePageItemRespVO;
  6 +import cn.iocoder.yudao.module.bpm.controller.admin.task.vo.instance.BpmProcessInstanceRespVO;
  7 +import cn.iocoder.yudao.module.bpm.dal.dataobject.definition.BpmProcessDefinitionExtDO;
  8 +import cn.iocoder.yudao.module.bpm.dal.dataobject.task.BpmProcessInstanceExtDO;
  9 +import cn.iocoder.yudao.module.bpm.framework.bpm.core.event.BpmProcessInstanceResultEvent;
  10 +import cn.iocoder.yudao.module.bpm.service.message.dto.BpmMessageSendWhenProcessInstanceApproveReqDTO;
  11 +import cn.iocoder.yudao.module.bpm.service.message.dto.BpmMessageSendWhenProcessInstanceRejectReqDTO;
  12 +import cn.iocoder.yudao.module.system.api.dept.dto.DeptRespDTO;
  13 +import cn.iocoder.yudao.module.system.api.user.dto.AdminUserRespDTO;
  14 +import org.flowable.engine.history.HistoricProcessInstance;
  15 +import org.flowable.engine.repository.ProcessDefinition;
  16 +import org.flowable.engine.runtime.ProcessInstance;
  17 +import org.flowable.task.api.Task;
  18 +import org.mapstruct.Mapper;
  19 +import org.mapstruct.Mapping;
  20 +import org.mapstruct.MappingTarget;
  21 +import org.mapstruct.Mappings;
  22 +import org.mapstruct.factory.Mappers;
  23 +
  24 +import java.util.List;
  25 +import java.util.Map;
  26 +import java.util.Optional;
  27 +
  28 +/**
  29 + * 流程实例 Convert
  30 + *
  31 + * @author 芋道源码
  32 + */
  33 +@Mapper
  34 +public interface BpmProcessInstanceConvert {
  35 +
  36 + BpmProcessInstanceConvert INSTANCE = Mappers.getMapper(BpmProcessInstanceConvert.class);
  37 +
  38 + default PageResult<BpmProcessInstancePageItemRespVO> convertPage(PageResult<BpmProcessInstanceExtDO> page,
  39 + Map<String, List<Task>> taskMap) {
  40 + List<BpmProcessInstancePageItemRespVO> list = convertList(page.getList());
  41 + list.forEach(respVO -> respVO.setTasks(convertList2(taskMap.get(respVO.getId()))));
  42 + return new PageResult<>(list, page.getTotal());
  43 + }
  44 +
  45 + List<BpmProcessInstancePageItemRespVO> convertList(List<BpmProcessInstanceExtDO> list);
  46 +
  47 + @Mapping(source = "processInstanceId", target = "id")
  48 + BpmProcessInstancePageItemRespVO convert(BpmProcessInstanceExtDO bean);
  49 +
  50 + List<BpmProcessInstancePageItemRespVO.Task> convertList2(List<Task> tasks);
  51 +
  52 + default BpmProcessInstanceRespVO convert2(HistoricProcessInstance processInstance, BpmProcessInstanceExtDO processInstanceExt,
  53 + ProcessDefinition processDefinition, BpmProcessDefinitionExtDO processDefinitionExt,
  54 + String bpmnXml, AdminUserRespDTO startUser, DeptRespDTO dept) {
  55 + BpmProcessInstanceRespVO respVO = convert2(processInstance);
  56 + copyTo(processInstanceExt, respVO);
  57 + // definition
  58 + respVO.setProcessDefinition(convert2(processDefinition));
  59 + copyTo(processDefinitionExt, respVO.getProcessDefinition());
  60 + respVO.getProcessDefinition().setBpmnXml(bpmnXml);
  61 + // user
  62 + if (startUser != null) {
  63 + respVO.setStartUser(convert2(startUser));
  64 + if (dept != null) {
  65 + respVO.getStartUser().setDeptName(dept.getName());
  66 + }
  67 + }
  68 + return respVO;
  69 + }
  70 +
  71 + BpmProcessInstanceRespVO convert2(HistoricProcessInstance bean);
  72 +
  73 + @Mapping(source = "from.id", target = "to.id", ignore = true)
  74 + void copyTo(BpmProcessInstanceExtDO from, @MappingTarget BpmProcessInstanceRespVO to);
  75 +
  76 + BpmProcessInstanceRespVO.ProcessDefinition convert2(ProcessDefinition bean);
  77 +
  78 + @Mapping(source = "from.id", target = "to.id", ignore = true)
  79 + void copyTo(BpmProcessDefinitionExtDO from, @MappingTarget BpmProcessInstanceRespVO.ProcessDefinition to);
  80 +
  81 + BpmProcessInstanceRespVO.User convert2(AdminUserRespDTO bean);
  82 +
  83 + default BpmProcessInstanceResultEvent convert(Object source, HistoricProcessInstance instance, Integer result) {
  84 + BpmProcessInstanceResultEvent event = new BpmProcessInstanceResultEvent(source);
  85 + event.setId(instance.getId());
  86 + event.setProcessDefinitionKey(instance.getProcessDefinitionKey());
  87 + event.setBusinessKey(instance.getBusinessKey());
  88 + event.setResult(result);
  89 + return event;
  90 + }
  91 +
  92 + default BpmProcessInstanceResultEvent convert(Object source, ProcessInstance instance, Integer result) {
  93 + BpmProcessInstanceResultEvent event = new BpmProcessInstanceResultEvent(source);
  94 + event.setId(instance.getId());
  95 + event.setProcessDefinitionKey(instance.getProcessDefinitionKey());
  96 + event.setBusinessKey(instance.getBusinessKey());
  97 + event.setResult(result);
  98 + return event;
  99 + }
  100 +
  101 + default BpmMessageSendWhenProcessInstanceApproveReqDTO convert2ApprovedReq(ProcessInstance instance){
  102 + return new BpmMessageSendWhenProcessInstanceApproveReqDTO()
  103 + .setStartUserId(NumberUtils.parseLong(instance.getStartUserId()))
  104 + .setProcessInstanceId(instance.getId())
  105 + .setProcessInstanceName(instance.getName());
  106 + }
  107 +
  108 + default BpmMessageSendWhenProcessInstanceRejectReqDTO convert2RejectReq(ProcessInstance instance, String comment) {
  109 + return new BpmMessageSendWhenProcessInstanceRejectReqDTO()
  110 + .setProcessInstanceName(instance.getName())
  111 + .setProcessInstanceId(instance.getId())
  112 + .setComment(comment)
  113 + .setStartUserId(NumberUtils.parseLong(instance.getStartUserId()));
  114 + }
  115 +
  116 +}
... ...
yudao-module-bpm/yudao-module-bpm-impl-flowable/src/main/java/cn/iocoder/yudao/module/bpm/convert/task/BpmTaskConvert.java 0 → 100644
  1 +package cn.iocoder.yudao.module.bpm.convert.task;
  2 +
  3 +import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils;
  4 +import cn.iocoder.yudao.framework.common.util.number.NumberUtils;
  5 +import cn.iocoder.yudao.module.bpm.controller.admin.task.vo.task.BpmTaskDonePageItemRespVO;
  6 +import cn.iocoder.yudao.module.bpm.controller.admin.task.vo.task.BpmTaskRespVO;
  7 +import cn.iocoder.yudao.module.bpm.controller.admin.task.vo.task.BpmTaskTodoPageItemRespVO;
  8 +import cn.iocoder.yudao.module.bpm.dal.dataobject.task.BpmTaskExtDO;
  9 +import cn.iocoder.yudao.module.bpm.service.message.dto.BpmMessageSendWhenTaskCreatedReqDTO;
  10 +import cn.iocoder.yudao.module.system.api.dept.dto.DeptRespDTO;
  11 +import cn.iocoder.yudao.module.system.api.user.dto.AdminUserRespDTO;
  12 +
  13 +import org.flowable.common.engine.impl.db.SuspensionState;
  14 +import org.flowable.engine.history.HistoricProcessInstance;
  15 +import org.flowable.engine.runtime.ProcessInstance;
  16 +import org.flowable.task.api.Task;
  17 +import org.flowable.task.api.history.HistoricTaskInstance;
  18 +import org.mapstruct.*;
  19 +import org.mapstruct.factory.Mappers;
  20 +
  21 +import java.util.List;
  22 +import java.util.Map;
  23 +
  24 +/**
  25 + * Bpm 任务 Convert
  26 + *
  27 + * @author 芋道源码
  28 + */
  29 +@Mapper
  30 +public interface BpmTaskConvert {
  31 +
  32 + BpmTaskConvert INSTANCE = Mappers.getMapper(BpmTaskConvert.class);
  33 +
  34 + default List<BpmTaskTodoPageItemRespVO> convertList1(List<Task> tasks, Map<String, ProcessInstance> processInstanceMap,
  35 + Map<Long, AdminUserRespDTO> userMap) {
  36 + return CollectionUtils.convertList(tasks, task -> {
  37 + BpmTaskTodoPageItemRespVO respVO = convert1(task);
  38 + ProcessInstance processInstance = processInstanceMap.get(task.getProcessInstanceId());
  39 + if (processInstance != null) {
  40 + AdminUserRespDTO startUser = userMap.get(NumberUtils.parseLong(processInstance.getStartUserId()));
  41 + respVO.setProcessInstance(convert(processInstance, startUser));
  42 + }
  43 + return respVO;
  44 + });
  45 + }
  46 +
  47 + @Mapping(source = "suspended", target = "suspensionState", qualifiedByName = "convertSuspendedToSuspensionState")
  48 + BpmTaskTodoPageItemRespVO convert1(Task bean);
  49 +
  50 + @Named("convertSuspendedToSuspensionState")
  51 + default Integer convertSuspendedToSuspensionState(boolean suspended) {
  52 + return suspended ? SuspensionState.SUSPENDED.getStateCode() :
  53 + SuspensionState.ACTIVE.getStateCode();
  54 + }
  55 +
  56 + default List<BpmTaskDonePageItemRespVO> convertList2(List<HistoricTaskInstance> tasks, Map<String, BpmTaskExtDO> bpmTaskExtDOMap,
  57 + Map<String, HistoricProcessInstance> historicProcessInstanceMap,
  58 + Map<Long, AdminUserRespDTO> userMap) {
  59 + return CollectionUtils.convertList(tasks, task -> {
  60 + BpmTaskDonePageItemRespVO respVO = convert2(task);
  61 + BpmTaskExtDO taskExtDO = bpmTaskExtDOMap.get(task.getId());
  62 + copyTo(taskExtDO, respVO);
  63 + HistoricProcessInstance processInstance = historicProcessInstanceMap.get(task.getProcessInstanceId());
  64 + if (processInstance != null) {
  65 + AdminUserRespDTO startUser = userMap.get(NumberUtils.parseLong(processInstance.getStartUserId()));
  66 + respVO.setProcessInstance(convert(processInstance, startUser));
  67 + }
  68 + return respVO;
  69 + });
  70 + }
  71 +
  72 + BpmTaskDonePageItemRespVO convert2(HistoricTaskInstance bean);
  73 +
  74 + @Mappings({
  75 + @Mapping(source = "processInstance.id", target = "id"),
  76 + @Mapping(source = "processInstance.name", target = "name"),
  77 + @Mapping(source = "processInstance.startUserId", target = "startUserId"),
  78 + @Mapping(source = "processInstance.processDefinitionId", target = "processDefinitionId"),
  79 + @Mapping(source = "startUser.nickname", target = "startUserNickname")
  80 + })
  81 + BpmTaskTodoPageItemRespVO.ProcessInstance convert(ProcessInstance processInstance, AdminUserRespDTO startUser);
  82 +
  83 + default List<BpmTaskRespVO> convertList3(List<HistoricTaskInstance> tasks, Map<String, BpmTaskExtDO> bpmTaskExtDOMap,
  84 + HistoricProcessInstance processInstance, Map<Long, AdminUserRespDTO> userMap,
  85 + Map<Long, DeptRespDTO> deptMap) {
  86 + return CollectionUtils.convertList(tasks, task -> {
  87 + BpmTaskRespVO respVO = convert3(task);
  88 + BpmTaskExtDO taskExtDO = bpmTaskExtDOMap.get(task.getId());
  89 + copyTo(taskExtDO, respVO);
  90 + if (processInstance != null) {
  91 + AdminUserRespDTO startUser = userMap.get(NumberUtils.parseLong(processInstance.getStartUserId()));
  92 + respVO.setProcessInstance(convert(processInstance, startUser));
  93 + }
  94 + AdminUserRespDTO assignUser = userMap.get(NumberUtils.parseLong(task.getAssignee()));
  95 + if (assignUser != null) {
  96 + respVO.setAssigneeUser(convert3(assignUser));
  97 + DeptRespDTO dept = deptMap.get(assignUser.getDeptId());
  98 + if (dept != null) {
  99 + respVO.getAssigneeUser().setDeptName(dept.getName());
  100 + }
  101 + }
  102 + return respVO;
  103 + });
  104 + }
  105 +
  106 + @Mapping(source = "taskDefinitionKey", target = "definitionKey")
  107 + BpmTaskRespVO convert3(HistoricTaskInstance bean);
  108 +
  109 + BpmTaskRespVO.User convert3(AdminUserRespDTO bean);
  110 +
  111 + @Mapping(target = "id", ignore = true)
  112 + void copyTo(BpmTaskExtDO from, @MappingTarget BpmTaskDonePageItemRespVO to);
  113 +
  114 + @Mappings({
  115 + @Mapping(source = "processInstance.id", target = "id"),
  116 + @Mapping(source = "processInstance.name", target = "name"),
  117 + @Mapping(source = "processInstance.startUserId", target = "startUserId"),
  118 + @Mapping(source = "processInstance.processDefinitionId", target = "processDefinitionId"),
  119 + @Mapping(source = "startUser.nickname", target = "startUserNickname")
  120 + })
  121 + BpmTaskTodoPageItemRespVO.ProcessInstance convert(HistoricProcessInstance processInstance, AdminUserRespDTO startUser);
  122 +
  123 + default BpmTaskExtDO convert2TaskExt(Task task){
  124 + BpmTaskExtDO taskExtDO = new BpmTaskExtDO()
  125 + .setTaskId(task.getId())
  126 + .setAssigneeUserId(NumberUtils.parseLong(task.getAssignee()))
  127 + .setName(task.getName())
  128 + .setProcessDefinitionId(task.getProcessDefinitionId())
  129 + .setProcessInstanceId(task.getProcessInstanceId());
  130 + taskExtDO.setCreateTime(task.getCreateTime());
  131 + return taskExtDO;
  132 + }
  133 +
  134 + default BpmMessageSendWhenTaskCreatedReqDTO convert(ProcessInstance processInstance, AdminUserRespDTO startUser, Task task) {
  135 + BpmMessageSendWhenTaskCreatedReqDTO reqDTO = new BpmMessageSendWhenTaskCreatedReqDTO();
  136 + reqDTO.setProcessInstanceId(processInstance.getProcessInstanceId())
  137 + .setProcessInstanceName(processInstance.getName())
  138 + .setStartUserId(startUser.getId())
  139 + .setStartUserNickname(startUser.getNickname())
  140 + .setTaskId(task.getId())
  141 + .setTaskName(task.getName())
  142 + .setAssigneeUserId(NumberUtils.parseLong(task.getAssignee()));
  143 + return reqDTO;
  144 + }
  145 +}
  146 +
  147 +
... ...
yudao-module-bpm/yudao-module-bpm-impl-flowable/src/main/java/cn/iocoder/yudao/module/bpm/convert/《芋道 Spring Boot 对象转换 MapStruct 入门》.md 0 → 100644
  1 +<http://www.iocoder.cn/Spring-Boot/MapStruct/?yudao>
... ...
yudao-module-bpm/yudao-module-bpm-impl-flowable/src/main/java/cn/iocoder/yudao/module/bpm/framework/flowable/config/BpmFlowableConfiguration.java 0 → 100644
  1 +package cn.iocoder.yudao.module.bpm.framework.flowable.config;
  2 +
  3 +import cn.hutool.core.collection.ListUtil;
  4 +import cn.iocoder.yudao.module.bpm.framework.flowable.core.behavior.BpmActivityBehaviorFactory;
  5 +import cn.iocoder.yudao.module.bpm.framework.flowable.core.behavior.script.BpmTaskAssignScript;
  6 +import cn.iocoder.yudao.module.bpm.service.definition.BpmTaskAssignRuleService;
  7 +import cn.iocoder.yudao.module.bpm.service.definition.BpmUserGroupService;
  8 +import cn.iocoder.yudao.module.system.api.dept.DeptApi;
  9 +import cn.iocoder.yudao.module.system.api.permission.PermissionApi;
  10 +import cn.iocoder.yudao.module.system.api.user.AdminUserApi;
  11 +import org.flowable.common.engine.api.delegate.event.FlowableEventListener;
  12 +import org.flowable.spring.SpringProcessEngineConfiguration;
  13 +import org.flowable.spring.boot.EngineConfigurationConfigurer;
  14 +import org.springframework.beans.factory.ObjectProvider;
  15 +import org.springframework.context.annotation.Bean;
  16 +import org.springframework.context.annotation.Configuration;
  17 +
  18 +import java.util.List;
  19 +
  20 +/**
  21 + * BPM 模块的 Flowable 配置类
  22 + *
  23 + * @author jason
  24 + */
  25 +@Configuration
  26 +public class BpmFlowableConfiguration {
  27 +
  28 + /**
  29 + * BPM 模块的 ProcessEngineConfigurationConfigurer 实现类:
  30 + *
  31 + * 1. 设置各种监听器
  32 + * 2. 设置自定义的 ActivityBehaviorFactory 实现
  33 + */
  34 + @Bean
  35 + public EngineConfigurationConfigurer<SpringProcessEngineConfiguration> bpmProcessEngineConfigurationConfigurer(
  36 + ObjectProvider<FlowableEventListener> listeners,
  37 + BpmActivityBehaviorFactory bpmActivityBehaviorFactory) {
  38 + return configuration -> {
  39 + // 注册监听器,例如说 BpmActivitiEventListener
  40 + configuration.setEventListeners(ListUtil.toList(listeners.iterator()));
  41 + // 设置 ActivityBehaviorFactory 实现类,用于流程任务的审核人的自定义
  42 + configuration.setActivityBehaviorFactory(bpmActivityBehaviorFactory);
  43 + };
  44 + }
  45 +
  46 + @Bean
  47 + public BpmActivityBehaviorFactory bpmActivityBehaviorFactory(BpmTaskAssignRuleService taskRuleService,
  48 + BpmUserGroupService userGroupService,
  49 + PermissionApi permissionApi,
  50 + DeptApi deptApi,
  51 + AdminUserApi adminUserApi,
  52 + List<BpmTaskAssignScript> scripts) {
  53 + BpmActivityBehaviorFactory bpmActivityBehaviorFactory = new BpmActivityBehaviorFactory();
  54 + bpmActivityBehaviorFactory.setBpmTaskRuleService(taskRuleService);
  55 + bpmActivityBehaviorFactory.setUserGroupService(userGroupService);
  56 + bpmActivityBehaviorFactory.setAdminUserApi(adminUserApi);
  57 + bpmActivityBehaviorFactory.setPermissionApi(permissionApi);
  58 + bpmActivityBehaviorFactory.setDeptApi(deptApi);
  59 + bpmActivityBehaviorFactory.setScripts(scripts);
  60 + return bpmActivityBehaviorFactory;
  61 + }
  62 +}
... ...
yudao-module-bpm/yudao-module-bpm-impl-flowable/src/main/java/cn/iocoder/yudao/module/bpm/framework/flowable/core/behavior/BpmActivityBehaviorFactory.java 0 → 100644
  1 +package cn.iocoder.yudao.module.bpm.framework.flowable.core.behavior;
  2 +
  3 +import cn.iocoder.yudao.module.bpm.framework.flowable.core.behavior.script.BpmTaskAssignScript;
  4 +import cn.iocoder.yudao.module.bpm.service.definition.BpmTaskAssignRuleService;
  5 +import cn.iocoder.yudao.module.bpm.service.definition.BpmUserGroupService;
  6 +import cn.iocoder.yudao.module.system.api.dept.DeptApi;
  7 +import cn.iocoder.yudao.module.system.api.permission.PermissionApi;
  8 +import cn.iocoder.yudao.module.system.api.user.AdminUserApi;
  9 +import lombok.Data;
  10 +import lombok.EqualsAndHashCode;
  11 +import lombok.Setter;
  12 +import lombok.ToString;
  13 +import org.flowable.bpmn.model.UserTask;
  14 +import org.flowable.engine.impl.bpmn.behavior.UserTaskActivityBehavior;
  15 +import org.flowable.engine.impl.bpmn.parser.factory.DefaultActivityBehaviorFactory;
  16 +
  17 +import java.util.List;
  18 +
  19 +/**
  20 + * 自定义的 ActivityBehaviorFactory 实现类,目的如下:
  21 + * 1. 自定义 {@link #createUserTaskActivityBehavior(UserTask)}:实现自定义的流程任务的 assignee 负责人的分配
  22 + *
  23 + * @author 芋道源码
  24 + */
  25 +@Data
  26 +@EqualsAndHashCode(callSuper = true)
  27 +@ToString(callSuper = true)
  28 +public class BpmActivityBehaviorFactory extends DefaultActivityBehaviorFactory {
  29 +
  30 + @Setter
  31 + private BpmTaskAssignRuleService bpmTaskRuleService;
  32 + @Setter
  33 + private BpmUserGroupService userGroupService;
  34 +
  35 + @Setter
  36 + private PermissionApi permissionApi;
  37 + @Setter
  38 + private DeptApi deptApi;
  39 + @Setter
  40 + private AdminUserApi adminUserApi;
  41 + @Setter
  42 + private List<BpmTaskAssignScript> scripts;
  43 +
  44 + @Override
  45 + public UserTaskActivityBehavior createUserTaskActivityBehavior(UserTask userTask) {
  46 + BpmUserTaskActivityBehavior userTaskActivityBehavior = new BpmUserTaskActivityBehavior(userTask);
  47 + userTaskActivityBehavior.setBpmTaskRuleService(bpmTaskRuleService);
  48 + userTaskActivityBehavior.setPermissionApi(permissionApi);
  49 + userTaskActivityBehavior.setDeptApi(deptApi);
  50 + userTaskActivityBehavior.setUserGroupService(userGroupService);
  51 + userTaskActivityBehavior.setAdminUserApi(adminUserApi);
  52 + userTaskActivityBehavior.setScripts(scripts);
  53 + return userTaskActivityBehavior;
  54 + }
  55 +}
... ...
yudao-module-bpm/yudao-module-bpm-impl-flowable/src/main/java/cn/iocoder/yudao/module/bpm/framework/flowable/core/behavior/BpmUserTaskActivityBehavior.java 0 → 100644
  1 +package cn.iocoder.yudao.module.bpm.framework.flowable.core.behavior;
  2 +
  3 +import cn.hutool.core.collection.CollUtil;
  4 +import cn.hutool.core.util.RandomUtil;
  5 +import cn.hutool.core.util.StrUtil;
  6 +import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum;
  7 +import cn.iocoder.yudao.framework.datapermission.core.annotation.DataPermission;
  8 +import cn.iocoder.yudao.framework.datapermission.core.dept.rule.DeptDataPermissionRule;
  9 +import cn.iocoder.yudao.module.bpm.dal.dataobject.definition.BpmTaskAssignRuleDO;
  10 +import cn.iocoder.yudao.module.bpm.dal.dataobject.definition.BpmUserGroupDO;
  11 +import cn.iocoder.yudao.module.bpm.enums.definition.BpmTaskAssignRuleTypeEnum;
  12 +import cn.iocoder.yudao.module.bpm.framework.flowable.core.behavior.script.BpmTaskAssignScript;
  13 +import cn.iocoder.yudao.module.bpm.service.definition.BpmTaskAssignRuleService;
  14 +import cn.iocoder.yudao.module.bpm.service.definition.BpmUserGroupService;
  15 +import cn.iocoder.yudao.module.system.api.dept.DeptApi;
  16 +import cn.iocoder.yudao.module.system.api.dept.dto.DeptRespDTO;
  17 +import cn.iocoder.yudao.module.system.api.permission.PermissionApi;
  18 +import cn.iocoder.yudao.module.system.api.user.AdminUserApi;
  19 +import cn.iocoder.yudao.module.system.api.user.dto.AdminUserRespDTO;
  20 +import com.google.common.annotations.VisibleForTesting;
  21 +import lombok.Setter;
  22 +import lombok.extern.slf4j.Slf4j;
  23 +import org.flowable.bpmn.model.UserTask;
  24 +import org.flowable.common.engine.api.FlowableException;
  25 +import org.flowable.common.engine.impl.el.ExpressionManager;
  26 +import org.flowable.engine.delegate.DelegateExecution;
  27 +import org.flowable.engine.impl.bpmn.behavior.UserTaskActivityBehavior;
  28 +import org.flowable.engine.impl.cfg.ProcessEngineConfigurationImpl;
  29 +import org.flowable.engine.impl.util.TaskHelper;
  30 +import org.flowable.task.service.TaskService;
  31 +import org.flowable.task.service.impl.persistence.entity.TaskEntity;
  32 +
  33 +import java.util.*;
  34 +
  35 +import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
  36 +import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertMap;
  37 +import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertSet;
  38 +import static cn.iocoder.yudao.framework.common.util.json.JsonUtils.toJsonString;
  39 +import static cn.iocoder.yudao.module.bpm.enums.ErrorCodeConstants.TASK_ASSIGN_SCRIPT_NOT_EXISTS;
  40 +import static cn.iocoder.yudao.module.bpm.enums.ErrorCodeConstants.TASK_CREATE_FAIL_NO_CANDIDATE_USER;
  41 +
  42 +/**
  43 + * 自定义的流程任务的 assignee 负责人的分配
  44 + * 第一步,获得对应的分配规则;
  45 + * 第二步,根据分配规则,计算出分配任务的候选人。如果找不到,则直接报业务异常,不继续执行后续的流程;
  46 + * 第三步,随机选择一个候选人,则选择作为 assignee 负责人。
  47 + *
  48 + * @author 芋道源码
  49 + */
  50 +@Slf4j
  51 +public class BpmUserTaskActivityBehavior extends UserTaskActivityBehavior {
  52 +
  53 + @Setter
  54 + private BpmTaskAssignRuleService bpmTaskRuleService;
  55 + @Setter
  56 + private BpmUserGroupService userGroupService;
  57 + @Setter
  58 + private DeptApi deptApi;
  59 + @Setter
  60 + private AdminUserApi adminUserApi;
  61 + @Setter
  62 + private PermissionApi permissionApi;
  63 +
  64 + /**
  65 + * 任务分配脚本
  66 + */
  67 + private Map<Long, BpmTaskAssignScript> scriptMap = Collections.emptyMap();
  68 +
  69 + public BpmUserTaskActivityBehavior(UserTask userTask) {
  70 + super(userTask);
  71 + }
  72 + public void setScripts(List<BpmTaskAssignScript> scripts) {
  73 + this.scriptMap = convertMap(scripts, script -> script.getEnum().getId());
  74 + }
  75 +
  76 + @Override
  77 + protected void handleAssignments(TaskService taskService, String assignee, String owner, List<String> candidateUsers, List<String> candidateGroups, TaskEntity task, ExpressionManager expressionManager, DelegateExecution execution, ProcessEngineConfigurationImpl processEngineConfiguration) {
  78 + // 第一步,获得任务的规则
  79 + BpmTaskAssignRuleDO rule = getTaskRule(task);
  80 + // 第二步,获得任务的候选用户们
  81 + Set<Long> candidateUserIds = calculateTaskCandidateUsers(task, rule);
  82 + // 第三步,设置一个作为负责人
  83 + Long assigneeUserId = chooseTaskAssignee(candidateUserIds);
  84 + TaskHelper.changeTaskAssignee(task, String.valueOf(assigneeUserId));
  85 + }
  86 +
  87 + private BpmTaskAssignRuleDO getTaskRule(TaskEntity task) {
  88 + List<BpmTaskAssignRuleDO> taskRules = bpmTaskRuleService.getTaskAssignRuleListByProcessDefinitionId(task.getProcessDefinitionId(),
  89 + task.getTaskDefinitionKey());
  90 + if (CollUtil.isEmpty(taskRules)) {
  91 + throw new FlowableException(StrUtil.format("流程任务({}/{}/{}) 找不到符合的任务规则",
  92 + task.getId(), task.getProcessDefinitionId(), task.getTaskDefinitionKey()));
  93 + }
  94 + if (taskRules.size() > 1) {
  95 + throw new FlowableException(StrUtil.format("流程任务({}/{}/{}) 找到过多任务规则({})",
  96 + task.getId(), task.getProcessDefinitionId(), task.getTaskDefinitionKey(), taskRules.size()));
  97 + }
  98 + return taskRules.get(0);
  99 + }
  100 +
  101 + @VisibleForTesting
  102 + Set<Long> calculateTaskCandidateUsers(TaskEntity task, BpmTaskAssignRuleDO rule) {
  103 + Set<Long> assigneeUserIds = null;
  104 + if (Objects.equals(BpmTaskAssignRuleTypeEnum.ROLE.getType(), rule.getType())) {
  105 + assigneeUserIds = calculateTaskCandidateUsersByRole(task, rule);
  106 + } else if (Objects.equals(BpmTaskAssignRuleTypeEnum.DEPT_MEMBER.getType(), rule.getType())) {
  107 + assigneeUserIds = calculateTaskCandidateUsersByDeptMember(task, rule);
  108 + } else if (Objects.equals(BpmTaskAssignRuleTypeEnum.DEPT_LEADER.getType(), rule.getType())) {
  109 + assigneeUserIds = calculateTaskCandidateUsersByDeptLeader(task, rule);
  110 + } else if (Objects.equals(BpmTaskAssignRuleTypeEnum.POST.getType(), rule.getType())) {
  111 + assigneeUserIds = calculateTaskCandidateUsersByPost(task, rule);
  112 + } else if (Objects.equals(BpmTaskAssignRuleTypeEnum.USER.getType(), rule.getType())) {
  113 + assigneeUserIds = calculateTaskCandidateUsersByUser(task, rule);
  114 + } else if (Objects.equals(BpmTaskAssignRuleTypeEnum.USER_GROUP.getType(), rule.getType())) {
  115 + assigneeUserIds = calculateTaskCandidateUsersByUserGroup(task, rule);
  116 + } else if (Objects.equals(BpmTaskAssignRuleTypeEnum.SCRIPT.getType(), rule.getType())) {
  117 + assigneeUserIds = calculateTaskCandidateUsersByScript(task, rule);
  118 + }
  119 +
  120 + // 移除被禁用的用户
  121 + removeDisableUsers(assigneeUserIds);
  122 + // 如果候选人为空,抛出异常 TODO 芋艿:没候选人的策略选择。1 - 挂起;2 - 直接结束;3 - 强制一个兜底人
  123 + if (CollUtil.isEmpty(assigneeUserIds)) {
  124 + log.error("[calculateTaskCandidateUsers][流程任务({}/{}/{}) 任务规则({}) 找不到候选人]",
  125 + task.getId(), task.getProcessDefinitionId(), task.getTaskDefinitionKey(), toJsonString(rule));
  126 + throw exception(TASK_CREATE_FAIL_NO_CANDIDATE_USER);
  127 + }
  128 + return assigneeUserIds;
  129 + }
  130 +
  131 + private Set<Long> calculateTaskCandidateUsersByRole(TaskEntity task, BpmTaskAssignRuleDO rule) {
  132 + return permissionApi.getUserRoleIdListByRoleIds(rule.getOptions());
  133 + }
  134 +
  135 + private Set<Long> calculateTaskCandidateUsersByDeptMember(TaskEntity task, BpmTaskAssignRuleDO rule) {
  136 + List<AdminUserRespDTO> users = adminUserApi.getUsersByDeptIds(rule.getOptions());
  137 + return convertSet(users, AdminUserRespDTO::getId);
  138 + }
  139 +
  140 + private Set<Long> calculateTaskCandidateUsersByDeptLeader(TaskEntity task, BpmTaskAssignRuleDO rule) {
  141 + List<DeptRespDTO> depts = deptApi.getDepts(rule.getOptions());
  142 + return convertSet(depts, DeptRespDTO::getLeaderUserId);
  143 + }
  144 +
  145 + private Set<Long> calculateTaskCandidateUsersByPost(TaskEntity task, BpmTaskAssignRuleDO rule) {
  146 + List<AdminUserRespDTO> users = adminUserApi.getUsersByPostIds(rule.getOptions());
  147 + return convertSet(users, AdminUserRespDTO::getId);
  148 + }
  149 +
  150 + private Set<Long> calculateTaskCandidateUsersByUser(TaskEntity task, BpmTaskAssignRuleDO rule) {
  151 + return rule.getOptions();
  152 + }
  153 +
  154 + private Set<Long> calculateTaskCandidateUsersByUserGroup(TaskEntity task, BpmTaskAssignRuleDO rule) {
  155 + List<BpmUserGroupDO> userGroups = userGroupService.getUserGroupList(rule.getOptions());
  156 + Set<Long> userIds = new HashSet<>();
  157 + userGroups.forEach(group -> userIds.addAll(group.getMemberUserIds()));
  158 + return userIds;
  159 + }
  160 +
  161 + private Set<Long> calculateTaskCandidateUsersByScript(TaskEntity task, BpmTaskAssignRuleDO rule) {
  162 + // 获得对应的脚本
  163 + List<BpmTaskAssignScript> scripts = new ArrayList<>(rule.getOptions().size());
  164 + rule.getOptions().forEach(id -> {
  165 + BpmTaskAssignScript script = scriptMap.get(id);
  166 + if (script == null) {
  167 + throw exception(TASK_ASSIGN_SCRIPT_NOT_EXISTS, id);
  168 + }
  169 + scripts.add(script);
  170 + });
  171 + // 逐个计算任务
  172 + Set<Long> userIds = new HashSet<>();
  173 + scripts.forEach(script -> CollUtil.addAll(userIds, script.calculateTaskCandidateUsers(task)));
  174 + return userIds;
  175 + }
  176 +
  177 + private Long chooseTaskAssignee(Set<Long> candidateUserIds) {
  178 + // TODO 芋艿:未来可以优化下,改成轮询的策略
  179 + int index = RandomUtil.randomInt(candidateUserIds.size());
  180 + return CollUtil.get(candidateUserIds, index);
  181 + }
  182 +
  183 + @VisibleForTesting
  184 + void removeDisableUsers(Set<Long> assigneeUserIds) {
  185 + if (CollUtil.isEmpty(assigneeUserIds)) {
  186 + return;
  187 + }
  188 + //TODO 芋艿 这里有数据权限的问题。默认会加上数据权限 dept_id IN (deptId). 导致查询不到数据
  189 + Map<Long, AdminUserRespDTO> userMap = adminUserApi.getUserMap(assigneeUserIds);
  190 + assigneeUserIds.removeIf(id -> {
  191 + AdminUserRespDTO user = userMap.get(id);
  192 + return user == null || !CommonStatusEnum.ENABLE.getStatus().equals(user.getStatus());
  193 + });
  194 + }
  195 +}
... ...
yudao-module-bpm/yudao-module-bpm-impl-flowable/src/main/java/cn/iocoder/yudao/module/bpm/framework/flowable/core/behavior/script/BpmTaskAssignScript.java 0 → 100644
  1 +package cn.iocoder.yudao.module.bpm.framework.flowable.core.behavior.script;
  2 +
  3 +import cn.iocoder.yudao.module.bpm.enums.definition.BpmTaskRuleScriptEnum;
  4 +import org.flowable.task.service.impl.persistence.entity.TaskEntity;
  5 +
  6 +import java.util.Set;
  7 +
  8 +/**
  9 + * Bpm 任务分配的自定义 Script 脚本
  10 + * 使用场景:
  11 + * 1. 设置审批人为发起人
  12 + * 2. 设置审批人为发起人的 Leader
  13 + * 3. 甚至审批人为发起人的 Leader 的 Leader
  14 + *
  15 + * @author 芋道源码
  16 + */
  17 +public interface BpmTaskAssignScript {
  18 +
  19 + /**
  20 + * 基于流程任务,获得任务的候选用户们
  21 + *
  22 + * @param task 任务
  23 + * @return 候选人用户的编号数组
  24 + */
  25 + Set<Long> calculateTaskCandidateUsers(TaskEntity task);
  26 +
  27 + /**
  28 + * 获得枚举值
  29 + *
  30 + * @return 枚举值
  31 + */
  32 + BpmTaskRuleScriptEnum getEnum();
  33 +}
  34 +
... ...
yudao-module-bpm/yudao-module-bpm-impl-flowable/src/main/java/cn/iocoder/yudao/module/bpm/framework/flowable/core/behavior/script/impl/BpmTaskAssignLeaderAbstractScript.java 0 → 100644
  1 +package cn.iocoder.yudao.module.bpm.framework.flowable.core.behavior.script.impl;
  2 +
  3 +import cn.iocoder.yudao.framework.common.util.number.NumberUtils;
  4 +import cn.iocoder.yudao.module.bpm.framework.flowable.core.behavior.script.BpmTaskAssignScript;
  5 +import cn.iocoder.yudao.module.bpm.service.task.BpmProcessInstanceService;
  6 +import cn.iocoder.yudao.module.system.api.dept.DeptApi;
  7 +import cn.iocoder.yudao.module.system.api.dept.dto.DeptRespDTO;
  8 +import cn.iocoder.yudao.module.system.api.user.AdminUserApi;
  9 +import cn.iocoder.yudao.module.system.api.user.dto.AdminUserRespDTO;
  10 +
  11 +import org.flowable.engine.runtime.ProcessInstance;
  12 +import org.flowable.task.service.impl.persistence.entity.TaskEntity;
  13 +import org.springframework.context.annotation.Lazy;
  14 +import org.springframework.util.Assert;
  15 +
  16 +import javax.annotation.Resource;
  17 +import java.util.Set;
  18 +
  19 +import static cn.iocoder.yudao.framework.common.util.collection.SetUtils.asSet;
  20 +import static java.util.Collections.emptySet;
  21 +
  22 +/**
  23 + * 分配给发起人的 Leader 审批的 Script 实现类
  24 + * 目前 Leader 的定义是,
  25 + *
  26 + * @author 芋道源码
  27 + */
  28 +public abstract class BpmTaskAssignLeaderAbstractScript implements BpmTaskAssignScript {
  29 +
  30 + @Resource
  31 + private AdminUserApi adminUserApi;
  32 + @Resource
  33 + private DeptApi deptApi;
  34 + @Resource
  35 + @Lazy // 解决循环依赖
  36 + private BpmProcessInstanceService bpmProcessInstanceService;
  37 +
  38 + protected Set<Long> calculateTaskCandidateUsers(TaskEntity task, int level) {
  39 + Assert.isTrue(level > 0, "level 必须大于 0");
  40 + // 获得发起人
  41 + ProcessInstance processInstance = bpmProcessInstanceService.getProcessInstance(task.getProcessInstanceId());
  42 + Long startUserId = NumberUtils.parseLong(processInstance.getStartUserId());
  43 + // 获得对应 leve 的部门
  44 + DeptRespDTO dept = null;
  45 + for (int i = 0; i < level; i++) {
  46 + // 获得 level 对应的部门
  47 + if (dept == null) {
  48 + dept = getStartUserDept(startUserId);
  49 + if (dept == null) { // 找不到发起人的部门,所以无法使用该规则
  50 + return emptySet();
  51 + }
  52 + } else {
  53 + DeptRespDTO parentDept = deptApi.getDept(dept.getParentId());
  54 + if (parentDept == null) { // 找不到父级部门,所以只好结束寻找。原因是:例如说,级别比较高的人,所在部门层级比较少
  55 + break;
  56 + }
  57 + dept = parentDept;
  58 + }
  59 + }
  60 + return dept.getLeaderUserId() != null ? asSet(dept.getLeaderUserId()) : emptySet();
  61 + }
  62 +
  63 + private DeptRespDTO getStartUserDept(Long startUserId) {
  64 + AdminUserRespDTO startUser = adminUserApi.getUser(startUserId);
  65 + if (startUser.getDeptId() == null) { // 找不到部门,所以无法使用该规则
  66 + return null;
  67 + }
  68 + return deptApi.getDept(startUser.getDeptId());
  69 + }
  70 +
  71 +}
... ...
yudao-module-bpm/yudao-module-bpm-impl-flowable/src/main/java/cn/iocoder/yudao/module/bpm/framework/flowable/core/behavior/script/impl/BpmTaskAssignLeaderX1Script.java 0 → 100644
  1 +package cn.iocoder.yudao.module.bpm.framework.flowable.core.behavior.script.impl;
  2 +
  3 +import cn.iocoder.yudao.framework.datapermission.core.annotation.DataPermission;
  4 +import cn.iocoder.yudao.module.bpm.enums.definition.BpmTaskRuleScriptEnum;
  5 +import org.flowable.task.service.impl.persistence.entity.TaskEntity;
  6 +import org.springframework.stereotype.Component;
  7 +
  8 +import java.util.Set;
  9 +
  10 +/**
  11 + * 分配给发起人的一级 Leader 审批的 Script 实现类
  12 + *
  13 + * @author 芋道源码
  14 + */
  15 +@Component
  16 +public class BpmTaskAssignLeaderX1Script extends BpmTaskAssignLeaderAbstractScript {
  17 +
  18 + @Override
  19 + @DataPermission(enable = false) // 不需要处理数据权限, 不然会有问题,查询不到数据
  20 + public Set<Long> calculateTaskCandidateUsers(TaskEntity task) {
  21 + return calculateTaskCandidateUsers(task, 1);
  22 + }
  23 +
  24 + @Override
  25 + public BpmTaskRuleScriptEnum getEnum() {
  26 + return BpmTaskRuleScriptEnum.LEADER_X1;
  27 + }
  28 +
  29 +}
... ...
yudao-module-bpm/yudao-module-bpm-impl-flowable/src/main/java/cn/iocoder/yudao/module/bpm/framework/flowable/core/behavior/script/impl/BpmTaskAssignLeaderX2Script.java 0 → 100644
  1 +package cn.iocoder.yudao.module.bpm.framework.flowable.core.behavior.script.impl;
  2 +
  3 +import cn.iocoder.yudao.framework.datapermission.core.annotation.DataPermission;
  4 +import cn.iocoder.yudao.module.bpm.enums.definition.BpmTaskRuleScriptEnum;
  5 +import org.flowable.task.service.impl.persistence.entity.TaskEntity;
  6 +import org.springframework.stereotype.Component;
  7 +
  8 +import java.util.Set;
  9 +
  10 +/**
  11 + * 分配给发起人的二级 Leader 审批的 Script 实现类
  12 + *
  13 + * @author 芋道源码
  14 + */
  15 +@Component
  16 +public class BpmTaskAssignLeaderX2Script extends BpmTaskAssignLeaderAbstractScript {
  17 +
  18 +
  19 + @Override
  20 + @DataPermission(enable = false) // 不需要处理数据权限, 不然会有问题,查询不到数据
  21 + public Set<Long> calculateTaskCandidateUsers(TaskEntity task) {
  22 + return calculateTaskCandidateUsers(task, 2);
  23 + }
  24 +
  25 + @Override
  26 + public BpmTaskRuleScriptEnum getEnum() {
  27 + return BpmTaskRuleScriptEnum.LEADER_X2;
  28 + }
  29 +
  30 +}
... ...
yudao-module-bpm/yudao-module-bpm-impl-flowable/src/main/java/cn/iocoder/yudao/module/bpm/framework/flowable/core/behavior/script/impl/BpmTaskAssignStartUserScript.java 0 → 100644
  1 +package cn.iocoder.yudao.module.bpm.framework.flowable.core.behavior.script.impl;
  2 +
  3 +import cn.iocoder.yudao.framework.common.util.collection.SetUtils;
  4 +import cn.iocoder.yudao.framework.common.util.number.NumberUtils;
  5 +import cn.iocoder.yudao.module.bpm.enums.definition.BpmTaskRuleScriptEnum;
  6 +
  7 +import cn.iocoder.yudao.module.bpm.framework.flowable.core.behavior.script.BpmTaskAssignScript;
  8 +import cn.iocoder.yudao.module.bpm.service.task.BpmProcessInstanceService;
  9 +import org.flowable.engine.runtime.ProcessInstance;
  10 +import org.flowable.task.service.impl.persistence.entity.TaskEntity;
  11 +import org.springframework.context.annotation.Lazy;
  12 +import org.springframework.stereotype.Component;
  13 +
  14 +import javax.annotation.Resource;
  15 +import java.util.Set;
  16 +
  17 +/**
  18 + * 分配给发起人审批的 Script 实现类
  19 + *
  20 + * @author 芋道源码
  21 + */
  22 +@Component
  23 +public class BpmTaskAssignStartUserScript implements BpmTaskAssignScript {
  24 +
  25 + @Resource
  26 + @Lazy // 解决循环依赖
  27 + private BpmProcessInstanceService bpmProcessInstanceService;
  28 +
  29 + @Override
  30 + public Set<Long> calculateTaskCandidateUsers(TaskEntity task) {
  31 + ProcessInstance processInstance = bpmProcessInstanceService.getProcessInstance(task.getProcessInstanceId());
  32 + Long startUserId = NumberUtils.parseLong(processInstance.getStartUserId());
  33 + return SetUtils.asSet(startUserId);
  34 + }
  35 +
  36 + @Override
  37 + public BpmTaskRuleScriptEnum getEnum() {
  38 + return BpmTaskRuleScriptEnum.START_USER;
  39 + }
  40 +
  41 +}
... ...
yudao-module-bpm/yudao-module-bpm-impl-flowable/src/main/java/cn/iocoder/yudao/module/bpm/framework/flowable/core/listener/BpmProcessInstanceEventListener.java 0 → 100644
  1 +package cn.iocoder.yudao.module.bpm.framework.flowable.core.listener;
  2 +
  3 +import cn.iocoder.yudao.module.bpm.dal.dataobject.task.BpmProcessInstanceExtDO;
  4 +import cn.iocoder.yudao.module.bpm.service.task.BpmProcessInstanceService;
  5 +import com.google.common.collect.ImmutableSet;
  6 +import org.flowable.common.engine.api.delegate.event.FlowableEngineEntityEvent;
  7 +import org.flowable.common.engine.api.delegate.event.FlowableEngineEventType;
  8 +import org.flowable.engine.delegate.event.AbstractFlowableEngineEventListener;
  9 +import org.flowable.engine.delegate.event.FlowableCancelledEvent;
  10 +import org.flowable.engine.delegate.event.FlowableProcessStartedEvent;
  11 +import org.flowable.engine.runtime.ProcessInstance;
  12 +import org.springframework.context.annotation.Lazy;
  13 +import org.springframework.stereotype.Component;
  14 +
  15 +import javax.annotation.Resource;
  16 +import java.util.Set;
  17 +/**
  18 + * 监听 {@link ProcessInstance} 的开始与完成,创建与更新对应的 {@link BpmProcessInstanceExtDO} 记录
  19 + *
  20 + * @author jason
  21 + */
  22 +@Component
  23 +public class BpmProcessInstanceEventListener extends AbstractFlowableEngineEventListener {
  24 +
  25 + @Resource
  26 + @Lazy
  27 + private BpmProcessInstanceService processInstanceService;
  28 +
  29 + public static final Set<FlowableEngineEventType> PROCESS_INSTANCE_EVENTS = ImmutableSet.<FlowableEngineEventType>builder()
  30 + .add(FlowableEngineEventType.PROCESS_CREATED)
  31 + .add(FlowableEngineEventType.PROCESS_CANCELLED)
  32 + .add(FlowableEngineEventType.PROCESS_COMPLETED)
  33 + .build();
  34 +
  35 + public BpmProcessInstanceEventListener(){
  36 + super(PROCESS_INSTANCE_EVENTS);
  37 + }
  38 +
  39 + @Override
  40 + protected void processCreated(FlowableEngineEntityEvent event) {
  41 + processInstanceService.createProcessInstanceExt((ProcessInstance)event.getEntity());
  42 + }
  43 +
  44 + @Override
  45 + protected void processCancelled(FlowableCancelledEvent event) {
  46 + processInstanceService.updateProcessInstanceExtCancel(event);
  47 + }
  48 +
  49 + @Override
  50 + protected void processCompleted(FlowableEngineEntityEvent event) {
  51 + processInstanceService.updateProcessInstanceExtComplete((ProcessInstance)event.getEntity());
  52 + }
  53 +}
... ...
yudao-module-bpm/yudao-module-bpm-impl-flowable/src/main/java/cn/iocoder/yudao/module/bpm/framework/flowable/core/listener/BpmTaskEventListener.java 0 → 100644
  1 +package cn.iocoder.yudao.module.bpm.framework.flowable.core.listener;
  2 +
  3 +import cn.iocoder.yudao.module.bpm.dal.dataobject.task.BpmTaskExtDO;
  4 +import cn.iocoder.yudao.module.bpm.service.task.BpmTaskService;
  5 +import com.google.common.collect.ImmutableSet;
  6 +import org.flowable.common.engine.api.delegate.event.FlowableEngineEntityEvent;
  7 +import org.flowable.common.engine.api.delegate.event.FlowableEngineEventType;
  8 +import org.flowable.engine.delegate.event.AbstractFlowableEngineEventListener;
  9 +import org.flowable.task.api.Task;
  10 +import org.springframework.context.annotation.Lazy;
  11 +import org.springframework.stereotype.Component;
  12 +
  13 +import javax.annotation.Resource;
  14 +import java.util.Set;
  15 +
  16 +/**
  17 + * 监听 {@link org.flowable.task.api.Task} 的开始与完成,创建与更新对应的 {@link BpmTaskExtDO} 记录
  18 + *
  19 + * @author jason
  20 + */
  21 +@Component
  22 +public class BpmTaskEventListener extends AbstractFlowableEngineEventListener {
  23 +
  24 + @Resource
  25 + @Lazy // 解决循环依赖
  26 + private BpmTaskService taskService;
  27 +
  28 + public static final Set<FlowableEngineEventType> TASK_EVENTS = ImmutableSet.<FlowableEngineEventType>builder()
  29 + .add(FlowableEngineEventType.TASK_CREATED)
  30 + .add(FlowableEngineEventType.TASK_ASSIGNED)
  31 + .add(FlowableEngineEventType.TASK_COMPLETED)
  32 + .build();
  33 +
  34 + public BpmTaskEventListener(){
  35 + super(TASK_EVENTS);
  36 + }
  37 +
  38 + @Override
  39 + protected void taskCreated(FlowableEngineEntityEvent event) {
  40 + taskService.createTaskExt((Task) event.getEntity());
  41 + }
  42 +
  43 + @Override
  44 + protected void taskCompleted(FlowableEngineEntityEvent event) {
  45 + taskService.updateTaskExtComplete((Task)event.getEntity());
  46 + }
  47 +
  48 + @Override
  49 + protected void taskAssigned(FlowableEngineEntityEvent event) {
  50 + taskService.updateTaskExtAssign((Task)event.getEntity());
  51 + }
  52 +}
... ...
yudao-module-bpm/yudao-module-bpm-impl-flowable/src/main/java/cn/iocoder/yudao/module/bpm/framework/package-info.java 0 → 100644
  1 +/**
  2 + * 属于 bpm 模块的 framework 封装
  3 + *
  4 + * @author 芋道源码
  5 + */
  6 +package cn.iocoder.yudao.module.bpm.framework;
... ...
yudao-module-bpm/yudao-module-bpm-impl-flowable/src/main/java/cn/iocoder/yudao/module/bpm/package-info.java 0 → 100644
  1 +/**
  2 + * bpm 包下,业务流程管理(Business Process Management),我们放工作流的功能,基于 activiti 7 版本实现。
  3 + * 例如说:流程定义、表单配置、审核中心(我的申请、我的待办、我的已办)等等
  4 + *
  5 + * bpm 解释:https://baike.baidu.com/item/BPM/1933
  6 + *
  7 + * 1. Controller URL:以 /bpm/ 开头,避免和其它 Module 冲突
  8 + * 2. DataObject 表名:以 bpm_ 开头,方便在数据库中区分
  9 + *
  10 + * 注意,由于 Bpm 模块下,容易和其它模块重名,所以类名都加载 Pay 的前缀~
  11 + */
  12 +package cn.iocoder.yudao.module.bpm;
... ...
yudao-module-bpm/yudao-module-bpm-impl-flowable/src/main/java/cn/iocoder/yudao/module/bpm/service/definition/BpmModelService.java 0 → 100644
  1 +package cn.iocoder.yudao.module.bpm.service.definition;
  2 +
  3 +import cn.iocoder.yudao.framework.common.pojo.PageResult;
  4 +import cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.model.*;
  5 +import org.flowable.bpmn.model.BpmnModel;
  6 +
  7 +import javax.validation.Valid;
  8 +
  9 +/**
  10 + * Flowable流程模型接口
  11 + *
  12 + * @author yunlongn
  13 + */
  14 +public interface BpmModelService {
  15 + /**
  16 + * 获得流程模型分页
  17 + *
  18 + * @param pageVO 分页查询
  19 + * @return 流程模型分页
  20 + */
  21 + PageResult<BpmModelPageItemRespVO> getModelPage(BpmModelPageReqVO pageVO);
  22 +
  23 + /**
  24 + * 创建流程模型
  25 + *
  26 + * @param modelVO 创建信息
  27 + * @param bpmnXml BPMN XML
  28 + * @return 创建的流程模型的编号
  29 + */
  30 + String createModel(@Valid BpmModelCreateReqVO modelVO, String bpmnXml);
  31 +
  32 + /**
  33 + * 获得流程模块
  34 + *
  35 + * @param id 编号
  36 + * @return 流程模型
  37 + */
  38 + BpmModelRespVO getModel(String id);
  39 +
  40 + /**
  41 + * 修改流程模型
  42 + *
  43 + * @param updateReqVO 更新信息
  44 + */
  45 + void updateModel(@Valid BpmModelUpdateReqVO updateReqVO);
  46 +
  47 + /**
  48 + * 将流程模型,部署成一个流程定义
  49 + *
  50 + * @param id 编号
  51 + */
  52 + void deployModel(String id);
  53 +
  54 + /**
  55 + * 删除模型
  56 + *
  57 + * @param id 编号
  58 + */
  59 + void deleteModel(String id);
  60 +
  61 + /**
  62 + * 修改模型的状态,实际更新的部署的流程定义的状态
  63 + *
  64 + * @param id 编号
  65 + * @param state 状态
  66 + */
  67 + void updateModelState(String id, Integer state);
  68 +
  69 + /**
  70 + * 获得流程模型编号对应的 BPMN Model
  71 + *
  72 + * @param id 流程模型编号
  73 + * @return BPMN Model
  74 + */
  75 + BpmnModel getBpmnModel(String id);
  76 +
  77 +}
... ...
yudao-module-bpm/yudao-module-bpm-impl-flowable/src/main/java/cn/iocoder/yudao/module/bpm/service/definition/BpmModelServiceImpl.java 0 → 100644
  1 +package cn.iocoder.yudao.module.bpm.service.definition;
  2 +
  3 +import cn.hutool.core.util.ArrayUtil;
  4 +import cn.hutool.core.util.StrUtil;
  5 +import cn.iocoder.yudao.framework.common.pojo.PageResult;
  6 +import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils;
  7 +import cn.iocoder.yudao.framework.common.util.json.JsonUtils;
  8 +import cn.iocoder.yudao.framework.common.util.object.PageUtils;
  9 +import cn.iocoder.yudao.framework.common.util.validation.ValidationUtils;
  10 +import cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.model.*;
  11 +import cn.iocoder.yudao.module.bpm.convert.definition.BpmModelConvert;
  12 +import cn.iocoder.yudao.module.bpm.dal.dataobject.definition.BpmFormDO;
  13 +import cn.iocoder.yudao.module.bpm.enums.definition.BpmModelFormTypeEnum;
  14 +import cn.iocoder.yudao.module.bpm.service.definition.dto.BpmModelMetaInfoRespDTO;
  15 +import cn.iocoder.yudao.module.bpm.service.definition.dto.BpmProcessDefinitionCreateReqDTO;
  16 +import lombok.extern.slf4j.Slf4j;
  17 +import org.flowable.bpmn.converter.BpmnXMLConverter;
  18 +import org.flowable.bpmn.model.BpmnModel;
  19 +import org.flowable.common.engine.impl.db.SuspensionState;
  20 +import org.flowable.common.engine.impl.util.io.BytesStreamSource;
  21 +import org.flowable.engine.RepositoryService;
  22 +import org.flowable.engine.repository.Deployment;
  23 +import org.flowable.engine.repository.Model;
  24 +import org.flowable.engine.repository.ModelQuery;
  25 +import org.flowable.engine.repository.ProcessDefinition;
  26 +import org.springframework.stereotype.Service;
  27 +import org.springframework.transaction.annotation.Transactional;
  28 +import org.springframework.util.ObjectUtils;
  29 +import org.springframework.validation.annotation.Validated;
  30 +
  31 +import javax.annotation.Resource;
  32 +import javax.validation.Valid;
  33 +import java.util.*;
  34 +
  35 +import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
  36 +import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertMap;
  37 +import static cn.iocoder.yudao.module.bpm.enums.ErrorCodeConstants.*;
  38 +
  39 +/**
  40 + * Flowable流程模型实现
  41 + * 主要进行 Flowable {@link Model} 的维护
  42 + *
  43 + * @author yunlongn
  44 + * @author 芋道源码
  45 + * @author jason
  46 + */
  47 +@Service
  48 +@Validated
  49 +@Slf4j
  50 +public class BpmModelServiceImpl implements BpmModelService {
  51 +
  52 + @Resource
  53 + private RepositoryService repositoryService;
  54 + @Resource
  55 + private BpmProcessDefinitionService processDefinitionService;
  56 + @Resource
  57 + private BpmFormService bpmFormService;
  58 + @Resource
  59 + private BpmTaskAssignRuleService taskAssignRuleService;
  60 +
  61 + @Override
  62 + public PageResult<BpmModelPageItemRespVO> getModelPage(BpmModelPageReqVO pageVO) {
  63 + ModelQuery modelQuery = repositoryService.createModelQuery();
  64 + if (StrUtil.isNotBlank(pageVO.getKey())) {
  65 + modelQuery.modelKey(pageVO.getKey());
  66 + }
  67 + if (StrUtil.isNotBlank(pageVO.getName())) {
  68 + modelQuery.modelNameLike("%" + pageVO.getName() + "%"); // 模糊匹配
  69 + }
  70 + if (StrUtil.isNotBlank(pageVO.getCategory())) {
  71 + modelQuery.modelCategory(pageVO.getCategory());
  72 + }
  73 + // 执行查询
  74 + List<Model> models = modelQuery.orderByCreateTime().desc()
  75 + .listPage(PageUtils.getStart(pageVO), pageVO.getPageSize());
  76 +
  77 + // 获得 Form Map
  78 + Set<Long> formIds = CollectionUtils.convertSet(models, model -> {
  79 + BpmModelMetaInfoRespDTO metaInfo = JsonUtils.parseObject(model.getMetaInfo(), BpmModelMetaInfoRespDTO.class);
  80 + return metaInfo != null ? metaInfo.getFormId() : null;
  81 + });
  82 + Map<Long, BpmFormDO> formMap = bpmFormService.getFormMap(formIds);
  83 +
  84 + // 获得 Deployment Map
  85 + Set<String> deploymentIds = new HashSet<>();
  86 + models.forEach(model -> CollectionUtils.addIfNotNull(deploymentIds, model.getDeploymentId()));
  87 + Map<String, Deployment> deploymentMap = processDefinitionService.getDeploymentMap(deploymentIds);
  88 + // 获得 ProcessDefinition Map
  89 + List<ProcessDefinition> processDefinitions = processDefinitionService.getProcessDefinitionListByDeploymentIds(deploymentIds);
  90 + Map<String, ProcessDefinition> processDefinitionMap = convertMap(processDefinitions, ProcessDefinition::getDeploymentId);
  91 +
  92 + // 拼接结果
  93 + long modelCount = modelQuery.count();
  94 + return new PageResult<>(BpmModelConvert.INSTANCE.convertList(models, formMap, deploymentMap, processDefinitionMap), modelCount);
  95 + }
  96 +
  97 + @Override
  98 + @Transactional(rollbackFor = Exception.class)
  99 + public String createModel(@Valid BpmModelCreateReqVO createReqVO, String bpmnXml) {
  100 + checkKeyNCName(createReqVO.getKey());
  101 + // 校验流程标识已经存在
  102 + Model keyModel = this.getModelByKey(createReqVO.getKey());
  103 + if (keyModel != null) {
  104 + throw exception(MODEL_KEY_EXISTS, createReqVO.getKey());
  105 + }
  106 +
  107 + // 创建流程定义
  108 + Model model = repositoryService.newModel();
  109 + BpmModelConvert.INSTANCE.copy(model, createReqVO);
  110 + // 保存流程定义
  111 + repositoryService.saveModel(model);
  112 + // 保存 BPMN XML
  113 + saveModelBpmnXml(model, bpmnXml);
  114 + return model.getId();
  115 + }
  116 +
  117 + private Model getModelByKey(String key) {
  118 + return repositoryService.createModelQuery().modelKey(key).singleResult();
  119 + }
  120 +
  121 + @Override
  122 + public BpmModelRespVO getModel(String id) {
  123 + Model model = repositoryService.getModel(id);
  124 + if (model == null) {
  125 + return null;
  126 + }
  127 + BpmModelRespVO modelRespVO = BpmModelConvert.INSTANCE.convert(model);
  128 + // 拼接 bpmn XML
  129 + byte[] bpmnBytes = repositoryService.getModelEditorSource(id);
  130 + modelRespVO.setBpmnXml(StrUtil.utf8Str(bpmnBytes));
  131 + return modelRespVO;
  132 + }
  133 +
  134 + @Override
  135 + @Transactional(rollbackFor = Exception.class) // 因为进行多个操作,所以开启事务
  136 + public void updateModel(@Valid BpmModelUpdateReqVO updateReqVO) {
  137 + // 校验流程模型存在
  138 + Model model = repositoryService.getModel(updateReqVO.getId());
  139 + if (model == null) {
  140 + throw exception(MODEL_NOT_EXISTS);
  141 + }
  142 +
  143 + // 修改流程定义
  144 + BpmModelConvert.INSTANCE.copy(model, updateReqVO);
  145 + // 更新模型
  146 + repositoryService.saveModel(model);
  147 + // 更新 BPMN XML
  148 + saveModelBpmnXml(model, updateReqVO.getBpmnXml());
  149 + }
  150 +
  151 + @Override
  152 + @Transactional(rollbackFor = Exception.class) // 因为进行多个操作,所以开启事务
  153 + public void deployModel(String id) {
  154 + // 校验流程模型存在
  155 + Model model = repositoryService.getModel(id);
  156 + if (ObjectUtils.isEmpty(model)) {
  157 + throw exception(MODEL_NOT_EXISTS);
  158 + }
  159 + // 校验流程图
  160 + byte[] bpmnBytes = repositoryService.getModelEditorSource(model.getId());
  161 + if (bpmnBytes == null) {
  162 + throw exception(MODEL_NOT_EXISTS);
  163 + }
  164 + // TODO 芋艿:校验流程图的有效性;例如说,是否有开始的元素,是否有结束的元素;
  165 + // 校验表单已配
  166 + BpmFormDO form = checkFormConfig(model.getMetaInfo());
  167 + //校验任务分配规则已配置
  168 + taskAssignRuleService.checkTaskAssignRuleAllConfig(id);
  169 +
  170 + BpmProcessDefinitionCreateReqDTO definitionCreateReqDTO = BpmModelConvert.INSTANCE.convert2(model, form).setBpmnBytes(bpmnBytes);
  171 + //校验模型是否发生修改。如果未修改,则不允许创建
  172 + if (processDefinitionService.isProcessDefinitionEquals(definitionCreateReqDTO)) { // 流程定义的信息相等
  173 + ProcessDefinition oldProcessInstance = processDefinitionService.getProcessDefinitionByDeploymentId(model.getDeploymentId());
  174 + if (oldProcessInstance != null && taskAssignRuleService.isTaskAssignRulesEquals(model.getId(), oldProcessInstance.getId())) {
  175 + throw exception(MODEL_DEPLOY_FAIL_TASK_INFO_EQUALS);
  176 + }
  177 + }
  178 + // 创建流程定义
  179 + String definitionId = processDefinitionService.createProcessDefinition(definitionCreateReqDTO);
  180 +
  181 + // 将老的流程定义进行挂起。也就是说,只有最新部署的流程定义,才可以发起任务。
  182 + updateProcessDefinitionSuspended(model.getDeploymentId());
  183 +
  184 + // 更新 model 的 deploymentId,进行关联
  185 + ProcessDefinition definition = processDefinitionService.getProcessDefinition(definitionId);
  186 + model.setDeploymentId(definition.getDeploymentId());
  187 + repositoryService.saveModel(model);
  188 +
  189 + //复制任务分配规则
  190 + taskAssignRuleService.copyTaskAssignRules(id, definition.getId());
  191 + }
  192 +
  193 +
  194 + @Override
  195 + @Transactional(rollbackFor = Exception.class)
  196 + public void deleteModel(String id) {
  197 + // 校验流程模型存在
  198 + Model model = repositoryService.getModel(id);
  199 + if (model == null) {
  200 + throw exception(MODEL_NOT_EXISTS);
  201 + }
  202 + // 执行删除
  203 + repositoryService.deleteModel(id);
  204 + // 禁用流程实例
  205 + updateProcessDefinitionSuspended(model.getDeploymentId());
  206 + }
  207 +
  208 + @Override
  209 + public void updateModelState(String id, Integer state) {
  210 + // 校验流程模型存在
  211 + Model model = repositoryService.getModel(id);
  212 + if (model == null) {
  213 + throw exception(MODEL_NOT_EXISTS);
  214 + }
  215 + // 校验流程定义存在
  216 + ProcessDefinition definition = processDefinitionService.getProcessDefinitionByDeploymentId(model.getDeploymentId());
  217 + if (definition == null) {
  218 + throw exception(PROCESS_DEFINITION_NOT_EXISTS);
  219 + }
  220 +
  221 + // 更新状态
  222 + processDefinitionService.updateProcessDefinitionState(definition.getId(), state);
  223 + }
  224 +
  225 + @Override
  226 + public BpmnModel getBpmnModel(String id) {
  227 + byte[] bpmnBytes = repositoryService.getModelEditorSource(id);
  228 + if (ArrayUtil.isEmpty(bpmnBytes)) {
  229 + return null;
  230 + }
  231 + BpmnXMLConverter converter = new BpmnXMLConverter();
  232 + return converter.convertToBpmnModel(new BytesStreamSource(bpmnBytes), true, true);
  233 + }
  234 +
  235 + private void checkKeyNCName(String key) {
  236 + if (!ValidationUtils.isXmlNCName(key)) {
  237 + throw exception(MODEL_KEY_VALID);
  238 + }
  239 + }
  240 +
  241 + /**
  242 + * 校验流程表单已配置
  243 + *
  244 + * @param metaInfoStr 流程模型 metaInfo 字段
  245 + * @return 流程表单
  246 + */
  247 + private BpmFormDO checkFormConfig(String metaInfoStr) {
  248 + BpmModelMetaInfoRespDTO metaInfo = JsonUtils.parseObject(metaInfoStr, BpmModelMetaInfoRespDTO.class);
  249 + if (metaInfo == null || metaInfo.getFormType() == null) {
  250 + throw exception(MODEL_DEPLOY_FAIL_FORM_NOT_CONFIG);
  251 + }
  252 + // 校验表单存在
  253 + if (Objects.equals(metaInfo.getFormType(), BpmModelFormTypeEnum.NORMAL.getType())) {
  254 + BpmFormDO form = bpmFormService.getForm(metaInfo.getFormId());
  255 + if (form == null) {
  256 + throw exception(FORM_NOT_EXISTS);
  257 + }
  258 + return form;
  259 + }
  260 + return null;
  261 + }
  262 +
  263 + private void saveModelBpmnXml(Model model, String bpmnXml) {
  264 + if (StrUtil.isEmpty(bpmnXml)) {
  265 + return;
  266 + }
  267 + repositoryService.addModelEditorSource(model.getId(), StrUtil.utf8Bytes(bpmnXml));
  268 + }
  269 +
  270 + /**
  271 + * 挂起 deploymentId 对应的流程定义。 这里一个deploymentId 只关联一个流程定义
  272 + * @param deploymentId 流程发布Id.
  273 + */
  274 + private void updateProcessDefinitionSuspended(String deploymentId) {
  275 + if (StrUtil.isEmpty(deploymentId)) {
  276 + return;
  277 + }
  278 + ProcessDefinition oldDefinition = processDefinitionService.getProcessDefinitionByDeploymentId(deploymentId);
  279 + if (oldDefinition == null) {
  280 + return;
  281 + }
  282 + processDefinitionService.updateProcessDefinitionState(oldDefinition.getId(), SuspensionState.SUSPENDED.getStateCode());
  283 + }
  284 +
  285 +
  286 +}
... ...
yudao-module-bpm/yudao-module-bpm-impl-flowable/src/main/java/cn/iocoder/yudao/module/bpm/service/definition/BpmProcessDefinitionService.java 0 → 100644
  1 +package cn.iocoder.yudao.module.bpm.service.definition;
  2 +
  3 +import cn.iocoder.yudao.framework.common.pojo.PageResult;
  4 +import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils;
  5 +import cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.process.BpmProcessDefinitionListReqVO;
  6 +import cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.process.BpmProcessDefinitionPageItemRespVO;
  7 +import cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.process.BpmProcessDefinitionPageReqVO;
  8 +import cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.process.BpmProcessDefinitionRespVO;
  9 +import cn.iocoder.yudao.module.bpm.dal.dataobject.definition.BpmProcessDefinitionExtDO;
  10 +import cn.iocoder.yudao.module.bpm.service.definition.dto.BpmProcessDefinitionCreateReqDTO;
  11 +import org.flowable.bpmn.model.BpmnModel;
  12 +import org.flowable.engine.repository.Deployment;
  13 +import org.flowable.engine.repository.ProcessDefinition;
  14 +
  15 +import javax.validation.Valid;
  16 +import java.util.List;
  17 +import java.util.Map;
  18 +import java.util.Set;
  19 +/**
  20 + * Flowable流程定义接口
  21 + *
  22 + * @author yunlong.li
  23 + * @author ZJQ
  24 + * @author 芋道源码
  25 + */
  26 +public interface BpmProcessDefinitionService {
  27 +
  28 + /**
  29 + * 获得流程定义分页
  30 + *
  31 + * @param pageReqVO 分页入参
  32 + * @return 流程定义 Page
  33 + */
  34 + PageResult<BpmProcessDefinitionPageItemRespVO> getProcessDefinitionPage(BpmProcessDefinitionPageReqVO pageReqVO);
  35 +
  36 + /**
  37 + * 获得流程定义列表
  38 + *
  39 + * @param listReqVO 列表入参
  40 + * @return 流程定义列表
  41 + */
  42 + List<BpmProcessDefinitionRespVO> getProcessDefinitionList(BpmProcessDefinitionListReqVO listReqVO);
  43 +
  44 + /**
  45 + * 创建流程定义
  46 + *
  47 + * @param createReqDTO 创建信息
  48 + * @return 流程编号
  49 + */
  50 + String createProcessDefinition(@Valid BpmProcessDefinitionCreateReqDTO createReqDTO);
  51 +
  52 + /**
  53 + * 更新流程定义状态
  54 + *
  55 + * @param id 流程定义的编号
  56 + * @param state 状态
  57 + */
  58 + void updateProcessDefinitionState(String id, Integer state);
  59 +
  60 + /**
  61 + * 获得流程定义对应的 BPMN XML
  62 + *
  63 + * @param id 流程定义编号
  64 + * @return BPMN XML
  65 + */
  66 + String getProcessDefinitionBpmnXML(String id);
  67 +
  68 + /**
  69 + * 获得需要创建的流程定义,是否和当前激活的流程定义相等
  70 + *
  71 + * @param createReqDTO 创建信息
  72 + * @return 是否相等
  73 + */
  74 + boolean isProcessDefinitionEquals(@Valid BpmProcessDefinitionCreateReqDTO createReqDTO);
  75 +
  76 + /**
  77 + * 获得编号对应的 BpmProcessDefinitionExtDO
  78 + *
  79 + * @param id 编号
  80 + * @return 流程定义拓展
  81 + */
  82 + BpmProcessDefinitionExtDO getProcessDefinitionExt(String id);
  83 +
  84 + /**
  85 + * 获得编号对应的 ProcessDefinition
  86 + *
  87 + * @param id 编号
  88 + * @return 流程定义
  89 + */
  90 + ProcessDefinition getProcessDefinition(String id);
  91 +
  92 + /**
  93 + * 获得编号对应的 ProcessDefinition
  94 + *
  95 + * 相比 {@link #getProcessDefinition(String)} 方法,category 的取值是正确
  96 + *
  97 + * @param id 编号
  98 + * @return 流程定义
  99 + */
  100 + ProcessDefinition getProcessDefinition2(String id);
  101 +
  102 + /**
  103 + * 获得 deploymentId 对应的 ProcessDefinition
  104 + *
  105 + * @param deploymentId 部署编号
  106 + * @return 流程定义
  107 + */
  108 + ProcessDefinition getProcessDefinitionByDeploymentId(String deploymentId);
  109 +
  110 + /**
  111 + * 获得 deploymentIds 对应的 ProcessDefinition 数组
  112 + *
  113 + * @param deploymentIds 部署编号的数组
  114 + * @return 流程定义的数组
  115 + */
  116 + List<ProcessDefinition> getProcessDefinitionListByDeploymentIds(Set<String> deploymentIds);
  117 +
  118 + /**
  119 + * 获得流程定义标识对应的激活的流程定义
  120 + *
  121 + * @param key 流程定义的标识
  122 + * @return 流程定义
  123 + */
  124 + ProcessDefinition getActiveProcessDefinition(String key);
  125 +
  126 + /**
  127 + * 获得 ids 对应的 Deployment Map
  128 + *
  129 + * @param ids 部署编号的数组
  130 + * @return 流程部署 Map
  131 + */
  132 + default Map<String, Deployment> getDeploymentMap(Set<String> ids) {
  133 + return CollectionUtils.convertMap(getDeployments(ids), Deployment::getId);
  134 + }
  135 +
  136 + /**
  137 + * 获得 ids 对应的 Deployment 数组
  138 + *
  139 + * @param ids 部署编号的数组
  140 + * @return 流程部署的数组
  141 + */
  142 + List<Deployment> getDeployments(Set<String> ids);
  143 +
  144 + /**
  145 + * 获得 id 对应的 Deployment
  146 + *
  147 + * @param id 部署编号
  148 + * @return 流程部署
  149 + */
  150 + Deployment getDeployment(String id);
  151 +
  152 + /**
  153 + * 获得 Bpmn 模型
  154 + *
  155 + * @param processDefinitionId 流程定义的编号
  156 + * @return Bpmn 模型
  157 + */
  158 + BpmnModel getBpmnModel(String processDefinitionId);
  159 +}
... ...
yudao-module-bpm/yudao-module-bpm-impl-flowable/src/main/java/cn/iocoder/yudao/module/bpm/service/definition/BpmProcessDefinitionServiceImpl.java 0 → 100644
  1 +package cn.iocoder.yudao.module.bpm.service.definition;
  2 +
  3 +import cn.hutool.core.collection.CollUtil;
  4 +import cn.hutool.core.util.ObjectUtil;
  5 +import cn.hutool.core.util.StrUtil;
  6 +import cn.iocoder.yudao.framework.common.pojo.PageResult;
  7 +import cn.iocoder.yudao.framework.common.util.object.PageUtils;
  8 +import cn.iocoder.yudao.framework.flowable.core.util.FlowableUtils;
  9 +import cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.process.BpmProcessDefinitionListReqVO;
  10 +import cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.process.BpmProcessDefinitionPageItemRespVO;
  11 +import cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.process.BpmProcessDefinitionPageReqVO;
  12 +import cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.process.BpmProcessDefinitionRespVO;
  13 +import cn.iocoder.yudao.module.bpm.convert.definition.BpmProcessDefinitionConvert;
  14 +import cn.iocoder.yudao.module.bpm.dal.dataobject.definition.BpmFormDO;
  15 +import cn.iocoder.yudao.module.bpm.dal.dataobject.definition.BpmProcessDefinitionExtDO;
  16 +import cn.iocoder.yudao.module.bpm.dal.mysql.definition.BpmProcessDefinitionExtMapper;
  17 +import cn.iocoder.yudao.module.bpm.service.definition.dto.BpmProcessDefinitionCreateReqDTO;
  18 +import lombok.extern.slf4j.Slf4j;
  19 +import org.flowable.bpmn.converter.BpmnXMLConverter;
  20 +import org.flowable.bpmn.model.BpmnModel;
  21 +import org.flowable.common.engine.impl.db.SuspensionState;
  22 +import org.flowable.common.engine.impl.util.io.BytesStreamSource;
  23 +import org.flowable.engine.RepositoryService;
  24 +import org.flowable.engine.repository.Deployment;
  25 +import org.flowable.engine.repository.ProcessDefinition;
  26 +import org.flowable.engine.repository.ProcessDefinitionQuery;
  27 +import org.springframework.stereotype.Service;
  28 +import org.springframework.validation.annotation.Validated;
  29 +
  30 +import javax.annotation.Resource;
  31 +import javax.validation.Valid;
  32 +import java.util.*;
  33 +
  34 +import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
  35 +import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.*;
  36 +import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertMap;
  37 +import static cn.iocoder.yudao.module.bpm.enums.ErrorCodeConstants.PROCESS_DEFINITION_KEY_NOT_MATCH;
  38 +import static cn.iocoder.yudao.module.bpm.enums.ErrorCodeConstants.PROCESS_DEFINITION_NAME_NOT_MATCH;
  39 +import static java.util.Collections.emptyList;
  40 +
  41 +/**
  42 + * 流程定义实现
  43 + * 主要进行 Flowable {@link ProcessDefinition} 和 {@link Deployment} 的维护
  44 + *
  45 + * @author yunlongn
  46 + * @author ZJQ
  47 + * @author 芋道源码
  48 + */
  49 +@Service
  50 +@Validated
  51 +@Slf4j
  52 +public class BpmProcessDefinitionServiceImpl implements BpmProcessDefinitionService {
  53 +
  54 + private static final String BPMN_FILE_SUFFIX = ".bpmn";
  55 +
  56 + @Resource
  57 + private RepositoryService repositoryService;
  58 +
  59 + @Resource
  60 + private BpmProcessDefinitionExtMapper processDefinitionMapper;
  61 +
  62 + @Resource
  63 + private BpmFormService formService;
  64 +
  65 + @Override
  66 + public ProcessDefinition getProcessDefinition(String id) {
  67 + return repositoryService.getProcessDefinition(id);
  68 + }
  69 +
  70 + @Override
  71 + public ProcessDefinition getProcessDefinition2(String id) {
  72 + return repositoryService.createProcessDefinitionQuery().processDefinitionId(id).singleResult();
  73 + }
  74 +
  75 + @Override
  76 + public ProcessDefinition getProcessDefinitionByDeploymentId(String deploymentId) {
  77 + if (StrUtil.isEmpty(deploymentId)) {
  78 + return null;
  79 + }
  80 + return repositoryService.createProcessDefinitionQuery().deploymentId(deploymentId).singleResult();
  81 + }
  82 +
  83 + @Override
  84 + public List<ProcessDefinition> getProcessDefinitionListByDeploymentIds(Set<String> deploymentIds) {
  85 + if (CollUtil.isEmpty(deploymentIds)) {
  86 + return emptyList();
  87 + }
  88 + return repositoryService.createProcessDefinitionQuery().deploymentIds(deploymentIds).list();
  89 + }
  90 +
  91 + @Override
  92 + public ProcessDefinition getActiveProcessDefinition(String key) {
  93 + return repositoryService.createProcessDefinitionQuery().processDefinitionKey(key).active().singleResult();
  94 + }
  95 +
  96 + @Override
  97 + public List<Deployment> getDeployments(Set<String> ids) {
  98 + if (CollUtil.isEmpty(ids)) {
  99 + return emptyList();
  100 + }
  101 + List<Deployment> list = new ArrayList<>(ids.size());
  102 + for (String id : ids) {
  103 + addIfNotNull(list, getDeployment(id));
  104 + }
  105 + return list;
  106 + }
  107 +
  108 + @Override
  109 + public Deployment getDeployment(String id) {
  110 + if (StrUtil.isEmpty(id)) {
  111 + return null;
  112 + }
  113 + return repositoryService.createDeploymentQuery().deploymentId(id).singleResult();
  114 + }
  115 +
  116 + @Override
  117 + public BpmnModel getBpmnModel(String processDefinitionId) {
  118 + return repositoryService.getBpmnModel(processDefinitionId);
  119 + }
  120 +
  121 + @Override
  122 + public String createProcessDefinition(@Valid BpmProcessDefinitionCreateReqDTO createReqDTO) {
  123 + // 创建 Deployment 部署
  124 + Deployment deploy = repositoryService.createDeployment()
  125 + .key(createReqDTO.getKey()).name(createReqDTO.getName()).category(createReqDTO.getCategory())
  126 + .addBytes(createReqDTO.getKey() + BPMN_FILE_SUFFIX, createReqDTO.getBpmnBytes())
  127 + .deploy();
  128 +
  129 + // 设置 ProcessDefinition 的 category 分类
  130 + ProcessDefinition definition = repositoryService.createProcessDefinitionQuery().deploymentId(deploy.getId()).singleResult();
  131 + repositoryService.setProcessDefinitionCategory(definition.getId(), createReqDTO.getCategory());
  132 + // 注意 1,ProcessDefinition 的 key 和 name 是通过 BPMN 中的 <bpmn2:process /> 的 id 和 name 决定
  133 + // 注意 2,目前该项目的设计上,需要保证 Model、Deployment、ProcessDefinition 使用相同的 key,保证关联性。
  134 + // 否则,会导致 ProcessDefinition 的分页无法查询到。
  135 + if (!Objects.equals(definition.getKey(), createReqDTO.getKey())) {
  136 + throw exception(PROCESS_DEFINITION_KEY_NOT_MATCH, createReqDTO.getKey(), definition.getKey());
  137 + }
  138 + if (!Objects.equals(definition.getName(), createReqDTO.getName())) {
  139 + throw exception(PROCESS_DEFINITION_NAME_NOT_MATCH, createReqDTO.getName(), definition.getName());
  140 + }
  141 +
  142 + // 插入拓展表
  143 + BpmProcessDefinitionExtDO definitionDO = BpmProcessDefinitionConvert.INSTANCE.convert2(createReqDTO)
  144 + .setProcessDefinitionId(definition.getId());
  145 + processDefinitionMapper.insert(definitionDO);
  146 + return definition.getId();
  147 + }
  148 +
  149 + @Override
  150 + public void updateProcessDefinitionState(String id, Integer state) {
  151 + // 激活
  152 + if (Objects.equals(SuspensionState.ACTIVE.getStateCode(), state)) {
  153 + repositoryService.activateProcessDefinitionById(id, false, null);
  154 + return;
  155 + }
  156 + // 挂起
  157 + if (Objects.equals(SuspensionState.SUSPENDED.getStateCode(), state)) {
  158 + // suspendProcessInstances = false,进行中的任务,不进行挂起。
  159 + // 原因:只要新的流程不允许发起即可,老流程继续可以执行。
  160 + repositoryService.suspendProcessDefinitionById(id, false, null);
  161 + return;
  162 + }
  163 + log.error("[updateProcessDefinitionState][流程定义({}) 修改未知状态({})]", id, state);
  164 + }
  165 +
  166 + @Override
  167 + public String getProcessDefinitionBpmnXML(String id) {
  168 + BpmnModel bpmnModel = repositoryService.getBpmnModel(id);
  169 + if (bpmnModel == null) {
  170 + return null;
  171 + }
  172 + BpmnXMLConverter converter = new BpmnXMLConverter();
  173 + return StrUtil.utf8Str(converter.convertToXML(bpmnModel));
  174 + }
  175 +
  176 + @Override
  177 + public boolean isProcessDefinitionEquals(@Valid BpmProcessDefinitionCreateReqDTO createReqDTO) {
  178 + // 校验 name、description 是否更新
  179 + ProcessDefinition oldProcessDefinition = getActiveProcessDefinition(createReqDTO.getKey());
  180 + if (oldProcessDefinition == null) {
  181 + return false;
  182 + }
  183 + BpmProcessDefinitionExtDO oldProcessDefinitionExt = getProcessDefinitionExt(oldProcessDefinition.getId());
  184 + if (!StrUtil.equals(createReqDTO.getName(), oldProcessDefinition.getName())
  185 + || !StrUtil.equals(createReqDTO.getDescription(), oldProcessDefinitionExt.getDescription())
  186 + || !StrUtil.equals(createReqDTO.getCategory(), oldProcessDefinition.getCategory())) {
  187 + return false;
  188 + }
  189 + // 校验 form 信息是否更新
  190 + if (!ObjectUtil.equal(createReqDTO.getFormType(), oldProcessDefinitionExt.getFormType())
  191 + || !ObjectUtil.equal(createReqDTO.getFormId(), oldProcessDefinitionExt.getFormId())
  192 + || !ObjectUtil.equal(createReqDTO.getFormConf(), oldProcessDefinitionExt.getFormConf())
  193 + || !ObjectUtil.equal(createReqDTO.getFormFields(), oldProcessDefinitionExt.getFormFields())
  194 + || !ObjectUtil.equal(createReqDTO.getFormCustomCreatePath(), oldProcessDefinitionExt.getFormCustomCreatePath())
  195 + || !ObjectUtil.equal(createReqDTO.getFormCustomViewPath(), oldProcessDefinitionExt.getFormCustomViewPath())) {
  196 + return false;
  197 + }
  198 + // 校验 BPMN XML 信息
  199 + BpmnModel newModel = buildBpmnModel(createReqDTO.getBpmnBytes());
  200 + BpmnModel oldModel = getBpmnModel(oldProcessDefinition.getId());
  201 + //TODO 貌似 flowable 不修改这个也不同。需要看看。 sourceSystemId 不同
  202 + if (FlowableUtils.equals(oldModel, newModel)) {
  203 + return false;
  204 + }
  205 + // 最终发现都一致,则返回 true
  206 + return true;
  207 + }
  208 +
  209 + /**
  210 + * 构建对应的 BPMN Model
  211 + *
  212 + * @param bpmnBytes 原始的 BPMN XML 字节数组
  213 + * @return BPMN Model
  214 + */
  215 + private BpmnModel buildBpmnModel(byte[] bpmnBytes) {
  216 + // 转换成 BpmnModel 对象
  217 + BpmnXMLConverter converter = new BpmnXMLConverter();
  218 + return converter.convertToBpmnModel(new BytesStreamSource(bpmnBytes), true, true);
  219 + }
  220 +
  221 +
  222 +
  223 + @Override
  224 + public BpmProcessDefinitionExtDO getProcessDefinitionExt(String id) {
  225 + return processDefinitionMapper.selectByProcessDefinitionId(id);
  226 + }
  227 +
  228 + @Override
  229 + public List<BpmProcessDefinitionRespVO> getProcessDefinitionList(BpmProcessDefinitionListReqVO listReqVO) {
  230 + // 拼接查询条件
  231 + ProcessDefinitionQuery definitionQuery = repositoryService.createProcessDefinitionQuery();
  232 + if (Objects.equals(SuspensionState.SUSPENDED.getStateCode(), listReqVO.getSuspensionState())) {
  233 + definitionQuery.suspended();
  234 + } else if (Objects.equals(SuspensionState.ACTIVE.getStateCode(), listReqVO.getSuspensionState())) {
  235 + definitionQuery.active();
  236 + }
  237 + // 执行查询
  238 + List<ProcessDefinition> processDefinitions = definitionQuery.list();
  239 +
  240 + // 获得 BpmProcessDefinitionDO Map
  241 + List<BpmProcessDefinitionExtDO> processDefinitionDOs = processDefinitionMapper.selectListByProcessDefinitionIds(
  242 + convertList(processDefinitions, ProcessDefinition::getId));
  243 + Map<String, BpmProcessDefinitionExtDO> processDefinitionDOMap = convertMap(processDefinitionDOs,
  244 + BpmProcessDefinitionExtDO::getProcessDefinitionId);
  245 + // 执行查询,并返回
  246 + return BpmProcessDefinitionConvert.INSTANCE.convertList3(processDefinitions, processDefinitionDOMap);
  247 + }
  248 +
  249 + @Override
  250 + public PageResult<BpmProcessDefinitionPageItemRespVO> getProcessDefinitionPage(BpmProcessDefinitionPageReqVO pageVO) {
  251 + ProcessDefinitionQuery definitionQuery = repositoryService.createProcessDefinitionQuery();
  252 + if (StrUtil.isNotBlank(pageVO.getKey())) {
  253 + definitionQuery.processDefinitionKey(pageVO.getKey());
  254 + }
  255 +
  256 + // 执行查询
  257 + List<ProcessDefinition> processDefinitions = definitionQuery.orderByProcessDefinitionVersion().desc()
  258 + .listPage(PageUtils.getStart(pageVO), pageVO.getPageSize());
  259 +
  260 + if (CollUtil.isEmpty(processDefinitions)) {
  261 + return new PageResult<>(emptyList(), definitionQuery.count());
  262 + }
  263 + // 获得 Deployment Map
  264 + Set<String> deploymentIds = new HashSet<>();
  265 + processDefinitions.forEach(definition -> addIfNotNull(deploymentIds, definition.getDeploymentId()));
  266 + Map<String, Deployment> deploymentMap = getDeploymentMap(deploymentIds);
  267 +
  268 + // 获得 BpmProcessDefinitionDO Map
  269 + List<BpmProcessDefinitionExtDO> processDefinitionDOs = processDefinitionMapper.selectListByProcessDefinitionIds(
  270 + convertList(processDefinitions, ProcessDefinition::getId));
  271 + Map<String, BpmProcessDefinitionExtDO> processDefinitionDOMap = convertMap(processDefinitionDOs,
  272 + BpmProcessDefinitionExtDO::getProcessDefinitionId);
  273 +
  274 + // 获得 Form Map
  275 + Set<Long> formIds = convertSet(processDefinitionDOs, BpmProcessDefinitionExtDO::getFormId);
  276 + Map<Long, BpmFormDO> formMap = formService.getFormMap(formIds);
  277 +
  278 + // 拼接结果
  279 + long definitionCount = definitionQuery.count();
  280 + return new PageResult<>(BpmProcessDefinitionConvert.INSTANCE.convertList(processDefinitions, deploymentMap,
  281 + processDefinitionDOMap, formMap), definitionCount);
  282 + }
  283 +
  284 +}
... ...
yudao-module-bpm/yudao-module-bpm-impl-flowable/src/main/java/cn/iocoder/yudao/module/bpm/service/definition/BpmTaskAssignRuleService.java 0 → 100644
  1 +package cn.iocoder.yudao.module.bpm.service.definition;
  2 +
  3 +import cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.rule.BpmTaskAssignRuleCreateReqVO;
  4 +import cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.rule.BpmTaskAssignRuleRespVO;
  5 +import cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.rule.BpmTaskAssignRuleUpdateReqVO;
  6 +import cn.iocoder.yudao.module.bpm.dal.dataobject.definition.BpmTaskAssignRuleDO;
  7 +import org.springframework.lang.Nullable;
  8 +
  9 +import javax.validation.Valid;
  10 +import java.util.List;
  11 +
  12 +/**
  13 + * BPM 任务分配规则 Service 接口
  14 + *
  15 + * @author 芋道源码
  16 + */
  17 +public interface BpmTaskAssignRuleService {
  18 +
  19 + /**
  20 + * 获得流程定义的任务分配规则数组
  21 + *
  22 + * @param processDefinitionId 流程定义的编号
  23 + * @param taskDefinitionKey 流程任务定义的 Key。允许空
  24 + * @return 任务规则数组
  25 + */
  26 + List<BpmTaskAssignRuleDO> getTaskAssignRuleListByProcessDefinitionId(String processDefinitionId,
  27 + @Nullable String taskDefinitionKey);
  28 +
  29 + /**
  30 + * 获得流程模型的任务规则数组
  31 + *
  32 + * @param modelId 流程模型的编号
  33 + * @return 任务规则数组
  34 + */
  35 + List<BpmTaskAssignRuleDO> getTaskAssignRuleListByModelId(String modelId);
  36 +
  37 + /**
  38 + * 获得流程定义的任务分配规则数组
  39 + *
  40 + * @param modelId 流程模型的编号
  41 + * @param processDefinitionId 流程定义的编号
  42 + * @return 任务规则数组
  43 + */
  44 + List<BpmTaskAssignRuleRespVO> getTaskAssignRuleList(String modelId, String processDefinitionId);
  45 +
  46 + /**
  47 + * 创建任务分配规则
  48 + *
  49 + * @param reqVO 创建信息
  50 + * @return 规则编号
  51 + */
  52 + Long createTaskAssignRule(@Valid BpmTaskAssignRuleCreateReqVO reqVO);
  53 +
  54 + /**
  55 + * 更新任务分配规则
  56 + *
  57 + * @param reqVO 创建信息
  58 + */
  59 + void updateTaskAssignRule(@Valid BpmTaskAssignRuleUpdateReqVO reqVO);
  60 +
  61 + /**
  62 + * 判断指定流程模型和流程定义的分配规则是否相等
  63 + *
  64 + * @param modelId 流程模型编号
  65 + * @param processDefinitionId 流程定义编号
  66 + * @return 是否相等
  67 + */
  68 + boolean isTaskAssignRulesEquals(String modelId, String processDefinitionId);
  69 +
  70 + /**
  71 + * 将流程流程模型的任务分配规则,复制一份给流程定义
  72 + * 目的:每次流程模型部署时,都会生成一个新的流程定义,此时考虑到每次部署的流程不可变性,所以需要复制一份给该流程定义
  73 + *
  74 + * @param fromModelId 流程模型编号
  75 + * @param toProcessDefinitionId 流程定义编号
  76 + */
  77 + void copyTaskAssignRules(String fromModelId, String toProcessDefinitionId);
  78 +
  79 + /**
  80 + * 校验流程模型的任务分配规则全部都配置了
  81 + * 目的:如果有规则未配置,会导致流程任务找不到负责人,进而流程无法进行下去!
  82 + *
  83 + * @param id 流程模型编号
  84 + */
  85 + void checkTaskAssignRuleAllConfig(String id);
  86 +
  87 +}
... ...
yudao-module-bpm/yudao-module-bpm-impl-flowable/src/main/java/cn/iocoder/yudao/module/bpm/service/definition/BpmTaskAssignRuleServiceImpl.java 0 → 100644
  1 +package cn.iocoder.yudao.module.bpm.service.definition;
  2 +
  3 +import cn.hutool.core.collection.CollUtil;
  4 +import cn.hutool.core.util.ObjectUtil;
  5 +import cn.hutool.core.util.StrUtil;
  6 +import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils;
  7 +import cn.iocoder.yudao.framework.common.util.object.ObjectUtils;
  8 +import cn.iocoder.yudao.framework.flowable.core.util.FlowableUtils;
  9 +import cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.rule.BpmTaskAssignRuleCreateReqVO;
  10 +import cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.rule.BpmTaskAssignRuleRespVO;
  11 +import cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.rule.BpmTaskAssignRuleUpdateReqVO;
  12 +import cn.iocoder.yudao.module.bpm.convert.definition.BpmTaskAssignRuleConvert;
  13 +import cn.iocoder.yudao.module.bpm.dal.dataobject.definition.BpmTaskAssignRuleDO;
  14 +import cn.iocoder.yudao.module.bpm.dal.mysql.definition.BpmTaskAssignRuleMapper;
  15 +import cn.iocoder.yudao.module.bpm.enums.DictTypeConstants;
  16 +import cn.iocoder.yudao.module.bpm.enums.definition.BpmTaskAssignRuleTypeEnum;
  17 +import cn.iocoder.yudao.module.system.api.dept.DeptApi;
  18 +import cn.iocoder.yudao.module.system.api.dept.PostApi;
  19 +import cn.iocoder.yudao.module.system.api.dict.DictDataApi;
  20 +import cn.iocoder.yudao.module.system.api.permission.RoleApi;
  21 +import cn.iocoder.yudao.module.system.api.user.AdminUserApi;
  22 +import lombok.extern.slf4j.Slf4j;
  23 +import org.flowable.bpmn.model.BpmnModel;
  24 +import org.flowable.bpmn.model.FlowElement;
  25 +import org.flowable.bpmn.model.UserTask;
  26 +import org.springframework.context.annotation.Lazy;
  27 +import org.springframework.stereotype.Service;
  28 +import org.springframework.validation.annotation.Validated;
  29 +
  30 +import javax.annotation.Resource;
  31 +import javax.validation.Valid;
  32 +import java.util.*;
  33 +
  34 +import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
  35 +import static cn.iocoder.yudao.module.bpm.enums.ErrorCodeConstants.*;
  36 +
  37 +/**
  38 + * BPM 任务分配规则 Service 实现类
  39 + */
  40 +@Service
  41 +@Validated
  42 +@Slf4j
  43 +public class BpmTaskAssignRuleServiceImpl implements BpmTaskAssignRuleService{
  44 +
  45 + @Resource
  46 + private BpmTaskAssignRuleMapper taskRuleMapper;
  47 + @Resource
  48 + @Lazy // 解决循环依赖
  49 + private BpmModelService modelService;
  50 + @Resource
  51 + @Lazy // 解决循环依赖
  52 + private BpmProcessDefinitionService processDefinitionService;
  53 + @Resource
  54 + private BpmUserGroupService userGroupService;
  55 + @Resource
  56 + private RoleApi roleApi;
  57 + @Resource
  58 + private DeptApi deptApi;
  59 + @Resource
  60 + private PostApi postApi;
  61 + @Resource
  62 + private AdminUserApi adminUserApi;
  63 + @Resource
  64 + private DictDataApi dictDataApi;
  65 +
  66 + @Override
  67 + public List<BpmTaskAssignRuleDO> getTaskAssignRuleListByProcessDefinitionId(String processDefinitionId, String taskDefinitionKey) {
  68 + return taskRuleMapper.selectListByProcessDefinitionId(processDefinitionId, taskDefinitionKey);
  69 + }
  70 +
  71 + @Override
  72 + public List<BpmTaskAssignRuleDO> getTaskAssignRuleListByModelId(String modelId) {
  73 + return taskRuleMapper.selectListByModelId(modelId);
  74 + }
  75 +
  76 + @Override
  77 + public List<BpmTaskAssignRuleRespVO> getTaskAssignRuleList(String modelId, String processDefinitionId) {
  78 + // 获得规则
  79 + List<BpmTaskAssignRuleDO> rules = Collections.emptyList();
  80 + BpmnModel model = null;
  81 + if (StrUtil.isNotEmpty(modelId)) {
  82 + rules = getTaskAssignRuleListByModelId(modelId);
  83 + model = modelService.getBpmnModel(modelId);
  84 + } else if (StrUtil.isNotEmpty(processDefinitionId)) {
  85 + rules = getTaskAssignRuleListByProcessDefinitionId(processDefinitionId, null);
  86 + model = processDefinitionService.getBpmnModel(processDefinitionId);
  87 + }
  88 + if (model == null) {
  89 + return Collections.emptyList();
  90 + }
  91 + // 获得用户任务,只有用户任务才可以设置分配规则
  92 + List<UserTask> userTasks = FlowableUtils.getBpmnModelElements(model, UserTask.class);
  93 + if (CollUtil.isEmpty(userTasks)) {
  94 + return Collections.emptyList();
  95 + }
  96 + // 转换数据
  97 + return BpmTaskAssignRuleConvert.INSTANCE.convertList(userTasks, rules);
  98 + }
  99 +
  100 + @Override
  101 + public Long createTaskAssignRule(@Valid BpmTaskAssignRuleCreateReqVO reqVO) {
  102 + // 校验参数
  103 + validTaskAssignRuleOptions(reqVO.getType(), reqVO.getOptions());
  104 + // 校验是否已经配置
  105 + BpmTaskAssignRuleDO existRule = taskRuleMapper.selectListByModelIdAndTaskDefinitionKey(
  106 + reqVO.getModelId(), reqVO.getTaskDefinitionKey());
  107 + if (existRule != null) {
  108 + throw exception(TASK_ASSIGN_RULE_EXISTS, reqVO.getModelId(), reqVO.getTaskDefinitionKey());
  109 + }
  110 +
  111 + // 存储
  112 + BpmTaskAssignRuleDO rule = BpmTaskAssignRuleConvert.INSTANCE.convert(reqVO)
  113 + .setProcessDefinitionId(BpmTaskAssignRuleDO.PROCESS_DEFINITION_ID_NULL); // 只有流程模型,才允许新建
  114 + taskRuleMapper.insert(rule);
  115 + return rule.getId();
  116 + }
  117 +
  118 + @Override
  119 + public void updateTaskAssignRule(@Valid BpmTaskAssignRuleUpdateReqVO reqVO) {
  120 + // 校验参数
  121 + validTaskAssignRuleOptions(reqVO.getType(), reqVO.getOptions());
  122 + // 校验是否存在
  123 + BpmTaskAssignRuleDO existRule = taskRuleMapper.selectById(reqVO.getId());
  124 + if (existRule == null) {
  125 + throw exception(TASK_ASSIGN_RULE_NOT_EXISTS);
  126 + }
  127 + // 只允许修改流程模型的规则
  128 + if (!Objects.equals(BpmTaskAssignRuleDO.PROCESS_DEFINITION_ID_NULL, existRule.getProcessDefinitionId())) {
  129 + throw exception(TASK_UPDATE_FAIL_NOT_MODEL);
  130 + }
  131 +
  132 + // 执行更新
  133 + taskRuleMapper.updateById(BpmTaskAssignRuleConvert.INSTANCE.convert(reqVO));
  134 + }
  135 +
  136 + @Override
  137 + public boolean isTaskAssignRulesEquals(String modelId, String processDefinitionId) {
  138 + // 调用 VO 接口的原因是,过滤掉流程模型不需要的规则,保持和 copyTaskAssignRules 方法的一致性
  139 + List<BpmTaskAssignRuleRespVO> modelRules = getTaskAssignRuleList(modelId, null);
  140 + List<BpmTaskAssignRuleRespVO> processInstanceRules = getTaskAssignRuleList(null, processDefinitionId);
  141 + if (modelRules.size() != processInstanceRules.size()) {
  142 + return false;
  143 + }
  144 +
  145 + // 遍历,匹配对应的规则
  146 + Map<String, BpmTaskAssignRuleRespVO> processInstanceRuleMap = CollectionUtils.convertMap(processInstanceRules,
  147 + BpmTaskAssignRuleRespVO::getTaskDefinitionKey);
  148 + for (BpmTaskAssignRuleRespVO modelRule : modelRules) {
  149 + BpmTaskAssignRuleRespVO processInstanceRule = processInstanceRuleMap.get(modelRule.getTaskDefinitionKey());
  150 + if (processInstanceRule == null) {
  151 + return false;
  152 + }
  153 + if (!ObjectUtil.equals(modelRule.getType(), processInstanceRule.getType())
  154 + || !ObjectUtil.equal(modelRule.getOptions(), processInstanceRule.getOptions())) {
  155 + return false;
  156 + }
  157 + }
  158 + return true;
  159 + }
  160 +
  161 + @Override
  162 + public void copyTaskAssignRules(String fromModelId, String toProcessDefinitionId) {
  163 + List<BpmTaskAssignRuleRespVO> rules = getTaskAssignRuleList(fromModelId, null);
  164 + if (CollUtil.isEmpty(rules)) {
  165 + return;
  166 + }
  167 + // 开始复制
  168 + List<BpmTaskAssignRuleDO> newRules = BpmTaskAssignRuleConvert.INSTANCE.convertList2(rules);
  169 + newRules.forEach(rule -> rule.setProcessDefinitionId(toProcessDefinitionId).setId(null)
  170 + .setCreateTime(null).setUpdateTime(null));
  171 + taskRuleMapper.insertBatch(newRules);
  172 + }
  173 +
  174 + @Override
  175 + public void checkTaskAssignRuleAllConfig(String id) {
  176 + // 一个用户任务都没配置,所以无需配置规则
  177 + List<BpmTaskAssignRuleRespVO> taskAssignRules = getTaskAssignRuleList(id, null);
  178 + if (CollUtil.isEmpty(taskAssignRules)) {
  179 + return;
  180 + }
  181 + // 校验未配置规则的任务
  182 + taskAssignRules.forEach(rule -> {
  183 + if (CollUtil.isEmpty(rule.getOptions())) {
  184 + throw exception(MODEL_DEPLOY_FAIL_TASK_ASSIGN_RULE_NOT_CONFIG, rule.getTaskDefinitionName());
  185 + }
  186 + });
  187 + }
  188 +
  189 + private void validTaskAssignRuleOptions(Integer type, Set<Long> options) {
  190 + if (Objects.equals(type, BpmTaskAssignRuleTypeEnum.ROLE.getType())) {
  191 + roleApi.validRoles(options);
  192 + } else if (ObjectUtils.equalsAny(type, BpmTaskAssignRuleTypeEnum.DEPT_MEMBER.getType(),
  193 + BpmTaskAssignRuleTypeEnum.DEPT_LEADER.getType())) {
  194 + deptApi.validDepts(options);
  195 + } else if (Objects.equals(type, BpmTaskAssignRuleTypeEnum.POST.getType())) {
  196 + postApi.validPosts(options);
  197 + } else if (Objects.equals(type, BpmTaskAssignRuleTypeEnum.USER.getType())) {
  198 + adminUserApi.validUsers(options);
  199 + } else if (Objects.equals(type, BpmTaskAssignRuleTypeEnum.USER_GROUP.getType())) {
  200 + userGroupService.validUserGroups(options);
  201 + } else if (Objects.equals(type, BpmTaskAssignRuleTypeEnum.SCRIPT.getType())) {
  202 + dictDataApi.validDictDatas(DictTypeConstants.TASK_ASSIGN_SCRIPT,
  203 + CollectionUtils.convertSet(options, String::valueOf));
  204 + } else {
  205 + throw new IllegalArgumentException(StrUtil.format("未知的规则类型({})", type));
  206 + }
  207 + }
  208 +}
... ...
yudao-module-bpm/yudao-module-bpm-impl-flowable/src/main/java/cn/iocoder/yudao/module/bpm/service/task/BpmActivityService.java 0 → 100644
  1 +package cn.iocoder.yudao.module.bpm.service.task;
  2 +
  3 +import cn.iocoder.yudao.module.bpm.controller.admin.task.vo.activity.BpmActivityRespVO;
  4 +
  5 +import java.util.List;
  6 +
  7 +/**
  8 + * BPM 活动实例 Service 接口
  9 + *
  10 + * @author 芋道源码
  11 + */
  12 +public interface BpmActivityService {
  13 +
  14 + /**
  15 + * 获得指定流程实例的活动实例列表
  16 + *
  17 + * @param processInstanceId 流程实例的编号
  18 + * @return 活动实例列表
  19 + */
  20 + List<BpmActivityRespVO> getActivityListByProcessInstanceId(String processInstanceId);
  21 +
  22 +}
... ...
yudao-module-bpm/yudao-module-bpm-impl-flowable/src/main/java/cn/iocoder/yudao/module/bpm/service/task/BpmActivityServiceImpl.java 0 → 100644
  1 +package cn.iocoder.yudao.module.bpm.service.task;
  2 +
  3 +import cn.hutool.core.io.IoUtil;
  4 +import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils;
  5 +import cn.iocoder.yudao.module.bpm.controller.admin.task.vo.activity.BpmActivityRespVO;
  6 +import cn.iocoder.yudao.module.bpm.convert.task.BpmActivityConvert;
  7 +import cn.iocoder.yudao.module.bpm.service.definition.BpmProcessDefinitionService;
  8 +import lombok.extern.slf4j.Slf4j;
  9 +
  10 +import org.flowable.bpmn.model.BpmnModel;
  11 +import org.flowable.engine.HistoryService;
  12 +import org.flowable.engine.history.HistoricActivityInstance;
  13 +import org.flowable.engine.history.HistoricProcessInstance;
  14 +import org.flowable.image.ProcessDiagramGenerator;
  15 +import org.springframework.stereotype.Service;
  16 +import org.springframework.validation.annotation.Validated;
  17 +
  18 +import javax.annotation.Resource;
  19 +import java.io.InputStream;
  20 +import java.util.Collections;
  21 +import java.util.List;
  22 +
  23 +import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
  24 +import static cn.iocoder.yudao.module.bpm.enums.ErrorCodeConstants.PROCESS_DEFINITION_BPMN_MODEL_NOT_EXISTS;
  25 +import static cn.iocoder.yudao.module.bpm.enums.ErrorCodeConstants.PROCESS_INSTANCE_NOT_EXISTS;
  26 +
  27 +/**
  28 + * BPM 活动实例 Service 实现类
  29 + *
  30 + * @author 芋道源码
  31 + */
  32 +@Service
  33 +@Slf4j
  34 +@Validated
  35 +public class BpmActivityServiceImpl implements BpmActivityService {
  36 +
  37 + @Resource
  38 + private HistoryService historyService;
  39 +
  40 + @Override
  41 + public List<BpmActivityRespVO> getActivityListByProcessInstanceId(String processInstanceId) {
  42 + List<HistoricActivityInstance> activityList = historyService.createHistoricActivityInstanceQuery()
  43 + .processInstanceId(processInstanceId).list();
  44 + return BpmActivityConvert.INSTANCE.convertList(activityList);
  45 + }
  46 +
  47 +
  48 +
  49 +}
... ...
yudao-module-bpm/yudao-module-bpm-impl-flowable/src/main/java/cn/iocoder/yudao/module/bpm/service/task/BpmProcessInstanceService.java 0 → 100644
  1 +package cn.iocoder.yudao.module.bpm.service.task;
  2 +
  3 +import cn.iocoder.yudao.framework.common.pojo.PageResult;
  4 +import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils;
  5 +import cn.iocoder.yudao.module.bpm.api.task.dto.BpmProcessInstanceCreateReqDTO;
  6 +import cn.iocoder.yudao.module.bpm.controller.admin.task.vo.instance.*;
  7 +import org.flowable.common.engine.api.delegate.event.FlowableEngineEntityEvent;
  8 +import org.flowable.engine.delegate.event.FlowableCancelledEvent;
  9 +import org.flowable.engine.history.HistoricProcessInstance;
  10 +import org.flowable.engine.runtime.ProcessInstance;
  11 +
  12 +import javax.validation.Valid;
  13 +import java.util.List;
  14 +import java.util.Map;
  15 +import java.util.Set;
  16 +
  17 +/**
  18 + * 流程实例 Service 接口
  19 + *
  20 + * @author 芋道源码
  21 + */
  22 +public interface BpmProcessInstanceService {
  23 +
  24 + /**
  25 + * 获得流程实例
  26 + *
  27 + * @param id 流程实例的编号
  28 + * @return 流程实例
  29 + */
  30 + ProcessInstance getProcessInstance(String id);
  31 +
  32 + /**
  33 + * 获得流程实例列表
  34 + *
  35 + * @param ids 流程实例的编号集合
  36 + * @return 流程实例列表
  37 + */
  38 + List<ProcessInstance> getProcessInstances(Set<String> ids);
  39 +
  40 + /**
  41 + * 获得流程实例 Map
  42 + *
  43 + * @param ids 流程实例的编号集合
  44 + * @return 流程实例列表 Map
  45 + */
  46 + default Map<String, ProcessInstance> getProcessInstanceMap(Set<String> ids) {
  47 + return CollectionUtils.convertMap(getProcessInstances(ids), ProcessInstance::getProcessInstanceId);
  48 + }
  49 +
  50 + /**
  51 + * 获得流程实例的分页
  52 + *
  53 + * @param userId 用户编号
  54 + * @param pageReqVO 分页请求
  55 + * @return 流程实例的分页
  56 + */
  57 + PageResult<BpmProcessInstancePageItemRespVO> getMyProcessInstancePage(Long userId,
  58 + @Valid BpmProcessInstanceMyPageReqVO pageReqVO);
  59 + /**
  60 + * 创建流程实例(提供给前端)
  61 + *
  62 + * @param userId 用户编号
  63 + * @param createReqVO 创建信息
  64 + * @return 实例的编号
  65 + */
  66 + String createProcessInstance(Long userId, @Valid BpmProcessInstanceCreateReqVO createReqVO);
  67 +
  68 + /**
  69 + * 创建流程实例(提供给内部)
  70 + *
  71 + * @param userId 用户编号
  72 + * @param createReqDTO 创建信息
  73 + * @return 实例的编号
  74 + */
  75 + String createProcessInstance(Long userId, @Valid BpmProcessInstanceCreateReqDTO createReqDTO);
  76 +
  77 + /**
  78 + * 获得流程实例 VO 信息
  79 + *
  80 + * @param id 流程实例的编号
  81 + * @return 流程实例
  82 + */
  83 + BpmProcessInstanceRespVO getProcessInstanceVO(String id);
  84 +
  85 + /**
  86 + * 取消流程实例
  87 + *
  88 + * @param userId 用户编号
  89 + * @param cancelReqVO 取消信息
  90 + */
  91 + void cancelProcessInstance(Long userId, @Valid BpmProcessInstanceCancelReqVO cancelReqVO);
  92 +
  93 + /**
  94 + * 获得历史的流程实例
  95 + *
  96 + * @param id 流程实例的编号
  97 + * @return 历史的流程实例
  98 + */
  99 + HistoricProcessInstance getHistoricProcessInstance(String id);
  100 +
  101 + /**
  102 + * 获得历史的流程实例列表
  103 + *
  104 + * @param ids 流程实例的编号集合
  105 + * @return 历史的流程实例列表
  106 + */
  107 + List<HistoricProcessInstance> getHistoricProcessInstances(Set<String> ids);
  108 +
  109 + /**
  110 + * 获得历史的流程实例 Map
  111 + *
  112 + * @param ids 流程实例的编号集合
  113 + * @return 历史的流程实例列表 Map
  114 + */
  115 + default Map<String, HistoricProcessInstance> getHistoricProcessInstanceMap(Set<String> ids) {
  116 + return CollectionUtils.convertMap(getHistoricProcessInstances(ids), HistoricProcessInstance::getId);
  117 + }
  118 +
  119 + /**
  120 + * 创建 ProcessInstance 拓展记录
  121 + *
  122 + * @param instance 流程任务
  123 + */
  124 + void createProcessInstanceExt(ProcessInstance instance);
  125 +
  126 + /**
  127 + * 更新 ProcessInstance 拓展记录为取消
  128 + *
  129 + * @param event 流程取消事件
  130 + */
  131 + void updateProcessInstanceExtCancel(FlowableCancelledEvent event);
  132 +
  133 + /**
  134 + * 更新 ProcessInstance 拓展记录为完成
  135 + *
  136 + * @param instance 流程任务
  137 + */
  138 + void updateProcessInstanceExtComplete(ProcessInstance instance);
  139 +
  140 + /**
  141 + * 更新 ProcessInstance 拓展记录为不通过
  142 + *
  143 + * @param id 流程编号
  144 + * @param comment 理由。例如说,审批不通过时,需要传递该值
  145 + */
  146 + void updateProcessInstanceExtReject(String id, String comment);
  147 +
  148 +
  149 +}
... ...
yudao-module-bpm/yudao-module-bpm-impl-flowable/src/main/java/cn/iocoder/yudao/module/bpm/service/task/BpmProcessInstanceServiceImpl.java 0 → 100644
  1 +package cn.iocoder.yudao.module.bpm.service.task;
  2 +
  3 +import cn.hutool.core.collection.CollUtil;
  4 +import cn.hutool.core.lang.Assert;
  5 +import cn.hutool.core.util.StrUtil;
  6 +import cn.iocoder.yudao.framework.common.pojo.PageResult;
  7 +import cn.iocoder.yudao.framework.common.util.number.NumberUtils;
  8 +import cn.iocoder.yudao.module.bpm.api.task.dto.BpmProcessInstanceCreateReqDTO;
  9 +import cn.iocoder.yudao.module.bpm.controller.admin.task.vo.instance.*;
  10 +import cn.iocoder.yudao.module.bpm.convert.task.BpmProcessInstanceConvert;
  11 +import cn.iocoder.yudao.module.bpm.dal.dataobject.definition.BpmProcessDefinitionExtDO;
  12 +import cn.iocoder.yudao.module.bpm.dal.dataobject.task.BpmProcessInstanceExtDO;
  13 +import cn.iocoder.yudao.module.bpm.dal.mysql.task.BpmProcessInstanceExtMapper;
  14 +import cn.iocoder.yudao.module.bpm.enums.task.BpmProcessInstanceDeleteReasonEnum;
  15 +import cn.iocoder.yudao.module.bpm.enums.task.BpmProcessInstanceResultEnum;
  16 +import cn.iocoder.yudao.module.bpm.enums.task.BpmProcessInstanceStatusEnum;
  17 +import cn.iocoder.yudao.module.bpm.framework.bpm.core.event.BpmProcessInstanceResultEventPublisher;
  18 +import cn.iocoder.yudao.module.bpm.service.definition.BpmProcessDefinitionService;
  19 +import cn.iocoder.yudao.module.bpm.service.message.BpmMessageService;
  20 +import cn.iocoder.yudao.module.system.api.dept.DeptApi;
  21 +import cn.iocoder.yudao.module.system.api.dept.dto.DeptRespDTO;
  22 +import cn.iocoder.yudao.module.system.api.user.AdminUserApi;
  23 +import cn.iocoder.yudao.module.system.api.user.dto.AdminUserRespDTO;
  24 +import lombok.extern.slf4j.Slf4j;
  25 +import org.flowable.engine.HistoryService;
  26 +import org.flowable.engine.RuntimeService;
  27 +import org.flowable.engine.delegate.event.FlowableCancelledEvent;
  28 +import org.flowable.engine.history.HistoricProcessInstance;
  29 +import org.flowable.engine.repository.ProcessDefinition;
  30 +import org.flowable.engine.runtime.ProcessInstance;
  31 +import org.flowable.task.api.Task;
  32 +import org.springframework.context.annotation.Lazy;
  33 +import org.springframework.stereotype.Service;
  34 +import org.springframework.transaction.annotation.Transactional;
  35 +import org.springframework.validation.annotation.Validated;
  36 +
  37 +import javax.annotation.Resource;
  38 +import javax.validation.Valid;
  39 +import java.util.*;
  40 +
  41 +import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
  42 +import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertList;
  43 +import static cn.iocoder.yudao.module.bpm.enums.ErrorCodeConstants.*;
  44 +import static cn.iocoder.yudao.module.bpm.enums.ErrorCodeConstants.PROCESS_INSTANCE_CANCEL_FAIL_NOT_SELF;
  45 +
  46 +/**
  47 + * 流程实例 Service 实现类
  48 + *
  49 + * ProcessDefinition & ProcessInstance & Execution & Task 的关系:
  50 + * 1. https://blog.csdn.net/bobozai86/article/details/105210414
  51 + *
  52 + * HistoricProcessInstance & ProcessInstance 的关系:
  53 + * 1.https://my.oschina.net/843294669/blog/719024
  54 + * 简单来说,前者 = 历史 + 运行中的流程实例,后者仅是运行中的流程实例
  55 + *
  56 + * @author 芋道源码
  57 + */
  58 +@Service
  59 +@Validated
  60 +@Slf4j
  61 +public class BpmProcessInstanceServiceImpl implements BpmProcessInstanceService {
  62 +
  63 + @Resource
  64 + private RuntimeService runtimeService;
  65 + @Resource
  66 + private BpmProcessInstanceExtMapper processInstanceExtMapper;
  67 + @Resource
  68 + @Lazy // 解决循环依赖
  69 + private BpmTaskService taskService;
  70 + @Resource
  71 + private BpmProcessDefinitionService processDefinitionService;
  72 + @Resource
  73 + private HistoryService historyService;
  74 + @Resource
  75 + private AdminUserApi adminUserApi;
  76 + @Resource
  77 + private DeptApi deptApi;
  78 + @Resource
  79 + private BpmProcessInstanceResultEventPublisher processInstanceResultEventPublisher;
  80 + @Resource
  81 + private BpmMessageService messageService;
  82 + @Override
  83 + public ProcessInstance getProcessInstance(String id) {
  84 + return runtimeService.createProcessInstanceQuery().processInstanceId(id).singleResult();
  85 + }
  86 +
  87 + @Override
  88 + public List<ProcessInstance> getProcessInstances(Set<String> ids) {
  89 + return runtimeService.createProcessInstanceQuery().processInstanceIds(ids).list();
  90 + }
  91 +
  92 + @Override
  93 + public PageResult<BpmProcessInstancePageItemRespVO> getMyProcessInstancePage(Long userId,
  94 + BpmProcessInstanceMyPageReqVO pageReqVO) {
  95 + // 通过 BpmProcessInstanceExtDO 表,先查询到对应的分页
  96 + PageResult<BpmProcessInstanceExtDO> pageResult = processInstanceExtMapper.selectPage(userId, pageReqVO);
  97 + if (CollUtil.isEmpty(pageResult.getList())) {
  98 + return new PageResult<>(pageResult.getTotal());
  99 + }
  100 +
  101 + // 获得流程 Task Map
  102 + List<String> processInstanceIds = convertList(pageResult.getList(), BpmProcessInstanceExtDO::getProcessInstanceId);
  103 + Map<String, List<Task>> taskMap = taskService.getTaskMapByProcessInstanceIds(processInstanceIds);
  104 + // 转换返回
  105 + return BpmProcessInstanceConvert.INSTANCE.convertPage(pageResult, taskMap);
  106 + }
  107 +
  108 + @Override
  109 + @Transactional(rollbackFor = Exception.class)
  110 + public String createProcessInstance(Long userId, @Valid BpmProcessInstanceCreateReqVO createReqVO) {
  111 + // 获得流程定义
  112 + ProcessDefinition definition = processDefinitionService.getProcessDefinition(createReqVO.getProcessDefinitionId());
  113 + // 发起流程
  114 + return createProcessInstance0(userId, definition, createReqVO.getVariables(), null);
  115 + }
  116 +
  117 + @Override
  118 + public String createProcessInstance(Long userId, @Valid BpmProcessInstanceCreateReqDTO createReqDTO) {
  119 + // 获得流程定义
  120 + ProcessDefinition definition = processDefinitionService.getActiveProcessDefinition(createReqDTO.getProcessDefinitionKey());
  121 + // 发起流程
  122 + return createProcessInstance0(userId, definition, createReqDTO.getVariables(), createReqDTO.getBusinessKey());
  123 + }
  124 +
  125 + @Override
  126 + public BpmProcessInstanceRespVO getProcessInstanceVO(String id) {
  127 + // 获得流程实例
  128 + HistoricProcessInstance processInstance = getHistoricProcessInstance(id);
  129 + if (processInstance == null) {
  130 + return null;
  131 + }
  132 + BpmProcessInstanceExtDO processInstanceExt = processInstanceExtMapper.selectByProcessInstanceId(id);
  133 + Assert.notNull(processInstanceExt, "流程实例拓展({}) 不存在", id);
  134 +
  135 + // 获得流程定义
  136 + ProcessDefinition processDefinition = processDefinitionService
  137 + .getProcessDefinition(processInstance.getProcessDefinitionId());
  138 + Assert.notNull(processDefinition, "流程定义({}) 不存在", processInstance.getProcessDefinitionId());
  139 + BpmProcessDefinitionExtDO processDefinitionExt = processDefinitionService.getProcessDefinitionExt(
  140 + processInstance.getProcessDefinitionId());
  141 + Assert.notNull(processDefinitionExt, "流程定义拓展({}) 不存在", id);
  142 + String bpmnXml = processDefinitionService.getProcessDefinitionBpmnXML(processInstance.getProcessDefinitionId());
  143 +
  144 + // 获得 User
  145 + AdminUserRespDTO startUser = adminUserApi.getUser(NumberUtils.parseLong(processInstance.getStartUserId()));
  146 + DeptRespDTO dept = null;
  147 + if (startUser != null) {
  148 + dept = deptApi.getDept(startUser.getDeptId());
  149 + }
  150 +
  151 + // 拼接结果
  152 + return BpmProcessInstanceConvert.INSTANCE.convert2(processInstance, processInstanceExt,
  153 + processDefinition, processDefinitionExt, bpmnXml, startUser, dept);
  154 + }
  155 +
  156 + @Override
  157 + public void cancelProcessInstance(Long userId, @Valid BpmProcessInstanceCancelReqVO cancelReqVO) {
  158 + // 校验流程实例存在
  159 + ProcessInstance instance = getProcessInstance(cancelReqVO.getId());
  160 + if (instance == null) {
  161 + throw exception(PROCESS_INSTANCE_CANCEL_FAIL_NOT_EXISTS);
  162 + }
  163 + // 只能取消自己的
  164 + if (!Objects.equals(instance.getStartUserId(), String.valueOf(userId))) {
  165 + throw exception(PROCESS_INSTANCE_CANCEL_FAIL_NOT_SELF);
  166 + }
  167 +
  168 + // 通过删除流程实例,实现流程实例的取消,
  169 + // 删除流程实例,正则执行任务ACT_RU_TASK. 任务会被删除。通过历史表查询
  170 + deleteProcessInstance(cancelReqVO.getId(),
  171 + BpmProcessInstanceDeleteReasonEnum.CANCEL_TASK.format(cancelReqVO.getReason()));
  172 + }
  173 +
  174 + /**
  175 + * 获得历史的流程实例
  176 + *
  177 + * @param id 流程实例的编号
  178 + * @return 历史的流程实例
  179 + */
  180 + @Override
  181 + public HistoricProcessInstance getHistoricProcessInstance(String id) {
  182 + return historyService.createHistoricProcessInstanceQuery().processInstanceId(id).singleResult();
  183 + }
  184 +
  185 + @Override
  186 + public List<HistoricProcessInstance> getHistoricProcessInstances(Set<String> ids) {
  187 + return historyService.createHistoricProcessInstanceQuery().processInstanceIds(ids).list();
  188 + }
  189 +
  190 + @Override
  191 + public void createProcessInstanceExt(ProcessInstance instance) {
  192 + // 获得流程定义
  193 + ProcessDefinition definition = processDefinitionService.getProcessDefinition2(instance.getProcessDefinitionId());
  194 + // 插入 BpmProcessInstanceExtDO 对象
  195 + BpmProcessInstanceExtDO instanceExtDO = new BpmProcessInstanceExtDO()
  196 + .setProcessInstanceId(instance.getId())
  197 + .setProcessDefinitionId(definition.getId())
  198 + .setName(instance.getProcessDefinitionName())
  199 + .setStartUserId(Long.valueOf(instance.getStartUserId()))
  200 + .setCategory(definition.getCategory())
  201 + .setStatus(BpmProcessInstanceStatusEnum.RUNNING.getStatus())
  202 + .setResult(BpmProcessInstanceResultEnum.PROCESS.getResult());
  203 +
  204 + processInstanceExtMapper.insert(instanceExtDO);
  205 + }
  206 +
  207 + @Override
  208 + public void updateProcessInstanceExtCancel(FlowableCancelledEvent event) {
  209 + // 判断是否为 Reject 不通过。如果是,则不进行更新
  210 + if (BpmProcessInstanceDeleteReasonEnum.isRejectReason((String)event.getCause())) {
  211 + return;
  212 + }
  213 +
  214 + // 需要主动查询,因为 instance 只有 id 属性
  215 + // 另外,此时如果去查询 ProcessInstance 的话,字段是不全的,所以去查询了 HistoricProcessInstance
  216 + HistoricProcessInstance processInstance = getHistoricProcessInstance(event.getProcessInstanceId());
  217 + // 更新拓展表
  218 + BpmProcessInstanceExtDO instanceExtDO = new BpmProcessInstanceExtDO()
  219 + .setProcessInstanceId(event.getProcessInstanceId())
  220 + .setEndTime(new Date()) // 由于 ProcessInstance 里没有办法拿到 endTime,所以这里设置
  221 + .setStatus(BpmProcessInstanceStatusEnum.FINISH.getStatus())
  222 + .setResult(BpmProcessInstanceResultEnum.CANCEL.getResult());
  223 +
  224 + processInstanceExtMapper.updateByProcessInstanceId(instanceExtDO);
  225 +
  226 + // 发送流程实例的状态事件
  227 + processInstanceResultEventPublisher.sendProcessInstanceResultEvent(
  228 + BpmProcessInstanceConvert.INSTANCE.convert(this, processInstance, instanceExtDO.getResult()));
  229 + }
  230 +
  231 + @Override
  232 + public void updateProcessInstanceExtComplete(ProcessInstance instance) {
  233 + // 需要主动查询,因为 instance 只有 id 属性
  234 + // 另外,此时如果去查询 ProcessInstance 的话,字段是不全的,所以去查询了 HistoricProcessInstance
  235 + HistoricProcessInstance processInstance = getHistoricProcessInstance(instance.getId());
  236 + // 更新拓展表
  237 + BpmProcessInstanceExtDO instanceExtDO = new BpmProcessInstanceExtDO()
  238 + .setProcessInstanceId(instance.getProcessInstanceId())
  239 + .setEndTime(new Date()) // 由于 ProcessInstance 里没有办法拿到 endTime,所以这里设置
  240 + .setStatus(BpmProcessInstanceStatusEnum.FINISH.getStatus())
  241 + .setResult(BpmProcessInstanceResultEnum.APPROVE.getResult()); // 如果正常完全,说明审批通过
  242 + processInstanceExtMapper.updateByProcessInstanceId(instanceExtDO);
  243 +
  244 + // 发送流程被通过的消息
  245 + messageService.sendMessageWhenProcessInstanceApprove(BpmProcessInstanceConvert.INSTANCE.convert2ApprovedReq(instance));
  246 +
  247 + // 发送流程实例的状态事件
  248 + processInstanceResultEventPublisher.sendProcessInstanceResultEvent(
  249 + BpmProcessInstanceConvert.INSTANCE.convert(this, processInstance, instanceExtDO.getResult()));
  250 + }
  251 +
  252 + @Transactional(rollbackFor = Exception.class)
  253 + public void updateProcessInstanceExtReject(String id, String comment) {
  254 + // 需要主动查询,因为 instance 只有 id 属性
  255 + ProcessInstance processInstance = getProcessInstance(id);
  256 + // 删除流程实例,以实现驳回任务时,取消整个审批流程
  257 + deleteProcessInstance(id, StrUtil.format(BpmProcessInstanceDeleteReasonEnum.REJECT_TASK.format(comment)));
  258 +
  259 + // 更新 status + result
  260 + // 注意,不能和上面的逻辑更换位置。因为 deleteProcessInstance 会触发流程的取消,进而调用 updateProcessInstanceExtCancel 方法,
  261 + // 设置 result 为 BpmProcessInstanceStatusEnum.CANCEL,显然和 result 不一定是一致的
  262 + BpmProcessInstanceExtDO instanceExtDO = new BpmProcessInstanceExtDO().setProcessInstanceId(id)
  263 + .setStatus(BpmProcessInstanceStatusEnum.FINISH.getStatus())
  264 + .setResult(BpmProcessInstanceResultEnum.REJECT.getResult());
  265 + processInstanceExtMapper.updateByProcessInstanceId(instanceExtDO);
  266 +
  267 + // 发送流程被不通过的消息
  268 + messageService.sendMessageWhenProcessInstanceReject(BpmProcessInstanceConvert.INSTANCE.convert2RejectReq(processInstance, comment));
  269 +
  270 + // 发送流程实例的状态事件
  271 + processInstanceResultEventPublisher.sendProcessInstanceResultEvent(
  272 + BpmProcessInstanceConvert.INSTANCE.convert(this, processInstance, instanceExtDO.getResult()));
  273 + }
  274 +
  275 + private void deleteProcessInstance(String id, String reason) {
  276 + runtimeService.deleteProcessInstance(id, reason);
  277 + }
  278 +
  279 + private String createProcessInstance0(Long userId, ProcessDefinition definition,
  280 + Map<String, Object> variables, String businessKey) {
  281 + // 校验流程定义
  282 + if (definition == null) {
  283 + throw exception(PROCESS_DEFINITION_NOT_EXISTS);
  284 + }
  285 + if (definition.isSuspended()) {
  286 + throw exception(PROCESS_DEFINITION_IS_SUSPENDED);
  287 + }
  288 +
  289 + // 创建流程实例
  290 + ProcessInstance instance = runtimeService.startProcessInstanceById(definition.getId(), businessKey, variables);
  291 + // 设置流程名字
  292 + runtimeService.setProcessInstanceName(instance.getId(), definition.getName());
  293 +
  294 + // 补全流程实例的拓展表
  295 + processInstanceExtMapper.updateByProcessInstanceId(new BpmProcessInstanceExtDO().setProcessInstanceId(instance.getId())
  296 + .setFormVariables(variables));
  297 +
  298 + return instance.getId();
  299 + }
  300 +}
... ...
yudao-module-bpm/yudao-module-bpm-impl-flowable/src/main/java/cn/iocoder/yudao/module/bpm/service/task/BpmTaskService.java 0 → 100644
  1 +package cn.iocoder.yudao.module.bpm.service.task;
  2 +
  3 +import cn.iocoder.yudao.framework.common.pojo.PageResult;
  4 +import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils;
  5 +import cn.iocoder.yudao.module.bpm.controller.admin.task.vo.task.*;
  6 +import org.flowable.task.api.Task;
  7 +
  8 +
  9 +import javax.validation.Valid;
  10 +import java.util.List;
  11 +import java.util.Map;
  12 +
  13 +/**
  14 + * 流程任务实例 Service 接口
  15 + *
  16 + * @author jason
  17 + * @author 芋道源码
  18 + */
  19 +public interface BpmTaskService {
  20 + /**
  21 + * 获得待办的流程任务分页
  22 + *
  23 + * @param userId 用户编号
  24 + * @param pageReqVO 分页请求
  25 + * @return 流程任务分页
  26 + */
  27 + PageResult<BpmTaskTodoPageItemRespVO> getTodoTaskPage(Long userId, BpmTaskTodoPageReqVO pageReqVO);
  28 + /**
  29 + * 获得已办的流程任务分页
  30 + *
  31 + * @param userId 用户编号
  32 + * @param pageReqVO 分页请求
  33 + * @return 流程任务分页
  34 + */
  35 + PageResult<BpmTaskDonePageItemRespVO> getDoneTaskPage(Long userId, BpmTaskDonePageReqVO pageReqVO);
  36 +
  37 + /**
  38 + * 获得流程任务 Map
  39 + *
  40 + * @param processInstanceIds 流程实例的编号数组
  41 + * @return 流程任务 Map
  42 + */
  43 + default Map<String, List<Task>> getTaskMapByProcessInstanceIds(List<String> processInstanceIds) {
  44 + return CollectionUtils.convertMultiMap(getTasksByProcessInstanceIds(processInstanceIds),
  45 + Task::getProcessInstanceId);
  46 + }
  47 +
  48 + /**
  49 + * 获得流程任务列表
  50 + *
  51 + * @param processInstanceIds 流程实例的编号数组
  52 + * @return 流程任务列表
  53 + */
  54 + List<Task> getTasksByProcessInstanceIds(List<String> processInstanceIds);
  55 +
  56 + /**
  57 + * 获得指令流程实例的流程任务列表,包括所有状态的
  58 + *
  59 + * @param processInstanceId 流程实例的编号
  60 + * @return 流程任务列表
  61 + */
  62 + List<BpmTaskRespVO> getTaskListByProcessInstanceId(String processInstanceId);
  63 +
  64 + /**
  65 + * 通过任务
  66 + *
  67 + * @param userId 用户编号
  68 + * @param reqVO 通过请求
  69 + */
  70 + void approveTask(Long userId, @Valid BpmTaskApproveReqVO reqVO);
  71 +
  72 + /**
  73 + * 不通过任务
  74 + *
  75 + * @param userId 用户编号
  76 + * @param reqVO 不通过请求
  77 + */
  78 + void rejectTask(Long userId, @Valid BpmTaskRejectReqVO reqVO);
  79 +
  80 + /**
  81 + * 将流程任务分配给指定用户
  82 + *
  83 + * @param userId 用户编号
  84 + * @param reqVO 分配请求
  85 + */
  86 + void updateTaskAssignee(Long userId, BpmTaskUpdateAssigneeReqVO reqVO);
  87 +
  88 + /**
  89 + * 将流程任务分配给指定用户
  90 + *
  91 + * @param id 流程任务编号
  92 + * @param userId 用户编号
  93 + */
  94 + void updateTaskAssignee(String id, Long userId);
  95 +
  96 + /**
  97 + * 创建 Task 拓展记录
  98 + *
  99 + * @param task 任务实体
  100 + */
  101 + void createTaskExt(Task task);
  102 +
  103 + /**
  104 + * 更新 Task 拓展记录为完成
  105 + *
  106 + * @param task 任务实体
  107 + */
  108 + void updateTaskExtComplete(Task task);
  109 +
  110 + /**
  111 + * 更新 Task 拓展记录,并发送通知
  112 + *
  113 + * @param task 任务实体
  114 + */
  115 + void updateTaskExtAssign(Task task);
  116 +
  117 +}
... ...
yudao-module-bpm/yudao-module-bpm-impl-flowable/src/main/java/cn/iocoder/yudao/module/bpm/service/task/BpmTaskServiceImpl.java 0 → 100644
  1 +package cn.iocoder.yudao.module.bpm.service.task;
  2 +
  3 +import cn.hutool.core.collection.CollUtil;
  4 +import cn.hutool.core.util.StrUtil;
  5 +import cn.iocoder.yudao.framework.common.pojo.PageResult;
  6 +import cn.iocoder.yudao.framework.common.util.number.NumberUtils;
  7 +import cn.iocoder.yudao.framework.common.util.object.PageUtils;
  8 +import cn.iocoder.yudao.module.bpm.controller.admin.task.vo.task.*;
  9 +import cn.iocoder.yudao.module.bpm.convert.task.BpmTaskConvert;
  10 +import cn.iocoder.yudao.module.bpm.dal.dataobject.task.BpmTaskExtDO;
  11 +import cn.iocoder.yudao.module.bpm.dal.mysql.task.BpmTaskExtMapper;
  12 +import cn.iocoder.yudao.module.bpm.enums.task.BpmProcessInstanceResultEnum;
  13 +import cn.iocoder.yudao.module.bpm.service.message.BpmMessageService;
  14 +import cn.iocoder.yudao.module.system.api.dept.DeptApi;
  15 +import cn.iocoder.yudao.module.system.api.dept.dto.DeptRespDTO;
  16 +import cn.iocoder.yudao.module.system.api.user.AdminUserApi;
  17 +import cn.iocoder.yudao.module.system.api.user.dto.AdminUserRespDTO;
  18 +import lombok.extern.slf4j.Slf4j;
  19 +import org.flowable.engine.HistoryService;
  20 +import org.flowable.engine.TaskService;
  21 +import org.flowable.engine.history.HistoricProcessInstance;
  22 +import org.flowable.engine.runtime.ProcessInstance;
  23 +import org.flowable.task.api.Task;
  24 +import org.flowable.task.api.TaskQuery;
  25 +import org.flowable.task.api.history.HistoricTaskInstance;
  26 +import org.flowable.task.api.history.HistoricTaskInstanceQuery;
  27 +import org.springframework.stereotype.Service;
  28 +import org.springframework.transaction.annotation.Transactional;
  29 +import org.springframework.transaction.support.TransactionSynchronization;
  30 +import org.springframework.transaction.support.TransactionSynchronizationManager;
  31 +
  32 +import javax.annotation.Resource;
  33 +import javax.validation.Valid;
  34 +import java.util.*;
  35 +
  36 +import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
  37 +import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertMap;
  38 +import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertSet;
  39 +import static cn.iocoder.yudao.module.bpm.enums.ErrorCodeConstants.*;
  40 +
  41 +/**
  42 + * 流程任务实例 Service 实现类
  43 + *
  44 + * @author 芋道源码
  45 + * @author jason
  46 + */
  47 +@Slf4j
  48 +@Service
  49 +public class BpmTaskServiceImpl implements BpmTaskService{
  50 +
  51 + @Resource
  52 + private TaskService taskService;
  53 + @Resource
  54 + private HistoryService historyService;
  55 +
  56 + @Resource
  57 + private BpmProcessInstanceService processInstanceService;
  58 + @Resource
  59 + private AdminUserApi adminUserApi;
  60 + @Resource
  61 + private DeptApi deptApi;
  62 + @Resource
  63 + private BpmTaskExtMapper taskExtMapper;
  64 + @Resource
  65 + private BpmMessageService messageService;
  66 +
  67 + @Override
  68 + public PageResult<BpmTaskTodoPageItemRespVO> getTodoTaskPage(Long userId, BpmTaskTodoPageReqVO pageVO) {
  69 + // 查询待办任务
  70 + TaskQuery taskQuery = taskService.createTaskQuery()
  71 + .taskAssignee(String.valueOf(userId)) // 分配给自己
  72 + .orderByTaskCreateTime().desc(); // 创建时间倒序
  73 + if (StrUtil.isNotBlank(pageVO.getName())) {
  74 + taskQuery.taskNameLike("%" + pageVO.getName() + "%");
  75 + }
  76 + if (pageVO.getBeginCreateTime() != null) {
  77 + taskQuery.taskCreatedAfter(pageVO.getBeginCreateTime());
  78 + }
  79 + if (pageVO.getEndCreateTime() != null) {
  80 + taskQuery.taskCreatedBefore(pageVO.getEndCreateTime());
  81 + }
  82 + // 执行查询
  83 + List<Task> tasks = taskQuery.listPage(PageUtils.getStart(pageVO), pageVO.getPageSize());
  84 + if (CollUtil.isEmpty(tasks)) {
  85 + return PageResult.empty(taskQuery.count());
  86 + }
  87 +
  88 + // 获得 ProcessInstance Map
  89 + Map<String, ProcessInstance> processInstanceMap = processInstanceService.getProcessInstanceMap(
  90 + convertSet(tasks, Task::getProcessInstanceId));
  91 + // 获得 User Map
  92 + Map<Long, AdminUserRespDTO> userMap = adminUserApi.getUserMap(
  93 + convertSet(processInstanceMap.values(), instance -> Long.valueOf(instance.getStartUserId())));
  94 + // 拼接结果
  95 + return new PageResult<>(BpmTaskConvert.INSTANCE.convertList1(tasks, processInstanceMap, userMap),
  96 + taskQuery.count());
  97 + }
  98 +
  99 + @Override
  100 + public PageResult<BpmTaskDonePageItemRespVO> getDoneTaskPage(Long userId, BpmTaskDonePageReqVO pageVO) {
  101 + // 查询已办任务
  102 + HistoricTaskInstanceQuery taskQuery = historyService.createHistoricTaskInstanceQuery()
  103 + .finished() // 已完成
  104 + .taskAssignee(String.valueOf(userId)) // 分配给自己
  105 + .orderByHistoricTaskInstanceEndTime().desc(); // 审批时间倒序
  106 + if (StrUtil.isNotBlank(pageVO.getName())) {
  107 + taskQuery.taskNameLike("%" + pageVO.getName() + "%");
  108 + }
  109 + if (pageVO.getBeginCreateTime() != null) {
  110 + taskQuery.taskCreatedAfter(pageVO.getBeginCreateTime());
  111 + }
  112 + if (pageVO.getEndCreateTime() != null) {
  113 + taskQuery.taskCreatedBefore(pageVO.getEndCreateTime());
  114 + }
  115 + // 执行查询
  116 + List<HistoricTaskInstance> tasks = taskQuery.listPage(PageUtils.getStart(pageVO), pageVO.getPageSize());
  117 + if (CollUtil.isEmpty(tasks)) {
  118 + return PageResult.empty(taskQuery.count());
  119 + }
  120 +
  121 + // 获得 TaskExtDO Map
  122 + List<BpmTaskExtDO> bpmTaskExtDOs = taskExtMapper.selectListByTaskIds(convertSet(tasks, HistoricTaskInstance::getId));
  123 + Map<String, BpmTaskExtDO> bpmTaskExtDOMap = convertMap(bpmTaskExtDOs, BpmTaskExtDO::getTaskId);
  124 + // 获得 ProcessInstance Map
  125 + Map<String, HistoricProcessInstance> historicProcessInstanceMap = processInstanceService.getHistoricProcessInstanceMap(
  126 + convertSet(tasks, HistoricTaskInstance::getProcessInstanceId));
  127 + // 获得 User Map
  128 + Map<Long, AdminUserRespDTO> userMap = adminUserApi.getUserMap(
  129 + convertSet(historicProcessInstanceMap.values(), instance -> Long.valueOf(instance.getStartUserId())));
  130 + // 拼接结果
  131 + return new PageResult<>(BpmTaskConvert.INSTANCE.convertList2(tasks, bpmTaskExtDOMap, historicProcessInstanceMap, userMap),
  132 + taskQuery.count());
  133 + }
  134 +
  135 + @Override
  136 + public List<Task> getTasksByProcessInstanceIds(List<String> processInstanceIds) {
  137 + if (CollUtil.isEmpty(processInstanceIds)) {
  138 + return Collections.emptyList();
  139 + }
  140 + return taskService.createTaskQuery().processInstanceIdIn(processInstanceIds).list();
  141 + }
  142 +
  143 + @Override
  144 + public List<BpmTaskRespVO> getTaskListByProcessInstanceId(String processInstanceId) {
  145 + // 获得任务列表
  146 + List<HistoricTaskInstance> tasks = historyService.createHistoricTaskInstanceQuery()
  147 + .processInstanceId(processInstanceId)
  148 + .orderByHistoricTaskInstanceStartTime().desc() // 创建时间倒序
  149 + .list();
  150 + if (CollUtil.isEmpty(tasks)) {
  151 + return Collections.emptyList();
  152 + }
  153 +
  154 + // 获得 TaskExtDO Map
  155 + List<BpmTaskExtDO> bpmTaskExtDOs = taskExtMapper.selectListByTaskIds(convertSet(tasks, HistoricTaskInstance::getId));
  156 + Map<String, BpmTaskExtDO> bpmTaskExtDOMap = convertMap(bpmTaskExtDOs, BpmTaskExtDO::getTaskId);
  157 + // 获得 ProcessInstance Map
  158 + HistoricProcessInstance processInstance = processInstanceService.getHistoricProcessInstance(processInstanceId);
  159 + // 获得 User Map
  160 + Set<Long> userIds = convertSet(tasks, task -> NumberUtils.parseLong(task.getAssignee()));
  161 + userIds.add(NumberUtils.parseLong(processInstance.getStartUserId()));
  162 + Map<Long, AdminUserRespDTO> userMap = adminUserApi.getUserMap(userIds);
  163 + // 获得 Dept Map
  164 + Map<Long, DeptRespDTO> deptMap = deptApi.getDeptMap(convertSet(userMap.values(), AdminUserRespDTO::getDeptId));
  165 +
  166 + // 拼接数据
  167 + return BpmTaskConvert.INSTANCE.convertList3(tasks, bpmTaskExtDOMap, processInstance, userMap, deptMap);
  168 + }
  169 +
  170 + @Override
  171 + @Transactional(rollbackFor = Exception.class)
  172 + public void approveTask(Long userId, @Valid BpmTaskApproveReqVO reqVO) {
  173 + // 校验任务存在
  174 + Task task = checkTask(userId, reqVO.getId());
  175 + // 校验流程实例存在
  176 + ProcessInstance instance = processInstanceService.getProcessInstance(task.getProcessInstanceId());
  177 + if (instance == null) {
  178 + throw exception(PROCESS_INSTANCE_NOT_EXISTS);
  179 + }
  180 +
  181 + // 完成任务,审批通过
  182 + taskService.complete(task.getId(), instance.getProcessVariables());
  183 + // 更新任务拓展表为通过
  184 + taskExtMapper.updateByTaskId(new BpmTaskExtDO().setTaskId(task.getId())
  185 + .setResult(BpmProcessInstanceResultEnum.APPROVE.getResult()).setComment(reqVO.getComment()));
  186 + }
  187 +
  188 + @Override
  189 + @Transactional(rollbackFor = Exception.class)
  190 + public void rejectTask(Long userId, @Valid BpmTaskRejectReqVO reqVO) {
  191 + Task task = checkTask(userId, reqVO.getId());
  192 + // 校验流程实例存在
  193 + ProcessInstance instance = processInstanceService.getProcessInstance(task.getProcessInstanceId());
  194 + if (instance == null) {
  195 + throw exception(PROCESS_INSTANCE_NOT_EXISTS);
  196 + }
  197 +
  198 + // 更新流程实例为不通过
  199 + processInstanceService.updateProcessInstanceExtReject(instance.getProcessInstanceId(), reqVO.getComment());
  200 +
  201 + // 更新任务拓展表为不通过
  202 + taskExtMapper.updateByTaskId(new BpmTaskExtDO().setTaskId(task.getId())
  203 + .setResult(BpmProcessInstanceResultEnum.REJECT.getResult()).setComment(reqVO.getComment()));
  204 + }
  205 +
  206 + @Override
  207 + public void updateTaskAssignee(Long userId, BpmTaskUpdateAssigneeReqVO reqVO) {
  208 + // 校验任务存在
  209 + Task task = checkTask(userId, reqVO.getId());
  210 + // 更新负责人
  211 + updateTaskAssignee(task.getId(), reqVO.getAssigneeUserId());
  212 + }
  213 +
  214 + @Override
  215 + public void updateTaskAssignee(String id, Long userId) {
  216 + taskService.setAssignee(id, String.valueOf(userId));
  217 + }
  218 +
  219 +
  220 + @Override
  221 + public void createTaskExt(Task task) {
  222 + BpmTaskExtDO taskExtDO = BpmTaskConvert.INSTANCE.convert2TaskExt(task)
  223 + .setResult(BpmProcessInstanceResultEnum.PROCESS.getResult());
  224 + taskExtMapper.insert(taskExtDO);
  225 + }
  226 +
  227 + @Override
  228 + public void updateTaskExtComplete(Task task) {
  229 + BpmTaskExtDO taskExtDO = BpmTaskConvert.INSTANCE.convert2TaskExt(task)
  230 + .setEndTime(new Date());
  231 + taskExtMapper.updateByTaskId(taskExtDO);
  232 + }
  233 +
  234 + @Override
  235 + public void updateTaskExtAssign(Task task) {
  236 + BpmTaskExtDO taskExtDO = new BpmTaskExtDO()
  237 + .setAssigneeUserId(NumberUtils.parseLong(task.getAssignee()))
  238 + .setTaskId(task.getId());
  239 + taskExtMapper.updateByTaskId(taskExtDO);
  240 + // 发送通知。在事务提交时,批量执行操作,所以直接查询会无法查询到 ProcessInstance,所以这里是通过监听事务的提交来实现。
  241 + TransactionSynchronizationManager.registerSynchronization(new TransactionSynchronization() {
  242 + @Override
  243 + public void afterCommit() {
  244 + ProcessInstance processInstance = processInstanceService.getProcessInstance(task.getProcessInstanceId());
  245 + AdminUserRespDTO startUser = adminUserApi.getUser(Long.valueOf(processInstance.getStartUserId()));
  246 + messageService.sendMessageWhenTaskAssigned(BpmTaskConvert.INSTANCE.convert(processInstance, startUser, task));
  247 + }
  248 + });
  249 + }
  250 +
  251 + /**
  252 + * 校验任务是否存在, 并且是否是分配给自己的任务
  253 + * @param userId 用户 id
  254 + * @param taskId task id
  255 + */
  256 + private Task checkTask(Long userId, String taskId) {
  257 + Task task = getTask(taskId);
  258 + if (task == null) {
  259 + throw exception(TASK_COMPLETE_FAIL_NOT_EXISTS);
  260 + }
  261 + if (!Objects.equals(userId, NumberUtils.parseLong(task.getAssignee()))) {
  262 + throw exception(TASK_COMPLETE_FAIL_ASSIGN_NOT_SELF);
  263 + }
  264 + return task;
  265 + }
  266 +
  267 + private Task getTask(String id) {
  268 + return taskService.createTaskQuery().taskId(id).singleResult();
  269 + }
  270 +}
... ...
yudao-module-member/yudao-module-member-impl/src/main/java/cn/iocoder/yudao/module/member/controller/admin/user/UserController.java 0 → 100644
  1 +package cn.iocoder.yudao.module.member.controller.admin.user;
  2 +
  3 +public class UserController {
  4 +}
... ...
yudao-module-system/yudao-module-system-impl/src/main/java/cn/iocoder/yudao/module/system/enums/common/SexEnum.java renamed to yudao-module-system/yudao-module-system-api/src/main/java/cn/iocoder/yudao/module/system/enums/common/SexEnum.java
yudao-module-system/yudao-module-system-impl/src/main/java/cn/iocoder/yudao/module/system/enums/dept/DeptIdEnum.java renamed to yudao-module-system/yudao-module-system-api/src/main/java/cn/iocoder/yudao/module/system/enums/dept/DeptIdEnum.java
yudao-module-system/yudao-module-system-impl/src/main/java/cn/iocoder/yudao/module/system/enums/errorcode/ErrorCodeTypeEnum.java renamed to yudao-module-system/yudao-module-system-api/src/main/java/cn/iocoder/yudao/module/system/enums/errorcode/ErrorCodeTypeEnum.java
yudao-module-system/yudao-module-system-impl/src/main/java/cn/iocoder/yudao/module/system/enums/notice/NoticeTypeEnum.java renamed to yudao-module-system/yudao-module-system-api/src/main/java/cn/iocoder/yudao/module/system/enums/notice/NoticeTypeEnum.java
yudao-framework/yudao-spring-boot-starter-security/src/main/java/cn/iocoder/yudao/framework/security/core/enums/DataScopeEnum.java renamed to yudao-module-system/yudao-module-system-api/src/main/java/cn/iocoder/yudao/module/system/enums/permission/DataScopeEnum.java
1   -package cn.iocoder.yudao.framework.security.core.enums;
  1 +package cn.iocoder.yudao.module.system.enums.permission;
2 2  
3 3 import lombok.AllArgsConstructor;
4 4 import lombok.Getter;
... ...
yudao-module-system/yudao-module-system-impl/src/main/java/cn/iocoder/yudao/module/system/enums/permission/MenuIdEnum.java renamed to yudao-module-system/yudao-module-system-api/src/main/java/cn/iocoder/yudao/module/system/enums/permission/MenuIdEnum.java
yudao-module-system/yudao-module-system-impl/src/main/java/cn/iocoder/yudao/module/system/enums/permission/MenuTypeEnum.java renamed to yudao-module-system/yudao-module-system-api/src/main/java/cn/iocoder/yudao/module/system/enums/permission/MenuTypeEnum.java
yudao-module-system/yudao-module-system-impl/src/main/java/cn/iocoder/yudao/module/system/enums/permission/RoleCodeEnum.java renamed to yudao-module-system/yudao-module-system-api/src/main/java/cn/iocoder/yudao/module/system/enums/permission/RoleCodeEnum.java
yudao-module-system/yudao-module-system-impl/src/main/java/cn/iocoder/yudao/module/system/enums/permission/RoleTypeEnum.java renamed to yudao-module-system/yudao-module-system-api/src/main/java/cn/iocoder/yudao/module/system/enums/permission/RoleTypeEnum.java
yudao-module-system/yudao-module-system-impl/src/main/java/cn/iocoder/yudao/module/system/enums/sms/SmsReceiveStatusEnum.java renamed to yudao-module-system/yudao-module-system-api/src/main/java/cn/iocoder/yudao/module/system/enums/sms/SmsReceiveStatusEnum.java
yudao-module-system/yudao-module-system-impl/src/main/java/cn/iocoder/yudao/module/system/enums/sms/SmsSendStatusEnum.java renamed to yudao-module-system/yudao-module-system-api/src/main/java/cn/iocoder/yudao/module/system/enums/sms/SmsSendStatusEnum.java
yudao-module-system/yudao-module-system-impl/src/main/java/cn/iocoder/yudao/module/system/enums/sms/SmsTemplateTypeEnum.java renamed to yudao-module-system/yudao-module-system-api/src/main/java/cn/iocoder/yudao/module/system/enums/sms/SmsTemplateTypeEnum.java
yudao-module-system/yudao-module-system-impl/src/main/java/cn/iocoder/yudao/module/system/controller/app/dict/AppDictDataController.java 0 → 100644
  1 +package cn.iocoder.yudao.module.system.controller.app.dict;
  2 +
  3 +public class AppDictDataController {
  4 +}
... ...
yudao-module-system/yudao-module-system-impl/src/main/java/cn/iocoder/yudao/module/system/dal/dataobject/permission/RoleDO.java
... ... @@ -2,7 +2,7 @@ package cn.iocoder.yudao.module.system.dal.dataobject.permission;
2 2  
3 3 import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum;
4 4 import cn.iocoder.yudao.framework.mybatis.core.type.JsonLongSetTypeHandler;
5   -import cn.iocoder.yudao.framework.security.core.enums.DataScopeEnum;
  5 +import cn.iocoder.yudao.module.system.enums.permission.DataScopeEnum;
6 6 import cn.iocoder.yudao.framework.tenant.core.db.TenantBaseDO;
7 7 import cn.iocoder.yudao.module.system.enums.permission.RoleTypeEnum;
8 8 import com.baomidou.mybatisplus.annotation.TableField;
... ...
yudao-module-system/yudao-module-system-impl/src/main/java/cn/iocoder/yudao/module/system/enums/logger/LoginLogTypeEnum.java deleted
1   -package cn.iocoder.yudao.module.system.enums.logger;
2   -
3   -import lombok.AllArgsConstructor;
4   -import lombok.Getter;
5   -
6   -/**
7   - * 登录日志的类型枚举
8   - */
9   -@Getter
10   -@AllArgsConstructor
11   -public enum LoginLogTypeEnum {
12   -
13   - LOGIN_USERNAME(100), // 使用账号登录
14   - LOGIN_SOCIAL(101), // 使用社交登录
15   - LOGIN_MOCK(102), // 使用 Mock 登录
16   - LOGIN_MOBILE(103), // 使用手机登陆
17   - LOGIN_SMS(104), // 使用短信登陆
18   -
19   - LOGOUT_SELF(200), // 自己主动登出
20   - LOGOUT_TIMEOUT(201), // 超时登出
21   - LOGOUT_DELETE(202), // 强制退出
22   - ;
23   -
24   - /**
25   - * 日志类型
26   - */
27   - private final Integer type;
28   -
29   -}
yudao-module-system/yudao-module-system-impl/src/main/java/cn/iocoder/yudao/module/system/enums/logger/LoginResultEnum.java deleted
1   -package cn.iocoder.yudao.module.system.enums.logger;
2   -
3   -import lombok.AllArgsConstructor;
4   -import lombok.Getter;
5   -
6   -/**
7   - * 登录结果的枚举类
8   - */
9   -@Getter
10   -@AllArgsConstructor
11   -public enum LoginResultEnum {
12   -
13   - SUCCESS(0), // 成功
14   - BAD_CREDENTIALS(10), // 账号或密码不正确
15   - USER_DISABLED(20), // 用户被禁用
16   - CAPTCHA_NOT_FOUND(30), // 图片验证码不存在
17   - CAPTCHA_CODE_ERROR(31), // 图片验证码不正确
18   -
19   - UNKNOWN_ERROR(100), // 未知异常
20   - ;
21   -
22   - /**
23   - * 结果
24   - */
25   - private final Integer result;
26   -
27   -}
yudao-module-system/yudao-module-system-impl/src/main/java/cn/iocoder/yudao/module/system/service/permission/PermissionServiceImpl.java
... ... @@ -8,7 +8,7 @@ import cn.iocoder.yudao.framework.common.util.collection.MapUtils;
8 8 import cn.iocoder.yudao.framework.common.util.json.JsonUtils;
9 9 import cn.iocoder.yudao.framework.datapermission.core.dept.service.dto.DeptDataPermissionRespDTO;
10 10 import cn.iocoder.yudao.framework.security.core.LoginUser;
11   -import cn.iocoder.yudao.framework.security.core.enums.DataScopeEnum;
  11 +import cn.iocoder.yudao.module.system.enums.permission.DataScopeEnum;
12 12 import cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils;
13 13 import cn.iocoder.yudao.framework.tenant.core.aop.TenantIgnore;
14 14 import cn.iocoder.yudao.module.system.dal.dataobject.dept.DeptDO;
... ...
yudao-module-system/yudao-module-system-impl/src/main/java/cn/iocoder/yudao/module/system/service/permission/RoleServiceImpl.java
... ... @@ -6,7 +6,7 @@ import cn.hutool.core.util.ObjectUtil;
6 6 import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum;
7 7 import cn.iocoder.yudao.framework.common.pojo.PageResult;
8 8 import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils;
9   -import cn.iocoder.yudao.framework.security.core.enums.DataScopeEnum;
  9 +import cn.iocoder.yudao.module.system.enums.permission.DataScopeEnum;
10 10 import cn.iocoder.yudao.framework.tenant.core.aop.TenantIgnore;
11 11 import cn.iocoder.yudao.module.system.controller.admin.permission.vo.role.RoleCreateReqVO;
12 12 import cn.iocoder.yudao.module.system.controller.admin.permission.vo.role.RoleExportReqVO;
... ...
yudao-module-system/yudao-module-system-impl/src/test/java/cn/iocoder/yudao/module/system/service/permission/PermissionServiceTest.java
... ... @@ -11,7 +11,7 @@ import cn.iocoder.yudao.module.system.mq.producer.permission.PermissionProducer;
11 11 import cn.iocoder.yudao.module.system.service.dept.DeptService;
12 12 import cn.iocoder.yudao.framework.datapermission.core.dept.service.dto.DeptDataPermissionRespDTO;
13 13 import cn.iocoder.yudao.framework.security.core.LoginUser;
14   -import cn.iocoder.yudao.framework.security.core.enums.DataScopeEnum;
  14 +import cn.iocoder.yudao.module.system.enums.permission.DataScopeEnum;
15 15 import cn.iocoder.yudao.module.system.test.BaseDbUnitTest;
16 16 import org.junit.jupiter.api.Test;
17 17 import org.springframework.boot.test.mock.mockito.MockBean;
... ...
yudao-module-system/yudao-module-system-impl/src/test/java/cn/iocoder/yudao/module/system/service/permission/RoleServiceTest.java
... ... @@ -3,7 +3,7 @@ package cn.iocoder.yudao.module.system.service.permission;
3 3 import cn.hutool.core.util.RandomUtil;
4 4 import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum;
5 5 import cn.iocoder.yudao.framework.common.pojo.PageResult;
6   -import cn.iocoder.yudao.framework.security.core.enums.DataScopeEnum;
  6 +import cn.iocoder.yudao.module.system.enums.permission.DataScopeEnum;
7 7 import cn.iocoder.yudao.module.system.controller.admin.permission.vo.role.RoleCreateReqVO;
8 8 import cn.iocoder.yudao.module.system.controller.admin.permission.vo.role.RolePageReqVO;
9 9 import cn.iocoder.yudao.module.system.controller.admin.permission.vo.role.RoleUpdateReqVO;
... ...
yudao-server/pom.xml
... ... @@ -47,12 +47,17 @@
47 47 <artifactId>yudao-module-pay-impl</artifactId>
48 48 <version>${revision}</version>
49 49 </dependency>
50   - <!-- 默认引入 bpm-activiti 实现,可以替换为 bpm-flowable 实现-->
  50 + <!-- 默认引入 yudao-module-bpm-impl-flowable 实现,可以替换为 yudao-module-bpm-impl-activiti 实现-->
51 51 <dependency>
52 52 <groupId>cn.iocoder.boot</groupId>
53   - <artifactId>yudao-module-bpm-impl-activiti</artifactId>
  53 + <artifactId>yudao-module-bpm-impl-flowable</artifactId>
54 54 <version>${revision}</version>
55 55 </dependency>
  56 +<!-- <dependency>-->
  57 +<!-- <groupId>cn.iocoder.boot</groupId>-->
  58 +<!-- <artifactId>yudao-module-bpm-impl-activiti</artifactId>-->
  59 +<!-- <version>${revision}</version>-->
  60 +<!-- </dependency>-->
56 61  
57 62 <!-- spring boot 配置所需依赖 -->
58 63 <dependency>
... ...
yudao-server/src/main/resources/application-local.yaml
... ... @@ -43,13 +43,15 @@ spring:
43 43 primary: master
44 44 datasource:
45 45 master:
46   - name: ruoyi-vue-pro
  46 +# name: ruoyi-vue-pro俺吧
  47 + name: ruoyi-vue-pro-flowable
47 48 url: jdbc:mysql://127.0.0.1:3306/${spring.datasource.dynamic.datasource.master.name}?useSSL=false&allowPublicKeyRetrieval=true&useUnicode=true&characterEncoding=UTF-8&serverTimezone=CTT
48 49 driver-class-name: com.mysql.jdbc.Driver
49 50 username: root
50 51 password: 123456
51 52 slave: # 模拟从库,可根据自己需要修改
52   - name: ruoyi-vue-pro
  53 +# name: ruoyi-vue-pro
  54 + name: ruoyi-vue-pro-flowable
53 55 url: jdbc:mysql://127.0.0.1:3306/${spring.datasource.dynamic.datasource.slave.name}?useSSL=false&allowPublicKeyRetrieval=true&useUnicode=true&characterEncoding=UTF-8&serverTimezone=CTT
54 56 driver-class-name: com.mysql.jdbc.Driver
55 57 username: root
... ...
yudao-server/src/main/resources/application.yaml
... ... @@ -27,10 +27,21 @@ spring:
27 27 # 3. create_drop: 启动时自动创建表,关闭时自动删除表
28 28 # 4. drop_create: 启动时,删除旧表,再创建新表
29 29 database-schema-update: false # 设置为 false,可通过 sql/activiti.sql 初始化
30   - db-history-used: true # activiti7 默认不生成历史信息表,需手动设置开启
  30 + db-history-used: true # activiti7 默认 false 不生成历史信息表,需手动设置开启
31 31 check-process-definitions: false # 设置为 false,禁用 /resources/processes 自动部署 BPMN XML 流程
32 32 history-level: full # full:保存历史数据的最高级别,可保存全部流程相关细节,包括流程流转各节点参数
33 33  
  34 +# 工作流 Flowable 配置
  35 +flowable:
  36 + # 1. false: 默认值,activiti启动时,对比数据库表中保存的版本,如果不匹配。将抛出异常
  37 + # 2. true: 启动时会对数据库中所有表进行更新操作,如果表存在,不做处理,反之,自动创建表
  38 + # 3. create_drop: 启动时自动创建表,关闭时自动删除表
  39 + # 4. drop_create: 启动时,删除旧表,再创建新表
  40 + database-schema-update: false # 设置为 false,可通过 https://github.com/flowable/flowable-sql 初始化
  41 + db-history-used: true # flowable6 默认 true 生成信息表,无需手动设置
  42 + check-process-definitions: false # 设置为 false,禁用 /resources/processes 自动部署 BPMN XML 流程
  43 + history-level: full # full:保存历史数据的最高级别,可保存全部流程相关细节,包括流程流转各节点参数
  44 +
34 45 # MyBatis Plus 的配置项
35 46 mybatis-plus:
36 47 configuration:
... ...
yudao-ui-admin/src/views/bpm/model/index.vue
... ... @@ -291,7 +291,7 @@ export default {
291 291 // 设置上传的请求头部
292 292 headers: getBaseHeader(),
293 293 // 上传的地址
294   - url: process.env.VUE_APP_BASE_API + '/admin-api/' + "/bpm/model/import",
  294 + url: process.env.VUE_APP_BASE_API + '/admin-api' + "/bpm/model/import",
295 295 // 表单
296 296 form: {},
297 297 // 校验规则
... ...