修改code review

pull/2/head
jason 2021-10-31 22:11:55 +08:00
parent 722eaf3513
commit f26c17cff0
21 changed files with 768 additions and 115 deletions

View File

@ -0,0 +1,114 @@
package cn.iocoder.yudao.adminserver.modules.activiti.controller.oa;
import cn.iocoder.yudao.adminserver.modules.activiti.controller.oa.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.service.oa.OALeaveService;
import cn.iocoder.yudao.framework.common.pojo.CommonResult;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.excel.core.util.ExcelUtils;
import cn.iocoder.yudao.framework.operatelog.core.annotations.OperateLog;
import cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiOperation;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;
import javax.validation.Valid;
import java.io.IOException;
import java.util.Collection;
import java.util.List;
import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
import static cn.iocoder.yudao.framework.operatelog.core.enums.OperateTypeEnum.EXPORT;
@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) {
// TODO @芋艿processKey 自己去理解下。不过得把 leave 变成枚举
createReqVO.setProcessKey("leave");
return success(leaveService.createLeave(createReqVO));
}
@PostMapping("/form-key/create")
@ApiOperation("创建外置请假申请")
public CommonResult<Long> createFormKeyLeave(@Valid @RequestBody OALeaveCreateReqVO createReqVO) {
// TODO @芋艿processKey 自己去理解下。不过得把 formkey 变成枚举
createReqVO.setProcessKey("leave-formkey");
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) {
//值查询自己申请请假
// TODO @芋艿:这里的传值,到底前端搞,还是后端搞。
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);
}
}

View File

@ -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;
}

View File

@ -0,0 +1,13 @@
package cn.iocoder.yudao.adminserver.modules.activiti.controller.oa.vo;
import lombok.*;
import io.swagger.annotations.*;
@ApiModel("请假申请创建 Request VO")
@Data
@EqualsAndHashCode(callSuper = true)
@ToString(callSuper = true)
public class OALeaveCreateReqVO extends OALeaveBaseVO {
private String processKey;
}

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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;
}

View File

@ -0,0 +1,15 @@
package cn.iocoder.yudao.adminserver.modules.activiti.controller.oa.vo;
import lombok.*;
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;
}

View File

@ -0,0 +1,32 @@
package cn.iocoder.yudao.adminserver.modules.activiti.controller.oa.vo;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.ToString;
import javax.validation.constraints.NotNull;
import java.util.Map;
@ApiModel("请假申请更新 Request VO")
@Data
@EqualsAndHashCode(callSuper = true)
@ToString(callSuper = true)
public class OALeaveUpdateReqVO extends OALeaveBaseVO {
@ApiModelProperty(value = "请假表单主键", required = true)
@NotNull(message = "请假表单主键不能为空")
private Long id;
// TODO @jsonswagger 和 validator 的注解要加哈。
private String taskId;
private String comment;
private Map<String,Object> variables;
// TODO @芋艿variables 的作用是啥。
}

View File

