feat(bpm): 新增工单模块设计和数据库结构

- 添加工单模块前端设计文档,详细描述了页面架构、权限设计和API调用流程
- 新增工单模块数据库表结构,包括工单主表、分配规则表和跟踪记录表
- 创建工单类型、状态和优先级的字典数据
- 添加示例分配规则数据
This commit is contained in:
aikai 2025-06-20 16:00:50 +08:00
parent 1144d4692a
commit 197605f4d2
20 changed files with 1581 additions and 0 deletions

View File

@ -0,0 +1,71 @@
package cn.iocoder.yudao.module.bpm.dal.dataobject.oa;
import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO;
import cn.iocoder.yudao.framework.mybatis.core.type.JsonLongSetTypeHandler;
import com.baomidou.mybatisplus.annotation.KeySequence;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.*;
/**
* BPM OA 工单跟踪记录 DO
*
* @author 系统
*/
@TableName(value = "bpm_oa_work_order_track", autoResultMap = true)
@KeySequence("bpm_oa_work_order_track_seq") // 用于 OraclePostgreSQLKingbaseDB2H2 数据库的主键自增如果是 MySQL 等数据库可不写
@Data
@EqualsAndHashCode(callSuper = true)
@ToString(callSuper = true)
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class BpmOAWorkOrderTrackDO extends BaseDO {
/**
* 跟踪记录ID
*/
@TableId
private Long id;
/**
* 工单ID
*/
private Long workOrderId;
/**
* 操作人ID
*/
private Long operatorId;
/**
* 操作人姓名
*/
private String operatorName;
/**
* 操作类型
*
* 枚举值
* - CREATE: 创建工单
* - ASSIGN: 分配工单
* - PROCESS: 处理中
* - COMPLETE: 完成工单
* - CANCEL: 取消工单
* - COMMENT: 添加备注
*/
private String operationType;
/**
* 操作内容/备注
*/
private String content;
/**
* 附件文件列表JSON格式
*/
@TableField(typeHandler = JsonLongSetTypeHandler.class)
private String attachments;
}

View File

@ -0,0 +1,98 @@
package cn.iocoder.yudao.module.bpm.controller.admin.oa;
import cn.iocoder.yudao.framework.common.pojo.CommonResult;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
import cn.iocoder.yudao.module.bpm.controller.admin.oa.vo.workorder.*;
import cn.iocoder.yudao.module.bpm.dal.dataobject.oa.BpmOAWorkOrderDO;
import cn.iocoder.yudao.module.bpm.service.oa.BpmOAWorkOrderService;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.extern.slf4j.Slf4j;
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.annotation.security.PermitAll;
import javax.validation.Valid;
import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
import static cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils.getLoginUserId;
/**
* 管理后台 - BPM OA 工单
*
* @author 系统
*/
@Tag(name = "管理后台 - BPM OA 工单")
@RestController
@RequestMapping("/admin-api/bpm/oa/work-order")
@Validated
@Slf4j
public class BpmOAWorkOrderController {
@Resource
private BpmOAWorkOrderService workOrderService;
@PostMapping("/create")
@Operation(summary = "创建工单")
@PreAuthorize("@ss.hasPermission('bpm:oa-work-order:create')")
public CommonResult<Long> createWorkOrder(@Valid @RequestBody BpmOAWorkOrderCreateReqVO createReqVO) {
return success(workOrderService.createWorkOrder(getLoginUserId(), createReqVO));
}
@GetMapping("/page")
@Operation(summary = "获得工单分页")
@PreAuthorize("@ss.hasPermission('bpm:oa-work-order:query')")
public CommonResult<PageResult<BpmOAWorkOrderRespVO>> getWorkOrderPage(@Valid BpmOAWorkOrderPageReqVO pageReqVO) {
return success(workOrderService.getWorkOrderPage(getLoginUserId(), pageReqVO));
}
@GetMapping("/my-page")
@Operation(summary = "获得我发起的工单分页")
@PreAuthorize("@ss.hasPermission('bpm:oa-work-order:query')")
public CommonResult<PageResult<BpmOAWorkOrderRespVO>> getMyWorkOrderPage(@Valid BpmOAWorkOrderPageReqVO pageReqVO) {
return success(workOrderService.getMyWorkOrderPage(getLoginUserId(), pageReqVO));
}
@GetMapping("/assigned-page")
@Operation(summary = "获得分配给我的工单分页")
@PreAuthorize("@ss.hasPermission('bpm:oa-work-order:query')")
public CommonResult<PageResult<BpmOAWorkOrderRespVO>> getAssignedWorkOrderPage(@Valid BpmOAWorkOrderPageReqVO pageReqVO) {
return success(workOrderService.getAssignedWorkOrderPage(getLoginUserId(), pageReqVO));
}
@GetMapping("/get/{id}")
@Operation(summary = "获得工单详情")
@Parameter(name = "id", description = "编号", required = true, example = "1024")
@PreAuthorize("@ss.hasPermission('bpm:oa-work-order:query')")
public CommonResult<BpmOAWorkOrderRespVO> getWorkOrder(@PathVariable("id") Long id) {
return success(workOrderService.getWorkOrderDetail(id));
}
@PostMapping("/track")
@Operation(summary = "添加工单跟踪记录")
@PreAuthorize("@ss.hasPermission('bpm:oa-work-order:update')")
public CommonResult<Boolean> addTrackInfo(@Valid @RequestBody BpmOAWorkOrderTrackReqVO trackReqVO) {
workOrderService.addTrackInfo(getLoginUserId(), trackReqVO);
return success(true);
}
@PutMapping("/update")
@Operation(summary = "修改工单")
@PreAuthorize("@ss.hasPermission('bpm:oa-work-order:update')")
public CommonResult<Boolean> updateWorkOrder(@Valid @RequestBody BpmOAWorkOrderUpdateReqVO updateReqVO) {
workOrderService.updateWorkOrder(updateReqVO);
return success(true);
}
@GetMapping("/my-assigned-count")
@Operation(summary = "获得我的待处理工单数量")
@PermitAll
public CommonResult<Long> getMyAssignedWorkOrderCount() {
return success(workOrderService.getMyAssignedWorkOrderCount(getLoginUserId()));
}
}

