mirror of
https://gitee.com/huangge1199_admin/vue-pro.git
synced 2025-01-31 17:40:05 +08:00
1.实现了工作流引擎 中 请假流程demo(定义在 resources/leave.bpmn)
2.增加一个一级菜单 OA 办公 下面两个菜单: 请假申请,待办任务 3.暂时不知如何找部门领导, 暂时写死为 admin 4.activity 用户组使用 用户岗位来代替。 5.新增一个用户 hradmin, 密码 123456 岗位是 人力资源 6.演示流程。 a. admin 登陆 申请请假 b. admin 待办任务(审批) c. hradmin 登陆 待办任务(审批) d. admin 登陆 待办任务 (确认)
This commit is contained in:
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>
|
130
yudao-admin-server/src/main/resources/processes/leave.bpmn
Normal file
130
yudao-admin-server/src/main/resources/processes/leave.bpmn
Normal file
@ -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>
|
54
yudao-admin-ui/src/api/oa/leave.js
Normal file
54
yudao-admin-ui/src/api/oa/leave.js
Normal file
@ -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'
|
||||
})
|
||||
}
|
75
yudao-admin-ui/src/api/oa/todo.js
Normal file
75
yudao-admin-ui/src/api/oa/todo.js
Normal file
@ -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'
|
||||
}
|
||||
|
||||
/**
|
||||
|
347
yudao-admin-ui/src/views/oa/leave/index.vue
Normal file
347
yudao-admin-ui/src/views/oa/leave/index.vue
Normal file
@ -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>
|
284
yudao-admin-ui/src/views/oa/todo/index.vue
Normal file
284
yudao-admin-ui/src/views/oa/todo/index.vue
Normal file
@ -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
Block a user