@ -0,0 +1,34 @@
package cn.iocoder.yudao.adminserver.modules.activiti.convert.oa;
import java.util.*;
import cn.iocoder.yudao.adminserver.modules.activiti.dal.dataobject.oa.OALeaveDO;
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.*;
/**
* 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);
}

View File

@ -0,0 +1,39 @@
package cn.iocoder.yudao.adminserver.modules.activiti.convert.workflow;
import cn.iocoder.yudao.adminserver.modules.activiti.controller.workflow.vo.TaskStepVO;
import cn.iocoder.yudao.adminserver.modules.activiti.controller.workflow.vo.TodoTaskRespVO;
import org.activiti.api.task.model.Task;
import org.activiti.engine.history.HistoricActivityInstance;
import org.activiti.engine.repository.ProcessDefinition;
import org.mapstruct.Mapper;
import org.mapstruct.Mapping;
import org.mapstruct.Mappings;
import org.mapstruct.Named;
import org.mapstruct.factory.Mappers;
@Mapper
public interface TaskConvert {
TaskConvert INSTANCE = Mappers.getMapper(TaskConvert.class);
@Mappings(value = {
@Mapping(source = "task.id", target = "id"),
@Mapping(source = "task.businessKey", target = "businessKey"),
@Mapping(source = "task.assignee", target = "status",qualifiedByName = "convertAssigneeToStatus"),
@Mapping(source = "definition.name", target = "processName"),
@Mapping(source = "definition.key", target = "processKey")
})
TodoTaskRespVO convert(Task task, ProcessDefinition definition);
@Named("convertAssigneeToStatus")
default Integer convertAssigneeToStatus(String assignee) {
//TODO 不应该通过 assignee 定义状态 需要定义更多的状态
return assignee == null ? 1 : 2;
}
@Mappings(value = {
@Mapping(source = "activityName", target = "stepName"),
@Mapping(source = "assignee", target = "assignee")
})
TaskStepVO convert(HistoricActivityInstance instance);
}

View File

@ -1,9 +0,0 @@
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);
}

View File

@ -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;
}

View File

@ -2,10 +2,10 @@ package cn.iocoder.yudao.adminserver.modules.activiti.dal.mysql.oa;
import java.util.*;
import cn.iocoder.yudao.adminserver.modules.activiti.dal.dataobject.oa.OALeaveDO;
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.*;
@ -15,10 +15,10 @@ import cn.iocoder.yudao.adminserver.modules.activiti.controller.oa.vo.*;
* @author
*/
@Mapper
public interface OaLeaveMapper extends BaseMapperX<OaLeaveDO> {
public interface OaLeaveMapper extends BaseMapperX<OALeaveDO> {
default PageResult<OaLeaveDO> selectPage(OaLeavePageReqVO reqVO) {
return selectPage(reqVO, new QueryWrapperX<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())
@ -30,8 +30,8 @@ public interface OaLeaveMapper extends BaseMapperX<OaLeaveDO> {
.orderByDesc("id") );
}
default List<OaLeaveDO> selectList(OaLeaveExportReqVO reqVO) {
return selectList(new QueryWrapperX<OaLeaveDO>()
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())

View File

@ -8,6 +8,6 @@ import cn.iocoder.yudao.framework.common.exception.ErrorCode;
* 001 oa
* activiti 使 1-003-000-000
*/
public interface OaErrorCodeConstants {
public interface OAErrorCodeConstants {
ErrorCode LEAVE_NOT_EXISTS = new ErrorCode(1003001001, "请假申请不存在");
}

View File

@ -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.OALeaveUpdateReqVO;
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.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);
}

View File

@ -1,8 +1,7 @@
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.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.DelegateExecution;
import org.activiti.engine.delegate.ExecutionListener;
import org.springframework.stereotype.Component;
@ -17,27 +16,15 @@ public class ReportBackEndProcessor implements ExecutionListener {
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);
// }
@Override
@Transactional(rollbackFor = Exception.class)
public void notify(DelegateExecution delegateExecution) {
final String businessKey = delegateExecution.getProcessInstanceBusinessKey();
// TODO @jsonservice 不要出现 dao 的元素,例如说 UpdateWrapper。这里我们可以调用 updateById 方法
UpdateWrapper<OaLeaveDO> updateWrapper = new UpdateWrapper<>();
updateWrapper.eq("id", Long.valueOf(businessKey));
OaLeaveDO updateDo = new OaLeaveDO();
updateDo.setStatus(2); // TODO @jsonstatus 要枚举起来,不要出现 magic number
leaveMapper.update(updateDo, updateWrapper);
OALeaveDO updateDo = new OALeaveDO();
updateDo.setId(Long.valueOf(businessKey));
// TODO @jsonstatus 要枚举起来,不要出现 magic number
updateDo.setStatus(2);
leaveMapper.updateById(updateDo);
}
}

View File

@ -0,0 +1,137 @@
package cn.iocoder.yudao.adminserver.modules.activiti.service.oa.impl;
import cn.iocoder.yudao.adminserver.modules.activiti.controller.oa.vo.OALeaveCreateReqVO;
import cn.iocoder.yudao.adminserver.modules.activiti.controller.oa.vo.OALeaveUpdateReqVO;
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.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.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils;
import org.activiti.api.task.model.Task;
import org.activiti.api.task.model.builders.TaskPayloadBuilder;
import org.activiti.api.task.runtime.TaskRuntime;
import org.activiti.engine.RuntimeService;
import org.activiti.engine.runtime.ProcessInstance;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.validation.annotation.Validated;
import javax.annotation.Resource;
import java.util.*;
import static cn.iocoder.yudao.adminserver.modules.activiti.enums.OAErrorCodeConstants.LEAVE_NOT_EXISTS;
import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
/**
* Service
*
* @author
*/
@Service
@Validated
public class OALeaveServiceImpl implements OALeaveService {
@Resource
private OaLeaveMapper leaveMapper;
@Resource
private RuntimeService runtimeService;
@Resource
private org.activiti.engine.TaskService activitiTaskService;
@Resource
private TaskRuntime taskRuntime;
@Override
@Transactional(rollbackFor = Exception.class)
public Long createLeave(OALeaveCreateReqVO createReqVO) {
// 插入 OA 请假单
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"); // TODO @芋艿:需要部门的负责人
Long id = leave.getId();
String businessKey = String.valueOf(id);
ProcessInstance processInstance = runtimeService.startProcessInstanceByKey(createReqVO.getProcessKey(), businessKey, variables);
String processInstanceId = processInstance.getProcessInstanceId();
// 将工作流的编号,更新到 OA 请假单中
OALeaveDO updateDo = new OALeaveDO();
updateDo.setProcessInstanceId(processInstanceId);
updateDo.setId(id);
leaveMapper.updateById(updateDo);
return id;
}
@Override
@Transactional(rollbackFor = Exception.class)
public void updateLeave(OALeaveUpdateReqVO updateReqVO) {
// 校验存在
this.validateLeaveExists(updateReqVO.getId());
final Task task = taskRuntime.task(updateReqVO.getTaskId());
activitiTaskService.addComment(task.getId(), task.getProcessInstanceId(), updateReqVO.getComment());
Map<String, Object> variables = updateReqVO.getVariables();
//如何得到部门领导人, 暂时写死
variables.put("deptLeader", "admin");
taskRuntime.complete(TaskPayloadBuilder.complete().withTaskId(task.getId())
.withVariables(variables)
.build());
// TOTO @芋道源码 貌似 IDEA 会自动加上final不需要加 final 哈。虽然是不变,但是代码比较少这么去写)
Object reApply = variables.get("reApply");
if(Objects.equals(reApply, true)){
// 更新 表单
OALeaveDO updateObj = OALeaveConvert.INSTANCE.convert(updateReqVO);
leaveMapper.updateById(updateObj);
}
}
@Override
public void deleteLeave(Long id) {
// 校验存在
this.validateLeaveExists(id);
// 删除
leaveMapper.deleteById(id);
// TODO @jason需要调用 runtimeService 的 delete 方法,删除???
// TOTO @芋道源码 目前页面暂时没有实现基于业务表单的删除, 该代码自动生成的。
// TODO @芋道源码 我理解提交流程后,是不允许删除的? 只能在流程处理中作废流程
}
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);
}
}