View File

@ -0,0 +1,44 @@
package cn.iocoder.yudao.module.bpm.controller.admin.oa.vo.workorder;
import cn.iocoder.yudao.framework.common.pojo.UploadUserFile;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.extension.handlers.JacksonTypeHandler;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import org.springframework.format.annotation.DateTimeFormat;
import javax.validation.constraints.NotEmpty;
import javax.validation.constraints.NotNull;
import java.time.LocalDateTime;
import java.util.List;
import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND;
@Schema(description = "管理后台 - BPM OA 工单创建 Request VO")
@Data
public class BpmOAWorkOrderCreateReqVO {
@Schema(description = "工单标题", requiredMode = Schema.RequiredMode.REQUIRED, example = "系统登录问题")
@NotEmpty(message = "工单标题不能为空")
private String title;
@Schema(description = "工单类型", requiredMode = Schema.RequiredMode.REQUIRED, example = "it_support")
@NotEmpty(message = "工单类型不能为空")
private String type;
@Schema(description = "优先级别", requiredMode = Schema.RequiredMode.REQUIRED, example = "2")
@NotNull(message = "优先级别不能为空")
private Integer level;
@Schema(description = "工单内容描述", requiredMode = Schema.RequiredMode.REQUIRED, example = "用户无法登录系统,提示密码错误")
@NotEmpty(message = "工单内容不能为空")
private String content;
@Schema(description = "期望完成时间", example = "2024-12-20 18:00:00")
@DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
private LocalDateTime expectedTime;
@TableField(typeHandler = JacksonTypeHandler.class)
private List<UploadUserFile> fileItems;
}

View File

@ -0,0 +1,39 @@
package cn.iocoder.yudao.module.bpm.controller.admin.oa.vo.workorder;
import cn.iocoder.yudao.framework.common.pojo.PageParam;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.ToString;
import org.springframework.format.annotation.DateTimeFormat;
import java.time.LocalDateTime;
import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND;
@Schema(description = "管理后台 - BPM OA 工单分页查询 Request VO")
@Data
@EqualsAndHashCode(callSuper = true)
@ToString(callSuper = true)
public class BpmOAWorkOrderPageReqVO extends PageParam {
@Schema(description = "工单标题", example = "系统登录问题")
private String title;
@Schema(description = "工单类型", example = "it_support")
private String type;
@Schema(description = "工单状态", example = "1")
private Integer status;
@Schema(description = "责任人ID", example = "1")
private Long assigneeUserId;
@Schema(description = "发起人ID", example = "1")
private Long fromUserId;
@Schema(description = "创建时间")
@DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
private LocalDateTime[] createTime;
}

View File

@ -0,0 +1,91 @@
package cn.iocoder.yudao.module.bpm.controller.admin.oa.vo.workorder;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import java.time.LocalDateTime;
import java.util.List;
@Schema(description = "管理后台 - BPM OA 工单 Response VO")
@Data
public class BpmOAWorkOrderRespVO {
@Schema(description = "工单ID", example = "1")
private Long id;
@Schema(description = "工单标题", example = "系统登录问题")
private String title;
@Schema(description = "工单类型", example = "it_support")
private String type;
@Schema(description = "工单类型名称", example = "IT支持")
private String typeName;
@Schema(description = "优先级别", example = "2")
private Integer level;
@Schema(description = "优先级名称", example = "")
private String levelName;
@Schema(description = "工单内容描述", example = "用户无法登录系统,提示密码错误")
private String content;
@Schema(description = "发起人ID", example = "1")
private Long fromUserId;
@Schema(description = "发起人姓名", example = "张三")
private String fromUserName;
@Schema(description = "发起部门ID", example = "100")
private Long fromDeptId;
@Schema(description = "发起部门名称", example = "技术部")
private String fromDeptName;
@Schema(description = "责任人ID", example = "2")
private Long assigneeUserId;
@Schema(description = "责任人姓名", example = "李四")
private String assigneeUserName;
@Schema(description = "责任部门ID", example = "101")
private Long assigneeDeptId;
@Schema(description = "责任部门名称", example = "运维部")
private String assigneeDeptName;
@Schema(description = "工单状态", example = "2")
private Integer status;
@Schema(description = "工单状态名称", example = "处理中")
private String statusName;
@Schema(description = "期望完成时间", example = "2024-12-20 18:00:00")
private LocalDateTime expectedTime;
@Schema(description = "实际完成时间", example = "2024-12-20 16:30:00")
private LocalDateTime completedTime;
@Schema(description = "工单处理结果说明", example = "已成功修复系统登录问题")
private String resultDescription;
@Schema(description = "BPM流程结果", example = "2")
private Integer result;
@Schema(description = "BPM流程实例ID", example = "proc_inst_123456")
private String processInstanceId;
@Schema(description = "附件文件列表")
private List<String> fileItems;
@Schema(description = "工单跟踪记录")
private List<BpmOAWorkOrderTrackInfo> trackInfo;
@Schema(description = "创建时间", example = "2024-12-19 10:00:00")
private LocalDateTime createTime;
@Schema(description = "更新时间", example = "2024-12-19 15:30:00")
private LocalDateTime updateTime;
}

View File

@ -0,0 +1,33 @@
package cn.iocoder.yudao.module.bpm.controller.admin.oa.vo.workorder;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
/**
* BPM OA 工单跟踪信息
*
* @author 系统
*/
@Schema(description = "BPM OA 工单跟踪信息")
@Data
public class BpmOAWorkOrderTrackInfo {
@Schema(description = "跟踪ID")
private String trackId;
@Schema(description = "操作人ID")
private Long operatorId;
@Schema(description = "操作人姓名")
private String operatorName;
@Schema(description = "操作内容")
private String content;
@Schema(description = "操作时间")
private String trackTime;
@Schema(description = "操作类型")
private String operationType;
}

View File

