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 @@ + + + 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 @@ + + + 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 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()); + + } }