1.实现了工作流引擎 中 请假流程demo(定义在 resources/leave.bpmn)
2.增加一个一级菜单 OA 办公 下面两个菜单: 请假申请,待办任务 3.暂时不知如何找部门领导, 暂时写死为 admin 4.activity 用户组使用 用户岗位来代替。 5.新增一个用户 hradmin, 密码 123456 岗位是 人力资源 6.演示流程。 a. admin 登陆 申请请假 b. admin 待办任务(审批) c. hradmin 登陆 待办任务(审批) d. admin 登陆 待办任务 (确认)pull/2/head
parent
1bb10d007e
commit
ee8dcd0888
|
@ -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;
|
||||
|
|
|
@ -31,6 +31,11 @@
|
|||
<artifactId>yudao-spring-boot-starter-biz-sms</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>cn.iocoder.boot</groupId>
|
||||
<artifactId>yudao-spring-boot-starter-activiti</artifactId>
|
||||
</dependency>
|
||||
|
||||
<!-- Web 相关 -->
|
||||
<dependency>
|
||||
<groupId>cn.iocoder.boot</groupId>
|
||||
|
@ -107,6 +112,8 @@
|
|||
<artifactId>yudao-spring-boot-starter-excel</artifactId>
|
||||
</dependency>
|
||||
|
||||
|
||||
|
||||
<dependency>
|
||||
<groupId>org.apache.velocity</groupId>
|
||||
<artifactId>velocity-engine-core</artifactId>
|
||||
|
|
|
@ -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<Long> createLeave(@Valid @RequestBody OaLeaveCreateReqVO createReqVO) {
|
||||
return success(leaveService.createLeave(createReqVO));
|
||||
}
|
||||
|
||||
@PutMapping("/update")
|
||||
@ApiOperation("更新请假申请")
|
||||
@PreAuthorize("@ss.hasPermission('oa:leave:update')")
|
||||
public CommonResult<Boolean> 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<Boolean> 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<OaLeaveRespVO> 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<List<OaLeaveRespVO>> getLeaveList(@RequestParam("ids") Collection<Long> ids) {
|
||||
List<OaLeaveDO> list = leaveService.getLeaveList(ids);
|
||||
return success(OaLeaveConvert.INSTANCE.convertList(list));
|
||||
}
|
||||
|
||||
@GetMapping("/page")
|
||||
@ApiOperation("获得请假申请分页")
|
||||
@PreAuthorize("@ss.hasPermission('oa:leave:query')")
|
||||
public CommonResult<PageResult<OaLeaveRespVO>> getLeavePage(@Valid OaLeavePageReqVO pageVO) {
|
||||
//值查询自己申请请假
|
||||
pageVO.setUserId(SecurityFrameworkUtils.getLoginUser().getUsername());
|
||||
PageResult<OaLeaveDO> 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<OaLeaveDO> list = leaveService.getLeaveList(exportReqVO);
|
||||
// 导出 Excel
|
||||
List<OaLeaveExcelVO> datas = OaLeaveConvert.INSTANCE.convertList02(list);
|
||||
ExcelUtils.write(response, "请假申请.xls", "数据", OaLeaveExcelVO.class, datas);
|
||||
}
|
||||
|
||||
}
|
|
@ -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;
|
||||
|
||||
}
|
|
@ -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 {
|
||||
|
||||
}
|
|
@ -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;
|
||||
|
||||
}
|
|
@ -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;
|
||||
|
||||
}
|
|
@ -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;
|
||||
|
||||
}
|
|
@ -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;
|
||||
|
||||
}
|
|
@ -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;
|
||||
|
||||
}
|
|
@ -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<PageResult<TodoTaskRespVO>> getTodoTaskPage(@Valid TodoTaskPageReqVO pageVO) {
|
||||
return success(taskService.getTodoTaskPage(pageVO));
|
||||
}
|
||||
|
||||
@GetMapping("/claim")
|
||||
@ApiOperation("签收任务")
|
||||
public CommonResult<Boolean> claimTask(@RequestParam("id") String taskId) {
|
||||
taskService.claimTask(taskId);
|
||||
return success(true);
|
||||
}
|
||||
|
||||
|
||||
@PostMapping("/task-steps")
|
||||
public CommonResult<TaskHandleVO> getTaskSteps(@RequestBody TaskQueryReqVO taskQuery) {
|
||||
return success( taskService.getTaskSteps(taskQuery));
|
||||
}
|
||||
|
||||
@PostMapping("/complete")
|
||||
public CommonResult<Boolean> complete(@RequestBody TaskReqVO taskReq) {
|
||||
taskService.completeTask(taskReq);
|
||||
return success(true);
|
||||
}
|
||||
|
||||
|
||||
@GetMapping("/process/history-steps")
|
||||
public CommonResult<List<TaskStepVO>> getHistorySteps(@RequestParam("id") String processInstanceId) {
|
||||
return success( taskService.getHistorySteps(processInstanceId));
|
||||
}
|
||||
}
|
|
@ -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<TaskStepVO> historyTask;
|
||||
|
||||
|
||||
private String taskVariable;
|
||||
}
|
|
@ -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;
|
||||
}
|
|
@ -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<String,Object> variables;
|
||||
|
||||
private String comment;
|
||||
}
|
|
@ -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;
|
||||
|
||||
}
|
|
@ -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;
|
||||
}
|
|
@ -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;
|
||||
|
||||
}
|
|
@ -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<OaLeaveRespVO> convertList(List<OaLeaveDO> list);
|
||||
|
||||
PageResult<OaLeaveRespVO> convertPage(PageResult<OaLeaveDO> page);
|
||||
|
||||
List<OaLeaveExcelVO> convertList02(List<OaLeaveDO> list);
|
||||
|
||||
}
|
|
@ -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);
|
||||
}
|
|
@ -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;
|
||||
|
||||
}
|
|
@ -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<OaLeaveDO> {
|
||||
|
||||
default PageResult<OaLeaveDO> selectPage(OaLeavePageReqVO reqVO) {
|
||||
return selectPage(reqVO, new QueryWrapperX<OaLeaveDO>()
|
||||
.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<OaLeaveDO> selectList(OaLeaveExportReqVO reqVO) {
|
||||
return selectList(new QueryWrapperX<OaLeaveDO>()
|
||||
.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") );
|
||||
}
|
||||
|
||||
}
|
|
@ -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, "请假申请不存在");
|
||||
}
|
|
@ -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<String> 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<String> getUserRoles(String userId) {
|
||||
return Arrays.asList("ROLE_ACTIVITI_USER");
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<String> getGroups() {
|
||||
throw new UnsupportedOperationException("getGroups is now un supported");
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<String> getUsers() {
|
||||
throw new UnsupportedOperationException("getGroups is now un supported");
|
||||
}
|
||||
}
|
|
@ -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<String> 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();
|
||||
}
|
||||
|
||||
}
|
||||
}
|
|
@ -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<OaLeaveDO> getLeaveList(Collection<Long> ids);
|
||||
|
||||
/**
|
||||
* 获得请假申请分页
|
||||
*
|
||||
* @param pageReqVO 分页查询
|
||||
* @return 请假申请分页
|
||||
*/
|
||||
PageResult<OaLeaveDO> getLeavePage(OaLeavePageReqVO pageReqVO);
|
||||
|
||||
/**
|
||||
* 获得请假申请列表, 用于 Excel 导出
|
||||
*
|
||||
* @param exportReqVO 查询条件
|
||||
* @return 请假申请列表
|
||||
*/
|
||||
List<OaLeaveDO> getLeaveList(OaLeaveExportReqVO exportReqVO);
|
||||
|
||||
}
|
|
@ -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<OaLeaveDO> updateWrapper = new UpdateWrapper<>();
|
||||
updateWrapper.eq("id", Long.valueOf(businessKey));
|
||||
OaLeaveDO updateDo = new OaLeaveDO();
|
||||
updateDo.setStatus(2);
|
||||
leaveMapper.update(updateDo, updateWrapper);
|
||||
}
|
||||
}
|
|
@ -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<String, Object> 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<OaLeaveDO> 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<OaLeaveDO> getLeaveList(Collection<Long> ids) {
|
||||
return leaveMapper.selectBatchIds(ids);
|
||||
}
|
||||
|
||||
@Override
|
||||
public PageResult<OaLeaveDO> getLeavePage(OaLeavePageReqVO pageReqVO) {
|
||||
return leaveMapper.selectPage(pageReqVO);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<OaLeaveDO> getLeaveList(OaLeaveExportReqVO exportReqVO) {
|
||||
return leaveMapper.selectList(exportReqVO);
|
||||
}
|
||||
|
||||
}
|
|
@ -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<TodoTaskRespVO> 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<TaskStepVO> getHistorySteps(String processInstanceId);
|
||||
}
|
|
@ -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<String,String> taskVariable = ImmutableMap.<String,String>builder()
|
||||
.put("deptLeaderVerify","deptLeaderApproved")
|
||||
.put("hrVerify","hrApproved")
|
||||
.build();
|
||||
|
||||
public TaskServiceImpl() {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public PageResult<TodoTaskRespVO> getTodoTaskPage(TodoTaskPageReqVO pageReqVO) {
|
||||
final LoginUser loginUser = SecurityFrameworkUtils.getLoginUser();
|
||||
final Pageable pageable = Pageable.of((pageReqVO.getPageNo() - 1) * pageReqVO.getPageSize(), pageReqVO.getPageSize());
|
||||
Page<Task> pageTasks = taskRuntime.tasks(pageable);
|
||||
List<Task> tasks = pageTasks.getContent();
|
||||
int totalItems = pageTasks.getTotalItems();
|
||||
final List<TodoTaskRespVO> 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<HistoricProcessInstance> 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<String, Object> 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<OaLeaveDO> 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<String> activeActivityIds = runtimeService.getActiveActivityIds(executionId);
|
||||
// List<String> 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<TaskStepVO> steps = getTaskSteps(task.getProcessInstanceId());
|
||||
|
||||
handleVO.setHistoryTask(steps);
|
||||
return handleVO;
|
||||
}
|
||||
|
||||
|
||||
private List<TaskStepVO> getTaskSteps(String processInstanceId) {
|
||||
|
||||
List<TaskStepVO> steps = new ArrayList<>();
|
||||
|
||||
List<HistoricActivityInstance> 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<Comment> comments = activitiTaskService.getTaskComments(instance.getTaskId());
|
||||
if(comments.size()>0){
|
||||
step.setComment(comments.get(0).getFullMessage());
|
||||
}else{
|
||||
step.setComment("");
|
||||
}
|
||||
steps.add(step);
|
||||
});
|
||||
|
||||
List<HistoricActivityInstance> 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<TaskStepVO> getHistorySteps(String processInstanceId) {
|
||||
|
||||
return getTaskSteps(processInstanceId);
|
||||
}
|
||||
|
||||
|
||||
|
||||
// private List<String> getHighLightedFlows(ProcessDefinitionEntity processDefinition, String processInstanceId) {
|
||||
//
|
||||
// List<String> highLightedFlows = new ArrayList<String>();
|
||||
// List<HistoricActivityInstance> historicActivityInstances = historyService
|
||||
// .createHistoricActivityInstanceQuery()
|
||||
// .processInstanceId(processInstanceId)
|
||||
// .orderByHistoricActivityInstanceStartTime().asc().list();
|
||||
//
|
||||
// List<String> historicActivityInstanceList = new ArrayList<String>();
|
||||
// for (HistoricActivityInstance hai : historicActivityInstances) {
|
||||
// historicActivityInstanceList.add(hai.getActivityId());
|
||||
// }
|
||||
|
||||
// // add current activities to list
|
||||
// List<String> 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<PvmTransition> 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;
|
||||
// }
|
||||
}
|
|
@ -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<String> getUserPosts(Set<Long> 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);
|
||||
|
|
|
@ -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"
|
||||
|
||||
--- #################### 芋道相关配置 ####################
|
||||
|
||||
|
|
|
@ -0,0 +1,52 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
|
||||
<!DOCTYPE configuration PUBLIC "-//mybatis.org//DTD Config 3.0//EN" "http://mybatis.org/dtd/mybatis-3-config.dtd">
|
||||
|
||||
<configuration>
|
||||
<settings>
|
||||
<setting name="lazyLoadingEnabled" value="false" />
|
||||
<setting name="mapUnderscoreToCamelCase" value="true"/>
|
||||
</settings>
|
||||
<typeAliases>
|
||||
<typeAlias type="org.activiti.engine.impl.persistence.ByteArrayRefTypeHandler" alias="ByteArrayRefTypeHandler"/>
|
||||
<typeAlias type="org.activiti.engine.impl.db.IbatisVariableTypeHandler" alias="IbatisVariableTypeHandler"/>
|
||||
</typeAliases>
|
||||
<typeHandlers>
|
||||
<typeHandler handler="ByteArrayRefTypeHandler"
|
||||
javaType="org.activiti.engine.impl.persistence.entity.ByteArrayRef"
|
||||
jdbcType="VARCHAR"/>
|
||||
<typeHandler handler="IbatisVariableTypeHandler"
|
||||
javaType="org.activiti.engine.impl.variable.VariableType"
|
||||
jdbcType="VARCHAR"/>
|
||||
</typeHandlers>
|
||||
<mappers>
|
||||
<mapper resource="org/activiti/db/mapping/common.xml" />
|
||||
<mapper resource="org/activiti/db/mapping/entity/Attachment.xml" />
|
||||
<mapper resource="org/activiti/db/mapping/entity/ByteArray.xml" />
|
||||
<mapper resource="org/activiti/db/mapping/entity/Comment.xml" />
|
||||
<mapper resource="org/activiti/db/mapping/entity/DeadLetterJob.xml" />
|
||||
<mapper resource="org/activiti/db/mapping/entity/Deployment.xml" />
|
||||
<mapper resource="org/activiti/db/mapping/entity/Execution.xml" />
|
||||
<mapper resource="org/activiti/db/mapping/entity/HistoricActivityInstance.xml" />
|
||||
<mapper resource="org/activiti/db/mapping/entity/HistoricDetail.xml" />
|
||||
<mapper resource="org/activiti/db/mapping/entity/HistoricProcessInstance.xml" />
|
||||
<mapper resource="org/activiti/db/mapping/entity/HistoricVariableInstance.xml" />
|
||||
<mapper resource="org/activiti/db/mapping/entity/HistoricTaskInstance.xml" />
|
||||
<mapper resource="org/activiti/db/mapping/entity/HistoricIdentityLink.xml" />
|
||||
<mapper resource="org/activiti/db/mapping/entity/IdentityLink.xml" />
|
||||
<mapper resource="org/activiti/db/mapping/entity/Job.xml" />
|
||||
<mapper resource="org/activiti/db/mapping/entity/Model.xml" />
|
||||
<mapper resource="org/activiti/db/mapping/entity/ProcessDefinition.xml" />
|
||||
<mapper resource="org/activiti/db/mapping/entity/ProcessDefinitionInfo.xml" />
|
||||
<mapper resource="org/activiti/db/mapping/entity/Property.xml" />
|
||||
<mapper resource="org/activiti/db/mapping/entity/Resource.xml" />
|
||||
<mapper resource="org/activiti/db/mapping/entity/SuspendedJob.xml" />
|
||||
<mapper resource="org/activiti/db/mapping/entity/TableData.xml" />
|
||||
<mapper resource="org/activiti/db/mapping/entity/Task.xml" />
|
||||
<mapper resource="org/activiti/db/mapping/entity/TimerJob.xml" />
|
||||
<mapper resource="org/activiti/db/mapping/entity/VariableInstance.xml" />
|
||||
<mapper resource="org/activiti/db/mapping/entity/EventSubscription.xml" />
|
||||
<mapper resource="org/activiti/db/mapping/entity/EventLogEntry.xml" />
|
||||
<mapper resource="org/activiti/db/mapping/entity/IntegrationContext.xml" />
|
||||
</mappers>
|
||||
</configuration>
|
|
@ -0,0 +1,130 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<definitions xmlns="http://www.omg.org/spec/BPMN/20100524/MODEL" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:activiti="http://activiti.org/bpmn" xmlns:bpmndi="http://www.omg.org/spec/BPMN/20100524/DI" xmlns:omgdc="http://www.omg.org/spec/DD/20100524/DC" xmlns:omgdi="http://www.omg.org/spec/DD/20100524/DI" typeLanguage="http://www.w3.org/2001/XMLSchema" expressionLanguage="http://www.w3.org/1999/XPath" targetNamespace="http://bpmn.io/schema/bpmn">
|
||||
<process id="leave" name="请假流程-普通表单" isExecutable="true">
|
||||
<documentation>请假流程演示</documentation>
|
||||
<startEvent id="startevent1" name="Start" activiti:initiator="applyUserId"></startEvent>
|
||||
<userTask id="deptLeaderVerify" name="部门领导审批" activiti:assignee="${deptLeader}"></userTask>
|
||||
<exclusiveGateway id="exclusivegateway5" name="Exclusive Gateway"></exclusiveGateway>
|
||||
<userTask id="hrVerify" name="人事审批" activiti:candidateGroups="hr"></userTask>
|
||||
<exclusiveGateway id="exclusivegateway6" name="Exclusive Gateway"></exclusiveGateway>
|
||||
<userTask id="reportBack" name="申请人确认" activiti:assignee="${applyUserId}">
|
||||
<extensionElements>
|
||||
<activiti:taskListener event="complete" delegateExpression="${reportBackEndProcessor}"></activiti:taskListener>
|
||||
</extensionElements>
|
||||
</userTask>
|
||||
<endEvent id="endevent1" name="End"></endEvent>
|
||||
<sequenceFlow id="flow2" sourceRef="startevent1" targetRef="deptLeaderVerify"></sequenceFlow>
|
||||
<sequenceFlow id="flow3" sourceRef="deptLeaderVerify" targetRef="exclusivegateway5"></sequenceFlow>
|
||||
<sequenceFlow id="flow5" name="部门领导审批-同意" sourceRef="exclusivegateway5" targetRef="hrVerify">
|
||||
<conditionExpression xsi:type="tFormalExpression"><![CDATA[${deptLeaderApproved}]]></conditionExpression>
|
||||
</sequenceFlow>
|
||||
<sequenceFlow id="flow6" sourceRef="hrVerify" targetRef="exclusivegateway6"></sequenceFlow>
|
||||
<sequenceFlow id="flow7" name="人事审批-同意" sourceRef="exclusivegateway6" targetRef="reportBack">
|
||||
<conditionExpression xsi:type="tFormalExpression"><![CDATA[${hrApproved}]]></conditionExpression>
|
||||
</sequenceFlow>
|
||||
<sequenceFlow id="flow8" sourceRef="reportBack" targetRef="endevent1"></sequenceFlow>
|
||||
<sequenceFlow id="flow4" name="部门领导审批-不同意" sourceRef="exclusivegateway5" targetRef="endevent1" >
|
||||
<conditionExpression xsi:type="tFormalExpression"><![CDATA[${!deptLeaderApproved}]]></conditionExpression>
|
||||
</sequenceFlow>
|
||||
<sequenceFlow sourceRef="exclusivegateway6" name="人事审批-不同意" targetRef="endevent1" id="flow9">
|
||||
<conditionExpression xsi:type="tFormalExpression"><![CDATA[${!hrApproved}]]></conditionExpression>
|
||||
</sequenceFlow>
|
||||
</process>
|
||||
<bpmndi:BPMNDiagram id="BPMNDiagram_leave">
|
||||
<bpmndi:BPMNPlane bpmnElement="leave" id="BPMNPlane_leave">
|
||||
<bpmndi:BPMNShape bpmnElement="startevent1" id="BPMNShape_startevent1">
|
||||
<omgdc:Bounds height="35.0" width="35.0" x="0.0" y="46.0"></omgdc:Bounds>
|
||||
</bpmndi:BPMNShape>
|
||||
<bpmndi:BPMNShape bpmnElement="deptLeaderVerify" id="BPMNShape_deptLeaderVerify">
|
||||
<omgdc:Bounds height="55.0" width="105.0" x="80.0" y="36.0"></omgdc:Bounds>
|
||||
</bpmndi:BPMNShape>
|
||||
<bpmndi:BPMNShape bpmnElement="exclusivegateway5" id="BPMNShape_exclusivegateway5">
|
||||
<omgdc:Bounds height="40.0" width="40.0" x="240.0" y="43.0"></omgdc:Bounds>
|
||||
</bpmndi:BPMNShape>
|
||||
<bpmndi:BPMNShape bpmnElement="hrVerify" id="BPMNShape_hrVerify">
|
||||
<omgdc:Bounds height="55.0" width="105.0" x="348.0" y="36.0"></omgdc:Bounds>
|
||||
</bpmndi:BPMNShape>
|
||||
<bpmndi:BPMNShape bpmnElement="exclusivegateway6" id="BPMNShape_exclusivegateway6">
|
||||
<omgdc:Bounds height="40.0" width="40.0" x="485.0" y="43.0"></omgdc:Bounds>
|
||||
</bpmndi:BPMNShape>
|
||||
<bpmndi:BPMNShape bpmnElement="reportBack" id="BPMNShape_reportBack">
|
||||
<omgdc:Bounds height="55.0" width="105.0" x="580.0" y="36.0"></omgdc:Bounds>
|
||||
</bpmndi:BPMNShape>
|
||||
<bpmndi:BPMNShape bpmnElement="endevent1" id="BPMNShape_endevent1">
|
||||
<omgdc:Bounds height="35.0" width="35.0" x="615.0" y="195.0"></omgdc:Bounds>
|
||||
</bpmndi:BPMNShape>
|
||||
<bpmndi:BPMNEdge bpmnElement="flow2" id="BPMNEdge_flow2">
|
||||
<omgdi:waypoint x="35.0" y="63.0"></omgdi:waypoint>
|
||||
<omgdi:waypoint x="80.0" y="63.0"></omgdi:waypoint>
|
||||
</bpmndi:BPMNEdge>
|
||||
<bpmndi:BPMNEdge bpmnElement="flow3" id="BPMNEdge_flow3">
|
||||
<omgdi:waypoint x="185.0" y="63.0"></omgdi:waypoint>
|
||||
<omgdi:waypoint x="240.0" y="63.0"></omgdi:waypoint>
|
||||
</bpmndi:BPMNEdge>
|
||||
<bpmndi:BPMNEdge bpmnElement="flow4" id="BPMNEdge_flow4">
|
||||
<omgdi:waypoint x="260.0" y="83.0"></omgdi:waypoint>
|
||||
<omgdi:waypoint x="260.0" y="114.0"></omgdi:waypoint>
|
||||
<bpmndi:BPMNLabel>
|
||||
<omgdc:Bounds height="11.0" width="33.0" x="270.0" y="83.0"></omgdc:Bounds>
|
||||
</bpmndi:BPMNLabel>
|
||||
</bpmndi:BPMNEdge>
|
||||
<bpmndi:BPMNEdge bpmnElement="flow5" id="BPMNEdge_flow5">
|
||||
<omgdi:waypoint x="280.0" y="63.0"></omgdi:waypoint>
|
||||
<omgdi:waypoint x="348.0" y="63.0"></omgdi:waypoint>
|
||||
<bpmndi:BPMNLabel>
|
||||
<omgdc:Bounds height="11.0" width="22.0" x="300.0" y="46.0"></omgdc:Bounds>
|
||||
</bpmndi:BPMNLabel>
|
||||
</bpmndi:BPMNEdge>
|
||||
<bpmndi:BPMNEdge bpmnElement="flow6" id="BPMNEdge_flow6">
|
||||
<omgdi:waypoint x="453.0" y="63.0"></omgdi:waypoint>
|
||||
<omgdi:waypoint x="485.0" y="63.0"></omgdi:waypoint>
|
||||
</bpmndi:BPMNEdge>
|
||||
<bpmndi:BPMNEdge bpmnElement="flow7" id="BPMNEdge_flow7">
|
||||
<omgdi:waypoint x="525.0" y="63.0"></omgdi:waypoint>
|
||||
<omgdi:waypoint x="580.0" y="63.0"></omgdi:waypoint>
|
||||
<bpmndi:BPMNLabel>
|
||||
<omgdc:Bounds height="11.0" width="22.0" x="539.0" y="46.0"></omgdc:Bounds>
|
||||
</bpmndi:BPMNLabel>
|
||||
</bpmndi:BPMNEdge>
|
||||
<bpmndi:BPMNEdge bpmnElement="flow8" id="BPMNEdge_flow8">
|
||||
<omgdi:waypoint x="632.0" y="91.0"></omgdi:waypoint>
|
||||
<omgdi:waypoint x="632.0" y="195.0"></omgdi:waypoint>
|
||||
</bpmndi:BPMNEdge>
|
||||
<bpmndi:BPMNEdge bpmnElement="flow9" id="BPMNEdge_flow9">
|
||||
<omgdi:waypoint x="505.0" y="83.0"></omgdi:waypoint>
|
||||
<omgdi:waypoint x="504.0" y="141.0"></omgdi:waypoint>
|
||||
<omgdi:waypoint x="313.0" y="141.0"></omgdi:waypoint>
|
||||
<bpmndi:BPMNLabel>
|
||||
<omgdc:Bounds height="11.0" width="33.0" x="515.0" y="83.0"></omgdc:Bounds>
|
||||
</bpmndi:BPMNLabel>
|
||||
</bpmndi:BPMNEdge>
|
||||
<bpmndi:BPMNEdge bpmnElement="flow10" id="BPMNEdge_flow10">
|
||||
<omgdi:waypoint x="240.0" y="212.0"></omgdi:waypoint>
|
||||
<omgdi:waypoint x="132.0" y="212.0"></omgdi:waypoint>
|
||||
<omgdi:waypoint x="132.0" y="91.0"></omgdi:waypoint>
|
||||
<bpmndi:BPMNLabel>
|
||||
<omgdc:Bounds height="11.0" width="44.0" x="142.0" y="192.0"></omgdc:Bounds>
|
||||
</bpmndi:BPMNLabel>
|
||||
</bpmndi:BPMNEdge>
|
||||
<bpmndi:BPMNEdge bpmnElement="flow11" id="BPMNEdge_flow11">
|
||||
<omgdi:waypoint x="260.0" y="169.0"></omgdi:waypoint>
|
||||
<omgdi:waypoint x="260.0" y="192.0"></omgdi:waypoint>
|
||||
</bpmndi:BPMNEdge>
|
||||
<bpmndi:BPMNEdge bpmnElement="flow12" id="BPMNEdge_flow12">
|
||||
<omgdi:waypoint x="280.0" y="212.0"></omgdi:waypoint>
|
||||
<omgdi:waypoint x="615.0" y="212.0"></omgdi:waypoint>
|
||||
<bpmndi:BPMNLabel>
|
||||
<omgdc:Bounds height="11.0" width="44.0" x="429.0" y="219.0"></omgdc:Bounds>
|
||||
</bpmndi:BPMNLabel>
|
||||
</bpmndi:BPMNEdge>
|
||||
<bpmndi:BPMNEdge bpmnElement="flow4">
|
||||
<omgdi:waypoint x="260.0" y="63.0"/>
|
||||
<omgdi:waypoint x="632.5" y="212.5"/>
|
||||
</bpmndi:BPMNEdge>
|
||||
<bpmndi:BPMNEdge bpmnElement="flow9">
|
||||
<omgdi:waypoint x="505.0" y="63.0"/>
|
||||
<omgdi:waypoint x="632.5" y="212.5"/>
|
||||
</bpmndi:BPMNEdge>
|
||||
</bpmndi:BPMNPlane>
|
||||
</bpmndi:BPMNDiagram>
|
||||
</definitions>
|
|
@ -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'
|
||||
})
|
||||
}
|
|
@ -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'
|
||||
})
|
||||
}
|
|
@ -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'
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -0,0 +1,347 @@
|
|||
<template>
|
||||
<div class="app-container">
|
||||
|
||||
<!-- 搜索工作栏 -->
|
||||
<el-form :model="queryParams" ref="queryForm" :inline="true" v-show="showSearch" label-width="68px">
|
||||
<el-form-item label="流程id" prop="processInstanceId">
|
||||
<el-input v-model="queryParams.processInstanceId" placeholder="请输入流程id" clearable size="small" @keyup.enter.native="handleQuery"/>
|
||||
</el-form-item>
|
||||
<el-form-item label="状态" prop="status">
|
||||
<el-select v-model="queryParams.status" placeholder="请选择状态">
|
||||
<el-option
|
||||
v-for="dict in leaveStatusData"
|
||||
:key="parseInt(dict.value)"
|
||||
:label="dict.label"
|
||||
:value="parseInt(dict.value)"
|
||||
/>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="开始时间">
|
||||
<el-date-picker v-model="dateRangeStartTime" size="small" style="width: 240px" value-format="yyyy-MM-dd"
|
||||
type="daterange" range-separator="-" start-placeholder="开始日期" end-placeholder="结束日期" />
|
||||
</el-form-item>
|
||||
<el-form-item label="结束时间">
|
||||
<el-date-picker v-model="dateRangeEndTime" size="small" style="width: 240px" value-format="yyyy-MM-dd"
|
||||
type="daterange" range-separator="-" start-placeholder="开始日期" end-placeholder="结束日期" />
|
||||
</el-form-item>
|
||||
<el-form-item label="请假类型" prop="leaveType">
|
||||
<el-select v-model="queryParams.leaveType" placeholder="请选择请假类型">
|
||||
<el-option
|
||||
v-for="dict in leaveTypeDictData"
|
||||
:key="parseInt(dict.value)"
|
||||
:label="dict.label"
|
||||
:value="parseInt(dict.value)"
|
||||
/>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="原因" prop="reason">
|
||||
<el-input v-model="queryParams.reason" placeholder="请输入原因" clearable size="small" @keyup.enter.native="handleQuery"/>
|
||||
</el-form-item>
|
||||
<el-form-item label="申请时间">
|
||||
<el-date-picker v-model="dateRangeApplyTime" size="small" style="width: 240px" value-format="yyyy-MM-dd"
|
||||
type="daterange" range-separator="-" start-placeholder="开始日期" end-placeholder="结束日期" />
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<el-button type="primary" icon="el-icon-search" size="mini" @click="handleQuery">搜索</el-button>
|
||||
<el-button icon="el-icon-refresh" size="mini" @click="resetQuery">重置</el-button>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
|
||||
<!-- 操作工具栏 -->
|
||||
<el-row :gutter="10" class="mb8">
|
||||
<el-col :span="1.5">
|
||||
<el-button type="primary" plain icon="el-icon-plus" size="mini" @click="handleAdd"
|
||||
v-hasPermi="['oa:leave:create']">新增</el-button>
|
||||
</el-col>
|
||||
<right-toolbar :showSearch.sync="showSearch" @queryTable="getList"></right-toolbar>
|
||||
</el-row>
|
||||
|
||||
<!-- 列表 -->
|
||||
<el-table v-loading="loading" :data="list">
|
||||
<el-table-column label="请假表单主键" align="center" prop="id" />
|
||||
<el-table-column label="状态" align="center" prop="status" :formatter="statusFormat" />
|
||||
<el-table-column label="申请人id" align="center" prop="userId" />
|
||||
<el-table-column label="开始时间" align="center" prop="startTime" width="180">
|
||||
<template slot-scope="scope">
|
||||
<span>{{ parseTime(scope.row.startTime) }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="结束时间" align="center" prop="endTime" width="180">
|
||||
<template slot-scope="scope">
|
||||
<span>{{ parseTime(scope.row.endTime) }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="请假类型" align="center" prop="leaveType" />
|
||||
<el-table-column label="原因" align="center" prop="reason" />
|
||||
<el-table-column label="申请时间" align="center" prop="applyTime" width="180">
|
||||
<template slot-scope="scope">
|
||||
<span>{{ parseTime(scope.row.applyTime) }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="操作" align="center" class-name="small-padding fixed-width">
|
||||
<template slot-scope="scope">
|
||||
<el-button size="mini" type="text" icon="el-icon-edit" @click="handleStep(scope.row)">审批进度</el-button>
|
||||
<el-button size="mini" type="text" icon="el-icon-edit" @click="handleDetail(scope.row)">详情</el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
<!-- 分页组件 -->
|
||||
<pagination v-show="total > 0" :total="total" :page.sync="queryParams.pageNo" :limit.sync="queryParams.pageSize"
|
||||
@pagination="getList"/>
|
||||
|
||||
<!-- 对话框(添加 / 修改) -->
|
||||
<el-dialog :title="title" :visible.sync="open" width="500px" append-to-body>
|
||||
<el-form ref="form" :model="form" :rules="rules" label-width="80px">
|
||||
<el-form-item label="开始时间" prop="startTime">
|
||||
<el-date-picker clearable size="small" v-model="form.startTime" type="date" value-format="timestamp" placeholder="选择开始时间" />
|
||||
</el-form-item>
|
||||
<el-form-item label="结束时间" prop="endTime">
|
||||
<el-date-picker clearable size="small" v-model="form.endTime" type="date" value-format="timestamp" placeholder="选择结束时间" />
|
||||
</el-form-item>
|
||||
<el-form-item label="请假类型" prop="leaveType">
|
||||
<el-select v-model="form.leaveType" placeholder="请选择">
|
||||
<el-option
|
||||
v-for="dict in leaveTypeDictData"
|
||||
:key="parseInt(dict.value)"
|
||||
:label="dict.label"
|
||||
:value="parseInt(dict.value)"
|
||||
/>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="原因" prop="reason">
|
||||
<el-input v-model="form.reason" placeholder="请输入原因" />
|
||||
</el-form-item>
|
||||
<el-form-item label="申请时间" prop="applyTime">
|
||||
<el-date-picker clearable size="small" v-model="form.applyTime" type="date" value-format="timestamp" placeholder="选择申请时间" />
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<div slot="footer" class="dialog-footer">
|
||||
<el-button type="primary" @click="submitForm">确 定</el-button>
|
||||
<el-button @click="cancel">取 消</el-button>
|
||||
</div>
|
||||
</el-dialog>
|
||||
|
||||
<el-dialog :title="title" :visible.sync="dialogDetailVisible" width="500px" append-to-body>
|
||||
<el-form ref="form" :model="form" label-width="80px">
|
||||
<el-form-item label="状态" >
|
||||
{{ getDictDataLabel(DICT_TYPE.OA_LEAVE_STATUS, form.status) }}
|
||||
</el-form-item>
|
||||
<el-form-item label="申请人id" >{{form.userId}}</el-form-item>
|
||||
<el-form-item label="开始时间" >{{ parseTime(form.startTime) }}</el-form-item>
|
||||
<el-form-item label="结束时间" prop="endTime">{{ parseTime(form.endTime) }}</el-form-item>
|
||||
<el-form-item label="请假类型" prop="leaveType">
|
||||
{{ getDictDataLabel(DICT_TYPE.OA_LEAVE_TYPE, form.leaveType) }}
|
||||
</el-form-item>
|
||||
<el-form-item label="原因" prop="reason">{{form.reason}}</el-form-item>
|
||||
<el-form-item label="申请时间" prop="applyTime">{{ parseTime(form.applyTime) }}</el-form-item>
|
||||
</el-form>
|
||||
<div slot="footer" class="dialog-footer">
|
||||
<el-button type="primary" @click="dialogDetailVisible = false">确 定</el-button>
|
||||
<el-button @click="dialogDetailVisible = false">取 消</el-button>
|
||||
</div>
|
||||
</el-dialog>
|
||||
|
||||
<el-dialog :title="title" :visible.sync="dialogStepsVisible" width="600px" append-to-body>
|
||||
<el-steps :active="handleTask.historyTask.length-1" finish-status="success" >
|
||||
<el-step :title="item.stepName " :description="' 办理人:' + item.assignee " icon="el-icon-edit" v-for="(item) in handleTask.historyTask"></el-step>
|
||||
</el-steps>
|
||||
<br/>
|
||||
<el-steps direction="vertical" :active="handleTask.historyTask.length-1">
|
||||
<el-step :title="item.stepName" :description=" ' 意见:'+ item.comment" v-for="(item) in handleTask.historyTask"></el-step>
|
||||
</el-steps>
|
||||
<div slot="footer" class="dialog-footer">
|
||||
<el-button type="primary" @click="dialogStepsVisible = false">确 定</el-button>
|
||||
<el-button @click="dialogStepsVisible = false">取 消</el-button>
|
||||
</div>
|
||||
</el-dialog>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { createLeave, updateLeave, deleteLeave, getLeave, getLeavePage, exportLeaveExcel } from "@/api/oa/leave"
|
||||
import { getDictDataLabel, getDictDatas, DICT_TYPE } from '@/utils/dict'
|
||||
import { processHistorySteps } from '@/api/oa/todo'
|
||||
export default {
|
||||
name: "Leave",
|
||||
components: {
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
// 遮罩层
|
||||
loading: true,
|
||||
// 显示搜索条件
|
||||
showSearch: true,
|
||||
// 总条数
|
||||
total: 0,
|
||||
// 请假申请列表
|
||||
list: [],
|
||||
// 弹出层标题
|
||||
title: "",
|
||||
// 是否显示弹出层
|
||||
open: false,
|
||||
//进度弹出层
|
||||
dialogDetailVisible: false,
|
||||
//审批进度弹出层
|
||||
dialogStepsVisible: false,
|
||||
dateRangeStartTime: [],
|
||||
dateRangeEndTime: [],
|
||||
dateRangeApplyTime: [],
|
||||
// 查询参数
|
||||
queryParams: {
|
||||
pageNo: 1,
|
||||
pageSize: 10,
|
||||
processInstanceId: null,
|
||||
status: null,
|
||||
userId: null,
|
||||
leaveType: null,
|
||||
reason: null,
|
||||
},
|
||||
// 表单参数
|
||||
form: {},
|
||||
handleTask: {
|
||||
historyTask:[{
|
||||
stepName:"步骤一"
|
||||
}
|
||||
],
|
||||
taskVariable: "",
|
||||
formObject: {}
|
||||
},
|
||||
steps:[{
|
||||
stepName:"步骤一"
|
||||
}],
|
||||
// 表单校验
|
||||
rules: {
|
||||
startTime: [{ required: true, message: "开始时间不能为空", trigger: "blur" }],
|
||||
endTime: [{ required: true, message: "结束时间不能为空", trigger: "blur" }],
|
||||
applyTime: [{ required: true, message: "申请时间不能为空", trigger: "blur" }],
|
||||
},
|
||||
statusFormat(row, column) {
|
||||
return getDictDataLabel(DICT_TYPE.OA_LEAVE_STATUS, row.status)
|
||||
},
|
||||
leaveTypeDictData: getDictDatas(DICT_TYPE.OA_LEAVE_TYPE),
|
||||
leaveStatusData: getDictDatas(DICT_TYPE.OA_LEAVE_STATUS)
|
||||
};
|
||||
},
|
||||
created() {
|
||||
this.getList();
|
||||
},
|
||||
methods: {
|
||||
/** 查询列表 */
|
||||
getList() {
|
||||
this.loading = true;
|
||||
// 处理查询参数
|
||||
let params = {...this.queryParams};
|
||||
this.addBeginAndEndTime(params, this.dateRangeStartTime, 'startTime');
|
||||
this.addBeginAndEndTime(params, this.dateRangeEndTime, 'endTime');
|
||||
this.addBeginAndEndTime(params, this.dateRangeApplyTime, 'applyTime');
|
||||
// 执行查询
|
||||
getLeavePage(params).then(response => {
|
||||
this.list = response.data.list;
|
||||
this.total = response.data.total;
|
||||
this.loading = false;
|
||||
});
|
||||
},
|
||||
/** 取消按钮 */
|
||||
cancel() {
|
||||
this.open = false;
|
||||
this.reset();
|
||||
},
|
||||
/** 表单重置 */
|
||||
reset() {
|
||||
this.form = {
|
||||
id: undefined,
|
||||
processInstanceId: undefined,
|
||||
status: undefined,
|
||||
userId: undefined,
|
||||
startTime: undefined,
|
||||
endTime: undefined,
|
||||
leaveType: undefined,
|
||||
reason: undefined,
|
||||
applyTime: undefined,
|
||||
};
|
||||
this.resetForm("form");
|
||||
},
|
||||
/** 搜索按钮操作 */
|
||||
handleQuery() {
|
||||
this.queryParams.pageNo = 1;
|
||||
this.getList();
|
||||
},
|
||||
/** 重置按钮操作 */
|
||||
resetQuery() {
|
||||
this.dateRangeStartTime = [];
|
||||
this.dateRangeEndTime = [];
|
||||
this.dateRangeApplyTime = [];
|
||||
this.resetForm("queryForm");
|
||||
this.handleQuery();
|
||||
},
|
||||
/** 新增按钮操作 */
|
||||
handleAdd() {
|
||||
this.reset();
|
||||
this.open = true;
|
||||
this.title = "添加请假申请";
|
||||
},
|
||||
/** 详情按钮操作 */
|
||||
handleDetail(row) {
|
||||
this.reset();
|
||||
const id = row.id;
|
||||
getLeave(id).then(response => {
|
||||
this.form = response.data;
|
||||
this.dialogDetailVisible = true
|
||||
this.title = "请假详情";
|
||||
});
|
||||
},
|
||||
/** 提交按钮 */
|
||||
submitForm() {
|
||||
this.$refs["form"].validate(valid => {
|
||||
if (!valid) {
|
||||
return;
|
||||
}
|
||||
// 修改的提交
|
||||
if (this.form.id != null) {
|
||||
updateLeave(this.form).then(response => {
|
||||
this.msgSuccess("修改成功");
|
||||
this.open = false;
|
||||
this.getList();
|
||||
});
|
||||
return;
|
||||
}
|
||||
// 添加的提交
|
||||
createLeave(this.form).then(response => {
|
||||
this.msgSuccess("新增成功");
|
||||
this.open = false;
|
||||
this.getList();
|
||||
});
|
||||
});
|
||||
},
|
||||
/** 审批进度 */
|
||||
handleStep(row) {
|
||||
const id = row.processInstanceId;
|
||||
processHistorySteps(id).then(response => {
|
||||
this.handleTask.historyTask = response.data;
|
||||
this.dialogStepsVisible = true
|
||||
this.title = "审批进度";
|
||||
});
|
||||
},
|
||||
/** 导出按钮操作 */
|
||||
handleExport() {
|
||||
// 处理查询参数
|
||||
let params = {...this.queryParams};
|
||||
params.pageNo = undefined;
|
||||
params.pageSize = undefined;
|
||||
this.addBeginAndEndTime(params, this.dateRangeStartTime, 'startTime');
|
||||
this.addBeginAndEndTime(params, this.dateRangeEndTime, 'endTime');
|
||||
this.addBeginAndEndTime(params, this.dateRangeApplyTime, 'applyTime');
|
||||
// 执行导出
|
||||
this.$confirm('是否确认导出所有请假申请数据项?', "警告", {
|
||||
confirmButtonText: "确定",
|
||||
cancelButtonText: "取消",
|
||||
type: "warning"
|
||||
}).then(function() {
|
||||
return exportLeaveExcel(params);
|
||||
}).then(response => {
|
||||
this.downloadExcel(response, '请假申请.xls');
|
||||
})
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
|
@ -0,0 +1,284 @@
|
|||
<template>
|
||||
<div class="app-container">
|
||||
|
||||
<!-- 搜索工作栏 -->
|
||||
<el-form :model="queryParams" ref="queryForm" :inline="true" v-show="showSearch" label-width="68px">
|
||||
<el-form-item label="状态" prop="status">
|
||||
<el-select v-model="queryParams.status" placeholder="请选择状态">
|
||||
<el-option
|
||||
v-for="dict in leaveStatusData"
|
||||
:key="parseInt(dict.value)"
|
||||
:label="dict.label"
|
||||
:value="parseInt(dict.value)"
|
||||
/>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<el-button type="primary" icon="el-icon-search" size="mini" @click="handleQuery">搜索</el-button>
|
||||
<el-button icon="el-icon-refresh" size="mini" @click="resetQuery">重置</el-button>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
|
||||
|
||||
|
||||
<!-- 列表 -->
|
||||
<el-table v-loading="loading" :data="list">
|
||||
<el-table-column label="任务Id" align="center" prop="id" />
|
||||
<el-table-column label="流程名称" align="center" prop="processName" />
|
||||
<el-table-column label="任务状态" align="center" :formatter="statusFormat" prop="status" />
|
||||
<!-- <el-table-column label="申请人id" align="center" prop="userId" />-->
|
||||
<!-- <el-table-column label="开始时间" align="center" prop="startTime" width="180">-->
|
||||
<!-- <template slot-scope="scope">-->
|
||||
<!-- <span>{{ parseTime(scope.row.startTime) }}</span>-->
|
||||
<!-- </template>-->
|
||||
<!-- </el-table-column>-->
|
||||
<!-- <el-table-column label="结束时间" align="center" prop="endTime" width="180">-->
|
||||
<!-- <template slot-scope="scope">-->
|
||||
<!-- <span>{{ parseTime(scope.row.endTime) }}</span>-->
|
||||
<!-- </template>-->
|
||||
<!-- </el-table-column>-->
|
||||
<!-- <el-table-column label="请假类型" align="center" prop="leaveType" />-->
|
||||
<!-- <el-table-column label="原因" align="center" prop="reason" />-->
|
||||
<!-- <el-table-column label="申请时间" align="center" prop="applyTime" width="180">-->
|
||||
<!-- <template slot-scope="scope">-->
|
||||
<!-- <span>{{ parseTime(scope.row.applyTime) }}</span>-->
|
||||
<!-- </template>-->
|
||||
<!-- </el-table-column>-->
|
||||
<el-table-column label="操作" align="center" class-name="small-padding fixed-width">
|
||||
<template slot-scope="scope">
|
||||
<el-button size="mini" type="text" icon="el-icon-edit" v-if="scope.row.status == 1" @click="handleClaim(scope.row)">签收</el-button>
|
||||
<el-button size="mini" type="text" icon="el-icon-edit" v-if="scope.row.status == 2" @click="handleLeaveApprove(scope.row)">办理</el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
<!-- 分页组件 -->
|
||||
<pagination v-show="total > 0" :total="total" :page.sync="queryParams.pageNo" :limit.sync="queryParams.pageSize"
|
||||
@pagination="getList"/>
|
||||
|
||||
<el-dialog :title="title" :visible.sync="open" width="600px" append-to-body>
|
||||
<el-tabs tab-position="left" style="height: 500px;">
|
||||
<el-tab-pane label="详情">
|
||||
<el-form ref="form" :model="handleTask.formObject" label-width="80px">
|
||||
<el-form-item label="状态" >
|
||||
{{ getDictDataLabel(DICT_TYPE.OA_LEAVE_STATUS, handleTask.formObject.status) }}
|
||||
</el-form-item>
|
||||
<el-form-item label="申请人id" >{{handleTask.formObject.userId}}</el-form-item>
|
||||
<el-form-item label="开始时间" >{{ parseTime(handleTask.formObject.startTime) }}</el-form-item>
|
||||
<el-form-item label="结束时间" prop="endTime">{{ parseTime(handleTask.formObject.endTime) }}</el-form-item>
|
||||
<el-form-item label="请假类型" prop="leaveType">
|
||||
{{ getDictDataLabel(DICT_TYPE.OA_LEAVE_TYPE, handleTask.formObject.leaveType) }}
|
||||
</el-form-item>
|
||||
<el-form-item label="原因" prop="reason">{{handleTask.formObject.reason}}</el-form-item>
|
||||
<el-form-item label="申请时间" prop="applyTime">{{ parseTime(handleTask.formObject.applyTime) }}</el-form-item>
|
||||
</el-form>
|
||||
</el-tab-pane>
|
||||
<el-tab-pane label="任务处理">
|
||||
<el-steps :active="handleTask.historyTask.length-1" simple finish-status="success">
|
||||
<el-step :title="item.stepName" icon="el-icon-edit" v-for="(item) in handleTask.historyTask" ></el-step>
|
||||
</el-steps>
|
||||
<br/>
|
||||
<el-steps direction="vertical" :active="handleTask.historyTask.length-1" finish-status="success" space="60px">
|
||||
<el-step :title="item.stepName" :description="item.comment" v-for="(item) in handleTask.historyTask" ></el-step>
|
||||
</el-steps>
|
||||
<br/>
|
||||
<el-form ref="taskForm" :model="task" label-width="80px" v-show="handleTask.taskVariable !=''">
|
||||
<el-form-item label="处理意见" prop="approved">
|
||||
<el-select v-model="task.approved" placeholder="处理意见">
|
||||
<el-option
|
||||
v-for="dict in approvedData"
|
||||
:key="parseInt(dict.value)"
|
||||
:label="dict.label"
|
||||
:value="parseInt(dict.value)"
|
||||
/>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-input
|
||||
type="textarea"
|
||||
:rows="2"
|
||||
v-model="task.comment">
|
||||
</el-input>
|
||||
</el-form>
|
||||
<br/>
|
||||
<el-button type="primary" @click="submitTask">提交</el-button>
|
||||
</el-tab-pane>
|
||||
</el-tabs>
|
||||
</el-dialog>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { completeTask, taskSteps, deleteLeave, getLeave, getTodoTaskPage, claimTask } from "@/api/oa/todo";
|
||||
import { getDictDataLabel, getDictDatas, DICT_TYPE } from '@/utils/dict'
|
||||
export default {
|
||||
name: "Todo",
|
||||
components: {
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
// 遮罩层
|
||||
loading: true,
|
||||
// 显示搜索条件
|
||||
showSearch: true,
|
||||
// 总条数
|
||||
total: 0,
|
||||
// 请假申请列表
|
||||
list: [],
|
||||
// 弹出层标题
|
||||
title: "",
|
||||
// 是否显示弹出层
|
||||
open: false,
|
||||
// 查询参数
|
||||
queryParams: {
|
||||
pageNo: 1,
|
||||
pageSize: 10
|
||||
},
|
||||
// 表单参数
|
||||
form: {},
|
||||
handleTask: {
|
||||
historyTask:[{
|
||||
stepName:"步骤一"
|
||||
}
|
||||
],
|
||||
taskVariable: "",
|
||||
formObject: {}
|
||||
},
|
||||
steps:[{
|
||||
stepName:"步骤一"
|
||||
}],
|
||||
task: {
|
||||
approved : 1,
|
||||
variables: {},
|
||||
taskId: undefined,
|
||||
comment: ""
|
||||
},
|
||||
rules: {
|
||||
},
|
||||
leaveTypeDictData: getDictDatas(DICT_TYPE.OA_LEAVE_TYPE),
|
||||
leaveStatusData: getDictDatas(DICT_TYPE.OA_LEAVE_STATUS),
|
||||
approvedData: [
|
||||
{
|
||||
value: 1,
|
||||
label: '同意'
|
||||
},
|
||||
{
|
||||
value: 0,
|
||||
label: '不同意'
|
||||
}
|
||||
]
|
||||
};
|
||||
},
|
||||
created() {
|
||||
this.getList();
|
||||
},
|
||||
methods: {
|
||||
/** 查询列表 */
|
||||
getList() {
|
||||
this.loading = true;
|
||||
// 处理查询参数
|
||||
let params = {...this.queryParams};
|
||||
// 执行查询
|
||||
getTodoTaskPage(params).then(response => {
|
||||
this.list = response.data.list;
|
||||
this.total = response.data.total;
|
||||
this.loading = false;
|
||||
});
|
||||
},
|
||||
/** 取消按钮 */
|
||||
cancel() {
|
||||
this.open = false;
|
||||
this.reset();
|
||||
},
|
||||
/** 表单重置 */
|
||||
reset() {
|
||||
this.form = {
|
||||
id: undefined,
|
||||
processInstanceId: undefined,
|
||||
status: undefined,
|
||||
userId: undefined,
|
||||
startTime: undefined,
|
||||
endTime: undefined,
|
||||
leaveType: undefined,
|
||||
reason: undefined,
|
||||
applyTime: undefined,
|
||||
};
|
||||
this.resetForm("form");
|
||||
},
|
||||
|
||||
statusFormat(row, column) {
|
||||
return row.status == 1 ? "未签收" : "已签收";
|
||||
},
|
||||
/** 搜索按钮操作 */
|
||||
handleQuery() {
|
||||
this.queryParams.pageNo = 1;
|
||||
this.getList();
|
||||
},
|
||||
/** 重置按钮操作 */
|
||||
resetQuery() {
|
||||
this.dateRangeStartTime = [];
|
||||
this.dateRangeEndTime = [];
|
||||
this.dateRangeApplyTime = [];
|
||||
this.resetForm("queryForm");
|
||||
this.handleQuery();
|
||||
},
|
||||
|
||||
handleLeaveApprove(row) {
|
||||
this.reset();
|
||||
const businessKey = row.businessKey;
|
||||
const taskId = row.id;
|
||||
const processKey = row.processKey;
|
||||
const data = {
|
||||
taskId : taskId,
|
||||
businessKey: businessKey,
|
||||
processKey: processKey
|
||||
}
|
||||
taskSteps(data).then(response => {
|
||||
this.form = {};
|
||||
this.handleTask = response.data;
|
||||
this.task.taskId = taskId;
|
||||
this.open = true;
|
||||
this.title = "任务办理";
|
||||
});
|
||||
},
|
||||
/** 任务签收操作 */
|
||||
handleClaim(row) {
|
||||
this.reset();
|
||||
const id = row.id;
|
||||
claimTask(id).then(() => {
|
||||
this.getList();
|
||||
this.msgSuccess("签收成功");
|
||||
});
|
||||
},
|
||||
/** 提交任务 */
|
||||
submitTask() {
|
||||
const taskVariableName = this.handleTask.taskVariable;
|
||||
if (taskVariableName != "") {
|
||||
if (this.task.approved == 1) {
|
||||
this.task.variables[taskVariableName] = true;
|
||||
}
|
||||
if (this.task.approved == 0) {
|
||||
this.task.variables[taskVariableName] = false;
|
||||
}
|
||||
}
|
||||
completeTask(this.task).then(response => {
|
||||
this.msgSuccess("执行任务成功");
|
||||
this.open = false;
|
||||
this.getList();
|
||||
})
|
||||
},
|
||||
/** 删除按钮操作 */
|
||||
handleDelete(row) {
|
||||
const id = row.id;
|
||||
this.$confirm('是否确认删除请假申请编号为"' + id + '"的数据项?', "警告", {
|
||||
confirmButtonText: "确定",
|
||||
cancelButtonText: "取消",
|
||||
type: "warning"
|
||||
}).then(function() {
|
||||
return deleteLeave(id);
|
||||
}).then(() => {
|
||||
this.getList();
|
||||
this.msgSuccess("删除成功");
|
||||
})
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
|
@ -19,20 +19,29 @@
|
|||
<properties>
|
||||
<activiti.version>7.1.0.M6</activiti.version>
|
||||
</properties>
|
||||
|
||||
<dependencyManagement>
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.activiti.dependencies</groupId>
|
||||
<artifactId>activiti-dependencies</artifactId>
|
||||
<version>${activiti.version}</version>
|
||||
<scope>import</scope>
|
||||
<type>pom</type>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
</dependencyManagement>
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>cn.iocoder.boot</groupId>
|
||||
<artifactId>yudao-common</artifactId>
|
||||
</dependency>
|
||||
|
||||
|
||||
<dependency>
|
||||
<groupId>org.activiti.dependencies</groupId>
|
||||
<artifactId>activiti-dependencies</artifactId>
|
||||
<version>${activiti.version}</version>
|
||||
<type>pom</type>
|
||||
<groupId>org.mybatis</groupId>
|
||||
<artifactId>mybatis</artifactId>
|
||||
<optional>true</optional>
|
||||
</dependency>
|
||||
|
||||
<!--使用mybatis plus需排除掉mybatis-->
|
||||
<dependency>
|
||||
<groupId>org.activiti</groupId>
|
||||
|
@ -51,6 +60,10 @@
|
|||
<groupId>org.mybatis</groupId>
|
||||
<artifactId>mybatis</artifactId>
|
||||
</exclusion>
|
||||
<exclusion>
|
||||
<artifactId>el-api</artifactId>
|
||||
<groupId>javax.el</groupId>
|
||||
</exclusion>
|
||||
</exclusions>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
|
@ -39,6 +39,18 @@
|
|||
<artifactId>spring-boot-starter-security</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.activiti</groupId>
|
||||
<artifactId>activiti-engine</artifactId>
|
||||
<version>7.1.0.M6</version>
|
||||
<exclusions>
|
||||
<exclusion>
|
||||
<groupId>*</groupId>
|
||||
<artifactId>*</artifactId>
|
||||
</exclusion>
|
||||
</exclusions>
|
||||
<optional>true</optional>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
</project>
|
||||
|
|
|
@ -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<Long> postIds;
|
||||
|
||||
/**
|
||||
* group 目前指岗位代替
|
||||
*/
|
||||
private List<String> 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<GrantedAuthority> list = new ArrayList<>(1);
|
||||
list.add(new SimpleGrantedAuthority("ROLE_ACTIVITI_USER"));
|
||||
return list;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -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());
|
||||
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue