diff --git a/yudao-module-bpm/yudao-module-bpm-api/src/main/java/cn/iocoder/yudao/module/bpm/enums/ErrorCodeConstants.java b/yudao-module-bpm/yudao-module-bpm-api/src/main/java/cn/iocoder/yudao/module/bpm/enums/ErrorCodeConstants.java index fbf8b331..90017516 100644 --- a/yudao-module-bpm/yudao-module-bpm-api/src/main/java/cn/iocoder/yudao/module/bpm/enums/ErrorCodeConstants.java +++ b/yudao-module-bpm/yudao-module-bpm-api/src/main/java/cn/iocoder/yudao/module/bpm/enums/ErrorCodeConstants.java @@ -30,6 +30,7 @@ public interface ErrorCodeConstants { ErrorCode OA_REGULAR_NOT_EXISTS = new ErrorCode(1_009_001_106, "转正申请不存在"); ErrorCode OA_SHIFTJOBS_NOT_EXISTS = new ErrorCode(1_009_001_107, "调岗申请不存在"); ErrorCode OA_SECOND_NOT_EXISTS = new ErrorCode(1_009_001_108, "借调申请不存在"); + ErrorCode OA_IMPREST_NOT_EXISTS = new ErrorCode(1_009_001_109, "备用金申请不存在"); // ========== 流程模型 1-009-002-000 ========== ErrorCode MODEL_KEY_EXISTS = new ErrorCode(1_009_002_000, "已经存在流程标识为【{}】的流程"); diff --git a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/oa/BpmOAImprestController.java b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/oa/BpmOAImprestController.java new file mode 100644 index 00000000..f1a3b7ff --- /dev/null +++ b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/oa/BpmOAImprestController.java @@ -0,0 +1,52 @@ +package cn.iocoder.yudao.module.bpm.controller.admin.oa; + +import cn.iocoder.yudao.framework.common.pojo.CommonResult; +import cn.iocoder.yudao.module.bpm.controller.admin.oa.vo.imprest.BpmOAImprestCreateReqVO; +import cn.iocoder.yudao.module.bpm.controller.admin.oa.vo.imprest.BpmOAImprestRespVO; +import cn.iocoder.yudao.module.bpm.convert.oa.BpmOAImprestConvert; +import cn.iocoder.yudao.module.bpm.dal.dataobject.oa.BpmOAImprestDO; +import cn.iocoder.yudao.module.bpm.service.oa.BpmOAImprestService; +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.Parameter; +import io.swagger.v3.oas.annotations.tags.Tag; +import org.springframework.validation.annotation.Validated; +import org.springframework.web.bind.annotation.*; + +import javax.annotation.Resource; +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; + +/** + * OA 备用金申请 Controller + * + * @author 符溶馨 + + */ +@Tag(name = "管理后台 - OA 备用金申请") +@RestController +@RequestMapping("/bpm/oa/imprest") +@Validated +public class BpmOAImprestController { + + @Resource + private BpmOAImprestService imprestService; + + @PostMapping("/create") + @Operation(summary = "创建请求申请") + public CommonResult createImprest(@Valid @RequestBody BpmOAImprestCreateReqVO createReqVO) { + + return success(imprestService.createImprest(getLoginUserId(), createReqVO)); + } + + @GetMapping("/get") + @Operation(summary = "获得出差申请") + @Parameter(name = "id", description = "编号", required = true, example = "1024") + public CommonResult getImprest(@RequestParam("id") Long id) { + + BpmOAImprestDO imprest = imprestService.getImprest(id); + + return success(BpmOAImprestConvert.INSTANCE.convert(imprest)); + } +} diff --git a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/oa/vo/imprest/BpmOAImprestCreateReqVO.java b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/oa/vo/imprest/BpmOAImprestCreateReqVO.java new file mode 100644 index 00000000..f7b2d19d --- /dev/null +++ b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/oa/vo/imprest/BpmOAImprestCreateReqVO.java @@ -0,0 +1,47 @@ +package cn.iocoder.yudao.module.bpm.controller.admin.oa.vo.imprest; + +import cn.iocoder.yudao.module.bpm.controller.admin.upload.UploadUserFile; +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.ToString; +import org.springframework.format.annotation.DateTimeFormat; + +import javax.validation.constraints.NotNull; +import java.math.BigDecimal; +import java.time.LocalDate; +import java.util.List; + +import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY; + +/** + * 备用金申请 创建 Request VO + * + * @author 符溶馨 + */ +@Schema(description = "管理后台 - 备用金申请创建 Request VO") +@Data +@EqualsAndHashCode() +@ToString(callSuper = true) +public class BpmOAImprestCreateReqVO { + + @Schema(description = "费用类型 参见 bpm_oa_imprest_type 枚举", requiredMode = Schema.RequiredMode.REQUIRED) + @NotNull(message = "费用类型不能为空") + private String type; + + @Schema(description = "费用事由", requiredMode = Schema.RequiredMode.REQUIRED) + @NotNull(message = "费用事由不能为空") + private String reason; + + @Schema(description = "费用金额", requiredMode = Schema.RequiredMode.REQUIRED) + @NotNull(message = "费用金额不能为空") + private BigDecimal amount; + + @Schema(description = "使用日期", requiredMode = Schema.RequiredMode.REQUIRED) + @NotNull(message = "使用日期不能为空") + @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY) + private LocalDate date; + + @Schema(description = "上传文件", requiredMode = Schema.RequiredMode.NOT_REQUIRED) + private List fileItems; +} diff --git a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/oa/vo/imprest/BpmOAImprestRespVO.java b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/oa/vo/imprest/BpmOAImprestRespVO.java new file mode 100644 index 00000000..3d261fc7 --- /dev/null +++ b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/oa/vo/imprest/BpmOAImprestRespVO.java @@ -0,0 +1,46 @@ +package cn.iocoder.yudao.module.bpm.controller.admin.oa.vo.imprest; + +import cn.iocoder.yudao.module.bpm.controller.admin.oa.vo.BpmOABaseRespVO; +import cn.iocoder.yudao.module.bpm.controller.admin.upload.UploadUserFile; +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.ToString; +import org.springframework.format.annotation.DateTimeFormat; + +import javax.validation.constraints.NotNull; +import java.math.BigDecimal; +import java.time.LocalDate; +import java.util.List; + +import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY; + +/** + * @author 符溶馨 + */ +@Schema(description = "管理后台 - 备用金申请 请求Request VO") +@Data +@EqualsAndHashCode(callSuper = true) +@ToString(callSuper = true) +public class BpmOAImprestRespVO extends BpmOABaseRespVO { + + @Schema(description = "费用类型 参见 bpm_oa_imprest_type 枚举", requiredMode = Schema.RequiredMode.REQUIRED) + @NotNull(message = "费用类型不能为空") + private String type; + + @Schema(description = "费用事由", requiredMode = Schema.RequiredMode.REQUIRED) + @NotNull(message = "费用事由不能为空") + private String reason; + + @Schema(description = "费用金额", requiredMode = Schema.RequiredMode.REQUIRED) + @NotNull(message = "费用金额不能为空") + private BigDecimal amount; + + @Schema(description = "使用日期", requiredMode = Schema.RequiredMode.REQUIRED) + @NotNull(message = "使用日期不能为空") + @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY) + private LocalDate date; + + @Schema(description = "上传文件", requiredMode = Schema.RequiredMode.NOT_REQUIRED) + private List fileItems; +} diff --git a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/convert/oa/BpmOAImprestConvert.java b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/convert/oa/BpmOAImprestConvert.java new file mode 100644 index 00000000..341d37ff --- /dev/null +++ b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/convert/oa/BpmOAImprestConvert.java @@ -0,0 +1,22 @@ +package cn.iocoder.yudao.module.bpm.convert.oa; + +import cn.iocoder.yudao.module.bpm.controller.admin.oa.vo.imprest.BpmOAImprestCreateReqVO; +import cn.iocoder.yudao.module.bpm.controller.admin.oa.vo.imprest.BpmOAImprestRespVO; +import cn.iocoder.yudao.module.bpm.dal.dataobject.oa.BpmOAImprestDO; +import org.mapstruct.Mapper; +import org.mapstruct.factory.Mappers; + +/** + * 备用金申请 Convert + * + * @author 符溶馨 + */ +@Mapper +public interface BpmOAImprestConvert { + + BpmOAImprestConvert INSTANCE = Mappers.getMapper(BpmOAImprestConvert.class); + + BpmOAImprestDO convert(BpmOAImprestCreateReqVO bean); + + BpmOAImprestRespVO convert(BpmOAImprestDO bean); +} diff --git a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/dal/dataobject/oa/BpmOAImprestDO.java b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/dal/dataobject/oa/BpmOAImprestDO.java new file mode 100644 index 00000000..ae59927d --- /dev/null +++ b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/dal/dataobject/oa/BpmOAImprestDO.java @@ -0,0 +1,85 @@ +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.upload.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.math.BigDecimal; +import java.time.LocalDate; +import java.util.List; + +/** + * OA 备用金申请 DO + * + * + * @author 符溶馨 + + */ +@TableName(value ="bpm_oa_imprest", autoResultMap = true) +@Data +@EqualsAndHashCode(callSuper = true) +@ToString(callSuper = true) +@Builder +@NoArgsConstructor +@AllArgsConstructor +public class BpmOAImprestDO extends BaseDO { + + /** + * 出差表单主键 + */ + @TableId + private Long id; + + /** + * 申请人的用户编号 + * + * 关联 AdminUserDO 的 id 属性 + */ + private Long userId; + + /** + * 费用类型 + */ + private String type; + + /** + * 申请事由 + */ + private String reason; + + /** + * 申请金额 + */ + private BigDecimal amount; + + /** + * 使用日期 + */ + private LocalDate date; + + /** + * 申请的结果 + * + * 枚举 {@link BpmProcessInstanceResultEnum} + * 考虑到简单,所以直接复用了 BpmProcessInstanceResultEnum 枚举,也可以自己定义一个枚举哈 + */ + private Integer result; + + /** + * 对应的流程编号 + * + * 关联 ProcessInstance 的 id 属性 + */ + private String processInstanceId; + + /** + * 附件基本信息 + */ + @TableField(typeHandler = JacksonTypeHandler.class) + private List fileItems ; +} diff --git a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/dal/mysql/oa/BpmOAImprestMapper.java b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/dal/mysql/oa/BpmOAImprestMapper.java new file mode 100644 index 00000000..a447047a --- /dev/null +++ b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/dal/mysql/oa/BpmOAImprestMapper.java @@ -0,0 +1,15 @@ +package cn.iocoder.yudao.module.bpm.dal.mysql.oa; + +import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX; +import cn.iocoder.yudao.module.bpm.dal.dataobject.oa.BpmOAImprestDO; +import org.apache.ibatis.annotations.Mapper; + +/** + * 备用金申请 Mapper + * + * @author 符溶馨 + + */ +@Mapper +public interface BpmOAImprestMapper extends BaseMapperX { +} diff --git a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/oa/BpmOAImprestService.java b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/oa/BpmOAImprestService.java new file mode 100644 index 00000000..0e892fd9 --- /dev/null +++ b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/oa/BpmOAImprestService.java @@ -0,0 +1,40 @@ +package cn.iocoder.yudao.module.bpm.service.oa; + +import cn.iocoder.yudao.module.bpm.controller.admin.oa.vo.imprest.BpmOAImprestCreateReqVO; +import cn.iocoder.yudao.module.bpm.dal.dataobject.oa.BpmOAImprestDO; + +import javax.validation.Valid; + +/** + * 备用金申请 Service 接口 + * + * @author 符溶馨 + + */ +public interface BpmOAImprestService { + + /** + * 创建备用金申请 + * + * @param userId 用户编号 + * @param createReqVO 创建信息 + * @return 编号 + */ + Long createImprest(Long userId, @Valid BpmOAImprestCreateReqVO createReqVO); + + /** + * 更新备用金申请的状态 + * + * @param id 编号 + * @param result 结果 + */ + void updateImprestResult(Long id, Integer result); + + /** + * 获得备用金申请 + * + * @param id 编号 + * @return 备用金申请 + */ + BpmOAImprestDO getImprest(Long id); +} diff --git a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/oa/BpmOAImprestServiceImpl.java b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/oa/BpmOAImprestServiceImpl.java new file mode 100644 index 00000000..fbc7a83e --- /dev/null +++ b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/oa/BpmOAImprestServiceImpl.java @@ -0,0 +1,86 @@ +package cn.iocoder.yudao.module.bpm.service.oa; + +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.imprest.BpmOAImprestCreateReqVO; +import cn.iocoder.yudao.module.bpm.controller.admin.upload.UploadUserFile; +import cn.iocoder.yudao.module.bpm.convert.oa.BpmOAImprestConvert; +import cn.iocoder.yudao.module.bpm.dal.dataobject.oa.BpmOAImprestDO; +import cn.iocoder.yudao.module.bpm.dal.mysql.oa.BpmOAImprestMapper; +import cn.iocoder.yudao.module.bpm.enums.task.BpmProcessInstanceResultEnum; +import org.springframework.stereotype.Service; +import org.springframework.validation.annotation.Validated; + +import javax.annotation.Resource; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; +import static cn.iocoder.yudao.module.bpm.enums.ErrorCodeConstants.OA_IMPREST_NOT_EXISTS; + +/** + * OA 备用金申请 Service 实现类 + * + * @author 符溶馨 + + */ +@Service +@Validated +public class BpmOAImprestServiceImpl extends BpmOABaseService implements BpmOAImprestService{ + + /** + * OA 出差对应的流程定义 KEY + */ + public static final String PROCESS_KEY = "oa_imprest"; + + @Resource + private BpmOAImprestMapper imprestMapper; + + @Resource + private BpmProcessInstanceApi processInstanceApi; + + @Override + public Long createImprest(Long userId, BpmOAImprestCreateReqVO createReqVO) { + + //插入OA 备用金申请 + BpmOAImprestDO imprest = BpmOAImprestConvert.INSTANCE.convert(createReqVO).setUserId(userId) + .setResult(BpmProcessInstanceResultEnum.PROCESS.getResult()); + imprestMapper.insert(imprest) ; + + // 发起 BPM 流程 + Map processInstanceVariables = new HashMap<>(); + String processInstanceId = processInstanceApi.createProcessInstance(userId, + new BpmProcessInstanceCreateReqDTO().setProcessDefinitionKey(PROCESS_KEY) + .setVariables(processInstanceVariables).setBusinessKey(String.valueOf(imprest.getId()))).getCheckedData(); + + // 将工作流的编号,更新到 OA 备用金单中 + imprestMapper.updateById(new BpmOAImprestDO().setId(imprest.getId()).setProcessInstanceId(processInstanceId)); + + List fileItems = createReqVO.getFileItems() ; + //这里的逻辑,如果fileItems不为空,且有数据,那么说明是上传了附件的,则需要更工作流文件表对应的实例Id + if (fileItems != null && !fileItems.isEmpty()) { + uploadBpmFileProcessInstanceId(processInstanceId,fileItems) ; + } + return imprest.getId(); + } + + @Override + public void updateImprestResult(Long id, Integer result) { + + validateLeaveExists(id); + imprestMapper.updateById(new BpmOAImprestDO().setId(id).setResult(result)); + } + + private void validateLeaveExists(Long id) { + if (imprestMapper.selectById(id) == null) { + throw exception(OA_IMPREST_NOT_EXISTS); + } + } + + @Override + public BpmOAImprestDO getImprest(Long id) { + + return imprestMapper.selectById(id); + } +} diff --git a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/oa/listener/BpmOAImprestResultListener.java b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/oa/listener/BpmOAImprestResultListener.java new file mode 100644 index 00000000..0c6fbf2a --- /dev/null +++ b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/oa/listener/BpmOAImprestResultListener.java @@ -0,0 +1,31 @@ +package cn.iocoder.yudao.module.bpm.service.oa.listener; + +import cn.iocoder.yudao.module.bpm.framework.bpm.core.event.BpmProcessInstanceResultEvent; +import cn.iocoder.yudao.module.bpm.framework.bpm.core.event.BpmProcessInstanceResultEventListener; +import cn.iocoder.yudao.module.bpm.service.oa.BpmOAImprestService; +import cn.iocoder.yudao.module.bpm.service.oa.BpmOAImprestServiceImpl; +import org.springframework.stereotype.Component; + +import javax.annotation.Resource; + +/** + * OA 备用金单的结果的监听器实现类 + * + * @author 符溶馨 + */ +@Component +public class BpmOAImprestResultListener extends BpmProcessInstanceResultEventListener { + + @Resource + private BpmOAImprestService imprestService; + + @Override + protected String getProcessDefinitionKey() { + return BpmOAImprestServiceImpl.PROCESS_KEY; + } + + @Override + protected void onEvent(BpmProcessInstanceResultEvent event) { + imprestService.updateImprestResult(Long.parseLong(event.getBusinessKey()), event.getResult()); + } +} diff --git a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/oa/listener/BpmOARegularResultListener.java b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/oa/listener/BpmOARegularResultListener.java new file mode 100644 index 00000000..85da3c7a --- /dev/null +++ b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/oa/listener/BpmOARegularResultListener.java @@ -0,0 +1,32 @@ +package cn.iocoder.yudao.module.bpm.service.oa.listener; + +import cn.iocoder.yudao.module.bpm.framework.bpm.core.event.BpmProcessInstanceResultEvent; +import cn.iocoder.yudao.module.bpm.framework.bpm.core.event.BpmProcessInstanceResultEventListener; +import cn.iocoder.yudao.module.bpm.service.oa.BpmOARegularService; +import cn.iocoder.yudao.module.bpm.service.oa.BpmOARegularServiceImpl; +import org.springframework.stereotype.Component; + +import javax.annotation.Resource; + +/** + * OA 转正单的结果的监听器实现类 + * + * @author 符溶馨 + */ +@Component +public class BpmOARegularResultListener extends BpmProcessInstanceResultEventListener { + + @Resource + private BpmOARegularService regularService; + + @Override + protected String getProcessDefinitionKey() { + + return BpmOARegularServiceImpl.PROCESS_KEY; + } + + @Override + protected void onEvent(BpmProcessInstanceResultEvent event) { + regularService.updateRegularResult(Long.parseLong(event.getBusinessKey()), event.getResult()); + } +}