View File

@ -12,7 +12,6 @@ public interface TaskService {
void claimTask(String taskId);
void getTaskHistory(String taskId);
void completeTask(TaskReqVO taskReq);

View File

@ -1,12 +1,12 @@
package cn.iocoder.yudao.adminserver.modules.activiti.service.workflow.impl;
import cn.hutool.core.collection.CollUtil;
import cn.iocoder.yudao.adminserver.modules.activiti.controller.workflow.vo.*;
import cn.iocoder.yudao.adminserver.modules.activiti.dal.mysql.oa.OaLeaveMapper;
import cn.iocoder.yudao.adminserver.modules.activiti.convert.workflow.TaskConvert;
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.google.common.collect.ImmutableMap;
import org.activiti.api.runtime.shared.query.Page;
import org.activiti.api.runtime.shared.query.Pageable;
import org.activiti.api.task.model.Task;
@ -16,7 +16,6 @@ import org.activiti.api.task.runtime.TaskRuntime;
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.repository.ProcessDefinition;
import org.activiti.engine.task.Comment;
import org.springframework.stereotype.Service;
@ -25,7 +24,6 @@ import org.springframework.transaction.annotation.Transactional;
import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.stream.Collectors;
@ -44,13 +42,6 @@ public class TaskServiceImpl implements TaskService {
@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() {
@ -58,25 +49,16 @@ public class TaskServiceImpl implements TaskService {
@Override
public PageResult<TodoTaskRespVO> getTodoTaskPage(TodoTaskPageReqVO pageReqVO) {
final LoginUser loginUser = SecurityFrameworkUtils.getLoginUser();
// TODO @jason封装一个方法用于转换成 activiti 的分页对象
final Pageable pageable = Pageable.of((pageReqVO.getPageNo() - 1) * pageReqVO.getPageSize(), pageReqVO.getPageSize());
Page<Task> pageTasks = taskRuntime.tasks(pageable);
// TODO @jasonconvert 里转换
List<Task> tasks = pageTasks.getContent();
int totalItems = pageTasks.getTotalItems();
List<Task> tasks = pageTasks.getContent();
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;
ProcessDefinition definition = repositoryService.getProcessDefinition(task.getProcessDefinitionId());
return TaskConvert.INSTANCE.convert(task, definition);
}).collect(Collectors.toList());
// TODO @jason要注意泛型哈。
return new PageResult(respVOList, Long.valueOf(totalItems)); // TODO @jason(long) 转换即可
return new PageResult<>(respVOList, (long)totalItems);
}
@ -88,35 +70,22 @@ public class TaskServiceImpl implements TaskService {
.build());
}
@Override
public void getTaskHistory(String taskId) {
final List<HistoricProcessInstance> list = historyService.createHistoricProcessInstanceQuery().
processInstanceId("8e2801fc-1a38-11ec-98ce-74867a13730f").list();
}
// TODO @jason一个方法里会有多个方法的调用最好写下对应的注释。这样容易理解
/**
* userTask, 1variables). 2. (comment)
* variables
* @param taskReq
*/
@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
@ -142,22 +111,8 @@ public class TaskServiceImpl implements TaskService {
@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 String taskDefKey = task.getTaskDefinitionKey();
// final String variableName = Optional.ofNullable(taskVariable.get(taskDefKey)).orElse("");
// handleVO.setTaskVariable(variableName);
final Task task = taskRuntime.task(taskQuery.getTaskId());
List<TaskStepVO> steps = getTaskSteps(task.getProcessInstanceId());
handleVO.setHistoryTask(steps);
return handleVO;
}
@ -173,21 +128,13 @@ public class TaskServiceImpl implements TaskService {
// 获得对应的步骤
List<TaskStepVO> steps = new ArrayList<>();
finished.forEach(instance -> {
// TODO @jason放到 convert 里
TaskStepVO step = new TaskStepVO();
step.setStepName(instance.getActivityName());
step.setStartTime(instance.getStartTime());
step.setEndTime(instance.getEndTime());
step.setAssignee(instance.getAssignee());
step.setStatus(1);
// TODO @jason一般判数组为空使用 CollUtil.isEmpty 会好点哈。另外null 时候,不用填写 "" 的哈
TaskStepVO stepVO = TaskConvert.INSTANCE.convert(instance);
stepVO.setStatus(1);
List<Comment> comments = activitiTaskService.getTaskComments(instance.getTaskId());
if (comments.size() > 0) {
step.setComment(comments.get(0).getFullMessage());
} else {
step.setComment("");
if (!CollUtil.isEmpty(comments)) {
stepVO.setComment(Optional.ofNullable(comments.get(0)).map(t->t.getFullMessage()).orElse(""));
}
steps.add(step);
steps.add(stepVO);
});
// 获得未完成的活动
@ -197,16 +144,11 @@ public class TaskServiceImpl implements TaskService {
.activityType("userTask")
.unfinished().list();
// 获得对应的步骤
// TODO @json其实已完成和未完成它们的 convert 的逻辑,是一致的
for (HistoricActivityInstance instance : unfinished) {
TaskStepVO step = new TaskStepVO();
step.setStepName(instance.getActivityName());
step.setStartTime(instance.getStartTime());
step.setEndTime(instance.getEndTime());
step.setAssignee(Optional.ofNullable(instance.getAssignee()).orElse(""));
step.setComment("");
step.setStatus(0);
steps.add(step);
TaskStepVO stepVO = TaskConvert.INSTANCE.convert(instance);
stepVO.setComment("");
stepVO.setStatus(0);
steps.add(stepVO);
}
return steps;
}

View File

@ -139,7 +139,7 @@
<el-dialog :title="title" :visible.sync="dialogStepsVisible" width="600px" append-to-body>
<el-steps :active="stepActive" finish-status="success" >
<el-step :title="stepTitle(item)" :description="' 办理人:' + item.assignee " icon="el-icon-edit" v-for="(item) in handleTask.historyTask"></el-step>
<el-step :title="stepTitle(item)" :description="stepAssignee(item.assignee)" icon="el-icon-edit" v-for="(item) in handleTask.historyTask"></el-step>
</el-steps>
<br/>
<el-steps direction="vertical" :active="stepActive">
@ -253,6 +253,17 @@ export default {
}
return desc;
}
},
stepAssignee() {
return function (assignee) {
let desc = "";
if(assignee){
desc += "办理人:[" + assignee + "]";
}else{
desc += "办理人未签收";
}
return desc;
}
}
},
methods: {

View File

@ -100,6 +100,7 @@ public class SecurityFrameworkUtils {
WebFrameworkUtils.setLoginUserId(request, loginUser.getId());
WebFrameworkUtils.setLoginUserType(request, loginUser.getUserType());
// TODO @jason使用 userId 会不会更合适哈?
// TODO @芋道源码 该值被赋值给 user task 中assignee username 显示更直白一点
org.activiti.engine.impl.identity.Authentication.setAuthenticatedUserId(loginUser.getUsername());
}