@ -0,0 +1,25 @@
package cn.iocoder.yudao.module.bpm.controller.admin.oa.vo.workorder;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import javax.validation.constraints.NotEmpty;
import javax.validation.constraints.NotNull;
@Schema(description = "管理后台 - BPM OA 工单跟踪记录 Request VO")
@Data
public class BpmOAWorkOrderTrackReqVO {
@Schema(description = "工单ID", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
@NotNull(message = "工单ID不能为空")
private Long workOrderId;
@Schema(description = "操作类型", requiredMode = Schema.RequiredMode.REQUIRED, example = "PROCESS")
@NotEmpty(message = "操作类型不能为空")
private String operationType;
@Schema(description = "操作内容", requiredMode = Schema.RequiredMode.REQUIRED, example = "已开始处理该工单,预计今天下午完成")
@NotEmpty(message = "操作内容不能为空")
private String content;
}

View File

@ -0,0 +1,34 @@
package cn.iocoder.yudao.module.bpm.controller.admin.oa.vo.workorder;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import org.springframework.format.annotation.DateTimeFormat;
import javax.validation.constraints.NotNull;
import java.time.LocalDateTime;
import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND;
@Schema(description = "管理后台 - BPM OA 工单修改 Request VO")
@Data
public class BpmOAWorkOrderUpdateReqVO {
@Schema(description = "工单ID", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
@NotNull(message = "工单ID不能为空")
private Long id;
@Schema(description = "工单状态", example = "3")
private Integer status;
@Schema(description = "期望完成时间", example = "2024-12-20 18:00:00")
@DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
private LocalDateTime expectedTime;
@Schema(description = "实际完成时间", example = "2024-12-20 16:30:00")
@DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
private LocalDateTime completedTime;
@Schema(description = "工单处理结果说明", example = "已成功修复系统登录问题,用户可以正常登录")
private String resultDescription;
}

View File

@ -0,0 +1,61 @@
package cn.iocoder.yudao.module.bpm.dal.dataobject.oa;
import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.*;
/**
* BPM OA 工单分配规则 DO
*
* @author 系统
*/
@TableName("bpm_oa_work_order_assign_rule")
@Data
@EqualsAndHashCode(callSuper = true)
@ToString(callSuper = true)
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class BpmOAWorkOrderAssignRuleDO extends BaseDO {
/**
* 规则ID主键
*/
@TableId
private Long id;
/**
* 工单类型
* 字典值work_order_type
*/
private String workOrderType;
/**
* 责任部门ID
*/
private Long deptId;
/**
* 责任人ID
*/
private Long assigneeUserId;
/**
* 规则优先级
* 数值越小优先级越高
*/
private Integer priority;
/**
* 规则状态
* 1-启用0-禁用
*/
private Integer status;
/**
* 规则描述
*/
private String description;
}

View File

@ -0,0 +1,125 @@
package cn.iocoder.yudao.module.bpm.dal.dataobject.oa;
import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO;
import cn.iocoder.yudao.module.bpm.controller.admin.oa.vo.workorder.BpmOAWorkOrderTrackInfo;
import cn.iocoder.yudao.framework.common.pojo.UploadUserFile;
import cn.iocoder.yudao.module.bpm.enums.task.BpmProcessInstanceResultEnum;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import com.baomidou.mybatisplus.extension.handlers.JacksonTypeHandler;
import lombok.*;
import java.time.LocalDateTime;
import java.util.List;
/**
* BPM OA 工单 DO
*
* @author 系统
*/
@TableName(value = "bpm_oa_work_order", autoResultMap = true)
@Data
@EqualsAndHashCode(callSuper = true)
@ToString(callSuper = true)
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class BpmOAWorkOrderDO extends BaseDO {
/**
* 工单ID主键
*/
@TableId
private Long id;
/**
* 工单标题
*/
private String title;
/**
* 工单类型
* 字典值work_order_type
*/
private String type;
/**
* 优先级别
* 1-2-3-4-紧急
*/
private Integer level;
/**
* 工单内容描述
*/
private String content;
/**
* 发起人ID
*/
private Long fromUserId;
/**
* 发起人部门ID
*/
private Long fromDeptId;
/**
* 责任人ID分配给谁处理
*/
private Long assigneeUserId;
/**
* 责任部门ID
*/
private Long assigneeDeptId;
/**
* 工单状态
* 1-待分配2-处理中3-已完成4-已取消5-已关闭
*/
private Integer status;
/**
* 期望完成时间
*/
private LocalDateTime expectedTime;
/**
* 实际完成时间
*/
private LocalDateTime completedTime;
/**
* 工单处理结果说明
*/
private String resultDescription;
/**
* BPM流程结果
*
* 枚举 {@link BpmProcessInstanceResultEnum}
*/
private Integer result;
/**
* 对应的BPM流程实例ID
*
* 关联 ProcessInstance id 属性
*/
private String processInstanceId;
/**
* 附件信息
*/
@TableField(typeHandler = JacksonTypeHandler.class)
private List<UploadUserFile> fileItems;
/**
* 工单跟踪记录信息
*/
@TableField(typeHandler = JacksonTypeHandler.class)
private List<BpmOAWorkOrderTrackInfo> trackInfo;
}

View File

@ -0,0 +1,71 @@
package cn.iocoder.yudao.module.bpm.dal.dataobject.oa;
import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO;
import cn.iocoder.yudao.framework.mybatis.core.type.JsonLongSetTypeHandler;
import com.baomidou.mybatisplus.annotation.KeySequence;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.*;
/**
* BPM OA 工单跟踪记录 DO
*
* @author 系统
*/
@TableName(value = "bpm_oa_work_order_track", autoResultMap = true)
@KeySequence("bpm_oa_work_order_track_seq") // 用于 OraclePostgreSQLKingbaseDB2H2 数据库的主键自增如果是 MySQL 等数据库可不写
@Data
@EqualsAndHashCode(callSuper = true)
@ToString(callSuper = true)
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class BpmOAWorkOrderTrackDO extends BaseDO {
/**
* 跟踪记录ID
*/
@TableId
private Long id;
/**
* 工单ID
*/
private Long workOrderId;
/**
* 操作人ID
*/
private Long operatorId;
/**
* 操作人姓名
*/
private String operatorName;
/**
* 操作类型
*
* 枚举值
* - CREATE: 创建工单
* - ASSIGN: 分配工单
* - PROCESS: 处理中
* - COMPLETE: 完成工单
* - CANCEL: 取消工单
* - COMMENT: 添加备注
*/
private String operationType;
/**
* 操作内容/备注
*/
private String content;
/**
* 附件文件列表JSON格式
*/
@TableField(typeHandler = JsonLongSetTypeHandler.class)
private String attachments;
}

View File

@ -0,0 +1,49 @@
package cn.iocoder.yudao.module.bpm.dal.mysql.oa;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX;
import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX;
import cn.iocoder.yudao.module.bpm.dal.dataobject.oa.BpmOAWorkOrderAssignRuleDO;
import org.apache.ibatis.annotations.Mapper;
import java.util.List;
/**
* BPM OA 工单分配规则 Mapper
*
* @author 系统
*/
@Mapper
public interface BpmOAWorkOrderAssignRuleMapper extends BaseMapperX<BpmOAWorkOrderAssignRuleDO> {
/**
* 根据工单类型查询启用的分配规则
*/
default List<BpmOAWorkOrderAssignRuleDO> selectRulesByType(String workOrderType) {
return selectList(new LambdaQueryWrapperX<BpmOAWorkOrderAssignRuleDO>()
.eq(BpmOAWorkOrderAssignRuleDO::getWorkOrderType, workOrderType)
.eq(BpmOAWorkOrderAssignRuleDO::getStatus, 1)
.orderByAsc(BpmOAWorkOrderAssignRuleDO::getPriority));
}
/**
* 根据部门ID查询分配规则
*/
default List<BpmOAWorkOrderAssignRuleDO> selectRulesByDept(Long deptId) {
return selectList(new LambdaQueryWrapperX<BpmOAWorkOrderAssignRuleDO>()
.eq(BpmOAWorkOrderAssignRuleDO::getDeptId, deptId)
.eq(BpmOAWorkOrderAssignRuleDO::getStatus, 1)
.orderByAsc(BpmOAWorkOrderAssignRuleDO::getPriority));
}
/**
* 根据责任人ID查询分配规则
*/
default List<BpmOAWorkOrderAssignRuleDO> selectRulesByAssignee(Long assigneeUserId) {
return selectList(new LambdaQueryWrapperX<BpmOAWorkOrderAssignRuleDO>()
.eq(BpmOAWorkOrderAssignRuleDO::getAssigneeUserId, assigneeUserId)
.eq(BpmOAWorkOrderAssignRuleDO::getStatus, 1)
.orderByAsc(BpmOAWorkOrderAssignRuleDO::getPriority));
}
}

View File

@ -0,0 +1,67 @@
package cn.iocoder.yudao.module.bpm.dal.mysql.oa;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX;
import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX;
import cn.iocoder.yudao.module.bpm.controller.admin.oa.vo.workorder.BpmOAWorkOrderPageReqVO;
import cn.iocoder.yudao.module.bpm.dal.dataobject.oa.BpmOAWorkOrderDO;
import org.apache.ibatis.annotations.Mapper;
/**
* BPM OA 工单 Mapper
*
* @author 系统
*/
@Mapper
public interface BpmOAWorkOrderMapper extends BaseMapperX<BpmOAWorkOrderDO> {
/**
* 工单分页查询
*/
default PageResult<BpmOAWorkOrderDO> selectPage(Long loginUserId, BpmOAWorkOrderPageReqVO pageVO) {
return selectPage(pageVO, new LambdaQueryWrapperX<BpmOAWorkOrderDO>()
.likeIfPresent(BpmOAWorkOrderDO::getTitle, pageVO.getTitle())
.eqIfPresent(BpmOAWorkOrderDO::getType, pageVO.getType())
.eqIfPresent(BpmOAWorkOrderDO::getStatus, pageVO.getStatus())
.eqIfPresent(BpmOAWorkOrderDO::getAssigneeUserId, pageVO.getAssigneeUserId())
.eqIfPresent(BpmOAWorkOrderDO::getFromUserId, pageVO.getFromUserId())
.betweenIfPresent(BpmOAWorkOrderDO::getCreateTime, pageVO.getCreateTime())
.orderByDesc(BpmOAWorkOrderDO::getId));
}
/**
* 查询我的工单分页我发起的
*/
default PageResult<BpmOAWorkOrderDO> selectMyPage(Long loginUserId, BpmOAWorkOrderPageReqVO pageVO) {
return selectPage(pageVO, new LambdaQueryWrapperX<BpmOAWorkOrderDO>()
.eq(BpmOAWorkOrderDO::getFromUserId, loginUserId)
.likeIfPresent(BpmOAWorkOrderDO::getTitle, pageVO.getTitle())
.eqIfPresent(BpmOAWorkOrderDO::getType, pageVO.getType())
.eqIfPresent(BpmOAWorkOrderDO::getStatus, pageVO.getStatus())
.betweenIfPresent(BpmOAWorkOrderDO::getCreateTime, pageVO.getCreateTime())
.orderByDesc(BpmOAWorkOrderDO::getId));
}
/**
* 查询我负责的工单分页分配给我的
*/
default PageResult<BpmOAWorkOrderDO> selectAssignedPage(Long loginUserId, BpmOAWorkOrderPageReqVO pageVO) {
return selectPage(pageVO, new LambdaQueryWrapperX<BpmOAWorkOrderDO>()
.eq(BpmOAWorkOrderDO::getAssigneeUserId, loginUserId)
.likeIfPresent(BpmOAWorkOrderDO::getTitle, pageVO.getTitle())
.eqIfPresent(BpmOAWorkOrderDO::getType, pageVO.getType())
.eqIfPresent(BpmOAWorkOrderDO::getStatus, pageVO.getStatus())
.betweenIfPresent(BpmOAWorkOrderDO::getCreateTime, pageVO.getCreateTime())
.orderByDesc(BpmOAWorkOrderDO::getId));
}
/**
* 查询我负责工单的数量
*/
default Long selectMyAssignedCount(Long userId) {
return selectCount(new LambdaQueryWrapperX<BpmOAWorkOrderDO>()
.eq(BpmOAWorkOrderDO::getAssigneeUserId, userId)
.in(BpmOAWorkOrderDO::getStatus, 1, 2)); // 待分配和处理中
}
}

View File

@ -0,0 +1,27 @@
package cn.iocoder.yudao.module.bpm.dal.mysql.oa;
import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX;
import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX;
import cn.iocoder.yudao.module.bpm.dal.dataobject.oa.BpmOAWorkOrderTrackDO;
import org.apache.ibatis.annotations.Mapper;
import java.util.List;
/**
* BPM OA 工单跟踪记录 Mapper
*
* @author 系统
*/
@Mapper
public interface BpmOAWorkOrderTrackMapper extends BaseMapperX<BpmOAWorkOrderTrackDO> {
/**
* 根据工单ID查询跟踪记录列表
*/
default List<BpmOAWorkOrderTrackDO> selectByWorkOrderId(Long workOrderId) {
return selectList(new LambdaQueryWrapperX<BpmOAWorkOrderTrackDO>()
.eq(BpmOAWorkOrderTrackDO::getWorkOrderId, workOrderId)
.orderByAsc(BpmOAWorkOrderTrackDO::getCreateTime));
}
}

View File

@ -0,0 +1,56 @@
package cn.iocoder.yudao.module.bpm.enums.oa;
import lombok.AllArgsConstructor;
import lombok.Getter;
/**
* 工单优先级枚举
*
* @author 系统
*/
@Getter
@AllArgsConstructor
public enum WorkOrderLevelEnum {
LOW(1, ""),
MEDIUM(2, ""),
HIGH(3, ""),
URGENT(4, "紧急");
/**
* 级别值
*/
private final Integer level;
/**
* 级别名称
*/
private final String name;
/**
* 根据级别值获取枚举
*/
public static WorkOrderLevelEnum getByLevel(Integer level) {
for (WorkOrderLevelEnum levelEnum : values()) {
if (levelEnum.getLevel().equals(level)) {
return levelEnum;
}
}
return null;
}
/**
* 判断是否为紧急级别
*/
public static boolean isUrgent(Integer level) {
return URGENT.getLevel().equals(level);
}
/**
* 判断是否为高优先级高或紧急
*/
public static boolean isHighPriority(Integer level) {
return HIGH.getLevel().equals(level) || URGENT.getLevel().equals(level);
}
}

View File

@ -0,0 +1,64 @@
package cn.iocoder.yudao.module.bpm.enums.oa;
import lombok.AllArgsConstructor;
import lombok.Getter;
/**
* 工单状态枚举
*
* @author 系统
*/
@Getter
@AllArgsConstructor
public enum WorkOrderStatusEnum {
PENDING_ASSIGN(1, "待分配"),
PROCESSING(2, "处理中"),
COMPLETED(3, "已完成"),
CANCELLED(4, "已取消"),
CLOSED(5, "已关闭");
/**
* 状态值
*/
private final Integer status;
/**
* 状态名称
*/
private final String name;
/**
* 根据状态值获取枚举
*/
public static WorkOrderStatusEnum valueOf(Integer status) {
for (WorkOrderStatusEnum statusEnum : values()) {
if (statusEnum.getStatus().equals(status)) {
return statusEnum;
}
}
return null;
}
/**
* 判断是否为处理中状态
*/
public static boolean isProcessing(Integer status) {
return PROCESSING.getStatus().equals(status);
}
/**
* 判断是否为已完成状态
*/
public static boolean isCompleted(Integer status) {
return COMPLETED.getStatus().equals(status);
}
/**
* 判断是否为待分配状态
*/
public static boolean isPendingAssign(Integer status) {
return PENDING_ASSIGN.getStatus().equals(status);
}
}

View File

@ -0,0 +1,47 @@
package cn.iocoder.yudao.module.bpm.enums.oa;
import lombok.AllArgsConstructor;
import lombok.Getter;
/**
* 工单跟踪记录操作类型枚举
*
* @author 系统
*/
@AllArgsConstructor
@Getter
public enum WorkOrderTrackTypeEnum {
CREATE("CREATE", "创建工单"),
ASSIGN("ASSIGN", "分配工单"),
PROCESS("PROCESS", "处理中"),
COMPLETE("COMPLETE", "完成工单"),
CANCEL("CANCEL", "取消工单"),
COMMENT("COMMENT", "添加备注"),
TRANSFER("TRANSFER", "转派工单"),
REOPEN("REOPEN", "重新打开"),
CLOSE("CLOSE", "关闭工单");
/**
* 操作类型
*/
private final String type;
/**
* 操作描述
*/
private final String description;
/**
* 根据类型获取枚举
*/
public static WorkOrderTrackTypeEnum getByType(String type) {
for (WorkOrderTrackTypeEnum trackType : values()) {
if (trackType.getType().equals(type)) {
return trackType;
}
}
return null;
}
}

View File

@ -0,0 +1,43 @@
package cn.iocoder.yudao.module.bpm.enums.oa;
import lombok.AllArgsConstructor;
import lombok.Getter;
/**
* 工单类型枚举
*
* @author 系统
*/
@Getter
@AllArgsConstructor
public enum WorkOrderTypeEnum {
IT_SUPPORT("it_support", "IT支持"),
EQUIPMENT_REPAIR("equipment_repair", "设备维修"),
SYSTEM_ISSUE("system_issue", "系统问题"),
PERMISSION_REQUEST("permission_request", "权限申请"),
OTHER("other", "其他");
/**
* 类型值
*/
private final String type;
/**
* 类型名称
*/
private final String name;
/**
* 根据类型值获取枚举
*/
public static WorkOrderTypeEnum getByType(String type) {
for (WorkOrderTypeEnum typeEnum : values()) {
if (typeEnum.getType().equals(type)) {
return typeEnum;
}
}
return null;
}
}

View File

@ -0,0 +1,116 @@
package cn.iocoder.yudao.module.bpm.service.oa;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.module.bpm.controller.admin.oa.vo.workorder.*;
import cn.iocoder.yudao.module.bpm.dal.dataobject.oa.BpmOAWorkOrderDO;
import javax.validation.Valid;
/**
* BPM OA 工单 Service 接口
*
* @author 系统
*/
public interface BpmOAWorkOrderService {
/**
* 创建工单
*
* @param userId 发起人ID
* @param createReqVO 创建请求
* @return 工单ID
*/
Long createWorkOrder(Long userId, @Valid BpmOAWorkOrderCreateReqVO createReqVO);
/**
* 更新工单状态结果
*
* @param id 工单ID
* @param result BPM流程结果
*/
void updateWorkOrderResult(Long id, Integer result);
/**
* 分配工单
*
* @param id 工单ID
* @param assigneeUserId 责任人ID
* @param assigneeDeptId 责任部门ID
*/
void assignWorkOrder(Long id, Long assigneeUserId, Long assigneeDeptId);
/**
* 添加工单跟踪信息
*
* @param userId 操作人ID
* @param trackReqVO 跟踪信息
*/
void addTrackInfo(Long userId, @Valid BpmOAWorkOrderTrackReqVO trackReqVO);
/**
* 更新工单
*
* @param updateReqVO 更新请求
*/
void updateWorkOrder(@Valid BpmOAWorkOrderUpdateReqVO updateReqVO);
/**
* 获取工单详情
*
* @param id 工单ID
* @return 工单DO
*/
BpmOAWorkOrderDO getWorkOrder(Long id);
/**
* 获取工单详情带扩展信息
*
* @param id 工单ID
* @return 工单详情VO
*/
BpmOAWorkOrderRespVO getWorkOrderDetail(Long id);
/**
* 根据流程实例ID获取工单
*
* @param processInstanceId 流程实例ID
* @return 工单DO
*/
BpmOAWorkOrderDO getWorkOrderByProcessInstanceId(String processInstanceId);
/**
* 获取工单分页
*
* @param loginUserId 登录用户ID
* @param pageVO 分页请求
* @return 分页结果
*/
PageResult<BpmOAWorkOrderRespVO> getWorkOrderPage(Long loginUserId, BpmOAWorkOrderPageReqVO pageVO);
/**
* 获取我发起的工单分页
*
* @param loginUserId 登录用户ID
* @param pageVO 分页请求
* @return 分页结果
*/
PageResult<BpmOAWorkOrderRespVO> getMyWorkOrderPage(Long loginUserId, BpmOAWorkOrderPageReqVO pageVO);
/**
* 获取分配给我的工单分页
*
* @param loginUserId 登录用户ID
* @param pageVO 分页请求
* @return 分页结果
*/
PageResult<BpmOAWorkOrderRespVO> getAssignedWorkOrderPage(Long loginUserId, BpmOAWorkOrderPageReqVO pageVO);
/**
* 获取我负责工单的数量
*
* @param userId 用户ID
* @return 工单数量
*/
Long getMyAssignedWorkOrderCount(Long userId);
}

View File

@ -0,0 +1,420 @@
package cn.iocoder.yudao.module.bpm.service.oa;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.common.pojo.UploadUserFile;
import cn.iocoder.yudao.module.bpm.api.task.BpmProcessInstanceApi;
import cn.iocoder.yudao.module.bpm.api.task.dto.BpmProcessInstanceCreateReqDTO;
import cn.iocoder.yudao.module.bpm.controller.admin.oa.vo.workorder.*;
import cn.iocoder.yudao.module.bpm.dal.dataobject.oa.BpmOAWorkOrderAssignRuleDO;
import cn.iocoder.yudao.module.bpm.dal.dataobject.oa.BpmOAWorkOrderDO;
import cn.iocoder.yudao.module.bpm.dal.dataobject.oa.BpmOAWorkOrderTrackDO;
import cn.iocoder.yudao.module.bpm.dal.mysql.oa.BpmOAWorkOrderAssignRuleMapper;
import cn.iocoder.yudao.module.bpm.dal.mysql.oa.BpmOAWorkOrderMapper;
import cn.iocoder.yudao.module.bpm.dal.mysql.oa.BpmOAWorkOrderTrackMapper;
import cn.iocoder.yudao.module.bpm.enums.task.BpmProcessInstanceResultEnum;
import cn.iocoder.yudao.module.system.api.dept.DeptApi;
import cn.iocoder.yudao.module.system.api.dept.dto.DeptRespDTO;
import cn.iocoder.yudao.module.system.api.user.AdminUserApi;
import cn.iocoder.yudao.module.system.api.user.dto.AdminUserRespDTO;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.validation.annotation.Validated;
import javax.annotation.Resource;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertMap;
import static cn.iocoder.yudao.module.bpm.enums.ErrorCodeConstants.OA_WORK_TASK_NOT_EXISTS;
/**
* BPM OA 工单 Service 实现类
*
* @author 系统
*/
@Service
@Validated
public class BpmOAWorkOrderServiceImpl extends BpmOABaseService implements BpmOAWorkOrderService {
/**
* 工单对应的流程定义 KEY
*/
public static final String PROCESS_KEY = "work_order";
@Resource
private BpmOAWorkOrderMapper workOrderMapper;
@Resource
private BpmOAWorkOrderAssignRuleMapper assignRuleMapper;
@Resource
private BpmOAWorkOrderTrackMapper trackMapper;
@Resource
private BpmProcessInstanceApi processInstanceApi;
@Resource
private AdminUserApi userApi;
@Resource
private DeptApi deptApi;
@Override
@Transactional(rollbackFor = Exception.class)
public Long createWorkOrder(Long userId, BpmOAWorkOrderCreateReqVO createReqVO) {
// 获取当前登录用户信息
AdminUserRespDTO userRespDTO = userApi.getUser(userId).getCheckedData();
// 创建工单DO
BpmOAWorkOrderDO workOrder = BpmOAWorkOrderDO.builder()
.title(createReqVO.getTitle())
.type(createReqVO.getType())
.level(createReqVO.getLevel())
.content(createReqVO.getContent())
.expectedTime(createReqVO.getExpectedTime())
.fromUserId(userId)
.fromDeptId(userRespDTO.getDeptId())
.status(1) // 默认状态待分配
.result(BpmProcessInstanceResultEnum.PROCESS.getResult())
.build();
workOrderMapper.insert(workOrder);
// 自动分配责任人根据规则
autoAssignWorkOrder(workOrder);
// 发起 BPM 流程
Map<String, Object> processInstanceVariables = new HashMap<>();
String processInstanceId = processInstanceApi.createProcessInstance(userId,
new BpmProcessInstanceCreateReqDTO().setProcessDefinitionKey(PROCESS_KEY)
.setVariables(processInstanceVariables).setBusinessKey(String.valueOf(workOrder.getId()))).getCheckedData();
// 更新工单的流程实例ID
workOrderMapper.updateById(new BpmOAWorkOrderDO().setId(workOrder.getId()).setProcessInstanceId(processInstanceId));
// 创建初始跟踪记录
createTrackRecord(workOrder.getId(), userId, userRespDTO.getNickname(), "CREATE", "创建工单", null);
List<UploadUserFile> fileItems = createReqVO.getFileItems();
//这里的逻辑如果fileItems不为空且有数据那么说明是上传了附件的则需要更工作流文件表对应的实例Id
if (fileItems != null && !fileItems.isEmpty()) {
uploadBpmFileProcessInstanceId(processInstanceId, fileItems);
}
return workOrder.getId();
}
@Override
public void updateWorkOrderResult(Long id, Integer result) {
validateWorkOrderExists(id);
// BPM流程完成时将工单状态设置为已完成
int status = result.equals(BpmProcessInstanceResultEnum.APPROVE.getResult()) ? 3 : 4; // 3-已完成4-已取消
LocalDateTime completedTime = result.equals(BpmProcessInstanceResultEnum.APPROVE.getResult()) ? LocalDateTime.now() : null;
workOrderMapper.updateById(new BpmOAWorkOrderDO()
.setId(id)
.setResult(result)
.setStatus(status)
.setCompletedTime(completedTime));
}
@Override
public void assignWorkOrder(Long id, Long assigneeUserId, Long assigneeDeptId) {
validateWorkOrderExists(id);
workOrderMapper.updateById(new BpmOAWorkOrderDO()
.setId(id)
.setAssigneeUserId(assigneeUserId)
.setAssigneeDeptId(assigneeDeptId)
.setStatus(2)); // 2-处理中
// 创建分配跟踪记录
AdminUserRespDTO assigneeUser = userApi.getUser(assigneeUserId).getCheckedData();
createTrackRecord(id, assigneeUserId, assigneeUser.getNickname(), "ASSIGN", "工单已分配给:" + assigneeUser.getNickname(), null);
}
@Override
public void addTrackInfo(Long userId, BpmOAWorkOrderTrackReqVO trackReqVO) {
AdminUserRespDTO userRespDTO = userApi.getUser(userId).getCheckedData();
createTrackRecord(trackReqVO.getWorkOrderId(), userId, userRespDTO.getNickname(),
trackReqVO.getOperationType(), trackReqVO.getContent(), null);
}
@Override
public void updateWorkOrder(BpmOAWorkOrderUpdateReqVO updateReqVO) {
validateWorkOrderExists(updateReqVO.getId());
BpmOAWorkOrderDO updateData = BpmOAWorkOrderDO.builder()
.id(updateReqVO.getId())
.status(updateReqVO.getStatus())
.expectedTime(updateReqVO.getExpectedTime())
.completedTime(updateReqVO.getCompletedTime())
.resultDescription(updateReqVO.getResultDescription())
.build();
workOrderMapper.updateById(updateData);
}
@Override
public BpmOAWorkOrderDO getWorkOrder(Long id) {
return workOrderMapper.selectById(id);
}
@Override
public BpmOAWorkOrderRespVO getWorkOrderDetail(Long id) {
BpmOAWorkOrderDO workOrder = validateWorkOrderExists(id);
// 转换为VO
BpmOAWorkOrderRespVO respVO = convertToRespVO(workOrder);
// 获取跟踪记录
List<BpmOAWorkOrderTrackDO> trackList = trackMapper.selectByWorkOrderId(id);
List<BpmOAWorkOrderTrackInfo> trackInfoList = trackList.stream()
.map(this::convertToTrackInfo)
.collect(Collectors.toList());
respVO.setTrackInfo(trackInfoList);
return respVO;
}
@Override
public BpmOAWorkOrderDO getWorkOrderByProcessInstanceId(String processInstanceId) {
return workOrderMapper.selectOne(BpmOAWorkOrderDO::getProcessInstanceId, processInstanceId);
}
@Override
public PageResult<BpmOAWorkOrderRespVO> getWorkOrderPage(Long loginUserId, BpmOAWorkOrderPageReqVO pageVO) {
PageResult<BpmOAWorkOrderDO> pageResult = workOrderMapper.selectPage(loginUserId, pageVO);
return convertToPageResult(pageResult);
}
@Override
public PageResult<BpmOAWorkOrderRespVO> getMyWorkOrderPage(Long loginUserId, BpmOAWorkOrderPageReqVO pageVO) {
PageResult<BpmOAWorkOrderDO> pageResult = workOrderMapper.selectMyPage(loginUserId, pageVO);
return convertToPageResult(pageResult);
}
@Override
public PageResult<BpmOAWorkOrderRespVO> getAssignedWorkOrderPage(Long loginUserId, BpmOAWorkOrderPageReqVO pageVO) {
PageResult<BpmOAWorkOrderDO> pageResult = workOrderMapper.selectAssignedPage(loginUserId, pageVO);
return convertToPageResult(pageResult);
}
@Override
public Long getMyAssignedWorkOrderCount(Long userId) {
return workOrderMapper.selectMyAssignedCount(userId);
}
/**
* 创建跟踪记录
*/
private void createTrackRecord(Long workOrderId, Long operatorId, String operatorName, String operationType, String content, String attachments) {
BpmOAWorkOrderTrackDO track = BpmOAWorkOrderTrackDO.builder()
.workOrderId(workOrderId)
.operatorId(operatorId)
.operatorName(operatorName)
.operationType(operationType)
.content(content)
.attachments(attachments)
.build();
trackMapper.insert(track);
}
/**
* 自动分配工单责任人
*/
private void autoAssignWorkOrder(BpmOAWorkOrderDO workOrder) {
// 根据工单类型查询分配规则
List<BpmOAWorkOrderAssignRuleDO> rules = assignRuleMapper.selectRulesByType(workOrder.getType());
if (!rules.isEmpty()) {
// 选择第一个匹配的规则按优先级排序
BpmOAWorkOrderAssignRuleDO rule = rules.get(0);
workOrder.setAssigneeUserId(rule.getAssigneeUserId());
workOrder.setAssigneeDeptId(rule.getDeptId());
workOrder.setStatus(2); // 2-处理中
}
// 如果没有匹配的规则保持待分配状态
}
/**
* 校验工单是否存在
*/
private BpmOAWorkOrderDO validateWorkOrderExists(Long id) {
BpmOAWorkOrderDO workOrder = workOrderMapper.selectById(id);
if (workOrder == null) {
throw exception(OA_WORK_TASK_NOT_EXISTS); // 暂时复用现有错误码
}
return workOrder;
}
/**
* 上传BPM文件流程实例ID
* 重写父类方法使用父类的实现
*/
@Override
public void uploadBpmFileProcessInstanceId(String processInstanceId, List<UploadUserFile> fileItems) {
super.uploadBpmFileProcessInstanceId(processInstanceId, fileItems);
}
/**
* 转换DO为RespVO
*/
private BpmOAWorkOrderRespVO convertToRespVO(BpmOAWorkOrderDO workOrder) {
if (workOrder == null) {
return null;
}
BpmOAWorkOrderRespVO respVO = new BpmOAWorkOrderRespVO();
respVO.setId(workOrder.getId());
respVO.setTitle(workOrder.getTitle());
respVO.setType(workOrder.getType());
respVO.setLevel(workOrder.getLevel());
respVO.setContent(workOrder.getContent());
respVO.setFromUserId(workOrder.getFromUserId());
respVO.setFromDeptId(workOrder.getFromDeptId());
respVO.setAssigneeUserId(workOrder.getAssigneeUserId());
respVO.setAssigneeDeptId(workOrder.getAssigneeDeptId());
respVO.setStatus(workOrder.getStatus());
respVO.setExpectedTime(workOrder.getExpectedTime());
respVO.setCompletedTime(workOrder.getCompletedTime());
respVO.setResultDescription(workOrder.getResultDescription());
respVO.setResult(workOrder.getResult());
respVO.setProcessInstanceId(workOrder.getProcessInstanceId());
respVO.setCreateTime(workOrder.getCreateTime());
respVO.setUpdateTime(workOrder.getUpdateTime());
// 设置类型名称
respVO.setTypeName(getWorkOrderTypeName(workOrder.getType()));
// 设置优先级名称
respVO.setLevelName(getWorkOrderLevelName(workOrder.getLevel()));
// 设置状态名称
respVO.setStatusName(getWorkOrderStatusName(workOrder.getStatus()));
// 获取用户和部门名称
if (workOrder.getFromUserId() != null) {
AdminUserRespDTO fromUser = userApi.getUser(workOrder.getFromUserId()).getCheckedData();
respVO.setFromUserName(fromUser.getNickname());
}
if (workOrder.getAssigneeUserId() != null) {
AdminUserRespDTO assigneeUser = userApi.getUser(workOrder.getAssigneeUserId()).getCheckedData();
respVO.setAssigneeUserName(assigneeUser.getNickname());
}
if (workOrder.getFromDeptId() != null) {
DeptRespDTO fromDept = deptApi.getDept(workOrder.getFromDeptId()).getCheckedData();
respVO.setFromDeptName(fromDept.getName());
}
if (workOrder.getAssigneeDeptId() != null) {
DeptRespDTO assigneeDept = deptApi.getDept(workOrder.getAssigneeDeptId()).getCheckedData();
respVO.setAssigneeDeptName(assigneeDept.getName());
}
return respVO;
}
/**
* 转换跟踪记录DO为TrackInfo
*/
private BpmOAWorkOrderTrackInfo convertToTrackInfo(BpmOAWorkOrderTrackDO trackDO) {
if (trackDO == null) {
return null;
}
BpmOAWorkOrderTrackInfo trackInfo = new BpmOAWorkOrderTrackInfo();
trackInfo.setTrackId(String.valueOf(trackDO.getId()));
trackInfo.setOperatorId(trackDO.getOperatorId());
trackInfo.setOperatorName(trackDO.getOperatorName());
trackInfo.setContent(trackDO.getContent());
trackInfo.setOperationType(trackDO.getOperationType());
trackInfo.setTrackTime(trackDO.getCreateTime().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")));
return trackInfo;
}
/**
* 转换分页结果
*/
private PageResult<BpmOAWorkOrderRespVO> convertToPageResult(PageResult<BpmOAWorkOrderDO> pageResult) {
if (pageResult == null || pageResult.getList() == null) {
return new PageResult<>();
}
List<BpmOAWorkOrderRespVO> respList = pageResult.getList().stream()
.map(this::convertToRespVO)
.collect(Collectors.toList());
return new PageResult<>(respList, pageResult.getTotal());
}
/**
* 获取工单类型名称
*/
private String getWorkOrderTypeName(String type) {
switch (type) {
case "it_support":
return "IT支持";
case "equipment_repair":
return "设备维修";
case "system_issue":
return "系统问题";
case "permission_request":
return "权限申请";
case "other":
return "其他";
default:
return type;
}
}
/**
* 获取工单优先级名称
*/
private String getWorkOrderLevelName(Integer level) {
if (level == null) {
return "";
}
switch (level) {
case 1:
return "";
case 2:
return "";
case 3:
return "";
case 4:
return "紧急";
default:
return String.valueOf(level);
}
}
/**
* 获取工单状态名称
*/
private String getWorkOrderStatusName(Integer status) {
if (status == null) {
return "";
}
switch (status) {
case 1:
return "待分配";
case 2:
return "处理中";
case 3:
return "已完成";
case 4:
return "已取消";
case 5:
return "已关闭";
default:
return String.valueOf(status);
}
}
}