From ee8dcd08882f0bcd05c82760bf7ede0adee280bb Mon Sep 17 00:00:00 2001
From: jason <2667446@qq.com>
Date: Wed, 13 Oct 2021 23:43:03 +0800
Subject: [PATCH] =?UTF-8?q?1.=E5=AE=9E=E7=8E=B0=E4=BA=86=E5=B7=A5=E4=BD=9C?=
=?UTF-8?q?=E6=B5=81=E5=BC=95=E6=93=8E=20=E4=B8=AD=20=E8=AF=B7=E5=81=87?=
=?UTF-8?q?=E6=B5=81=E7=A8=8Bdemo=EF=BC=88=E5=AE=9A=E4=B9=89=E5=9C=A8=20re?=
=?UTF-8?q?sources/leave.bpmn)=202.=E5=A2=9E=E5=8A=A0=E4=B8=80=E4=B8=AA?=
=?UTF-8?q?=E4=B8=80=E7=BA=A7=E8=8F=9C=E5=8D=95=20OA=20=E5=8A=9E=E5=85=AC?=
=?UTF-8?q?=20=E4=B8=8B=E9=9D=A2=E4=B8=A4=E4=B8=AA=E8=8F=9C=E5=8D=95?=
=?UTF-8?q?=EF=BC=9A=20=E8=AF=B7=E5=81=87=E7=94=B3=E8=AF=B7=EF=BC=8C?=
=?UTF-8?q?=E5=BE=85=E5=8A=9E=E4=BB=BB=E5=8A=A1=203.=E6=9A=82=E6=97=B6?=
=?UTF-8?q?=E4=B8=8D=E7=9F=A5=E5=A6=82=E4=BD=95=E6=89=BE=E9=83=A8=E9=97=A8?=
=?UTF-8?q?=E9=A2=86=E5=AF=BC=EF=BC=8C=20=E6=9A=82=E6=97=B6=E5=86=99?=
=?UTF-8?q?=E6=AD=BB=E4=B8=BA=20admin=204.activity=20=E7=94=A8=E6=88=B7?=
=?UTF-8?q?=E7=BB=84=E4=BD=BF=E7=94=A8=20=E7=94=A8=E6=88=B7=E5=B2=97?=
=?UTF-8?q?=E4=BD=8D=E6=9D=A5=E4=BB=A3=E6=9B=BF=E3=80=82=205.=E6=96=B0?=
=?UTF-8?q?=E5=A2=9E=E4=B8=80=E4=B8=AA=E7=94=A8=E6=88=B7=20hradmin?=
=?UTF-8?q?=EF=BC=8C=20=E5=AF=86=E7=A0=81=20123456=20=20=E5=B2=97=E4=BD=8D?=
=?UTF-8?q?=E6=98=AF=20=E4=BA=BA=E5=8A=9B=E8=B5=84=E6=BA=90=206.=E6=BC=94?=
=?UTF-8?q?=E7=A4=BA=E6=B5=81=E7=A8=8B=E3=80=82=20=20=20a.=20admin=20?=
=?UTF-8?q?=E7=99=BB=E9=99=86=20=E7=94=B3=E8=AF=B7=E8=AF=B7=E5=81=87=20=20?=
=?UTF-8?q?=20b.=20admin=20=E5=BE=85=E5=8A=9E=E4=BB=BB=E5=8A=A1=EF=BC=88?=
=?UTF-8?q?=E5=AE=A1=E6=89=B9=EF=BC=89=20=20=20c.=20hradmin=20=E7=99=BB?=
=?UTF-8?q?=E9=99=86=20=E5=BE=85=E5=8A=9E=E4=BB=BB=E5=8A=A1=EF=BC=88?=
=?UTF-8?q?=E5=AE=A1=E6=89=B9=EF=BC=89=20=20=20d.=20admin=20=E7=99=BB?=
=?UTF-8?q?=E9=99=86=20=E5=BE=85=E5=8A=9E=E4=BB=BB=E5=8A=A1=20=EF=BC=88?=
=?UTF-8?q?=E7=A1=AE=E8=AE=A4)?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
sql/ruoyi-vue-pro.sql | 43 +++
yudao-admin-server/pom.xml | 7 +
.../controller/oa/OaLeaveController.java | 104 ++++++
.../controller/oa/vo/OaLeaveBaseVO.java | 48 +++
.../controller/oa/vo/OaLeaveCreateReqVO.java | 14 +
.../controller/oa/vo/OaLeaveExcelVO.java | 44 +++
.../controller/oa/vo/OaLeaveExportReqVO.java | 54 +++
.../controller/oa/vo/OaLeavePageReqVO.java | 56 +++
.../controller/oa/vo/OaLeaveRespVO.java | 16 +
.../controller/oa/vo/OaLeaveUpdateReqVO.java | 18 +
.../controller/workflow/TaskController.java | 57 +++
.../controller/workflow/vo/TaskHandleVO.java | 19 +
.../workflow/vo/TaskQueryReqVO.java | 15 +
.../controller/workflow/vo/TaskReqVO.java | 17 +
.../controller/workflow/vo/TaskStepVO.java | 22 ++
.../workflow/vo/TodoTaskPageReqVO.java | 16 +
.../workflow/vo/TodoTaskRespVO.java | 30 ++
.../activiti/convert/oa/OaLeaveConvert.java | 34 ++
.../convert/workflow/TodoTaskConvert.java | 9 +
.../activiti/dal/dataobject/oa/OaLeaveDO.java | 60 +++
.../activiti/dal/mysql/oa/OaLeaveMapper.java | 46 +++
.../activiti/enums/OaErrorCodeConstants.java | 13 +
.../config/UserGroupManagerService.java | 61 +++
.../service/config/UserGroupsProvider.java | 31 ++
.../activiti/service/oa/OaLeaveService.java | 76 ++++
.../service/oa/ReportBackEndProcessor.java | 30 ++
.../service/oa/impl/OaLeaveServiceImpl.java | 112 ++++++
.../service/workflow/TaskService.java | 23 ++
.../workflow/impl/TaskServiceImpl.java | 264 +++++++++++++
.../service/auth/impl/SysAuthServiceImpl.java | 21 +-
.../src/main/resources/application.yaml | 19 +-
.../mybatis-config/mybatis-config.xml | 52 +++
.../src/main/resources/processes/leave.bpmn | 130 +++++++
yudao-admin-ui/src/api/oa/leave.js | 54 +++
yudao-admin-ui/src/api/oa/todo.js | 75 ++++
yudao-admin-ui/src/utils/dict.js | 3 +
yudao-admin-ui/src/views/oa/leave/index.vue | 347 ++++++++++++++++++
yudao-admin-ui/src/views/oa/todo/index.vue | 284 ++++++++++++++
.../pom.xml | 25 +-
.../config/YudaoActivitiConfiguration.java | 32 ++
.../pom.xml | 12 +
.../framework/security/core/LoginUser.java | 22 +-
.../core/util/SecurityFrameworkUtils.java | 7 +-
43 files changed, 2405 insertions(+), 17 deletions(-)
create mode 100644 yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/activiti/controller/oa/OaLeaveController.java
create mode 100644 yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/activiti/controller/oa/vo/OaLeaveBaseVO.java
create mode 100644 yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/activiti/controller/oa/vo/OaLeaveCreateReqVO.java
create mode 100644 yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/activiti/controller/oa/vo/OaLeaveExcelVO.java
create mode 100644 yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/activiti/controller/oa/vo/OaLeaveExportReqVO.java
create mode 100644 yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/activiti/controller/oa/vo/OaLeavePageReqVO.java
create mode 100644 yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/activiti/controller/oa/vo/OaLeaveRespVO.java
create mode 100644 yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/activiti/controller/oa/vo/OaLeaveUpdateReqVO.java
create mode 100644 yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/activiti/controller/workflow/TaskController.java
create mode 100644 yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/activiti/controller/workflow/vo/TaskHandleVO.java
create mode 100644 yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/activiti/controller/workflow/vo/TaskQueryReqVO.java
create mode 100644 yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/activiti/controller/workflow/vo/TaskReqVO.java
create mode 100644 yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/activiti/controller/workflow/vo/TaskStepVO.java
create mode 100644 yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/activiti/controller/workflow/vo/TodoTaskPageReqVO.java
create mode 100644 yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/activiti/controller/workflow/vo/TodoTaskRespVO.java
create mode 100644 yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/activiti/convert/oa/OaLeaveConvert.java
create mode 100644 yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/activiti/convert/workflow/TodoTaskConvert.java
create mode 100644 yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/activiti/dal/dataobject/oa/OaLeaveDO.java
create mode 100644 yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/activiti/dal/mysql/oa/OaLeaveMapper.java
create mode 100644 yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/activiti/enums/OaErrorCodeConstants.java
create mode 100644 yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/activiti/service/config/UserGroupManagerService.java
create mode 100644 yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/activiti/service/config/UserGroupsProvider.java
create mode 100644 yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/activiti/service/oa/OaLeaveService.java
create mode 100644 yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/activiti/service/oa/ReportBackEndProcessor.java
create mode 100644 yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/activiti/service/oa/impl/OaLeaveServiceImpl.java
create mode 100644 yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/activiti/service/workflow/TaskService.java
create mode 100644 yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/activiti/service/workflow/impl/TaskServiceImpl.java
create mode 100644 yudao-admin-server/src/main/resources/mybatis-config/mybatis-config.xml
create mode 100644 yudao-admin-server/src/main/resources/processes/leave.bpmn
create mode 100644 yudao-admin-ui/src/api/oa/leave.js
create mode 100644 yudao-admin-ui/src/api/oa/todo.js
create mode 100644 yudao-admin-ui/src/views/oa/leave/index.vue
create mode 100644 yudao-admin-ui/src/views/oa/todo/index.vue
create mode 100644 yudao-framework/yudao-spring-boot-starter-activiti/src/main/java/cn/iocoder/yudao/framework/activiti/config/YudaoActivitiConfiguration.java
diff --git a/sql/ruoyi-vue-pro.sql b/sql/ruoyi-vue-pro.sql
index 35b521bb1..866c46b56 100644
--- a/sql/ruoyi-vue-pro.sql
+++ b/sql/ruoyi-vue-pro.sql
@@ -1108,6 +1108,12 @@ INSERT INTO `sys_dict_data` VALUES (76, 2, '接收失败', '20', 'sys_sms_receiv
INSERT INTO `sys_dict_data` VALUES (77, 0, '调试(钉钉)', 'DEBUG_DING_TALK', 'sys_sms_channel_code', 0, NULL, '1', '2021-04-13 00:20:37', '1', '2021-04-13 00:20:37', b'0');
INSERT INTO `sys_dict_data` VALUES (78, 1, '自动生成', '1', 'sys_error_code_type', 0, NULL, '1', '2021-04-21 00:06:48', '1', '2021-04-13 22:06:44', b'0');
INSERT INTO `sys_dict_data` VALUES (79, 2, '手动编辑', '2', 'sys_error_code_type', 0, NULL, '1', '2021-04-21 00:07:14', '1', '2021-04-13 22:06:49', b'0');
+INSERT INTO `sys_dict_data` VALUES (80,0,'病假','1','oa_leave_type',0,NULL,'1','2021-09-21 22:35:28','1','2021-09-21 14:59:27',0x00);
+INSERT INTO `sys_dict_data` VALUES (81,1,'事假','2','oa_leave_type',0,NULL,'1','2021-09-21 22:36:11','1','2021-09-21 14:59:27',0x00);
+INSERT INTO `sys_dict_data` VALUES (82,2,'婚假','3','oa_leave_type',0,NULL,'1','2021-09-21 22:36:38','1','2021-09-21 14:59:27',0x00);
+INSERT INTO `sys_dict_data` VALUES (83,0,'处理中','1','oa_leave_status',0,NULL,'1','2021-09-21 22:46:46','1','2021-10-12 22:12:20',0x00);
+INSERT INTO `sys_dict_data` VALUES (84,1,'流程结束','2','oa_leave_status',0,NULL,'1','2021-09-21 22:47:03','1','2021-10-12 22:12:58',0x00);
+INSERT INTO `sys_dict_data` VALUES (85,2,'完成','3','oa_leave_status',0,NULL,'1','2021-09-21 22:47:25','1','2021-10-12 14:13:06',0x01);
COMMIT;
-- ----------------------------
@@ -1155,6 +1161,9 @@ INSERT INTO `sys_dict_type` VALUES (112, '短信模板的类型', 'sys_sms_templ
INSERT INTO `sys_dict_type` VALUES (113, '短信发送状态', 'sys_sms_send_status', 0, NULL, '1', '2021-04-11 20:18:03', '1', '2021-04-11 09:30:02', b'0');
INSERT INTO `sys_dict_type` VALUES (114, '短信接收状态', 'sys_sms_receive_status', 0, NULL, '1', '2021-04-11 20:27:14', '1', '2021-04-11 20:27:14', b'0');
INSERT INTO `sys_dict_type` VALUES (115, '错误码的类型', 'sys_error_code_type', 0, NULL, '1', '2021-04-21 00:06:30', '1', '2021-04-13 22:07:12', b'0');
+INSERT INTO `sys_dict_type` VALUES (116,'请假类型','oa_leave_type',0,NULL,'1','2021-09-21 22:34:33','1','2021-09-21 15:00:38',0x00);
+INSERT INTO `sys_dict_type` VALUES (117,'请假流程状态','oa_leave_status',0,NULL,'1','2021-09-21 22:46:04','1','2021-09-21 15:00:38',0x00);
+
COMMIT;
-- ----------------------------
@@ -1357,6 +1366,7 @@ INSERT INTO `sys_menu` VALUES (1, '系统管理', '', 1, 1, 0, '/system', 'syste
INSERT INTO `sys_menu` VALUES (2, '基础设施', '', 1, 2, 0, '/infra', 'monitor', NULL, 0, 'admin', '2021-01-05 17:03:48', '', '2021-01-20 14:18:35', b'0');
INSERT INTO `sys_menu` VALUES (3, '研发工具', '', 1, 3, 0, '/tool', 'tool', NULL, 0, 'admin', '2021-01-05 17:03:48', '', '2021-02-06 12:44:42', b'0');
INSERT INTO `sys_menu` VALUES (4, '若依官网', '', 1, 4, 0, 'http://ruoyi.vip', 'guide', NULL, 0, 'admin', '2021-01-05 17:03:48', '', '2021-01-20 21:54:28', b'1');
+INSERT INTO `sys_menu` VALUES (5,'OA 办公','',1,4,0,'/oa','people',NULL,0,'admin','2021-09-20 16:26:19','1','2021-09-20 13:55:54',0x00);
INSERT INTO `sys_menu` VALUES (100, '用户管理', 'system:user:list', 2, 1, 1, 'user', 'user', 'system/user/index', 0, 'admin', '2021-01-05 17:03:48', '', '2021-01-05 22:36:45', b'0');
INSERT INTO `sys_menu` VALUES (101, '角色管理', '', 2, 2, 1, 'role', 'peoples', 'system/role/index', 0, 'admin', '2021-01-05 17:03:48', '1', '2021-03-14 22:04:49', b'0');
INSERT INTO `sys_menu` VALUES (102, '菜单管理', '', 2, 3, 1, 'menu', 'tree-table', 'system/menu/index', 0, 'admin', '2021-01-05 17:03:48', '1', '2021-03-14 22:04:28', b'0');
@@ -1485,6 +1495,14 @@ INSERT INTO `sys_menu` VALUES (1113, '错误码更新', 'system:error-code:updat
INSERT INTO `sys_menu` VALUES (1114, '错误码删除', 'system:error-code:delete', 3, 4, 1110, '', '', '', 0, '', '2021-04-13 21:46:42', '', '2021-04-13 22:09:51', b'0');
INSERT INTO `sys_menu` VALUES (1115, '错误码导出', 'system:error-code:export', 3, 5, 1110, '', '', '', 0, '', '2021-04-13 21:46:42', '', '2021-04-13 22:09:55', b'0');
INSERT INTO `sys_menu` VALUES (1116, '日志中心', '', 2, 8, 2, 'log-center', 'log', 'infra/skywalking/log', 0, '1', '2021-04-26 22:35:45', '1', '2021-04-26 22:37:25', b'0');
+INSERT INTO `sys_menu` VALUES (1118,'请假申请','',2,0,5,'oa/leave','user','oa/leave/index',0,'','2021-09-20 08:51:03','1','2021-10-12 22:19:02',0x00);
+INSERT INTO `sys_menu` VALUES (1119,'请假申请查询','oa:leave:query',3,1,1118,'','','',0,'','2021-09-20 08:51:03','','2021-09-20 08:51:03',0x00);
+INSERT INTO `sys_menu` VALUES (1120,'请假申请创建','oa:leave:create',3,2,1118,'','','',0,'','2021-09-20 08:51:03','','2021-09-20 08:51:03',0x00);
+INSERT INTO `sys_menu` VALUES (1121,'请假申请更新','oa:leave:update',3,3,1118,'','','',0,'','2021-09-20 08:51:03','','2021-09-20 08:51:03',0x00);
+INSERT INTO `sys_menu` VALUES (1122,'请假申请删除','oa:leave:delete',3,4,1118,'','','',0,'','2021-09-20 08:51:03','','2021-09-20 08:51:03',0x00);
+INSERT INTO `sys_menu` VALUES (1123,'请假申请导出','oa:leave:export',3,5,1118,'','','',0,'','2021-09-20 08:51:03','','2021-09-20 08:51:03',0x00);
+INSERT INTO `sys_menu` VALUES (1124,'待办任务','',2,2,5,'todo','edit','oa/todo/index',0,'1','2021-09-20 22:10:09','1','2021-09-21 23:17:12',0x00);
+
COMMIT;
-- ----------------------------
@@ -1958,6 +1976,7 @@ INSERT INTO `sys_user` VALUES (2, 'ry', '$2a$10$7JB720yubVSZvUI0rEqK/.VqGOZTH.ul
INSERT INTO `sys_user` VALUES (100, 'yudao', '$2a$10$11U48RhyJ5pSBYWSn12AD./ld671.ycSzJHbyrtpeoMeYiw31eo8a', '芋道', '不要吓我', 100, '[1]', 'yudao@iocoder.cn', '15601691300', 1, '', 1, '', NULL, '', '2021-01-07 09:07:17', '1', '2021-03-14 22:35:17', b'0');
INSERT INTO `sys_user` VALUES (103, 'yuanma', '', '源码', NULL, 100, NULL, 'yuanma@iocoder.cn', '15601701300', 0, '', 0, '', NULL, '', '2021-01-13 23:50:35', '', '2021-01-13 23:50:35', b'0');
INSERT INTO `sys_user` VALUES (104, 'test', '$2a$10$.TOFpaIiI3PzEwkGrNq0Eu6Cc3rOqJMxTb1DqeSEM8StxaGPBRKoi', '测试号', NULL, 100, '[]', '', '15601691200', 1, '', 0, '', NULL, '', '2021-01-21 02:13:53', '1', '2021-03-14 22:36:38', b'0');
+INSERT INTO `sys_user` VALUES (105,'hradmin','$2a$10$JEhJOL25X1eMnFfR3PILo.MoAljf29YukpL2w6H9GvVGjmqOCuh.O','hr-mgr','hr 管理员',100,'[3]','','',1,'',0,'',NULL,'1','2021-09-25 16:50:41','1','2021-09-25 01:14:09',0x00);
COMMIT;
-- ----------------------------
@@ -1987,6 +2006,7 @@ INSERT INTO `sys_user_role` VALUES (4, 100, 101, '', NULL, '', NULL, b'0');
INSERT INTO `sys_user_role` VALUES (5, 100, 1, '', NULL, '', NULL, b'0');
INSERT INTO `sys_user_role` VALUES (6, 100, 2, '', NULL, '', NULL, b'0');
INSERT INTO `sys_user_role` VALUES (7, 104, 101, '', NULL, '', NULL, b'0');
+INSERT INTO `sys_user_role` VALUES (8,105,1,'1','2021-09-25 16:51:44','1','2021-09-25 16:51:44',0x00);
COMMIT;
-- ----------------------------
@@ -2425,4 +2445,27 @@ INSERT INTO `tool_test_demo` VALUES (106, '老五1', 0, 1, 1, '牛逼哈2', '',
INSERT INTO `tool_test_demo` VALUES (107, '哈哈哈哈', 1, 0, 1, 'biubiubui', '', '2021-02-06 14:00:54', '', '2021-02-06 14:00:54', b'0');
COMMIT;
+
+DROP TABLE IF EXISTS `oa_leave`;
+/*!40101 SET @saved_cs_client = @@character_set_client */;
+/*!40101 SET character_set_client = utf8 */;
+CREATE TABLE `oa_leave` (
+ `id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '请假表单主键',
+ `process_instance_id` varchar(64) DEFAULT NULL COMMENT '流程id',
+ `status` tinyint(4) NOT NULL COMMENT '状态',
+ `user_id` varchar(20) NOT NULL COMMENT '申请人id',
+ `start_time` datetime NOT NULL COMMENT '开始时间',
+ `end_time` datetime NOT NULL COMMENT '结束时间',
+ `leave_type` varchar(20) DEFAULT NULL COMMENT '请假类型',
+ `reason` varchar(2000) DEFAULT NULL COMMENT '原因',
+ `apply_time` datetime NOT NULL COMMENT '申请时间',
+ `creator` varchar(64) DEFAULT '' COMMENT '创建者',
+ `create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
+ `updater` varchar(64) DEFAULT '' COMMENT '更新者',
+ `update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
+ `deleted` bit(1) NOT NULL DEFAULT b'0' COMMENT '是否删除',
+ PRIMARY KEY (`id`)
+) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8mb4 COMMENT='请假申请表';
+/*!40101 SET character_set_client = @saved_cs_client */;
+
SET FOREIGN_KEY_CHECKS = 1;
diff --git a/yudao-admin-server/pom.xml b/yudao-admin-server/pom.xml
index 7a04d6647..624feb2a9 100644
--- a/yudao-admin-server/pom.xml
+++ b/yudao-admin-server/pom.xml
@@ -31,6 +31,11 @@
yudao-spring-boot-starter-biz-sms
+
+ cn.iocoder.boot
+ yudao-spring-boot-starter-activiti
+
+
cn.iocoder.boot
@@ -107,6 +112,8 @@
yudao-spring-boot-starter-excel
+
+
org.apache.velocity
velocity-engine-core
diff --git a/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/activiti/controller/oa/OaLeaveController.java b/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/activiti/controller/oa/OaLeaveController.java
new file mode 100644
index 000000000..e8dd527b9
--- /dev/null
+++ b/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/activiti/controller/oa/OaLeaveController.java
@@ -0,0 +1,104 @@
+package cn.iocoder.yudao.adminserver.modules.activiti.controller.oa;
+
+import cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils;
+import org.springframework.web.bind.annotation.*;
+import javax.annotation.Resource;
+import org.springframework.validation.annotation.Validated;
+import org.springframework.security.access.prepost.PreAuthorize;
+
+import io.swagger.annotations.*;
+
+import javax.validation.constraints.*;
+import javax.validation.*;
+import javax.servlet.http.*;
+import java.util.*;
+import java.io.IOException;
+
+import cn.iocoder.yudao.framework.common.pojo.PageResult;
+import cn.iocoder.yudao.framework.common.pojo.CommonResult;
+import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
+
+import cn.iocoder.yudao.framework.excel.core.util.ExcelUtils;
+
+import cn.iocoder.yudao.framework.operatelog.core.annotations.OperateLog;
+import static cn.iocoder.yudao.framework.operatelog.core.enums.OperateTypeEnum.*;
+
+import cn.iocoder.yudao.adminserver.modules.activiti.controller.oa.vo.*;
+import cn.iocoder.yudao.adminserver.modules.activiti.dal.dataobject.oa.OaLeaveDO;
+import cn.iocoder.yudao.adminserver.modules.activiti.convert.oa.OaLeaveConvert;
+import cn.iocoder.yudao.adminserver.modules.activiti.service.oa.OaLeaveService;
+
+@Api(tags = "请假申请")
+@RestController
+@RequestMapping("/oa/leave")
+@Validated
+public class OaLeaveController {
+
+ @Resource
+ private OaLeaveService leaveService;
+
+ @PostMapping("/create")
+ @ApiOperation("创建请假申请")
+ @PreAuthorize("@ss.hasPermission('oa:leave:create')")
+ public CommonResult createLeave(@Valid @RequestBody OaLeaveCreateReqVO createReqVO) {
+ return success(leaveService.createLeave(createReqVO));
+ }
+
+ @PutMapping("/update")
+ @ApiOperation("更新请假申请")
+ @PreAuthorize("@ss.hasPermission('oa:leave:update')")
+ public CommonResult updateLeave(@Valid @RequestBody OaLeaveUpdateReqVO updateReqVO) {
+ leaveService.updateLeave(updateReqVO);
+ return success(true);
+ }
+
+ @DeleteMapping("/delete")
+ @ApiOperation("删除请假申请")
+ @ApiImplicitParam(name = "id", value = "编号", required = true)
+ @PreAuthorize("@ss.hasPermission('oa:leave:delete')")
+ public CommonResult deleteLeave(@RequestParam("id") Long id) {
+ leaveService.deleteLeave(id);
+ return success(true);
+ }
+
+ @GetMapping("/get")
+ @ApiOperation("获得请假申请")
+ @ApiImplicitParam(name = "id", value = "编号", required = true, example = "1024", dataTypeClass = Long.class)
+ @PreAuthorize("@ss.hasPermission('oa:leave:query')")
+ public CommonResult getLeave(@RequestParam("id") Long id) {
+ OaLeaveDO leave = leaveService.getLeave(id);
+ return success(OaLeaveConvert.INSTANCE.convert(leave));
+ }
+
+ @GetMapping("/list")
+ @ApiOperation("获得请假申请列表")
+ @ApiImplicitParam(name = "ids", value = "编号列表", required = true, example = "1024,2048", dataTypeClass = List.class)
+ @PreAuthorize("@ss.hasPermission('oa:leave:query')")
+ public CommonResult> getLeaveList(@RequestParam("ids") Collection ids) {
+ List list = leaveService.getLeaveList(ids);
+ return success(OaLeaveConvert.INSTANCE.convertList(list));
+ }
+
+ @GetMapping("/page")
+ @ApiOperation("获得请假申请分页")
+ @PreAuthorize("@ss.hasPermission('oa:leave:query')")
+ public CommonResult> getLeavePage(@Valid OaLeavePageReqVO pageVO) {
+ //值查询自己申请请假
+ pageVO.setUserId(SecurityFrameworkUtils.getLoginUser().getUsername());
+ PageResult pageResult = leaveService.getLeavePage(pageVO);
+ return success(OaLeaveConvert.INSTANCE.convertPage(pageResult));
+ }
+
+ @GetMapping("/export-excel")
+ @ApiOperation("导出请假申请 Excel")
+ @PreAuthorize("@ss.hasPermission('oa:leave:export')")
+ @OperateLog(type = EXPORT)
+ public void exportLeaveExcel(@Valid OaLeaveExportReqVO exportReqVO,
+ HttpServletResponse response) throws IOException {
+ List list = leaveService.getLeaveList(exportReqVO);
+ // 导出 Excel
+ List datas = OaLeaveConvert.INSTANCE.convertList02(list);
+ ExcelUtils.write(response, "请假申请.xls", "数据", OaLeaveExcelVO.class, datas);
+ }
+
+}
diff --git a/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/activiti/controller/oa/vo/OaLeaveBaseVO.java b/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/activiti/controller/oa/vo/OaLeaveBaseVO.java
new file mode 100644
index 000000000..ed7f458af
--- /dev/null
+++ b/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/activiti/controller/oa/vo/OaLeaveBaseVO.java
@@ -0,0 +1,48 @@
+package cn.iocoder.yudao.adminserver.modules.activiti.controller.oa.vo;
+
+import lombok.*;
+import java.util.*;
+import io.swagger.annotations.*;
+import javax.validation.constraints.*;
+import org.springframework.format.annotation.DateTimeFormat;
+
+import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND;
+
+/**
+* 请假申请 Base VO,提供给添加、修改、详细的子 VO 使用
+* 如果子 VO 存在差异的字段,请不要添加到这里,影响 Swagger 文档生成
+*/
+@Data
+public class OaLeaveBaseVO {
+
+ @ApiModelProperty(value = "流程id")
+ private String processInstanceId;
+
+ @ApiModelProperty(value = "状态", required = true)
+ private Integer status;
+
+ @ApiModelProperty(value = "申请人id", required = true)
+ private String userId;
+
+ @ApiModelProperty(value = "开始时间", required = true)
+ @NotNull(message = "开始时间不能为空")
+ @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
+ private Date startTime;
+
+ @ApiModelProperty(value = "结束时间", required = true)
+ @NotNull(message = "结束时间不能为空")
+ @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
+ private Date endTime;
+
+ @ApiModelProperty(value = "请假类型")
+ private String leaveType;
+
+ @ApiModelProperty(value = "原因")
+ private String reason;
+
+ @ApiModelProperty(value = "申请时间", required = true)
+ @NotNull(message = "申请时间不能为空")
+ @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
+ private Date applyTime;
+
+}
diff --git a/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/activiti/controller/oa/vo/OaLeaveCreateReqVO.java b/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/activiti/controller/oa/vo/OaLeaveCreateReqVO.java
new file mode 100644
index 000000000..29cede1ff
--- /dev/null
+++ b/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/activiti/controller/oa/vo/OaLeaveCreateReqVO.java
@@ -0,0 +1,14 @@
+package cn.iocoder.yudao.adminserver.modules.activiti.controller.oa.vo;
+
+import lombok.*;
+import java.util.*;
+import io.swagger.annotations.*;
+import javax.validation.constraints.*;
+
+@ApiModel("请假申请创建 Request VO")
+@Data
+@EqualsAndHashCode(callSuper = true)
+@ToString(callSuper = true)
+public class OaLeaveCreateReqVO extends OaLeaveBaseVO {
+
+}
diff --git a/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/activiti/controller/oa/vo/OaLeaveExcelVO.java b/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/activiti/controller/oa/vo/OaLeaveExcelVO.java
new file mode 100644
index 000000000..6c309c180
--- /dev/null
+++ b/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/activiti/controller/oa/vo/OaLeaveExcelVO.java
@@ -0,0 +1,44 @@
+package cn.iocoder.yudao.adminserver.modules.activiti.controller.oa.vo;
+
+import lombok.*;
+import java.util.*;
+import io.swagger.annotations.*;
+
+import com.alibaba.excel.annotation.ExcelProperty;
+
+/**
+ * 请假申请 Excel VO
+ *
+ * @author 芋艿
+ */
+@Data
+public class OaLeaveExcelVO {
+
+ @ExcelProperty("请假表单主键")
+ private Long id;
+
+ @ExcelProperty("流程id")
+ private String processInstanceId;
+
+ @ExcelProperty("状态")
+ private Integer status;
+
+ @ExcelProperty("申请人id")
+ private String userId;
+
+ @ExcelProperty("开始时间")
+ private Date startTime;
+
+ @ExcelProperty("结束时间")
+ private Date endTime;
+
+ @ExcelProperty("请假类型")
+ private String leaveType;
+
+ @ExcelProperty("原因")
+ private String reason;
+
+ @ExcelProperty("申请时间")
+ private Date applyTime;
+
+}
diff --git a/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/activiti/controller/oa/vo/OaLeaveExportReqVO.java b/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/activiti/controller/oa/vo/OaLeaveExportReqVO.java
new file mode 100644
index 000000000..811c50205
--- /dev/null
+++ b/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/activiti/controller/oa/vo/OaLeaveExportReqVO.java
@@ -0,0 +1,54 @@
+package cn.iocoder.yudao.adminserver.modules.activiti.controller.oa.vo;
+
+import lombok.*;
+import java.util.*;
+import io.swagger.annotations.*;
+import cn.iocoder.yudao.framework.common.pojo.PageParam;
+import org.springframework.format.annotation.DateTimeFormat;
+
+import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND;
+
+@ApiModel(value = "请假申请 Excel 导出 Request VO", description = "参数和 OaLeavePageReqVO 是一致的")
+@Data
+public class OaLeaveExportReqVO {
+
+ @ApiModelProperty(value = "流程id")
+ private String processInstanceId;
+
+ @ApiModelProperty(value = "状态")
+ private Integer status;
+
+ @ApiModelProperty(value = "申请人id")
+ private String userId;
+
+ @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
+ @ApiModelProperty(value = "开始开始时间")
+ private Date beginStartTime;
+
+ @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
+ @ApiModelProperty(value = "结束开始时间")
+ private Date endStartTime;
+
+ @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
+ @ApiModelProperty(value = "开始结束时间")
+ private Date beginEndTime;
+
+ @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
+ @ApiModelProperty(value = "结束结束时间")
+ private Date endEndTime;
+
+ @ApiModelProperty(value = "请假类型")
+ private String leaveType;
+
+ @ApiModelProperty(value = "原因")
+ private String reason;
+
+ @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
+ @ApiModelProperty(value = "开始申请时间")
+ private Date beginApplyTime;
+
+ @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
+ @ApiModelProperty(value = "结束申请时间")
+ private Date endApplyTime;
+
+}
diff --git a/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/activiti/controller/oa/vo/OaLeavePageReqVO.java b/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/activiti/controller/oa/vo/OaLeavePageReqVO.java
new file mode 100644
index 000000000..fe879c4ae
--- /dev/null
+++ b/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/activiti/controller/oa/vo/OaLeavePageReqVO.java
@@ -0,0 +1,56 @@
+package cn.iocoder.yudao.adminserver.modules.activiti.controller.oa.vo;
+
+import lombok.*;
+import java.util.*;
+import io.swagger.annotations.*;
+import cn.iocoder.yudao.framework.common.pojo.PageParam;
+import org.springframework.format.annotation.DateTimeFormat;
+
+import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND;
+
+@ApiModel("请假申请分页 Request VO")
+@Data
+@EqualsAndHashCode(callSuper = true)
+@ToString(callSuper = true)
+public class OaLeavePageReqVO extends PageParam {
+
+ @ApiModelProperty(value = "流程id")
+ private String processInstanceId;
+
+ @ApiModelProperty(value = "状态")
+ private Integer status;
+
+ @ApiModelProperty(value = "申请人id")
+ private String userId;
+
+ @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
+ @ApiModelProperty(value = "开始开始时间")
+ private Date beginStartTime;
+
+ @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
+ @ApiModelProperty(value = "结束开始时间")
+ private Date endStartTime;
+
+ @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
+ @ApiModelProperty(value = "开始结束时间")
+ private Date beginEndTime;
+
+ @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
+ @ApiModelProperty(value = "结束结束时间")
+ private Date endEndTime;
+
+ @ApiModelProperty(value = "请假类型")
+ private String leaveType;
+
+ @ApiModelProperty(value = "原因")
+ private String reason;
+
+ @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
+ @ApiModelProperty(value = "开始申请时间")
+ private Date beginApplyTime;
+
+ @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
+ @ApiModelProperty(value = "结束申请时间")
+ private Date endApplyTime;
+
+}
diff --git a/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/activiti/controller/oa/vo/OaLeaveRespVO.java b/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/activiti/controller/oa/vo/OaLeaveRespVO.java
new file mode 100644
index 000000000..7f359d7b1
--- /dev/null
+++ b/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/activiti/controller/oa/vo/OaLeaveRespVO.java
@@ -0,0 +1,16 @@
+package cn.iocoder.yudao.adminserver.modules.activiti.controller.oa.vo;
+
+import lombok.*;
+import java.util.*;
+import io.swagger.annotations.*;
+
+@ApiModel("请假申请 Response VO")
+@Data
+@EqualsAndHashCode(callSuper = true)
+@ToString(callSuper = true)
+public class OaLeaveRespVO extends OaLeaveBaseVO {
+
+ @ApiModelProperty(value = "请假表单主键", required = true)
+ private Long id;
+
+}
diff --git a/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/activiti/controller/oa/vo/OaLeaveUpdateReqVO.java b/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/activiti/controller/oa/vo/OaLeaveUpdateReqVO.java
new file mode 100644
index 000000000..dc81fa31e
--- /dev/null
+++ b/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/activiti/controller/oa/vo/OaLeaveUpdateReqVO.java
@@ -0,0 +1,18 @@
+package cn.iocoder.yudao.adminserver.modules.activiti.controller.oa.vo;
+
+import lombok.*;
+import java.util.*;
+import io.swagger.annotations.*;
+import javax.validation.constraints.*;
+
+@ApiModel("请假申请更新 Request VO")
+@Data
+@EqualsAndHashCode(callSuper = true)
+@ToString(callSuper = true)
+public class OaLeaveUpdateReqVO extends OaLeaveBaseVO {
+
+ @ApiModelProperty(value = "请假表单主键", required = true)
+ @NotNull(message = "请假表单主键不能为空")
+ private Long id;
+
+}
diff --git a/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/activiti/controller/workflow/TaskController.java b/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/activiti/controller/workflow/TaskController.java
new file mode 100644
index 000000000..3a717f116
--- /dev/null
+++ b/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/activiti/controller/workflow/TaskController.java
@@ -0,0 +1,57 @@
+package cn.iocoder.yudao.adminserver.modules.activiti.controller.workflow;
+
+import cn.iocoder.yudao.adminserver.modules.activiti.controller.workflow.vo.*;
+import cn.iocoder.yudao.adminserver.modules.activiti.service.workflow.TaskService;
+import cn.iocoder.yudao.framework.common.pojo.CommonResult;
+import cn.iocoder.yudao.framework.common.pojo.PageResult;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import org.springframework.web.bind.annotation.*;
+
+import javax.annotation.Resource;
+import javax.validation.Valid;
+import java.util.List;
+
+import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
+
+@Api(tags = "工作流待办任务")
+@RestController
+@RequestMapping("/workflow/task")
+public class TaskController {
+
+ @Resource
+ private TaskService taskService;
+
+
+
+ @GetMapping("/todo/page")
+ @ApiOperation("获取待办任务分页")
+ public CommonResult> getTodoTaskPage(@Valid TodoTaskPageReqVO pageVO) {
+ return success(taskService.getTodoTaskPage(pageVO));
+ }
+
+ @GetMapping("/claim")
+ @ApiOperation("签收任务")
+ public CommonResult claimTask(@RequestParam("id") String taskId) {
+ taskService.claimTask(taskId);
+ return success(true);
+ }
+
+
+ @PostMapping("/task-steps")
+ public CommonResult getTaskSteps(@RequestBody TaskQueryReqVO taskQuery) {
+ return success( taskService.getTaskSteps(taskQuery));
+ }
+
+ @PostMapping("/complete")
+ public CommonResult complete(@RequestBody TaskReqVO taskReq) {
+ taskService.completeTask(taskReq);
+ return success(true);
+ }
+
+
+ @GetMapping("/process/history-steps")
+ public CommonResult> getHistorySteps(@RequestParam("id") String processInstanceId) {
+ return success( taskService.getHistorySteps(processInstanceId));
+ }
+}
diff --git a/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/activiti/controller/workflow/vo/TaskHandleVO.java b/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/activiti/controller/workflow/vo/TaskHandleVO.java
new file mode 100644
index 000000000..3ef40fa32
--- /dev/null
+++ b/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/activiti/controller/workflow/vo/TaskHandleVO.java
@@ -0,0 +1,19 @@
+package cn.iocoder.yudao.adminserver.modules.activiti.controller.workflow.vo;
+
+import lombok.Data;
+import lombok.ToString;
+
+import java.util.List;
+
+@Data
+@ToString
+public class TaskHandleVO {
+
+ private Object formObject;
+
+
+ private List historyTask;
+
+
+ private String taskVariable;
+}
diff --git a/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/activiti/controller/workflow/vo/TaskQueryReqVO.java b/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/activiti/controller/workflow/vo/TaskQueryReqVO.java
new file mode 100644
index 000000000..fab24a948
--- /dev/null
+++ b/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/activiti/controller/workflow/vo/TaskQueryReqVO.java
@@ -0,0 +1,15 @@
+package cn.iocoder.yudao.adminserver.modules.activiti.controller.workflow.vo;
+
+import lombok.Data;
+import lombok.ToString;
+
+@Data
+@ToString
+public class TaskQueryReqVO {
+
+ private String processKey;
+
+ private String taskId;
+
+ private String businessKey;
+}
diff --git a/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/activiti/controller/workflow/vo/TaskReqVO.java b/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/activiti/controller/workflow/vo/TaskReqVO.java
new file mode 100644
index 000000000..8e3eb6079
--- /dev/null
+++ b/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/activiti/controller/workflow/vo/TaskReqVO.java
@@ -0,0 +1,17 @@
+package cn.iocoder.yudao.adminserver.modules.activiti.controller.workflow.vo;
+
+import lombok.Data;
+import lombok.ToString;
+
+import java.util.Map;
+
+@Data
+@ToString
+public class TaskReqVO {
+
+ private String taskId;
+
+ private Map variables;
+
+ private String comment;
+}
diff --git a/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/activiti/controller/workflow/vo/TaskStepVO.java b/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/activiti/controller/workflow/vo/TaskStepVO.java
new file mode 100644
index 000000000..fe2335562
--- /dev/null
+++ b/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/activiti/controller/workflow/vo/TaskStepVO.java
@@ -0,0 +1,22 @@
+package cn.iocoder.yudao.adminserver.modules.activiti.controller.workflow.vo;
+
+import lombok.Data;
+import lombok.ToString;
+
+import java.util.Date;
+
+@Data
+@ToString
+public class TaskStepVO {
+
+ private String stepName;
+
+ private Date startTime;
+
+ private Date endTime;
+
+ private String assignee;
+
+ private String comment;
+
+}
diff --git a/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/activiti/controller/workflow/vo/TodoTaskPageReqVO.java b/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/activiti/controller/workflow/vo/TodoTaskPageReqVO.java
new file mode 100644
index 000000000..b5dddbc61
--- /dev/null
+++ b/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/activiti/controller/workflow/vo/TodoTaskPageReqVO.java
@@ -0,0 +1,16 @@
+package cn.iocoder.yudao.adminserver.modules.activiti.controller.workflow.vo;
+
+import cn.iocoder.yudao.framework.common.pojo.PageParam;
+import io.swagger.annotations.ApiModel;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import lombok.ToString;
+
+@ApiModel("待办任务申请分页 Request VO")
+@Data
+@EqualsAndHashCode(callSuper = true)
+@ToString(callSuper = true)
+public class TodoTaskPageReqVO extends PageParam {
+
+ private String assignee;
+}
diff --git a/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/activiti/controller/workflow/vo/TodoTaskRespVO.java b/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/activiti/controller/workflow/vo/TodoTaskRespVO.java
new file mode 100644
index 000000000..5fef60eb5
--- /dev/null
+++ b/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/activiti/controller/workflow/vo/TodoTaskRespVO.java
@@ -0,0 +1,30 @@
+package cn.iocoder.yudao.adminserver.modules.activiti.controller.workflow.vo;
+
+import io.swagger.annotations.ApiModel;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import lombok.ToString;
+
+@ApiModel("待办任务 Response VO")
+@Data
+@ToString
+public class TodoTaskRespVO {
+
+ private String id;
+
+ /**
+ * 1:未签收
+ * 2:已签收
+ */
+ private Integer status;
+
+
+ private String processName;
+
+
+ private String processKey;
+
+
+ private String businessKey;
+
+}
diff --git a/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/activiti/convert/oa/OaLeaveConvert.java b/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/activiti/convert/oa/OaLeaveConvert.java
new file mode 100644
index 000000000..cabf892fe
--- /dev/null
+++ b/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/activiti/convert/oa/OaLeaveConvert.java
@@ -0,0 +1,34 @@
+package cn.iocoder.yudao.adminserver.modules.activiti.convert.oa;
+
+import java.util.*;
+
+import cn.iocoder.yudao.framework.common.pojo.PageResult;
+
+import org.mapstruct.Mapper;
+import org.mapstruct.factory.Mappers;
+import cn.iocoder.yudao.adminserver.modules.activiti.controller.oa.vo.*;
+import cn.iocoder.yudao.adminserver.modules.activiti.dal.dataobject.oa.OaLeaveDO;
+
+/**
+ * 请假申请 Convert
+ *
+ * @author 芋艿
+ */
+@Mapper
+public interface OaLeaveConvert {
+
+ OaLeaveConvert INSTANCE = Mappers.getMapper(OaLeaveConvert.class);
+
+ OaLeaveDO convert(OaLeaveCreateReqVO bean);
+
+ OaLeaveDO convert(OaLeaveUpdateReqVO bean);
+
+ OaLeaveRespVO convert(OaLeaveDO bean);
+
+ List convertList(List list);
+
+ PageResult convertPage(PageResult page);
+
+ List convertList02(List list);
+
+}
diff --git a/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/activiti/convert/workflow/TodoTaskConvert.java b/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/activiti/convert/workflow/TodoTaskConvert.java
new file mode 100644
index 000000000..787cbadd3
--- /dev/null
+++ b/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/activiti/convert/workflow/TodoTaskConvert.java
@@ -0,0 +1,9 @@
+package cn.iocoder.yudao.adminserver.modules.activiti.convert.workflow;
+
+import org.mapstruct.Mapper;
+import org.mapstruct.factory.Mappers;
+
+@Mapper
+public interface TodoTaskConvert {
+ TodoTaskConvert INSTANCE = Mappers.getMapper(TodoTaskConvert.class);
+}
diff --git a/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/activiti/dal/dataobject/oa/OaLeaveDO.java b/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/activiti/dal/dataobject/oa/OaLeaveDO.java
new file mode 100644
index 000000000..dc0aae769
--- /dev/null
+++ b/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/activiti/dal/dataobject/oa/OaLeaveDO.java
@@ -0,0 +1,60 @@
+package cn.iocoder.yudao.adminserver.modules.activiti.dal.dataobject.oa;
+
+import lombok.*;
+import java.util.*;
+import com.baomidou.mybatisplus.annotation.*;
+import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO;
+
+/**
+ * 请假申请 DO
+ *
+ * @author 芋艿
+ */
+@TableName("oa_leave")
+@Data
+@EqualsAndHashCode(callSuper = true)
+@ToString(callSuper = true)
+@Builder
+@NoArgsConstructor
+@AllArgsConstructor
+public class OaLeaveDO extends BaseDO {
+
+ /**
+ * 请假表单主键
+ */
+ @TableId
+ private Long id;
+ /**
+ * 流程id
+ */
+ private String processInstanceId;
+ /**
+ * 状态
+ */
+ private Integer status;
+ /**
+ * 申请人id
+ */
+ private String userId;
+ /**
+ * 开始时间
+ */
+ private Date startTime;
+ /**
+ * 结束时间
+ */
+ private Date endTime;
+ /**
+ * 请假类型
+ */
+ private String leaveType;
+ /**
+ * 原因
+ */
+ private String reason;
+ /**
+ * 申请时间
+ */
+ private Date applyTime;
+
+}
diff --git a/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/activiti/dal/mysql/oa/OaLeaveMapper.java b/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/activiti/dal/mysql/oa/OaLeaveMapper.java
new file mode 100644
index 000000000..6a641c6c0
--- /dev/null
+++ b/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/activiti/dal/mysql/oa/OaLeaveMapper.java
@@ -0,0 +1,46 @@
+package cn.iocoder.yudao.adminserver.modules.activiti.dal.mysql.oa;
+
+import java.util.*;
+
+import cn.iocoder.yudao.framework.common.pojo.PageResult;
+import cn.iocoder.yudao.framework.mybatis.core.query.QueryWrapperX;
+import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX;
+import cn.iocoder.yudao.adminserver.modules.activiti.dal.dataobject.oa.OaLeaveDO;
+import org.apache.ibatis.annotations.Mapper;
+import cn.iocoder.yudao.adminserver.modules.activiti.controller.oa.vo.*;
+
+/**
+ * 请假申请 Mapper
+ *
+ * @author 芋艿
+ */
+@Mapper
+public interface OaLeaveMapper extends BaseMapperX {
+
+ default PageResult selectPage(OaLeavePageReqVO reqVO) {
+ return selectPage(reqVO, new QueryWrapperX()
+ .eqIfPresent("process_instance_id", reqVO.getProcessInstanceId())
+ .eqIfPresent("status", reqVO.getStatus())
+ .eqIfPresent("user_id", reqVO.getUserId())
+ .betweenIfPresent("start_time", reqVO.getBeginStartTime(), reqVO.getEndStartTime())
+ .betweenIfPresent("end_time", reqVO.getBeginEndTime(), reqVO.getEndEndTime())
+ .eqIfPresent("leave_type", reqVO.getLeaveType())
+ .eqIfPresent("reason", reqVO.getReason())
+ .betweenIfPresent("apply_time", reqVO.getBeginApplyTime(), reqVO.getEndApplyTime())
+ .orderByDesc("id") );
+ }
+
+ default List selectList(OaLeaveExportReqVO reqVO) {
+ return selectList(new QueryWrapperX()
+ .eqIfPresent("process_instance_id", reqVO.getProcessInstanceId())
+ .eqIfPresent("status", reqVO.getStatus())
+ .eqIfPresent("user_id", reqVO.getUserId())
+ .betweenIfPresent("start_time", reqVO.getBeginStartTime(), reqVO.getEndStartTime())
+ .betweenIfPresent("end_time", reqVO.getBeginEndTime(), reqVO.getEndEndTime())
+ .eqIfPresent("leave_type", reqVO.getLeaveType())
+ .eqIfPresent("reason", reqVO.getReason())
+ .betweenIfPresent("apply_time", reqVO.getBeginApplyTime(), reqVO.getEndApplyTime())
+ .orderByDesc("id") );
+ }
+
+}
diff --git a/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/activiti/enums/OaErrorCodeConstants.java b/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/activiti/enums/OaErrorCodeConstants.java
new file mode 100644
index 000000000..78a946112
--- /dev/null
+++ b/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/activiti/enums/OaErrorCodeConstants.java
@@ -0,0 +1,13 @@
+package cn.iocoder.yudao.adminserver.modules.activiti.enums;
+
+import cn.iocoder.yudao.framework.common.exception.ErrorCode;
+/**
+ * activiti 系统 错误码枚举类
+ *
+ * 003 activiti
+ * 001 oa
+ * activiti 系统,使用 1-003-000-000 段
+ */
+public interface OaErrorCodeConstants {
+ ErrorCode LEAVE_NOT_EXISTS = new ErrorCode(1003001001, "请假申请不存在");
+}
diff --git a/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/activiti/service/config/UserGroupManagerService.java b/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/activiti/service/config/UserGroupManagerService.java
new file mode 100644
index 000000000..0b10f3c53
--- /dev/null
+++ b/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/activiti/service/config/UserGroupManagerService.java
@@ -0,0 +1,61 @@
+package cn.iocoder.yudao.adminserver.modules.activiti.service.config;
+
+import cn.iocoder.yudao.adminserver.modules.system.dal.dataobject.user.SysUserDO;
+import cn.iocoder.yudao.adminserver.modules.system.service.dept.SysPostService;
+import cn.iocoder.yudao.adminserver.modules.system.service.permission.SysPermissionService;
+import cn.iocoder.yudao.adminserver.modules.system.service.user.SysUserService;
+import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum;
+import cn.iocoder.yudao.framework.security.core.LoginUser;
+import org.activiti.api.runtime.shared.identity.UserGroupManager;
+import org.springframework.security.core.userdetails.UserDetails;
+import org.springframework.security.core.userdetails.UserDetailsService;
+import org.springframework.stereotype.Service;
+
+
+import javax.annotation.Resource;
+import java.util.*;
+import java.util.stream.Collectors;
+
+import static java.util.Collections.singleton;
+
+@Service
+public class UserGroupManagerService implements UserGroupManager {
+
+ @Resource
+ private UserDetailsService userDetailsService;
+
+ @Resource
+ private SysUserService userService;
+
+ @Resource
+ private SysPostService sysPostService;
+
+ /**
+ * 暂时使用岗位来代替
+ * @param userId
+ * @return
+ */
+ @Override
+ public List getUserGroups(String userId) {
+ final LoginUser loginUser = (LoginUser) userDetailsService.loadUserByUsername(userId);
+ final Long id = loginUser.getId();
+ final SysUserDO user = userService.getUser(id);
+ return sysPostService.getPosts(user.getPostIds()).stream().map(post -> post.getCode()).collect(Collectors.toList());
+
+ }
+
+ @Override
+ public List getUserRoles(String userId) {
+ return Arrays.asList("ROLE_ACTIVITI_USER");
+ }
+
+ @Override
+ public List getGroups() {
+ throw new UnsupportedOperationException("getGroups is now un supported");
+ }
+
+ @Override
+ public List getUsers() {
+ throw new UnsupportedOperationException("getGroups is now un supported");
+ }
+}
diff --git a/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/activiti/service/config/UserGroupsProvider.java b/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/activiti/service/config/UserGroupsProvider.java
new file mode 100644
index 000000000..3f8b55299
--- /dev/null
+++ b/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/activiti/service/config/UserGroupsProvider.java
@@ -0,0 +1,31 @@
+package cn.iocoder.yudao.adminserver.modules.activiti.service.config;
+
+import cn.iocoder.yudao.framework.security.core.LoginUser;
+import org.activiti.api.runtime.shared.security.PrincipalGroupsProvider;
+import org.springframework.security.core.Authentication;
+import org.springframework.stereotype.Service;
+
+import java.security.Principal;
+import java.util.Collections;
+import java.util.List;
+
+@Service
+public class UserGroupsProvider implements PrincipalGroupsProvider {
+
+ @Override
+ public List getGroups(Principal principal) {
+
+ if(principal instanceof Authentication){
+ Authentication authentication = (Authentication) principal;
+ final Object user = authentication.getPrincipal();
+ if( user instanceof LoginUser){
+ return ((LoginUser) user).getGroups();
+ }else{
+ return Collections.emptyList();
+ }
+ }else{
+ return Collections.emptyList();
+ }
+
+ }
+}
diff --git a/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/activiti/service/oa/OaLeaveService.java b/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/activiti/service/oa/OaLeaveService.java
new file mode 100644
index 000000000..f5c84115a
--- /dev/null
+++ b/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/activiti/service/oa/OaLeaveService.java
@@ -0,0 +1,76 @@
+package cn.iocoder.yudao.adminserver.modules.activiti.service.oa;
+
+
+import cn.iocoder.yudao.adminserver.modules.activiti.controller.oa.vo.OaLeaveCreateReqVO;
+import cn.iocoder.yudao.adminserver.modules.activiti.controller.oa.vo.OaLeaveExportReqVO;
+import cn.iocoder.yudao.adminserver.modules.activiti.controller.oa.vo.OaLeavePageReqVO;
+import cn.iocoder.yudao.adminserver.modules.activiti.controller.oa.vo.OaLeaveUpdateReqVO;
+import cn.iocoder.yudao.adminserver.modules.activiti.dal.dataobject.oa.OaLeaveDO;
+import cn.iocoder.yudao.framework.common.pojo.PageResult;
+
+import javax.validation.Valid;
+import java.util.Collection;
+import java.util.List;
+
+/**
+ * 请假申请 Service 接口
+ *
+ * @author 芋艿
+ */
+public interface OaLeaveService {
+
+ /**
+ * 创建请假申请
+ *
+ * @param createReqVO 创建信息
+ * @return 编号
+ */
+ Long createLeave(@Valid OaLeaveCreateReqVO createReqVO);
+
+ /**
+ * 更新请假申请
+ *
+ * @param updateReqVO 更新信息
+ */
+ void updateLeave(@Valid OaLeaveUpdateReqVO updateReqVO);
+
+ /**
+ * 删除请假申请
+ *
+ * @param id 编号
+ */
+ void deleteLeave(Long id);
+
+ /**
+ * 获得请假申请
+ *
+ * @param id 编号
+ * @return 请假申请
+ */
+ OaLeaveDO getLeave(Long id);
+
+ /**
+ * 获得请假申请列表
+ *
+ * @param ids 编号
+ * @return 请假申请列表
+ */
+ List getLeaveList(Collection ids);
+
+ /**
+ * 获得请假申请分页
+ *
+ * @param pageReqVO 分页查询
+ * @return 请假申请分页
+ */
+ PageResult getLeavePage(OaLeavePageReqVO pageReqVO);
+
+ /**
+ * 获得请假申请列表, 用于 Excel 导出
+ *
+ * @param exportReqVO 查询条件
+ * @return 请假申请列表
+ */
+ List getLeaveList(OaLeaveExportReqVO exportReqVO);
+
+}
diff --git a/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/activiti/service/oa/ReportBackEndProcessor.java b/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/activiti/service/oa/ReportBackEndProcessor.java
new file mode 100644
index 000000000..05ed6fb7d
--- /dev/null
+++ b/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/activiti/service/oa/ReportBackEndProcessor.java
@@ -0,0 +1,30 @@
+package cn.iocoder.yudao.adminserver.modules.activiti.service.oa;
+
+import cn.iocoder.yudao.adminserver.modules.activiti.dal.dataobject.oa.OaLeaveDO;
+import cn.iocoder.yudao.adminserver.modules.activiti.dal.mysql.oa.OaLeaveMapper;
+import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
+import org.activiti.engine.delegate.DelegateTask;
+import org.activiti.engine.delegate.TaskListener;
+import org.springframework.stereotype.Component;
+import org.springframework.transaction.annotation.Transactional;
+
+import javax.annotation.Resource;
+
+@Component
+public class ReportBackEndProcessor implements TaskListener {
+
+ @Resource
+ private OaLeaveMapper leaveMapper;
+
+
+ @Override
+ @Transactional(rollbackFor = Exception.class)
+ public void notify(DelegateTask delegateTask) {
+ final String businessKey = delegateTask.getExecution().getProcessInstanceBusinessKey();
+ UpdateWrapper updateWrapper = new UpdateWrapper<>();
+ updateWrapper.eq("id", Long.valueOf(businessKey));
+ OaLeaveDO updateDo = new OaLeaveDO();
+ updateDo.setStatus(2);
+ leaveMapper.update(updateDo, updateWrapper);
+ }
+}
diff --git a/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/activiti/service/oa/impl/OaLeaveServiceImpl.java b/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/activiti/service/oa/impl/OaLeaveServiceImpl.java
new file mode 100644
index 000000000..c82e7a100
--- /dev/null
+++ b/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/activiti/service/oa/impl/OaLeaveServiceImpl.java
@@ -0,0 +1,112 @@
+package cn.iocoder.yudao.adminserver.modules.activiti.service.oa.impl;
+
+import cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils;
+import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
+import org.activiti.engine.RuntimeService;
+import org.activiti.engine.runtime.ProcessInstance;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+import javax.annotation.Resource;
+
+import org.springframework.transaction.annotation.Transactional;
+import org.springframework.validation.annotation.Validated;
+
+import java.util.*;
+import cn.iocoder.yudao.adminserver.modules.activiti.controller.oa.vo.*;
+import cn.iocoder.yudao.adminserver.modules.activiti.dal.dataobject.oa.OaLeaveDO;
+import cn.iocoder.yudao.framework.common.pojo.PageResult;
+
+import cn.iocoder.yudao.adminserver.modules.activiti.convert.oa.OaLeaveConvert;
+import cn.iocoder.yudao.adminserver.modules.activiti.dal.mysql.oa.OaLeaveMapper;
+import cn.iocoder.yudao.adminserver.modules.activiti.service.oa.OaLeaveService;
+
+import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
+import static cn.iocoder.yudao.adminserver.modules.activiti.enums.OaErrorCodeConstants.*;
+
+/**
+ * 请假申请 Service 实现类
+ *
+ * @author 芋艿
+ */
+@Service
+@Validated
+public class OaLeaveServiceImpl implements OaLeaveService {
+
+ @Resource
+ private OaLeaveMapper leaveMapper;
+
+ @Resource
+ private RuntimeService runtimeService;
+
+ @Override
+ @Transactional(rollbackFor = Exception.class)
+ public Long createLeave(OaLeaveCreateReqVO createReqVO) {
+ // 插入
+ OaLeaveDO leave = OaLeaveConvert.INSTANCE.convert(createReqVO);
+ leave.setStatus(1);
+ leave.setUserId(SecurityFrameworkUtils.getLoginUser().getUsername());
+ leaveMapper.insert(leave);
+
+ Map variables = new HashMap<>();
+ //如何得到部门领导人, 暂时写死
+ variables.put("deptLeader", "admin");
+ final Long id = leave.getId();
+ String businessKey = String.valueOf(id);
+ ProcessInstance processInstance = runtimeService.startProcessInstanceByKey("leave", businessKey, variables);
+
+ final String processInstanceId = processInstance.getProcessInstanceId();
+
+
+ UpdateWrapper updateWrapper = new UpdateWrapper<>();
+ updateWrapper.eq("id", id);
+ OaLeaveDO updateDo = new OaLeaveDO();
+ updateDo.setProcessInstanceId(processInstanceId);
+ leaveMapper.update(updateDo, updateWrapper);
+ // 返回
+ return id;
+ }
+
+ @Override
+ public void updateLeave(OaLeaveUpdateReqVO updateReqVO) {
+ // 校验存在
+ this.validateLeaveExists(updateReqVO.getId());
+ // 更新
+ OaLeaveDO updateObj = OaLeaveConvert.INSTANCE.convert(updateReqVO);
+ leaveMapper.updateById(updateObj);
+ }
+
+ @Override
+ public void deleteLeave(Long id) {
+ // 校验存在
+ this.validateLeaveExists(id);
+ // 删除
+ leaveMapper.deleteById(id);
+ }
+
+ private void validateLeaveExists(Long id) {
+ if (leaveMapper.selectById(id) == null) {
+ throw exception(LEAVE_NOT_EXISTS);
+ }
+ }
+
+ @Override
+ public OaLeaveDO getLeave(Long id) {
+ return leaveMapper.selectById(id);
+ }
+
+ @Override
+ public List getLeaveList(Collection ids) {
+ return leaveMapper.selectBatchIds(ids);
+ }
+
+ @Override
+ public PageResult getLeavePage(OaLeavePageReqVO pageReqVO) {
+ return leaveMapper.selectPage(pageReqVO);
+ }
+
+ @Override
+ public List getLeaveList(OaLeaveExportReqVO exportReqVO) {
+ return leaveMapper.selectList(exportReqVO);
+ }
+
+}
diff --git a/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/activiti/service/workflow/TaskService.java b/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/activiti/service/workflow/TaskService.java
new file mode 100644
index 000000000..ae0783b48
--- /dev/null
+++ b/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/activiti/service/workflow/TaskService.java
@@ -0,0 +1,23 @@
+package cn.iocoder.yudao.adminserver.modules.activiti.service.workflow;
+
+import cn.iocoder.yudao.adminserver.modules.activiti.controller.workflow.vo.*;
+import cn.iocoder.yudao.framework.common.pojo.PageResult;
+
+import javax.servlet.http.HttpServletResponse;
+import java.util.List;
+
+public interface TaskService {
+
+ PageResult getTodoTaskPage(TodoTaskPageReqVO pageReqVO);
+
+ void claimTask(String taskId);
+
+ void getTaskHistory(String taskId);
+
+ void completeTask(TaskReqVO taskReq);
+
+// void flowImage(String taskId, HttpServletResponse response);
+ TaskHandleVO getTaskSteps(TaskQueryReqVO taskQuery);
+
+ List getHistorySteps(String processInstanceId);
+}
diff --git a/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/activiti/service/workflow/impl/TaskServiceImpl.java b/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/activiti/service/workflow/impl/TaskServiceImpl.java
new file mode 100644
index 000000000..aae12755b
--- /dev/null
+++ b/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/activiti/service/workflow/impl/TaskServiceImpl.java
@@ -0,0 +1,264 @@
+package cn.iocoder.yudao.adminserver.modules.activiti.service.workflow.impl;
+
+import cn.iocoder.yudao.adminserver.modules.activiti.controller.workflow.vo.*;
+import cn.iocoder.yudao.adminserver.modules.activiti.convert.oa.OaLeaveConvert;
+import cn.iocoder.yudao.adminserver.modules.activiti.dal.dataobject.oa.OaLeaveDO;
+import cn.iocoder.yudao.adminserver.modules.activiti.dal.mysql.oa.OaLeaveMapper;
+import cn.iocoder.yudao.adminserver.modules.activiti.service.oa.OaLeaveService;
+import cn.iocoder.yudao.adminserver.modules.activiti.service.workflow.TaskService;
+import cn.iocoder.yudao.framework.common.pojo.PageResult;
+import cn.iocoder.yudao.framework.security.core.LoginUser;
+import cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils;
+import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
+import com.google.common.collect.ImmutableMap;
+import org.activiti.api.process.runtime.ProcessRuntime;
+import org.activiti.api.runtime.shared.query.Page;
+import org.activiti.api.runtime.shared.query.Pageable;
+import org.activiti.api.task.model.Task;
+import org.activiti.api.task.model.builders.ClaimTaskPayloadBuilder;
+import org.activiti.api.task.model.builders.GetTasksPayloadBuilder;
+import org.activiti.api.task.model.builders.TaskPayloadBuilder;
+import org.activiti.api.task.runtime.TaskRuntime;
+import org.activiti.bpmn.model.BpmnModel;
+import org.activiti.bpmn.model.Process;
+import org.activiti.engine.HistoryService;
+import org.activiti.engine.RepositoryService;
+import org.activiti.engine.history.HistoricActivityInstance;
+import org.activiti.engine.history.HistoricProcessInstance;
+import org.activiti.engine.history.HistoricVariableInstance;
+import org.activiti.engine.impl.persistence.entity.ProcessDefinitionEntity;
+import org.activiti.engine.repository.ProcessDefinition;
+import org.activiti.engine.task.Comment;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+
+import javax.annotation.Resource;
+import javax.servlet.http.HttpServletResponse;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+import java.util.Optional;
+import java.util.stream.Collectors;
+
+@Service
+public class TaskServiceImpl implements TaskService {
+
+ @Resource
+ private TaskRuntime taskRuntime;
+
+ @Resource
+ private org.activiti.engine.TaskService activitiTaskService;
+
+ @Resource
+ private HistoryService historyService;
+
+ @Resource
+ private RepositoryService repositoryService;
+
+ @Resource
+ private OaLeaveMapper leaveMapper;
+
+ private static Map taskVariable = ImmutableMap.builder()
+ .put("deptLeaderVerify","deptLeaderApproved")
+ .put("hrVerify","hrApproved")
+ .build();
+
+ public TaskServiceImpl() {
+
+ }
+
+ @Override
+ public PageResult getTodoTaskPage(TodoTaskPageReqVO pageReqVO) {
+ final LoginUser loginUser = SecurityFrameworkUtils.getLoginUser();
+ final Pageable pageable = Pageable.of((pageReqVO.getPageNo() - 1) * pageReqVO.getPageSize(), pageReqVO.getPageSize());
+ Page pageTasks = taskRuntime.tasks(pageable);
+ List tasks = pageTasks.getContent();
+ int totalItems = pageTasks.getTotalItems();
+ final List respVOList = tasks.stream().map(task -> {
+ TodoTaskRespVO respVO = new TodoTaskRespVO();
+ respVO.setId(task.getId());
+ final ProcessDefinition definition = repositoryService.getProcessDefinition(task.getProcessDefinitionId());
+ respVO.setProcessName(definition.getName());
+ respVO.setProcessKey(definition.getKey());
+ respVO.setBusinessKey(task.getBusinessKey());
+ respVO.setStatus(task.getAssignee() == null ? 1 : 2);
+ return respVO;
+ }).collect(Collectors.toList());
+ return new PageResult(respVOList, Long.valueOf(totalItems));
+ }
+
+
+ @Override
+ public void claimTask(String taskId) {
+ taskRuntime.claim(new ClaimTaskPayloadBuilder()
+ .withTaskId(taskId)
+ .withAssignee(SecurityFrameworkUtils.getLoginUser().getUsername())
+ .build());
+ }
+
+ @Override
+ public void getTaskHistory(String taskId) {
+
+ final List list = historyService.createHistoricProcessInstanceQuery().
+ processInstanceId("8e2801fc-1a38-11ec-98ce-74867a13730f").list();
+
+ }
+
+ @Override
+ @Transactional
+ public void completeTask(TaskReqVO taskReq) {
+ final Task task = taskRuntime.task(taskReq.getTaskId());
+
+ final Map variables = taskReq.getVariables();
+
+ activitiTaskService.addComment(taskReq.getTaskId(), task.getProcessInstanceId(), taskReq.getComment());
+
+ taskRuntime.complete(TaskPayloadBuilder.complete().withTaskId(taskReq.getTaskId())
+ .withVariables(taskReq.getVariables())
+ .build());
+
+ if(variables.containsValue(Boolean.FALSE)){
+ final String businessKey = task.getBusinessKey();
+ UpdateWrapper updateWrapper = new UpdateWrapper<>();
+ updateWrapper.eq("id", Long.valueOf(businessKey));
+ OaLeaveDO updateDo = new OaLeaveDO();
+ updateDo.setStatus(2);
+ leaveMapper.update(updateDo, updateWrapper);
+ }
+
+ }
+
+// @Override
+// public void flowImage(String taskId, HttpServletResponse response) {
+//
+// final Task task = taskRuntime.task(taskId);
+// BpmnModel bpmnModel = repositoryService.getBpmnModel(task.getProcessDefinitionId());
+// final Process process = bpmnModel.getMainProcess();
+// ProcessDefinitionEntity processDefinition = repositoryService.createProcessDefinitionQuery().processDefinitionId(task.getProcessDefinitionId()).singleResult();
+// List activeActivityIds = runtimeService.getActiveActivityIds(executionId);
+// List highLightedFlows = getHighLightedFlows(processDefinition, processInstance.getId());
+// ProcessDiagramGenerator diagramGenerator = processEngineConfiguration.getProcessDiagramGenerator();
+// InputStream imageStream =diagramGenerator.generateDiagram(bpmnModel, "png", activeActivityIds, highLightedFlows);
+//
+// // 输出资源内容到相应对象
+// byte[] b = new byte[1024];
+// int len;
+// while ((len = imageStream.read(b, 0, 1024)) != -1) {
+// response.getOutputStream().write(b, 0, len);
+// }
+// }
+
+ @Override
+ public TaskHandleVO getTaskSteps(TaskQueryReqVO taskQuery) {
+ TaskHandleVO handleVO = new TaskHandleVO();
+
+ String processKey = taskQuery.getProcessKey();
+ if ("leave".equals(processKey)) {
+ String businessKey = taskQuery.getBusinessKey();
+ final OaLeaveDO leave = leaveMapper.selectById(Long.valueOf(businessKey));
+ handleVO.setFormObject( OaLeaveConvert.INSTANCE.convert(leave));
+ }
+
+ final Task task = taskRuntime.task(taskQuery.getTaskId());
+ final String taskDefKey = task.getTaskDefinitionKey();
+ final String variableName = Optional.ofNullable(taskVariable.get(taskDefKey)).orElse("");
+
+
+ handleVO.setTaskVariable(variableName);
+ List steps = getTaskSteps(task.getProcessInstanceId());
+
+ handleVO.setHistoryTask(steps);
+ return handleVO;
+ }
+
+
+ private List getTaskSteps(String processInstanceId) {
+
+ List steps = new ArrayList<>();
+
+ List finished = historyService
+ .createHistoricActivityInstanceQuery()
+ .processInstanceId(processInstanceId)
+ .activityType("userTask")
+ .finished()
+ .orderByHistoricActivityInstanceStartTime().asc().list();
+
+ finished.forEach(instance->{
+ TaskStepVO step = new TaskStepVO();
+ step.setStepName(instance.getActivityName());
+ step.setStartTime(instance.getStartTime());
+ step.setEndTime(instance.getEndTime());
+ step.setAssignee(instance.getAssignee());
+ final List comments = activitiTaskService.getTaskComments(instance.getTaskId());
+ if(comments.size()>0){
+ step.setComment(comments.get(0).getFullMessage());
+ }else{
+ step.setComment("");
+ }
+ steps.add(step);
+ });
+
+ List unfinished = historyService
+ .createHistoricActivityInstanceQuery()
+ .processInstanceId(processInstanceId)
+ .activityType("userTask")
+ .unfinished().list();
+
+ if(unfinished.size()>0) {
+
+ final HistoricActivityInstance unFinishedActiviti = unfinished.get(0);
+ TaskStepVO step = new TaskStepVO();
+ step.setStepName(unFinishedActiviti.getActivityName());
+ step.setStartTime(unFinishedActiviti.getStartTime());
+ step.setEndTime(unFinishedActiviti.getEndTime());
+ step.setAssignee(Optional.ofNullable(unFinishedActiviti.getAssignee()).orElse(""));
+ step.setComment("");
+ steps.add(step);
+ }
+ return steps;
+ }
+
+
+ @Override
+ public List getHistorySteps(String processInstanceId) {
+
+ return getTaskSteps(processInstanceId);
+ }
+
+
+
+// private List getHighLightedFlows(ProcessDefinitionEntity processDefinition, String processInstanceId) {
+//
+// List highLightedFlows = new ArrayList();
+// List historicActivityInstances = historyService
+// .createHistoricActivityInstanceQuery()
+// .processInstanceId(processInstanceId)
+// .orderByHistoricActivityInstanceStartTime().asc().list();
+//
+// List historicActivityInstanceList = new ArrayList();
+// for (HistoricActivityInstance hai : historicActivityInstances) {
+// historicActivityInstanceList.add(hai.getActivityId());
+// }
+
+// // add current activities to list
+// List highLightedActivities = runtimeService.getActiveActivityIds(processInstanceId);
+// historicActivityInstanceList.addAll(highLightedActivities);
+
+ // activities and their sequence-flows
+// for (ActivityImpl activity : processDefinition.getActivities()) {
+// int index = historicActivityInstanceList.indexOf(activity.getId());
+//
+// if (index >= 0 && index + 1 < historicActivityInstanceList.size()) {
+// List pvmTransitionList = activity
+// .getOutgoingTransitions();
+// for (PvmTransition pvmTransition : pvmTransitionList) {
+// String destinationFlowId = pvmTransition.getDestination().getId();
+// if (destinationFlowId.equals(historicActivityInstanceList.get(index + 1))) {
+// highLightedFlows.add(pvmTransition.getId());
+// }
+// }
+// }
+// }
+// return highLightedFlows;
+// }
+}
diff --git a/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/system/service/auth/impl/SysAuthServiceImpl.java b/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/system/service/auth/impl/SysAuthServiceImpl.java
index f69c96736..63869170d 100644
--- a/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/system/service/auth/impl/SysAuthServiceImpl.java
+++ b/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/system/service/auth/impl/SysAuthServiceImpl.java
@@ -1,5 +1,6 @@
package cn.iocoder.yudao.adminserver.modules.system.service.auth.impl;
+import cn.iocoder.yudao.adminserver.modules.system.service.dept.SysPostService;
import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum;
import cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil;
import cn.iocoder.yudao.framework.security.core.LoginUser;
@@ -31,10 +32,14 @@ import org.springframework.stereotype.Service;
import org.springframework.util.Assert;
import javax.annotation.Resource;
+import java.util.List;
+import java.util.Optional;
import java.util.Set;
+import java.util.stream.Collectors;
import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
import static cn.iocoder.yudao.adminserver.modules.system.enums.SysErrorCodeConstants.*;
+import static java.util.Collections.EMPTY_LIST;
import static java.util.Collections.singleton;
/**
@@ -59,6 +64,8 @@ public class SysAuthServiceImpl implements SysAuthService {
private SysLoginLogService loginLogService;
@Resource
private SysUserSessionService userSessionService;
+ @Resource
+ private SysPostService sysPostService;
@Override
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
@@ -68,7 +75,9 @@ public class SysAuthServiceImpl implements SysAuthService {
throw new UsernameNotFoundException(username);
}
// 创建 LoginUser 对象
- return SysAuthConvert.INSTANCE.convert(user);
+ LoginUser loginUser = SysAuthConvert.INSTANCE.convert(user);
+ loginUser.setPostIds(user.getPostIds());
+ return loginUser;
}
@Override
@@ -92,11 +101,18 @@ public class SysAuthServiceImpl implements SysAuthService {
// 使用账号密码,进行登陆。
LoginUser loginUser = this.login0(reqVO.getUsername(), reqVO.getPassword());
loginUser.setRoleIds(this.getUserRoleIds(loginUser.getId())); // 获取用户角色列表
-
+ loginUser.setGroups(this.getUserPosts(loginUser.getPostIds()));
// 缓存登陆用户到 Redis 中,返回 sessionId 编号
return userSessionService.createUserSession(loginUser, userIp, userAgent);
}
+
+ private List getUserPosts(Set postIds) {
+ return Optional.ofNullable(postIds).map(ids->
+ sysPostService.getPosts(ids).stream().map(post -> post.getCode()).collect(Collectors.toList())
+ ).orElse(EMPTY_LIST);
+ }
+
private void verifyCaptcha(String username, String captchaUUID, String captchaCode) {
String code = captchaService.getCaptchaCode(captchaUUID);
// 验证码不存在
@@ -122,6 +138,7 @@ public class SysAuthServiceImpl implements SysAuthService {
// 调用 Spring Security 的 AuthenticationManager#authenticate(...) 方法,使用账号密码进行认证
// 在其内部,会调用到 loadUserByUsername 方法,获取 User 信息
authentication = authenticationManager.authenticate(new UsernamePasswordAuthenticationToken(username, password));
+ // org.activiti.engine.impl.identity.Authentication.setAuthenticatedUserId(username);
} catch (BadCredentialsException badCredentialsException) {
this.createLoginLog(username, SysLoginResultEnum.BAD_CREDENTIALS);
throw exception(AUTH_LOGIN_BAD_CREDENTIALS);
diff --git a/yudao-admin-server/src/main/resources/application.yaml b/yudao-admin-server/src/main/resources/application.yaml
index 486d4a487..49cfaa44a 100644
--- a/yudao-admin-server/src/main/resources/application.yaml
+++ b/yudao-admin-server/src/main/resources/application.yaml
@@ -22,9 +22,10 @@ spring:
# MyBatis Plus 的配置项
mybatis-plus:
- configuration:
- map-underscore-to-camel-case: true # 虽然默认为 true ,但是还是显示去指定下。
- log-impl: org.apache.ibatis.logging.stdout.StdOutImpl # 打印日志
+# 在 mybatis-config/mybatis-config.xml 中设置
+# configuration:
+# map-underscore-to-camel-case: true # 虽然默认为 true ,但是还是显示去指定下。
+# log-impl: org.apache.ibatis.logging.stdout.StdOutImpl # 打印日志
global-config:
db-config:
id-type: AUTO # 自增 ID
@@ -32,6 +33,18 @@ mybatis-plus:
logic-not-delete-value: 0 # 逻辑未删除值(默认为 0)
mapper-locations: classpath*:mapper/*.xml
type-aliases-package: ${yudao.info.base-package}.modules.*.dal.dataobject
+ config-location: classpath:mybatis-config/mybatis-config.xml
+ configuration-properties:
+ prefix: ""
+ wildcardEscapeClause: ""
+ limitBefore: ""
+ limitAfter: "LIMIT #{maxResults} OFFSET #{firstResult}"
+ limitBetween: ""
+ limitOuterJoinBetween: ""
+ limitBeforeNativeQuery: ""
+ orderBy: "order by ${orderByColumns}"
+ blobType: "BLOB"
+ boolValue: "TRUE"
--- #################### 芋道相关配置 ####################
diff --git a/yudao-admin-server/src/main/resources/mybatis-config/mybatis-config.xml b/yudao-admin-server/src/main/resources/mybatis-config/mybatis-config.xml
new file mode 100644
index 000000000..4f290bc98
--- /dev/null
+++ b/yudao-admin-server/src/main/resources/mybatis-config/mybatis-config.xml
@@ -0,0 +1,52 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/yudao-admin-server/src/main/resources/processes/leave.bpmn b/yudao-admin-server/src/main/resources/processes/leave.bpmn
new file mode 100644
index 000000000..34eeea0a5
--- /dev/null
+++ b/yudao-admin-server/src/main/resources/processes/leave.bpmn
@@ -0,0 +1,130 @@
+
+
+
+ 请假流程演示
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/yudao-admin-ui/src/api/oa/leave.js b/yudao-admin-ui/src/api/oa/leave.js
new file mode 100644
index 000000000..3fb0f806c
--- /dev/null
+++ b/yudao-admin-ui/src/api/oa/leave.js
@@ -0,0 +1,54 @@
+import request from '@/utils/request'
+
+// 创建请假申请
+export function createLeave(data) {
+ return request({
+ url: '/oa/leave/create',
+ method: 'post',
+ data: data
+ })
+}
+
+// 更新请假申请
+export function updateLeave(data) {
+ return request({
+ url: '/oa/leave/update',
+ method: 'put',
+ data: data
+ })
+}
+
+// 删除请假申请
+export function deleteLeave(id) {
+ return request({
+ url: '/oa/leave/delete?id=' + id,
+ method: 'delete'
+ })
+}
+
+// 获得请假申请
+export function getLeave(id) {
+ return request({
+ url: '/oa/leave/get?id=' + id,
+ method: 'get'
+ })
+}
+
+// 获得请假申请分页
+export function getLeavePage(query) {
+ return request({
+ url: '/oa/leave/page',
+ method: 'get',
+ params: query
+ })
+}
+
+// 导出请假申请 Excel
+export function exportLeaveExcel(query) {
+ return request({
+ url: '/oa/leave/export-excel',
+ method: 'get',
+ params: query,
+ responseType: 'blob'
+ })
+}
diff --git a/yudao-admin-ui/src/api/oa/todo.js b/yudao-admin-ui/src/api/oa/todo.js
new file mode 100644
index 000000000..35f857988
--- /dev/null
+++ b/yudao-admin-ui/src/api/oa/todo.js
@@ -0,0 +1,75 @@
+import request from '@/utils/request'
+
+// 创建请假申请
+export function createLeave(data) {
+ return request({
+ url: '/oa/leave/create',
+ method: 'post',
+ data: data
+ })
+}
+
+// 更新请假申请
+export function updateLeave(data) {
+ return request({
+ url: '/oa/leave/update',
+ method: 'put',
+ data: data
+ })
+}
+
+// 删除请假申请
+export function deleteLeave(id) {
+ return request({
+ url: '/oa/leave/delete?id=' + id,
+ method: 'delete'
+ })
+}
+
+// 获得请假申请
+export function getLeave(id) {
+ return request({
+ url: '/oa/leave/get?id=' + id,
+ method: 'get'
+ })
+}
+
+// 获得待办任务分页
+export function getTodoTaskPage(query) {
+ return request({
+ url: '/workflow/task/todo/page',
+ method: 'get',
+ params: query
+ })
+}
+
+// 签收任务
+export function claimTask(id) {
+ return request({
+ url: '/workflow/task/claim?id=' + id,
+ method: 'get'
+ })
+}
+
+export function completeTask(data) {
+ return request({
+ url: '/workflow/task/complete',
+ method: 'post',
+ data: data
+ })
+}
+
+export function taskSteps(data) {
+ return request({
+ url: '/workflow/task/task-steps',
+ method: 'post',
+ data: data
+ })
+}
+
+export function processHistorySteps(id) {
+ return request({
+ url: '/workflow/task/process/history-steps?id='+id,
+ method: 'get'
+ })
+}
diff --git a/yudao-admin-ui/src/utils/dict.js b/yudao-admin-ui/src/utils/dict.js
index 17d5bd00e..b29c00359 100644
--- a/yudao-admin-ui/src/utils/dict.js
+++ b/yudao-admin-ui/src/utils/dict.js
@@ -29,6 +29,9 @@ export const DICT_TYPE = {
INF_API_ERROR_LOG_PROCESS_STATUS: 'inf_api_error_log_process_status',
TOOL_CODEGEN_TEMPLATE_TYPE: 'tool_codegen_template_type',
+
+ OA_LEAVE_STATUS: 'oa_leave_status',
+ OA_LEAVE_TYPE: 'oa_leave_type'
}
/**
diff --git a/yudao-admin-ui/src/views/oa/leave/index.vue b/yudao-admin-ui/src/views/oa/leave/index.vue
new file mode 100644
index 000000000..d14706383
--- /dev/null
+++ b/yudao-admin-ui/src/views/oa/leave/index.vue
@@ -0,0 +1,347 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 搜索
+ 重置
+
+
+
+
+
+
+ 新增
+
+
+
+
+
+
+
+
+
+
+
+ {{ parseTime(scope.row.startTime) }}
+
+
+
+
+ {{ parseTime(scope.row.endTime) }}
+
+
+
+
+
+
+ {{ parseTime(scope.row.applyTime) }}
+
+
+
+
+ 审批进度
+ 详情
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {{ getDictDataLabel(DICT_TYPE.OA_LEAVE_STATUS, form.status) }}
+
+ {{form.userId}}
+ {{ parseTime(form.startTime) }}
+ {{ parseTime(form.endTime) }}
+
+ {{ getDictDataLabel(DICT_TYPE.OA_LEAVE_TYPE, form.leaveType) }}
+
+ {{form.reason}}
+ {{ parseTime(form.applyTime) }}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/yudao-admin-ui/src/views/oa/todo/index.vue b/yudao-admin-ui/src/views/oa/todo/index.vue
new file mode 100644
index 000000000..0d4107624
--- /dev/null
+++ b/yudao-admin-ui/src/views/oa/todo/index.vue
@@ -0,0 +1,284 @@
+
+
+
+
+
+
+
+
+
+
+
+ 搜索
+ 重置
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 签收
+ 办理
+
+
+
+
+
+
+
+
+
+
+
+ {{ getDictDataLabel(DICT_TYPE.OA_LEAVE_STATUS, handleTask.formObject.status) }}
+
+ {{handleTask.formObject.userId}}
+ {{ parseTime(handleTask.formObject.startTime) }}
+ {{ parseTime(handleTask.formObject.endTime) }}
+
+ {{ getDictDataLabel(DICT_TYPE.OA_LEAVE_TYPE, handleTask.formObject.leaveType) }}
+
+ {{handleTask.formObject.reason}}
+ {{ parseTime(handleTask.formObject.applyTime) }}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 提交
+
+
+
+
+
+
+
diff --git a/yudao-framework/yudao-spring-boot-starter-activiti/pom.xml b/yudao-framework/yudao-spring-boot-starter-activiti/pom.xml
index e9cee07f1..b1c08492a 100644
--- a/yudao-framework/yudao-spring-boot-starter-activiti/pom.xml
+++ b/yudao-framework/yudao-spring-boot-starter-activiti/pom.xml
@@ -19,20 +19,29 @@
7.1.0.M6
-
+
+
+
+ org.activiti.dependencies
+ activiti-dependencies
+ ${activiti.version}
+ import
+ pom
+
+
+
cn.iocoder.boot
yudao-common
-
- org.activiti.dependencies
- activiti-dependencies
- ${activiti.version}
- pom
+ org.mybatis
+ mybatis
+ true
+
org.activiti
@@ -51,6 +60,10 @@
org.mybatis
mybatis
+
+ el-api
+ javax.el
+
diff --git a/yudao-framework/yudao-spring-boot-starter-activiti/src/main/java/cn/iocoder/yudao/framework/activiti/config/YudaoActivitiConfiguration.java b/yudao-framework/yudao-spring-boot-starter-activiti/src/main/java/cn/iocoder/yudao/framework/activiti/config/YudaoActivitiConfiguration.java
new file mode 100644
index 000000000..6e7355db9
--- /dev/null
+++ b/yudao-framework/yudao-spring-boot-starter-activiti/src/main/java/cn/iocoder/yudao/framework/activiti/config/YudaoActivitiConfiguration.java
@@ -0,0 +1,32 @@
+package cn.iocoder.yudao.framework.activiti.config;
+
+import org.activiti.api.runtime.shared.identity.UserGroupManager;
+import org.activiti.spring.SpringProcessEngineConfiguration;
+import org.activiti.spring.boot.ProcessEngineConfigurationConfigurer;
+import org.apache.ibatis.session.SqlSessionFactory;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.stereotype.Component;
+
+@Configuration
+public class YudaoActivitiConfiguration {
+
+
+
+
+ @Component
+ public static class SqlSessionFactoryProcessEngineConfigurationConfigurer
+ implements ProcessEngineConfigurationConfigurer {
+
+ private final SqlSessionFactory sqlSessionFactory;
+ public SqlSessionFactoryProcessEngineConfigurationConfigurer(SqlSessionFactory sessionFactory) {
+ this.sqlSessionFactory = sessionFactory;
+ }
+
+ @Override
+ public void configure(SpringProcessEngineConfiguration springProcessEngineConfiguration) {
+ springProcessEngineConfiguration.setSqlSessionFactory(sqlSessionFactory);
+ }
+ }
+
+
+}
diff --git a/yudao-framework/yudao-spring-boot-starter-security/pom.xml b/yudao-framework/yudao-spring-boot-starter-security/pom.xml
index 4a2b1878a..bdc69f264 100644
--- a/yudao-framework/yudao-spring-boot-starter-security/pom.xml
+++ b/yudao-framework/yudao-spring-boot-starter-security/pom.xml
@@ -39,6 +39,18 @@
spring-boot-starter-security
+
+ org.activiti
+ activiti-engine
+ 7.1.0.M6
+
+
+ *
+ *
+
+
+ true
+
diff --git a/yudao-framework/yudao-spring-boot-starter-security/src/main/java/cn/iocoder/yudao/framework/security/core/LoginUser.java b/yudao-framework/yudao-spring-boot-starter-security/src/main/java/cn/iocoder/yudao/framework/security/core/LoginUser.java
index 2c2ff8914..f6c5acad1 100644
--- a/yudao-framework/yudao-spring-boot-starter-security/src/main/java/cn/iocoder/yudao/framework/security/core/LoginUser.java
+++ b/yudao-framework/yudao-spring-boot-starter-security/src/main/java/cn/iocoder/yudao/framework/security/core/LoginUser.java
@@ -4,11 +4,10 @@ import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum;
import com.fasterxml.jackson.annotation.JsonIgnore;
import lombok.Data;
import org.springframework.security.core.GrantedAuthority;
+import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.userdetails.UserDetails;
-import java.util.Collection;
-import java.util.Date;
-import java.util.Set;
+import java.util.*;
/**
* 登陆用户信息
@@ -48,6 +47,18 @@ public class LoginUser implements UserDetails {
*/
private Integer status;
+
+ /**
+ * 所属岗位
+ */
+ private Set postIds;
+
+ /**
+ * group 目前指岗位代替
+ */
+ private List groups;
+
+
@Override
@JsonIgnore// 避免序列化
public String getPassword() {
@@ -55,7 +66,6 @@ public class LoginUser implements UserDetails {
}
@Override
- @JsonIgnore
public String getUsername() {
return username;
}
@@ -69,7 +79,9 @@ public class LoginUser implements UserDetails {
@Override
@JsonIgnore// 避免序列化
public Collection extends GrantedAuthority> getAuthorities() {
- return null;
+ List list = new ArrayList<>(1);
+ list.add(new SimpleGrantedAuthority("ROLE_ACTIVITI_USER"));
+ return list;
}
@Override
diff --git a/yudao-framework/yudao-spring-boot-starter-security/src/main/java/cn/iocoder/yudao/framework/security/core/util/SecurityFrameworkUtils.java b/yudao-framework/yudao-spring-boot-starter-security/src/main/java/cn/iocoder/yudao/framework/security/core/util/SecurityFrameworkUtils.java
index a8360c490..f63a9b7ba 100644
--- a/yudao-framework/yudao-spring-boot-starter-security/src/main/java/cn/iocoder/yudao/framework/security/core/util/SecurityFrameworkUtils.java
+++ b/yudao-framework/yudao-spring-boot-starter-security/src/main/java/cn/iocoder/yudao/framework/security/core/util/SecurityFrameworkUtils.java
@@ -90,13 +90,18 @@ public class SecurityFrameworkUtils {
public static void setLoginUser(LoginUser loginUser, HttpServletRequest request) {
// 创建 UsernamePasswordAuthenticationToken 对象
UsernamePasswordAuthenticationToken authenticationToken = new UsernamePasswordAuthenticationToken(
- loginUser, null, null);
+ loginUser, null, loginUser.getAuthorities());
authenticationToken.setDetails(new WebAuthenticationDetailsSource().buildDetails(request));
// 设置到上下文
+ //何时调用 SecurityContextHolder.clearContext. spring security filter 应该会调用 clearContext
SecurityContextHolder.getContext().setAuthentication(authenticationToken);
// 额外设置到 request 中,用于 ApiAccessLogFilter 可以获取到用户编号;
// 原因是,Spring Security 的 Filter 在 ApiAccessLogFilter 后面,在它记录访问日志时,线上上下文已经没有用户编号等信息
WebFrameworkUtils.setLoginUserId(request, loginUser.getId());
+
+ org.activiti.engine.impl.identity.Authentication.setAuthenticatedUserId(loginUser.getUsername());
+
+
}
}