src/main/java/com/ruoyi/approve/controller/ApproveFlowDefinitionController.java
¶Ô±ÈÐÂÎļþ @@ -0,0 +1,159 @@ package com.ruoyi.approve.controller; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.ruoyi.approve.mapper.ApproveFlowDefinitionMapper; import com.ruoyi.approve.mapper.ApproveFlowNodeDefinitionMapper; import com.ruoyi.approve.mapper.ApproveProcessMapper; import com.ruoyi.approve.pojo.ApproveFlowDefinition; import com.ruoyi.approve.pojo.ApproveFlowNodeDefinition; import com.ruoyi.approve.pojo.ApproveProcess; import com.ruoyi.approve.vo.ApproveFlowDefinitionVO; import com.ruoyi.common.utils.SecurityUtils; import com.ruoyi.framework.web.domain.AjaxResult; import org.springframework.transaction.annotation.Transactional; import org.springframework.web.bind.annotation.*; import java.time.LocalDateTime; import java.util.Collections; import java.util.List; @RestController @RequestMapping("/approveFlowDefinition") public class ApproveFlowDefinitionController { private final ApproveFlowDefinitionMapper definitionMapper; private final ApproveFlowNodeDefinitionMapper nodeMapper; private final ApproveProcessMapper processMapper; public ApproveFlowDefinitionController(ApproveFlowDefinitionMapper definitionMapper, ApproveFlowNodeDefinitionMapper nodeMapper, ApproveProcessMapper processMapper) { this.definitionMapper = definitionMapper; this.nodeMapper = nodeMapper; this.processMapper = processMapper; } @GetMapping("/list") public AjaxResult list(Integer approveType) { LambdaQueryWrapper<ApproveFlowDefinition> wrapper = new LambdaQueryWrapper<>(); wrapper.eq(ApproveFlowDefinition::getTenantId, SecurityUtils.getLoginUser().getTenantId()) .eq(ApproveFlowDefinition::getDeleteFlag, 0) .eq(approveType != null, ApproveFlowDefinition::getApproveType, approveType) .orderByDesc(ApproveFlowDefinition::getIsDefault) .orderByDesc(ApproveFlowDefinition::getUpdateTime); return AjaxResult.success(definitionMapper.selectList(wrapper)); } @GetMapping("/{id}") public AjaxResult get(@PathVariable Long id) { ApproveFlowDefinition definition = getOwned(id); ApproveFlowDefinitionVO result = new ApproveFlowDefinitionVO(); result.setDefinition(definition); result.setNodes(nodeMapper.selectList(new LambdaQueryWrapper<ApproveFlowNodeDefinition>() .eq(ApproveFlowNodeDefinition::getFlowDefinitionId, id) .eq(ApproveFlowNodeDefinition::getTenantId, definition.getTenantId()) .eq(ApproveFlowNodeDefinition::getDeleteFlag, 0) .orderByAsc(ApproveFlowNodeDefinition::getNodeOrder))); return AjaxResult.success(result); } @PostMapping @Transactional(rollbackFor = Exception.class) public AjaxResult add(@RequestBody ApproveFlowDefinitionVO request) { saveDefinition(request, false); return AjaxResult.success(); } @PutMapping("/{id}") @Transactional(rollbackFor = Exception.class) public AjaxResult update(@PathVariable Long id, @RequestBody ApproveFlowDefinitionVO request) { getOwned(id); request.getDefinition().setId(id); saveDefinition(request, true); return AjaxResult.success(); } @PutMapping("/{id}/enabled") public AjaxResult enabled(@PathVariable Long id, @RequestParam Integer enabled) { ApproveFlowDefinition definition = getOwned(id); definition.setEnabled(enabled == null || enabled == 0 ? 0 : 1); definition.setUpdateUser(SecurityUtils.getUserId()); definition.setUpdateTime(LocalDateTime.now()); definitionMapper.updateById(definition); return AjaxResult.success(); } @DeleteMapping("/{id}") public AjaxResult delete(@PathVariable Long id) { ApproveFlowDefinition definition = getOwned(id); Long activeCount = processMapper.selectCount(new LambdaQueryWrapper<ApproveProcess>() .eq(ApproveProcess::getTenantId, definition.getTenantId()) .eq(ApproveProcess::getFlowDefinitionId, id) .eq(ApproveProcess::getApproveDelete, 0) .in(ApproveProcess::getApproveStatus, 0, 1)); if (activeCount != null && activeCount > 0) throw new RuntimeException("该æµç¨ä»æè¿è¡ä¸ç审æ¹ï¼ä¸è½å é¤"); definition.setDeleteFlag(1); definition.setUpdateUser(SecurityUtils.getUserId()); definition.setUpdateTime(LocalDateTime.now()); definitionMapper.updateById(definition); return AjaxResult.success(); } private void saveDefinition(ApproveFlowDefinitionVO request, boolean update) { if (request == null || request.getDefinition() == null) throw new RuntimeException("æµç¨å®ä¹ä¸è½ä¸ºç©º"); List<ApproveFlowNodeDefinition> nodes = request.getNodes() == null ? Collections.emptyList() : request.getNodes(); if (nodes.isEmpty()) throw new RuntimeException("å®¡æ¹æµç¨è³å°å å«ä¸ä¸ªèç¹"); Long tenantId = SecurityUtils.getLoginUser().getTenantId(); Long userId = SecurityUtils.getUserId(); ApproveFlowDefinition definition = request.getDefinition(); definition.setTenantId(tenantId); definition.setUpdateUser(userId); definition.setUpdateTime(LocalDateTime.now()); definition.setDeleteFlag(0); if (definition.getEnabled() == null) definition.setEnabled(1); if (definition.getIsDefault() == null) definition.setIsDefault(0); if (definition.getIsDefault() == 1) { List<ApproveFlowDefinition> oldDefaults = definitionMapper.selectList(new LambdaQueryWrapper<ApproveFlowDefinition>() .eq(ApproveFlowDefinition::getTenantId, tenantId) .eq(ApproveFlowDefinition::getApproveType, definition.getApproveType()) .eq(ApproveFlowDefinition::getIsDefault, 1) .eq(ApproveFlowDefinition::getDeleteFlag, 0)); oldDefaults.stream().filter(item -> !item.getId().equals(definition.getId())).forEach(item -> { item.setIsDefault(0); definitionMapper.updateById(item); }); } if (update) { definitionMapper.updateById(definition); nodeMapper.delete(new LambdaQueryWrapper<ApproveFlowNodeDefinition>() .eq(ApproveFlowNodeDefinition::getFlowDefinitionId, definition.getId()) .eq(ApproveFlowNodeDefinition::getTenantId, tenantId)); } else { definition.setCreateUser(userId); definition.setCreateTime(LocalDateTime.now()); definitionMapper.insert(definition); } int order = 1; for (ApproveFlowNodeDefinition node : nodes) { node.setId(null); node.setFlowDefinitionId(definition.getId()); node.setNodeOrder(order++); node.setTenantId(tenantId); node.setCreateUser(userId); node.setUpdateUser(userId); node.setCreateTime(LocalDateTime.now()); node.setUpdateTime(LocalDateTime.now()); node.setDeleteFlag(0); if (node.getConditionOperator() == null) node.setConditionOperator("ALWAYS"); nodeMapper.insert(node); } } private ApproveFlowDefinition getOwned(Long id) { ApproveFlowDefinition definition = definitionMapper.selectOne(new LambdaQueryWrapper<ApproveFlowDefinition>() .eq(ApproveFlowDefinition::getId, id) .eq(ApproveFlowDefinition::getTenantId, SecurityUtils.getLoginUser().getTenantId()) .eq(ApproveFlowDefinition::getDeleteFlag, 0)); if (definition == null) throw new RuntimeException("æµç¨å®ä¹ä¸åå¨"); return definition; } } src/main/java/com/ruoyi/approve/controller/ApproveProcessController.java
@@ -2,7 +2,6 @@ import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.ruoyi.account.pojo.AccountExpense; import com.ruoyi.approve.pojo.ApproveProcess; import com.ruoyi.approve.service.IApproveProcessService; import com.ruoyi.approve.vo.ApproveGetAndUpdateVo; @@ -20,7 +19,6 @@ import javax.servlet.http.HttpServletResponse; import java.io.IOException; import java.text.ParseException; import java.util.List; @RestController @@ -115,7 +113,7 @@ @DeleteMapping("/deleteIds") @ApiOperation(value = "å é¤å®¡æ¹") @Transactional(rollbackFor = Exception.class) public AjaxResult deleteIds(@RequestBody Long[] ids) { public AjaxResult deleteIds(@RequestBody String[] ids) { if (ids == null || ids.length == 0) { return AjaxResult.warn("åæ°ä¸è½ä¸ºç©º"); } @@ -123,42 +121,34 @@ return AjaxResult.success("æä½æå"); } @ApiOperation(value = "å ¬åºç®¡ç导åº") @ApiOperation(value = "èªç±åå审æ¹å¯¼åº") @PostMapping("/exportOne") public void exportOne(HttpServletResponse response) { List<ApproveProcess> accountExpenses = approveProcessService.list(new LambdaQueryWrapper<ApproveProcess>() .eq(ApproveProcess::getApproveDelete, 0) .eq(ApproveProcess::getApproveType, 1)); List<ApproveProcess> accountExpenses = exportList(1); ExcelUtil<ApproveProcess> util = new ExcelUtil<ApproveProcess>(ApproveProcess.class); util.exportExcel(response, accountExpenses, "å ¬åºç®¡ç导åº"); util.exportExcel(response, accountExpenses, "èªç±åå审æ¹è¡¨"); } @ApiOperation(value = "请å管ç导åº") @PostMapping("/exportTwo") public void exportTwo(HttpServletResponse response) { List<ApproveProcess> accountExpenses = approveProcessService.list(new LambdaQueryWrapper<ApproveProcess>() .eq(ApproveProcess::getApproveDelete, 0) .eq(ApproveProcess::getApproveType, 2)); List<ApproveProcess> accountExpenses = exportList(2); ExcelUtil<ApproveProcess> util = new ExcelUtil<ApproveProcess>(ApproveProcess.class); util.exportExcel(response, accountExpenses, "请å管ç导åº"); } @ApiOperation(value = "åºå·®ç®¡ç导åº") @ApiOperation(value = "éå®åå审æ¹å¯¼åº") @PostMapping("/exportThree") public void exportThree(HttpServletResponse response) { List<ApproveProcess> accountExpenses = approveProcessService.list(new LambdaQueryWrapper<ApproveProcess>() .eq(ApproveProcess::getApproveDelete, 0) .eq(ApproveProcess::getApproveType, 3)); List<ApproveProcess> accountExpenses = exportList(3); ExcelUtil<ApproveProcess> util = new ExcelUtil<ApproveProcess>(ApproveProcess.class); util.exportExcel(response, accountExpenses, "åºå·®ç®¡ç导åº"); util.exportExcel(response, accountExpenses, "éå®åå审æ¹è¡¨"); } @ApiOperation(value = "æ¥é管ç导åº") @PostMapping("/exportFour") public void exportFour(HttpServletResponse response) { List<ApproveProcess> accountExpenses = approveProcessService.list(new LambdaQueryWrapper<ApproveProcess>() .eq(ApproveProcess::getApproveDelete, 0) .eq(ApproveProcess::getApproveType, 4)); List<ApproveProcess> accountExpenses = exportList(4); ExcelUtil<ApproveProcess> util = new ExcelUtil<ApproveProcess>(ApproveProcess.class); util.exportExcel(response, accountExpenses, "æ¥é管ç导åº"); } @@ -166,20 +156,37 @@ @ApiOperation(value = "éè´ç³è¯·å¯¼åº") @PostMapping("/exportFive") public void exportFive(HttpServletResponse response) { List<ApproveProcess> accountExpenses = approveProcessService.list(new LambdaQueryWrapper<ApproveProcess>() .eq(ApproveProcess::getApproveDelete, 0) .eq(ApproveProcess::getApproveType, 5)); List<ApproveProcess> accountExpenses = exportList(5); ExcelUtil<ApproveProcess> util = new ExcelUtil<ApproveProcess>(ApproveProcess.class); util.exportExcel(response, accountExpenses, "éè´ç³è¯·å¯¼åº"); util.exportExcel(response, accountExpenses, "éè´è®¡å审æ¹è¡¨"); } @ApiOperation(value = "åå审æ¹å¯¼åº") @PostMapping("/exportZero") public void exportZero(HttpServletResponse response) { List<ApproveProcess> accountExpenses = approveProcessService.list(new LambdaQueryWrapper<ApproveProcess>() .eq(ApproveProcess::getApproveDelete, 0) .eq(ApproveProcess::getApproveType, 0)); List<ApproveProcess> accountExpenses = exportList(1); ExcelUtil<ApproveProcess> util = new ExcelUtil<ApproveProcess>(ApproveProcess.class); util.exportExcel(response, accountExpenses, "åå审æ¹å¯¼åº"); util.exportExcel(response, accountExpenses, "èªç±åå审æ¹è¡¨"); } @ApiOperation(value = "æ¥ä»·å®¡æ¹å¯¼åº") @PostMapping("/exportSix") public void exportSix(HttpServletResponse response) { ExcelUtil<ApproveProcess> util = new ExcelUtil<>(ApproveProcess.class); util.exportExcel(response, exportList(6), "æ¥ä»·å®¡æ¹è¡¨"); } @ApiOperation(value = "åºåºå®¡æ¹å¯¼åº") @PostMapping("/exportSeven") public void exportSeven(HttpServletResponse response) { ExcelUtil<ApproveProcess> util = new ExcelUtil<>(ApproveProcess.class); util.exportExcel(response, exportList(7), "åºåºå®¡æ¹è¡¨"); } private List<ApproveProcess> exportList(int type) { return approveProcessService.list(new LambdaQueryWrapper<ApproveProcess>() .eq(ApproveProcess::getApproveDelete, 0) .eq(ApproveProcess::getApproveType, type) .eq(ApproveProcess::getTenantId, SecurityUtils.getLoginUser().getTenantId())); } } src/main/java/com/ruoyi/approve/enums/ApproveType.java
¶Ô±ÈÐÂÎļþ @@ -0,0 +1,34 @@ package com.ruoyi.approve.enums; import java.util.Arrays; public enum ApproveType { FREE_COLLABORATION(1, "èªç±åå审æ¹"), LEAVE(2, "请å管ç"), SALES_CONTRACT(3, "éå®å®¡æ¹"), REIMBURSEMENT(4, "æ¥é审æ¹"), PURCHASE_PLAN(5, "éè´å®¡æ¹"), QUOTATION(6, "æ¥ä»·å®¡æ¹"), OUTBOUND(7, "åºåºå®¡æ¹"); private final int code; private final String label; ApproveType(int code, String label) { this.code = code; this.label = label; } public int getCode() { return code; } public String getLabel() { return label; } public static ApproveType fromCode(Integer code) { return Arrays.stream(values()).filter(item -> item.code == code).findFirst() .orElseThrow(() -> new IllegalArgumentException("䏿¯æç审æ¹ç±»å")); } } src/main/java/com/ruoyi/approve/mapper/ApproveFlowDefinitionMapper.java
¶Ô±ÈÐÂÎļþ @@ -0,0 +1,7 @@ package com.ruoyi.approve.mapper; import com.baomidou.mybatisplus.core.mapper.BaseMapper; import com.ruoyi.approve.pojo.ApproveFlowDefinition; public interface ApproveFlowDefinitionMapper extends BaseMapper<ApproveFlowDefinition> { } src/main/java/com/ruoyi/approve/mapper/ApproveFlowNodeDefinitionMapper.java
¶Ô±ÈÐÂÎļþ @@ -0,0 +1,7 @@ package com.ruoyi.approve.mapper; import com.baomidou.mybatisplus.core.mapper.BaseMapper; import com.ruoyi.approve.pojo.ApproveFlowNodeDefinition; public interface ApproveFlowNodeDefinitionMapper extends BaseMapper<ApproveFlowNodeDefinition> { } src/main/java/com/ruoyi/approve/pojo/ApproveFlowDefinition.java
¶Ô±ÈÐÂÎļþ @@ -0,0 +1,50 @@ package com.ruoyi.approve.pojo; import com.baomidou.mybatisplus.annotation.IdType; import com.baomidou.mybatisplus.annotation.TableId; import com.baomidou.mybatisplus.annotation.TableName; import io.swagger.annotations.ApiModelProperty; import lombok.Data; import java.time.LocalDateTime; @Data @TableName("approve_flow_definition") public class ApproveFlowDefinition { @ApiModelProperty(value = "æµç¨å®ä¹ID") @TableId(type = IdType.AUTO) private Long id; @ApiModelProperty(value = "æµç¨åç§°") private String flowName; @ApiModelProperty(value = "审æ¹ç±»å") private Integer approveType; @ApiModelProperty(value = "å¯ç¨ç¶æï¼0åç¨ï¼1å¯ç¨") private Integer enabled; @ApiModelProperty(value = "æ¯å¦é»è®¤æµç¨ï¼0å¦ï¼1æ¯") private Integer isDefault; @ApiModelProperty(value = "æµç¨å¤æ³¨") private String remark; @ApiModelProperty(value = "ç§æ·ID") private Long tenantId; @ApiModelProperty(value = "åå»ºç¨æ·ID") private Long createUser; @ApiModelProperty(value = "æ´æ°ç¨æ·ID") private Long updateUser; @ApiModelProperty(value = "å建æ¶é´") private LocalDateTime createTime; @ApiModelProperty(value = "æ´æ°æ¶é´") private LocalDateTime updateTime; @ApiModelProperty(value = "å 餿 å¿ï¼0æ£å¸¸ï¼1å é¤") private Integer deleteFlag; } src/main/java/com/ruoyi/approve/pojo/ApproveFlowNodeDefinition.java
¶Ô±ÈÐÂÎļþ @@ -0,0 +1,59 @@ package com.ruoyi.approve.pojo; import com.baomidou.mybatisplus.annotation.IdType; import com.baomidou.mybatisplus.annotation.TableId; import com.baomidou.mybatisplus.annotation.TableName; import io.swagger.annotations.ApiModelProperty; import lombok.Data; import java.time.LocalDateTime; @Data @TableName("approve_flow_node_definition") public class ApproveFlowNodeDefinition { @ApiModelProperty(value = "æµç¨èç¹å®ä¹ID") @TableId(type = IdType.AUTO) private Long id; @ApiModelProperty(value = "æµç¨å®ä¹ID") private Long flowDefinitionId; @ApiModelProperty(value = "èç¹é¡ºåº") private Integer nodeOrder; @ApiModelProperty(value = "èç¹åç§°") private String nodeName; @ApiModelProperty(value = "审æ¹äººç±»å") private String approverType; @ApiModelProperty(value = "审æ¹äººé ç½®å¼") private String approverValue; @ApiModelProperty(value = "æ¡ä»¶å段") private String conditionField; @ApiModelProperty(value = "æ¡ä»¶æä½ç¬¦") private String conditionOperator; @ApiModelProperty(value = "æ¡ä»¶å¼") private String conditionValue; @ApiModelProperty(value = "ç§æ·ID") private Long tenantId; @ApiModelProperty(value = "åå»ºç¨æ·ID") private Long createUser; @ApiModelProperty(value = "æ´æ°ç¨æ·ID") private Long updateUser; @ApiModelProperty(value = "å建æ¶é´") private LocalDateTime createTime; @ApiModelProperty(value = "æ´æ°æ¶é´") private LocalDateTime updateTime; @ApiModelProperty(value = "å 餿 å¿ï¼0æ£å¸¸ï¼1å é¤") private Integer deleteFlag; } src/main/java/com/ruoyi/approve/pojo/ApproveLog.java
@@ -4,6 +4,7 @@ import com.baomidou.mybatisplus.annotation.TableId; import com.baomidou.mybatisplus.annotation.TableName; import com.fasterxml.jackson.annotation.JsonFormat; import io.swagger.annotations.ApiModelProperty; import lombok.Data; import java.io.Serializable; @@ -20,38 +21,57 @@ /** * */ @ApiModelProperty(value = "主é®ID") @TableId(type = IdType.AUTO) private Long id; /** * 审æ¹id */ @ApiModelProperty(value = "å®¡æ¹æ¥å¿ä¸å¡ID") private Long approveId; @ApiModelProperty(value = "å®¡æ¹æµç¨ä¸»é®") private Long approveProcessId; @ApiModelProperty(value = "审æ¹èç¹ä¸»é®") private Long approveNodeId; /** * 审æ¹èç¹é¡ºåº */ @ApiModelProperty(value = "审æ¹èç¹é¡ºåº") private Integer approveNodeOrder; /** * 审æ¹äººid */ @ApiModelProperty(value = "审æ¹ç¨æ·ID") private Long approveUser; @ApiModelProperty(value = "审æ¹ç¨æ·åç§°") private String approveUserName; /** * å®¡æ¹æ¶é´ */ @ApiModelProperty(value = "å®¡æ¹æ¶é´") @JsonFormat(pattern = "yyyy-MM-dd") private Date approveTime; /** * 审æ¹ç¶æ */ @ApiModelProperty(value = "审æ¹ç¶æ") private Integer approveStatus; /** * 审æ¹å¤æ³¨ */ @ApiModelProperty(value = "审æ¹å¤æ³¨") private String approveRemark; } @ApiModelProperty(value = "ç§æ·ID") private Long tenantId; } src/main/java/com/ruoyi/approve/pojo/ApproveNode.java
@@ -35,39 +35,47 @@ /** * */ @ApiModelProperty(value = "主é®ID") private Long id; /** * 审æ¹ç¼å· */ @ApiModelProperty(value = "å®¡æ¹æµç¨ç¼å·") private String approveProcessId; /** * 审æ¹èç¹é¡ºåº */ @ApiModelProperty(value = "审æ¹èç¹é¡ºåº") private Integer approveNodeOrder; /** * 审æ¹èç¹ç¨æ·åå */ @ApiModelProperty(value = "审æ¹èç¹ç¨æ·åç§°") private String approveNodeUser; /** * 审æ¹èç¹ç¨æ·id */ @ApiModelProperty(value = "审æ¹èç¹ç¨æ·ID") private Long approveNodeUserId; /** * 审æ¹èç¹æ¶é´ */ @ApiModelProperty(value = "审æ¹èç¹æ¶é´") @JsonFormat(pattern = "yyyy-MM-dd") private Date approveNodeTime; /** * 审æ¹èç¹ç¶æ:1åæï¼2æç»ï¼0å°æªå®¡æ ¸ï¼é»è®¤ä¸º0ï¼ */ @ApiModelProperty(value = "审æ¹èç¹ç¶æï¼0å°æªå®¡æ ¸ï¼1åæï¼2æç»") private Integer approveNodeStatus; @ApiModelProperty(value = "æ¯å¦ä¸ºç¬¬ä¸ä¸ªèç¹") @TableField(exist = false) private Boolean isFirst; @@ -75,12 +83,14 @@ /** * æ¯å¦ä¸ºæå䏿¥ */ @ApiModelProperty(value = "æ¯å¦ä¸ºæåä¸ä¸ªèç¹") @TableField(exist = false) private Boolean isLast; /** * æ¯å¦ä¸ºå½åå®¡æ ¸èç¹ */ @ApiModelProperty(value = "å½åç¨æ·æ¯å¦å¯å®¡æ ¸") @TableField(exist = false) private Boolean isShen = false; @@ -88,44 +98,67 @@ * ç§æ·id */ // @TableField(fill = FieldFill.INSERT) @ApiModelProperty(value = "ç§æ·ID") private Long tenantId; /** * å 餿 è®°:0æ£å¸¸ï¼1å é¤ */ @ApiModelProperty(value = "å 餿 å¿ï¼0æ£å¸¸ï¼1å é¤") private Integer deleteFlag; /** * å ¥åºç¨æ·id */ @ApiModelProperty(value = "åå»ºç¨æ·ID") private Long createUser; /** * å ¥åºæ¶é´ */ @ApiModelProperty(value = "å建æ¶é´") private LocalDateTime createTime; /** * ä¿®æ¹è */ @ApiModelProperty(value = "æ´æ°ç¨æ·ID") private Long updateUser; /** * ä¿®æ¹æ¶é´ */ @ApiModelProperty(value = "æ´æ°æ¶é´") private LocalDateTime updateTime; /** * 审æ¹èç¹æç»åå */ @ApiModelProperty(value = "审æ¹å¤çåå ") private String approveNodeReason; /** * 审æ¹èç¹å¤æ³¨ */ @ApiModelProperty(value = "审æ¹èç¹å¤æ³¨") private String approveNodeRemark; @ApiModelProperty(value = "审æ¹èç¹åç§°") private String approveNodeName; @ApiModelProperty(value = "æ¡ä»¶å段") private String conditionField; @ApiModelProperty(value = "æ¡ä»¶æä½ç¬¦") private String conditionOperator; @ApiModelProperty(value = "æ¡ä»¶å¼") private String conditionValue; @ApiModelProperty(value = "æ¯å¦ä¸ºå½åèç¹ï¼0å¦ï¼1æ¯") private Integer isCurrent; private static final long serialVersionUID = 1L; } } src/main/java/com/ruoyi/approve/pojo/ApproveProcess.java
@@ -4,6 +4,7 @@ import java.time.LocalDateTime; import java.util.Date; import java.util.List; import java.math.BigDecimal; import com.baomidou.mybatisplus.annotation.*; import com.fasterxml.jackson.annotation.JsonFormat; @@ -24,9 +25,11 @@ /** * */ @ApiModelProperty(value = "主é®ID") @TableId(type = IdType.AUTO) private Long id; @ApiModelProperty(value = "éä»¶å表") @TableField(exist = false) private List<CommonFile> commonFileList; @@ -40,6 +43,7 @@ /** * ç³è¯·äººid */ @ApiModelProperty(value = "ç³è¯·äººID") private Long approveUser; /** @@ -52,6 +56,7 @@ /** * ç³è¯·é¨é¨id */ @ApiModelProperty(value = "ç³è¯·é¨é¨ID") private Long approveDeptId; /** @@ -64,11 +69,13 @@ /** * 审æ¹ç¨æ·ids */ @ApiModelProperty(value = "审æ¹ç¨æ·IDå表ï¼å¤ä¸ªä»¥éå·åé") private String approveUserIds; /** * 审æ¹ç¨æ·åç§° */ @ApiModelProperty(value = "审æ¹ç¨æ·åç§°å表") private String approveUserNames; /** @@ -81,6 +88,7 @@ /** * å½å审æ¹ç¨æ·ID */ @ApiModelProperty(value = "å½å审æ¹ç¨æ·ID") private Long approveUserCurrentId; /** @@ -116,17 +124,20 @@ /** * å®¡æ¹æ¯å¦å é¤ï¼0æ£å¸¸ï¼1å é¤ */ @ApiModelProperty(value = "å 餿 å¿ï¼0æ£å¸¸ï¼1å é¤") private Integer approveDelete; /** * ç§æ·id */ // @TableField(fill = FieldFill.INSERT) @ApiModelProperty(value = "ç§æ·ID") private Long tenantId; /** * 审æ¹ç±»å */ @ApiModelProperty(value = "审æ¹ç±»åï¼1èªç±ååï¼2请åï¼3éå®ï¼4æ¥éï¼5éè´ï¼6æ¥ä»·ï¼7åºåº") private Integer approveType; /** @@ -135,12 +146,34 @@ @ApiModelProperty(value = "审æ¹å¤æ³¨") private String approveRemark; @ApiModelProperty(value = "å ³èä¸å¡ä¸»é®") private Long businessId; @ApiModelProperty(value = "ä¸å¡ç¼å·") private String businessNo; @ApiModelProperty(value = "审æ¹ä¸å¡æ é¢") private String businessTitle; @ApiModelProperty(value = "ä¸å¡éé¢") private BigDecimal amount; @ApiModelProperty(value = "ä¸å¡æ°æ®JSONå¿«ç §") private String businessData; @ApiModelProperty(value = "æµç¨å®ä¹ID") private Long flowDefinitionId; /** * å建æ¶é´ */ @ApiModelProperty(value = "å建æ¶é´") private LocalDateTime createTime; @ApiModelProperty(value = "æ´æ°æ¶é´") private LocalDateTime updateTime; private static final long serialVersionUID = 1L; } } src/main/java/com/ruoyi/approve/service/IApproveNodeService.java
@@ -2,6 +2,7 @@ import com.baomidou.mybatisplus.extension.service.IService; import com.ruoyi.approve.pojo.ApproveNode; import com.ruoyi.approve.vo.ApproveNodeVO; import java.io.IOException; import java.util.List; @@ -9,6 +10,7 @@ public interface IApproveNodeService extends IService<ApproveNode> { void initApproveNodes(String approveUserIds,String approveID,Long tenantId); void initApproveNodes(List<ApproveNodeVO> nodes, String approveID, Long tenantId); /** * 详æ * @param id @@ -17,5 +19,5 @@ void updateApproveNode(ApproveNode approveNode) throws IOException; void delApproveNodeByApproveId(Long id); void delApproveNodeByApproveId(String id); } src/main/java/com/ruoyi/approve/service/IApproveProcessService.java
@@ -27,7 +27,7 @@ IPage<ApproveProcess> listAll(Page page, ApproveProcess approveProcess); void delApprove(Long[] ids); void delApprove(String[] ids); void updateByApproveId(ApproveGetAndUpdateVo approveGetAndUpdateVo) throws IOException; src/main/java/com/ruoyi/approve/service/impl/ApproveNodeServiceImpl.java
@@ -3,11 +3,14 @@ import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import com.ruoyi.approve.mapper.ApproveLogMapper; import com.ruoyi.approve.mapper.ApproveNodeMapper; import com.ruoyi.approve.mapper.ApproveProcessMapper; import com.ruoyi.approve.pojo.ApproveLog; import com.ruoyi.approve.pojo.ApproveNode; import com.ruoyi.approve.pojo.ApproveProcess; import com.ruoyi.approve.service.IApproveNodeService; import com.ruoyi.approve.vo.ApproveNodeVO; import com.ruoyi.common.enums.FileNameType; import com.ruoyi.common.utils.SecurityUtils; import com.ruoyi.other.service.impl.TempFileServiceImpl; @@ -15,14 +18,16 @@ import com.ruoyi.project.system.mapper.SysUserMapper; import com.ruoyi.sales.mapper.CommonFileMapper; import com.ruoyi.sales.pojo.CommonFile; import com.ruoyi.sales.service.impl.CommonFileServiceImpl; import lombok.RequiredArgsConstructor; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import org.springframework.util.CollectionUtils; import org.springframework.util.StringUtils; import java.io.IOException; import java.math.BigDecimal; import java.time.LocalDateTime; import java.util.ArrayList; import java.util.Comparator; import java.util.Date; import java.util.List; @@ -30,142 +35,215 @@ @Service @RequiredArgsConstructor public class ApproveNodeServiceImpl extends ServiceImpl<ApproveNodeMapper, ApproveNode> implements IApproveNodeService { private final ApproveNodeMapper approveNodeMapper; private final ApproveProcessMapper approveProcessMapper; private final ApproveLogMapper approveLogMapper; private final SysUserMapper sysUserMapper; private final TempFileServiceImpl tempFileService; private final CommonFileMapper fileMapper; @Autowired private ApproveNodeMapper approveNodeMapper; @Autowired private ApproveProcessMapper approveProcessMapper; @Autowired private SysUserMapper sysUserMapper; @Autowired private TempFileServiceImpl tempFileService; @Autowired private CommonFileMapper fileMapper; public ApproveProcess getApproveById(String id) { LambdaQueryWrapper<ApproveProcess> queryWrapper = new LambdaQueryWrapper<>(); queryWrapper.eq(ApproveProcess::getApproveId, id); queryWrapper.eq(ApproveProcess::getApproveDelete, 0); queryWrapper.eq(ApproveProcess::getTenantId, SecurityUtils.getLoginUser().getTenantId()); queryWrapper.last("limit 1"); ApproveProcess one = approveProcessMapper.selectOne(queryWrapper); return one; private ApproveProcess getApproveById(String code) { ApproveProcess process = approveProcessMapper.selectOne(new LambdaQueryWrapper<ApproveProcess>() .eq(ApproveProcess::getApproveId, code) .eq(ApproveProcess::getApproveDelete, 0) .eq(ApproveProcess::getTenantId, tenantId()) .last("limit 1")); if (process == null) throw new RuntimeException("审æ¹ä¸åå¨"); return process; } @Override public void initApproveNodes(String approveUserIds,String approveID,Long tenantId) { Long userId = SecurityUtils.getLoginUser().getUser().getUserId(); ApproveProcess approve = getApproveById(approveID); String[] names = approveUserIds.split(","); String approveId = approve.getApproveId(); for (int i = 0; i < names.length; i++) { SysUser sysUser = sysUserMapper.selectUserById(Long.parseLong(names[i])); if (sysUser == null) continue; ApproveNode approveNode = new ApproveNode(); approveNode.setApproveProcessId(approveId); approveNode.setApproveNodeOrder(i +1); approveNode.setApproveNodeUser(sysUser.getNickName()); approveNode.setApproveNodeUserId(sysUser.getUserId()); approveNode.setApproveNodeTime(new Date()); approveNode.setApproveNodeStatus(0); approveNode.setTenantId(tenantId); approveNode.setDeleteFlag(0); approveNode.setCreateUser(userId); approveNode.setUpdateUser(userId); approveNode.setCreateTime(LocalDateTime.now()); approveNode.setUpdateTime(LocalDateTime.now()); approveNodeMapper.insert(approveNode); public void initApproveNodes(String approveUserIds, String approveID, Long tenantId) { if (!StringUtils.hasText(approveUserIds)) throw new RuntimeException("è¯·éæ©å®¡æ¹äºº"); List<ApproveNodeVO> nodes = new ArrayList<>(); for (String id : approveUserIds.split(",")) { ApproveNodeVO node = new ApproveNodeVO(); node.setUserId(Long.parseLong(id.trim())); node.setConditionOperator("ALWAYS"); nodes.add(node); } initApproveNodes(nodes, approveID, tenantId); } @Override public void initApproveNodes(List<ApproveNodeVO> nodes, String approveID, Long ignoredTenantId) { if (CollectionUtils.isEmpty(nodes)) throw new RuntimeException("å®¡æ¹æµç¨è³å°å å«ä¸ä¸ªèç¹"); Long tenantId = tenantId(); Long currentUserId = SecurityUtils.getUserId(); ApproveProcess process = getApproveById(approveID); int order = 1; ApproveNode first = null; Long previousUserId = null; for (ApproveNodeVO request : nodes) { if (request.getUserId() == null) throw new RuntimeException("审æ¹äººä¸è½ä¸ºç©º"); if (request.getUserId().equals(previousUserId)) throw new RuntimeException("ç¸é»å®¡æ¹èç¹ä¸è½éæ©åä¸å®¡æ¹äºº"); previousUserId = request.getUserId(); if (!matchesCondition(process.getAmount(), request)) continue; SysUser user = sysUserMapper.selectUserById(request.getUserId()); if (user == null || !tenantId.equals(user.getTenantId())) throw new RuntimeException("审æ¹äººä¸å卿ä¸å±äºå½åç§æ·"); ApproveNode node = new ApproveNode(); node.setApproveProcessId(process.getApproveId()); node.setApproveNodeOrder(order++); node.setApproveNodeName(StringUtils.hasText(request.getNodeName()) ? request.getNodeName() : "审æ¹"); node.setApproveNodeUser(user.getNickName()); node.setApproveNodeUserId(user.getUserId()); node.setApproveNodeStatus(0); node.setConditionField(request.getConditionField()); node.setConditionOperator(StringUtils.hasText(request.getConditionOperator()) ? request.getConditionOperator() : "ALWAYS"); node.setConditionValue(request.getConditionValue()); node.setIsCurrent(first == null ? 1 : 0); node.setTenantId(tenantId); node.setDeleteFlag(0); node.setCreateUser(currentUserId); node.setUpdateUser(currentUserId); node.setCreateTime(LocalDateTime.now()); node.setUpdateTime(LocalDateTime.now()); approveNodeMapper.insert(node); if (first == null) first = node; } if (first == null) throw new RuntimeException("æ²¡ææ»¡è¶³æ¡ä»¶ç审æ¹èç¹"); process.setApproveUserCurrentId(first.getApproveNodeUserId()); process.setApproveUserCurrentName(first.getApproveNodeUser()); process.setUpdateTime(LocalDateTime.now()); approveProcessMapper.updateById(process); } private boolean matchesCondition(BigDecimal amount, ApproveNodeVO node) { String operator = node.getConditionOperator(); if (!StringUtils.hasText(operator) || "ALWAYS".equalsIgnoreCase(operator)) return true; if (!"amount".equals(node.getConditionField())) throw new RuntimeException("å®¡æ¹æ¡ä»¶ä» æ¯æéé¢å段"); if (amount == null || !StringUtils.hasText(node.getConditionValue())) return false; try { if ("BETWEEN".equalsIgnoreCase(operator)) { String[] values = node.getConditionValue().replace("[", "").replace("]", "").split(","); if (values.length != 2) throw new RuntimeException("éé¢åºé´æ ¼å¼ä¸æ£ç¡®"); return amount.compareTo(new BigDecimal(values[0].trim())) >= 0 && amount.compareTo(new BigDecimal(values[1].trim())) <= 0; } int compared = amount.compareTo(new BigDecimal(node.getConditionValue())); if ("GT".equalsIgnoreCase(operator)) return compared > 0; if ("GTE".equalsIgnoreCase(operator)) return compared >= 0; if ("LT".equalsIgnoreCase(operator)) return compared < 0; if ("LTE".equalsIgnoreCase(operator)) return compared <= 0; if ("EQ".equalsIgnoreCase(operator)) return compared == 0; } catch (NumberFormatException ex) { throw new RuntimeException("å®¡æ¹æ¡ä»¶é颿 ¼å¼ä¸æ£ç¡®"); } throw new RuntimeException("䏿¯æçå®¡æ¹æ¡ä»¶æä½ç¬¦"); } @Override public List<ApproveNode> details(String id) { LambdaQueryWrapper<ApproveNode> queryWrapper = new LambdaQueryWrapper<>(); queryWrapper.eq(ApproveNode::getApproveProcessId, id); queryWrapper.eq(ApproveNode::getDeleteFlag, 0); queryWrapper.eq(ApproveNode::getTenantId, SecurityUtils.getLoginUser().getTenantId()); List<ApproveNode> list = list(queryWrapper); // æç § approveNodeOrder åæ®µååºæåº list.sort(Comparator.comparingInt(ApproveNode::getApproveNodeOrder)); LambdaQueryWrapper<ApproveProcess> approveProcessLambdaQueryWrapper = new LambdaQueryWrapper<>(); approveProcessLambdaQueryWrapper.eq(ApproveProcess::getApproveId, id) .eq(ApproveProcess::getApproveDelete, 0) .eq(ApproveProcess::getTenantId, SecurityUtils.getLoginUser().getTenantId()) .last("limit 1"); ApproveProcess approveProcess = approveProcessMapper.selectOne(approveProcessLambdaQueryWrapper); if(approveProcess != null && approveProcess.getApproveStatus() == 3){ return list; } for (ApproveNode approveNode : list) { List<CommonFile> commonFiles = fileMapper.selectList(new LambdaQueryWrapper<CommonFile>() .eq(CommonFile::getCommonId, approveNode.getId()) .eq(CommonFile::getType, FileNameType.ApproveNode.getValue())); if(!CollectionUtils.isEmpty(commonFiles)){ approveNode.setUrl(commonFiles.get(0).getUrl()); } if(approveNode.getApproveNodeStatus() == 1){ continue; } approveNode.setIsShen(true); break; } return list; } public void updateApproveProcessStatus(ApproveNode approveNode,Integer status) throws IOException { LambdaQueryWrapper<ApproveProcess> approveProcessLambdaQueryWrapper = new LambdaQueryWrapper<>(); approveProcessLambdaQueryWrapper.eq(ApproveProcess::getApproveId, approveNode.getApproveProcessId()) .eq(ApproveProcess::getApproveDelete, 0) .eq(ApproveProcess::getTenantId, SecurityUtils.getLoginUser().getTenantId()) .last("limit 1"); ApproveProcess approveProcess = approveProcessMapper.selectOne(approveProcessLambdaQueryWrapper); if(approveProcess == null) throw new RuntimeException("审æ¹ä¸åå¨"); LambdaQueryWrapper<ApproveNode> approveNodeLambdaQueryWrapper = new LambdaQueryWrapper<>(); approveNodeLambdaQueryWrapper.eq(ApproveNode::getApproveProcessId, approveNode.getApproveProcessId()) .eq(ApproveNode::getApproveNodeOrder, approveNode.getApproveNodeOrder() + 1) getApproveById(id); List<ApproveNode> nodes = approveNodeMapper.selectList(new LambdaQueryWrapper<ApproveNode>() .eq(ApproveNode::getApproveProcessId, id) .eq(ApproveNode::getDeleteFlag, 0) .eq(ApproveNode::getTenantId, SecurityUtils.getLoginUser().getTenantId()) .last("limit 1"); ApproveNode approveNode1 = approveNodeMapper.selectOne(approveNodeLambdaQueryWrapper); approveProcess.setApproveStatus(status); if(approveNode1 != null){ approveProcess.setApproveUserCurrentId(approveNode1.getApproveNodeUserId()); approveProcess.setApproveUserCurrentName(approveNode1.getApproveNodeUser()); .eq(ApproveNode::getTenantId, tenantId()) .orderByAsc(ApproveNode::getApproveNodeOrder)); for (ApproveNode node : nodes) { List<CommonFile> files = fileMapper.selectList(new LambdaQueryWrapper<CommonFile>() .eq(CommonFile::getCommonId, node.getId()) .eq(CommonFile::getType, FileNameType.ApproveNode.getValue())); if (!CollectionUtils.isEmpty(files)) node.setUrl(files.get(0).getUrl()); node.setIsShen(Integer.valueOf(1).equals(node.getIsCurrent()) && node.getApproveNodeUserId().equals(SecurityUtils.getUserId())); } approveProcessMapper.updateById(approveProcess); nodes.sort(Comparator.comparingInt(ApproveNode::getApproveNodeOrder)); return nodes; } // ç»å®éä»¶ if(!CollectionUtils.isEmpty(approveNode.getTempFileIds()) && approveNode.getApproveNodeStatus() == 1){ tempFileService.migrateTempFilesToFormal(approveNode.getId(), approveNode.getTempFileIds(), FileNameType.ApproveNode.getValue()); @Override @Transactional(rollbackFor = Exception.class) public void updateApproveNode(ApproveNode request) throws IOException { if (request == null || request.getId() == null) throw new RuntimeException("审æ¹èç¹ä¸è½ä¸ºç©º"); if (request.getApproveNodeStatus() == null || (request.getApproveNodeStatus() != 1 && request.getApproveNodeStatus() != 2)) { throw new RuntimeException("审æ¹ç»æä¸æ£ç¡®"); } if (!StringUtils.hasText(request.getApproveNodeReason())) throw new RuntimeException("å®¡æ¹æè§ä¸è½ä¸ºç©º"); Long tenantId = tenantId(); ApproveNode node = approveNodeMapper.selectOne(new LambdaQueryWrapper<ApproveNode>() .eq(ApproveNode::getId, request.getId()) .eq(ApproveNode::getTenantId, tenantId) .eq(ApproveNode::getDeleteFlag, 0)); if (node == null) throw new RuntimeException("审æ¹èç¹ä¸åå¨"); if (!Integer.valueOf(0).equals(node.getApproveNodeStatus()) || !Integer.valueOf(1).equals(node.getIsCurrent())) { throw new RuntimeException("该èç¹å·²ç»å¤çæä¸æ¯å½å审æ¹èç¹"); } if (!SecurityUtils.getUserId().equals(node.getApproveNodeUserId())) throw new RuntimeException("å½åç¨æ·æ æå®¡æ¹æ¤èç¹"); ApproveProcess process = getApproveById(node.getApproveProcessId()); if (Integer.valueOf(2).equals(process.getApproveStatus()) || Integer.valueOf(3).equals(process.getApproveStatus())) { throw new RuntimeException("å®¡æ¹æµç¨å·²ç»ç»æ"); } node.setApproveNodeStatus(request.getApproveNodeStatus()); node.setApproveNodeReason(request.getApproveNodeReason().trim()); node.setApproveNodeRemark(request.getApproveNodeRemark()); node.setApproveNodeTime(new Date()); node.setIsCurrent(0); node.setUpdateUser(SecurityUtils.getUserId()); node.setUpdateTime(LocalDateTime.now()); approveNodeMapper.updateById(node); if (node.getApproveNodeStatus() == 2) { process.setApproveStatus(3); process.setApproveUserCurrentId(null); process.setApproveUserCurrentName(null); process.setApproveOverTime(new Date()); } else { ApproveNode next = approveNodeMapper.selectOne(new LambdaQueryWrapper<ApproveNode>() .eq(ApproveNode::getApproveProcessId, node.getApproveProcessId()) .eq(ApproveNode::getTenantId, tenantId) .eq(ApproveNode::getDeleteFlag, 0) .eq(ApproveNode::getApproveNodeStatus, 0) .gt(ApproveNode::getApproveNodeOrder, node.getApproveNodeOrder()) .orderByAsc(ApproveNode::getApproveNodeOrder) .last("limit 1")); if (next == null) { process.setApproveStatus(2); process.setApproveOverTime(new Date()); process.setApproveUserCurrentId(null); process.setApproveUserCurrentName(null); } else { next.setIsCurrent(1); next.setUpdateTime(LocalDateTime.now()); approveNodeMapper.updateById(next); process.setApproveStatus(1); process.setApproveUserCurrentId(next.getApproveNodeUserId()); process.setApproveUserCurrentName(next.getApproveNodeUser()); } } process.setUpdateTime(LocalDateTime.now()); approveProcessMapper.updateById(process); ApproveLog log = new ApproveLog(); log.setApproveId(process.getId()); log.setApproveProcessId(process.getId()); log.setApproveNodeId(node.getId()); log.setApproveNodeOrder(node.getApproveNodeOrder()); log.setApproveUser(SecurityUtils.getUserId()); log.setApproveUserName(node.getApproveNodeUser()); log.setApproveTime(new Date()); log.setApproveStatus(node.getApproveNodeStatus()); log.setApproveRemark(node.getApproveNodeReason()); log.setTenantId(tenantId); approveLogMapper.insert(log); if (!CollectionUtils.isEmpty(request.getTempFileIds()) && node.getApproveNodeStatus() == 1) { tempFileService.migrateTempFilesToFormal(node.getId(), request.getTempFileIds(), FileNameType.ApproveNode.getValue()); } } @Override public void updateApproveNode(ApproveNode approveNode) throws IOException { // 审æ¹èç¹ç¶æ:1åæï¼2æç»ï¼0å°æªå®¡æ ¸ switch (approveNode.getApproveNodeStatus()){ case 1: updateApproveProcessStatus(approveNode, Boolean.TRUE.equals(approveNode.getIsLast()) ? 2 : 1); break; case 2: updateApproveProcessStatus(approveNode, 3); break; default: break; } approveNode.setApproveNodeTime(new Date()); approveNodeMapper.updateById(approveNode); public void delApproveNodeByApproveId(String id) { UpdateWrapper<ApproveNode> wrapper = new UpdateWrapper<>(); wrapper.lambda().set(ApproveNode::getDeleteFlag, 1) .set(ApproveNode::getIsCurrent, 0) .eq(ApproveNode::getApproveProcessId, id) .eq(ApproveNode::getTenantId, tenantId()); update(wrapper); } @Override public void delApproveNodeByApproveId(Long id) { UpdateWrapper<ApproveNode> queryWrapper = new UpdateWrapper<>(); queryWrapper.lambda().set(ApproveNode::getDeleteFlag, 1) .eq(ApproveNode::getApproveProcessId, id); update(queryWrapper); private Long tenantId() { return SecurityUtils.getLoginUser().getTenantId(); } } src/main/java/com/ruoyi/approve/service/impl/ApproveProcessServiceImpl.java
@@ -5,14 +5,22 @@ import com.baomidou.mybatisplus.core.metadata.IPage; import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.ObjectMapper; import com.ruoyi.approve.enums.ApproveType; import com.ruoyi.approve.mapper.ApproveFlowDefinitionMapper; import com.ruoyi.approve.mapper.ApproveFlowNodeDefinitionMapper; import com.ruoyi.approve.mapper.ApproveNodeMapper; import com.ruoyi.approve.mapper.ApproveProcessMapper; import com.ruoyi.approve.pojo.ApproveFlowDefinition; import com.ruoyi.approve.pojo.ApproveFlowNodeDefinition; import com.ruoyi.approve.pojo.ApproveNode; import com.ruoyi.approve.pojo.ApproveProcess; import com.ruoyi.approve.service.IApproveNodeService; import com.ruoyi.approve.service.IApproveProcessService; import com.ruoyi.approve.utils.DailyRedisCounter; import com.ruoyi.approve.vo.ApproveGetAndUpdateVo; import com.ruoyi.approve.vo.ApproveNodeVO; import com.ruoyi.approve.vo.ApproveProcessVO; import com.ruoyi.common.enums.FileNameType; import com.ruoyi.common.utils.SecurityUtils; @@ -22,12 +30,10 @@ import com.ruoyi.project.system.mapper.SysDeptMapper; import com.ruoyi.project.system.mapper.SysUserMapper; import com.ruoyi.sales.mapper.CommonFileMapper; import com.ruoyi.sales.mapper.SalesLedgerMapper; import com.ruoyi.sales.pojo.CommonFile; import lombok.AllArgsConstructor; import com.ruoyi.sales.pojo.SalesLedger; import lombok.RequiredArgsConstructor; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.Lazy; import org.springframework.data.redis.core.StringRedisTemplate; import org.springframework.stereotype.Service; import org.springframework.util.CollectionUtils; import org.springframework.util.StringUtils; @@ -41,7 +47,9 @@ import java.util.ArrayList; import java.util.Arrays; import java.util.Date; import java.util.LinkedHashMap; import java.util.List; import java.util.Map; import java.util.stream.Collectors; @Service @@ -49,174 +57,270 @@ public class ApproveProcessServiceImpl extends ServiceImpl<ApproveProcessMapper, ApproveProcess> implements IApproveProcessService { private static final DateTimeFormatter DATE_FORMAT = DateTimeFormatter.ofPattern("yyyyMMdd"); private final StringRedisTemplate redisTemplate; private final DailyRedisCounter dailyRedisCounter; private final SysDeptMapper sysDeptMapper; private final IApproveNodeService approveNodeService; private final SysUserMapper sysUserMapper; private final ApproveProcessMapper approveProcessMapper; private final ApproveNodeMapper approveNodeMapper; private final TempFileServiceImpl tempFileService; private final CommonFileMapper commonFileMapper; private final SalesLedgerMapper salesLedgerMapper; private final ApproveFlowDefinitionMapper flowDefinitionMapper; private final ApproveFlowNodeDefinitionMapper flowNodeDefinitionMapper; private final ObjectMapper objectMapper; @Override public void addApprove(ApproveProcessVO approveProcessVO) throws Exception { SysUser sysUser = sysUserMapper.selectUserById(approveProcessVO.getApproveUser()); SysDept sysDept = sysDeptMapper.selectDeptById(approveProcessVO.getApproveDeptId()); String[] split = approveProcessVO.getApproveUserIds().split(","); List<Long> longList = Arrays.stream(split) .map(Long::valueOf) // å°æ¯ä¸ª String 转æ¢ä¸º Long .collect(Collectors.toList()); List<SysUser> sysUsers = sysUserMapper.selectUserByIds(longList); if(CollectionUtils.isEmpty(sysUsers)) throw new RuntimeException("å®¡æ ¸ç¨æ·ä¸åå¨"); if(sysDept == null) throw new RuntimeException("é¨é¨ä¸åå¨"); if(sysUser == null) throw new RuntimeException("ç³è¯·äººä¸åå¨"); String today = LocalDate.now().format(DATE_FORMAT); Long approveId = dailyRedisCounter.incrementAndGetByDb(); String formattedCount = String.format("%03d", approveId); //æµç¨ ID String approveID = today + formattedCount; SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd"); ApproveProcess approveProcess = new ApproveProcess(); approveProcess.setApproveId(approveID); approveProcess.setApproveUser(approveProcessVO.getApproveUser()); approveProcess.setApproveUserName(sysUser.getNickName()); approveProcess.setApproveDeptId(approveProcessVO.getApproveDeptId()); approveProcess.setApproveDeptName(sysDept.getDeptName()); approveProcess.setApproveUserNames(sysUsers.stream().map(SysUser::getNickName).collect(Collectors.joining(","))); approveProcess.setApproveTime(StringUtils.isEmpty(approveProcessVO.getApproveTime()) ? null : dateFormat.parse(approveProcessVO.getApproveTime())); approveProcess.setApproveReason(approveProcessVO.getApproveReason()); approveProcess.setApproveOverTime(null); approveProcess.setApproveStatus(0); approveProcess.setApproveDelete(0); approveProcess.setApproveType(approveProcessVO.getApproveType()); approveProcess.setCreateTime(LocalDateTime.now()); approveProcess.setTenantId(approveProcessVO.getApproveDeptId()); approveProcess.setApproveUserIds(approveProcessVO.getApproveUserIds()); approveProcess.setApproveUserCurrentId(longList.get(0)); approveProcess.setApproveUserCurrentName(sysUsers .stream() .filter(SysUser -> SysUser.getUserId().equals(longList.get(0))) .collect(Collectors.toList()) .get(0) .getNickName()); // è®¾ç½®ç¶æä¸ºéæ°æäº¤ if(approveProcessVO.getId() != null){ ApproveProcess approveProcess1 = approveProcessMapper.selectById(approveProcessVO.getId()); approveProcess1.setApproveStatus(4); approveProcessMapper.updateById(approveProcess1); public void addApprove(ApproveProcessVO request) throws Exception { if (request == null || request.getApproveType() == null) throw new RuntimeException("审æ¹ç±»åä¸è½ä¸ºç©º"); ApproveType type = ApproveType.fromCode(request.getApproveType()); Long tenantId = tenantId(); SysUser applicant = SecurityUtils.getLoginUser().getUser(); Long deptId = resolveDeptId(request.getApproveDeptId()); SysDept dept = sysDeptMapper.selectDeptById(deptId); if (dept == null) throw new RuntimeException("ç³è¯·é¨é¨ä¸åå¨"); List<ApproveNodeVO> nodes = resolveNodes(request, tenantId); List<SysUser> approvers = validateApprovers(nodes, tenantId); prepareBusinessData(request, type, tenantId); String approveCode = LocalDate.now().format(DATE_FORMAT) + String.format("%03d", dailyRedisCounter.incrementAndGetByDb()); ApproveProcess process = new ApproveProcess(); process.setApproveId(approveCode); process.setApproveUser(applicant.getUserId()); process.setApproveUserName(applicant.getNickName()); process.setApproveDeptId(deptId); process.setApproveDeptName(dept.getDeptName()); process.setApproveUserIds(nodes.stream().map(item -> String.valueOf(item.getUserId())).collect(Collectors.joining(","))); process.setApproveUserNames(approvers.stream().map(SysUser::getNickName).collect(Collectors.joining(","))); process.setApproveTime(parseDate(request.getApproveTime())); process.setApproveReason(request.getApproveReason()); process.setApproveStatus(0); process.setApproveDelete(0); process.setApproveType(type.getCode()); process.setTenantId(tenantId); process.setBusinessId(request.getBusinessId()); process.setBusinessNo(request.getBusinessNo()); process.setBusinessTitle(request.getBusinessTitle()); process.setAmount(request.getAmount()); process.setBusinessData(request.getBusinessData()); process.setFlowDefinitionId(request.getFlowDefinitionId()); process.setCreateTime(LocalDateTime.now()); process.setUpdateTime(LocalDateTime.now()); approveProcessMapper.insert(process); approveNodeService.initApproveNodes(nodes, approveCode, tenantId); tempFileService.migrateTempFilesToFormal(process.getId(), request.getTempFileIds(), FileNameType.ApproveProcess.getValue()); } private void prepareBusinessData(ApproveProcessVO request, ApproveType type, Long tenantId) throws JsonProcessingException { if (type == ApproveType.SALES_CONTRACT) { if (request.getBusinessId() == null) throw new RuntimeException("è¯·éæ©éå®åå"); SalesLedger ledger = salesLedgerMapper.selectById(request.getBusinessId()); if (ledger == null || !tenantId.equals(ledger.getTenantId())) throw new RuntimeException("éå®ååä¸å卿ä¸å±äºå½åç§æ·"); Long duplicate = approveProcessMapper.selectCount(new LambdaQueryWrapper<ApproveProcess>() .eq(ApproveProcess::getTenantId, tenantId) .eq(ApproveProcess::getApproveType, ApproveType.SALES_CONTRACT.getCode()) .eq(ApproveProcess::getBusinessId, ledger.getId()) .in(ApproveProcess::getApproveStatus, Arrays.asList(0, 1)) .eq(ApproveProcess::getApproveDelete, 0)); if (duplicate != null && duplicate > 0) throw new RuntimeException("该éå®ååå·²æå¾ 审æµç¨"); Map<String, Object> snapshot = new LinkedHashMap<>(); snapshot.put("salesLedgerId", ledger.getId()); snapshot.put("salesContractNo", ledger.getSalesContractNo()); snapshot.put("customerContractNo", ledger.getCustomerContractNo()); snapshot.put("customerName", ledger.getCustomerName()); snapshot.put("projectName", ledger.getProjectName()); snapshot.put("salesman", ledger.getSalesman()); snapshot.put("contractAmount", ledger.getContractAmount()); snapshot.put("executionDate", ledger.getExecutionDate()); snapshot.put("paymentMethod", ledger.getPaymentMethod()); snapshot.put("remarks", ledger.getRemarks()); request.setBusinessNo(ledger.getSalesContractNo()); request.setBusinessTitle(StringUtils.hasText(request.getBusinessTitle()) ? request.getBusinessTitle() : "éå®åå审æ¹-" + ledger.getSalesContractNo()); request.setAmount(ledger.getContractAmount()); request.setBusinessData(objectMapper.writeValueAsString(snapshot)); } else if (type == ApproveType.PURCHASE_PLAN || type == ApproveType.FREE_COLLABORATION) { if (!StringUtils.hasText(request.getBusinessTitle())) throw new RuntimeException("å®¡æ¹æ é¢ä¸è½ä¸ºç©º"); if (type == ApproveType.PURCHASE_PLAN && request.getAmount() == null) throw new RuntimeException("éè´é¢ç®éé¢ä¸è½ä¸ºç©º"); if (!StringUtils.hasText(request.getBusinessNo())) { String prefix = type == ApproveType.PURCHASE_PLAN ? "CG" : "XT"; request.setBusinessNo(prefix + LocalDate.now().format(DATE_FORMAT) + String.format("%03d", dailyRedisCounter.incrementAndGetByDb())); } } save(approveProcess); //åå§å审æ¹èç¹ approveNodeService.initApproveNodes(approveProcessVO.getApproveUserIds(),approveID,approveProcessVO.getApproveDeptId()); // éä»¶ç»å® tempFileService.migrateTempFilesToFormal(approveProcess.getId(), approveProcessVO.getTempFileIds(), FileNameType.ApproveProcess.getValue()); } private List<ApproveNodeVO> resolveNodes(ApproveProcessVO request, Long tenantId) { if (!CollectionUtils.isEmpty(request.getNodes())) return request.getNodes(); if (request.getFlowDefinitionId() != null) { ApproveFlowDefinition definition = flowDefinitionMapper.selectOne(new LambdaQueryWrapper<ApproveFlowDefinition>() .eq(ApproveFlowDefinition::getId, request.getFlowDefinitionId()) .eq(ApproveFlowDefinition::getTenantId, tenantId) .eq(ApproveFlowDefinition::getApproveType, request.getApproveType()) .eq(ApproveFlowDefinition::getEnabled, 1) .eq(ApproveFlowDefinition::getDeleteFlag, 0)); if (definition == null) throw new RuntimeException("å®¡æ¹æµç¨å®ä¹ä¸å卿已åç¨"); List<ApproveFlowNodeDefinition> definitions = flowNodeDefinitionMapper.selectList( new LambdaQueryWrapper<ApproveFlowNodeDefinition>() .eq(ApproveFlowNodeDefinition::getFlowDefinitionId, definition.getId()) .eq(ApproveFlowNodeDefinition::getTenantId, tenantId) .eq(ApproveFlowNodeDefinition::getDeleteFlag, 0) .orderByAsc(ApproveFlowNodeDefinition::getNodeOrder)); List<ApproveNodeVO> result = new ArrayList<>(); for (ApproveFlowNodeDefinition item : definitions) { if (!"USER".equals(item.getApproverType()) || !StringUtils.hasText(item.getApproverValue())) { throw new RuntimeException("å½åé¢è®¾æµç¨å å«å°æªæå®ç审æ¹äºº"); } ApproveNodeVO node = new ApproveNodeVO(); node.setUserId(Long.valueOf(item.getApproverValue().split(",")[0].trim())); node.setNodeName(item.getNodeName()); node.setConditionField(item.getConditionField()); node.setConditionOperator(item.getConditionOperator()); node.setConditionValue(item.getConditionValue()); result.add(node); } if (!result.isEmpty()) return result; } if (!StringUtils.hasText(request.getApproveUserIds())) throw new RuntimeException("è¯·éæ©å®¡æ¹äºº"); List<ApproveNodeVO> result = new ArrayList<>(); for (String id : request.getApproveUserIds().split(",")) { ApproveNodeVO node = new ApproveNodeVO(); node.setUserId(Long.valueOf(id.trim())); node.setConditionOperator("ALWAYS"); result.add(node); } return result; } private List<SysUser> validateApprovers(List<ApproveNodeVO> nodes, Long tenantId) { List<SysUser> users = new ArrayList<>(); for (ApproveNodeVO node : nodes) { SysUser user = sysUserMapper.selectUserById(node.getUserId()); if (user == null || !tenantId.equals(user.getTenantId())) throw new RuntimeException("审æ¹äººä¸å卿ä¸å±äºå½åç§æ·"); users.add(user); } return users; } @Override public List<SysDept> selectDeptListByDeptIds(Long[] deptIds) { List<SysDept> sysDeptList =new ArrayList<SysDept>(); List<SysDept> departments = new ArrayList<>(); if (deptIds == null) return departments; for (Long deptId : deptIds) { SysDept sysDept = sysDeptMapper.selectDeptById(deptId); sysDeptList.add(sysDept); SysDept dept = sysDeptMapper.selectDeptById(deptId); if (dept != null) departments.add(dept); } return sysDeptList; return departments; } @Override public IPage<ApproveProcess> listAll(Page page,ApproveProcess approveProcess) { IPage<ApproveProcess> approveProcessIPage = approveProcessMapper.listPage(page,approveProcess); List<ApproveProcess> records = approveProcessIPage.getRecords(); for (ApproveProcess record : records) { List<CommonFile> commonFiles = commonFileMapper.selectList(new LambdaQueryWrapper<CommonFile>() .eq(CommonFile::getCommonId, record.getId()) .eq(CommonFile::getType, FileNameType.ApproveProcess.getValue())); record.setCommonFileList(commonFiles); } return approveProcessIPage; public IPage<ApproveProcess> listAll(Page page, ApproveProcess request) { request.setTenantId(tenantId()); IPage<ApproveProcess> result = approveProcessMapper.listPage(page, request); result.getRecords().forEach(record -> record.setCommonFileList(commonFileMapper.selectList( new LambdaQueryWrapper<CommonFile>() .eq(CommonFile::getCommonId, record.getId()) .eq(CommonFile::getType, FileNameType.ApproveProcess.getValue())))); return result; } @Override public void delApprove(Long[] ids) { for (Long id : ids) { UpdateWrapper<ApproveProcess> queryWrapper = new UpdateWrapper<>(); queryWrapper.lambda().set(ApproveProcess::getApproveDelete, 1) .eq(ApproveProcess::getApproveId, id); update(queryWrapper); // å é¤å ³èç审æ¹èç¹ approveNodeService.delApproveNodeByApproveId(id); public void delApprove(String[] ids) { if (ids == null) return; for (String code : ids) { ApproveProcess process = findOwnedByCode(code); if (!SecurityUtils.getUserId().equals(process.getApproveUser())) throw new RuntimeException("åªè½å 餿¬äººç³è¯·"); if (!(Integer.valueOf(0).equals(process.getApproveStatus()) || Integer.valueOf(3).equals(process.getApproveStatus()))) { throw new RuntimeException("å®¡æ ¸ä¸çæµç¨ä¸è½å é¤"); } UpdateWrapper<ApproveProcess> wrapper = new UpdateWrapper<>(); wrapper.lambda().set(ApproveProcess::getApproveDelete, 1) .set(ApproveProcess::getUpdateTime, LocalDateTime.now()) .eq(ApproveProcess::getApproveId, code) .eq(ApproveProcess::getTenantId, tenantId()); update(wrapper); approveNodeService.delApproveNodeByApproveId(code); } } @Override public ApproveProcess getApproveById(String id) { LambdaQueryWrapper<ApproveProcess> queryWrapper = new LambdaQueryWrapper<>(); queryWrapper.eq(ApproveProcess::getApproveId, id); queryWrapper.eq(ApproveProcess::getApproveDelete, 0); queryWrapper.eq(ApproveProcess::getTenantId, SecurityUtils.getLoginUser().getTenantId()); queryWrapper.last("limit 1"); ApproveProcess one = getOne(queryWrapper); one.setCommonFileList(commonFileMapper.selectList(new LambdaQueryWrapper<CommonFile>() .eq(CommonFile::getCommonId, one.getId()) ApproveProcess process = findOwnedByCode(id); process.setCommonFileList(commonFileMapper.selectList(new LambdaQueryWrapper<CommonFile>() .eq(CommonFile::getCommonId, process.getId()) .eq(CommonFile::getType, FileNameType.ApproveProcess.getValue()))); return one; return process; } private final ApproveNodeMapper approveNodeMapper; @Override public void updateByApproveId(ApproveGetAndUpdateVo approveGetAndUpdateVo) throws IOException { ApproveProcess approve = approveProcessMapper.selectById(approveGetAndUpdateVo.getId()); approve.setApproveUserIds(approveGetAndUpdateVo.getApproveUserIds()); approve.setApproveReason(approveGetAndUpdateVo.getApproveReason()); SysUser sysUser = sysUserMapper.selectUserById(approveGetAndUpdateVo.getApproveUser()); String[] split = approveGetAndUpdateVo.getApproveUserIds().split(","); if(split.length == 0){ throw new RuntimeException("è¯·éæ©å®¡æ¹äºº"); public void updateByApproveId(ApproveGetAndUpdateVo request) throws IOException { ApproveProcess process = approveProcessMapper.selectOne(new LambdaQueryWrapper<ApproveProcess>() .eq(ApproveProcess::getId, request.getId()) .eq(ApproveProcess::getTenantId, tenantId()) .eq(ApproveProcess::getApproveDelete, 0)); if (process == null) throw new RuntimeException("审æ¹ä¸åå¨"); if (!SecurityUtils.getUserId().equals(process.getApproveUser())) throw new RuntimeException("åªè½ç¼è¾æ¬äººç³è¯·"); if (!(Integer.valueOf(0).equals(process.getApproveStatus()) || Integer.valueOf(3).equals(process.getApproveStatus()))) { throw new RuntimeException("å½å审æ¹ç¶æä¸å 许ç¼è¾"); } List<SysUser> sysUsers = sysUserMapper.selectUserByIds(Arrays.asList(split).stream().map(Long::parseLong).collect(Collectors.toList())); if(CollectionUtils.isEmpty(sysUsers)) throw new RuntimeException("è¯·éæ©å®¡æ¹äºº"); if(sysUser == null) throw new RuntimeException("ç³è¯·äººä¸åå¨"); approve.setApproveUserName(sysUser.getNickName()); approve.setApproveUser(sysUser.getUserId()); //å®¡æ ¸ä¸ä¸å¯ä»¥ç¼è¾å®¡æ ¸äºº if(approve.getApproveStatus() != 1){ approve.setApproveUserCurrentId(Long.parseLong(split[0])); approve.setApproveUserCurrentName(sysUsers.stream().filter(user -> user.getUserId().equals(Long.parseLong(split[0]))).collect(Collectors.toList()).get(0).getNickName()); } updateById(approve); //ä¿®æ¹å®¡æ¹äºº // å å é¤ åæ°å¢ LambdaQueryWrapper<ApproveNode> approveNodeLambdaQueryWrapper = new LambdaQueryWrapper<>(); approveNodeLambdaQueryWrapper.eq(ApproveNode::getApproveProcessId, approve.getApproveId()) .eq(ApproveNode::getDeleteFlag, 0) .eq(ApproveNode::getTenantId, SecurityUtils.getLoginUser().getTenantId()) .orderByAsc(ApproveNode::getApproveNodeOrder); approveNodeMapper.delete(approveNodeLambdaQueryWrapper); approveNodeService.initApproveNodes(approveGetAndUpdateVo.getApproveUserIds(),approve.getApproveId(),approve.getTenantId()); process.setApproveReason(request.getApproveReason()); process.setBusinessTitle(request.getBusinessTitle()); process.setAmount(request.getAmount()); process.setBusinessData(request.getBusinessData()); process.setUpdateTime(LocalDateTime.now()); process.setApproveStatus(0); process.setApproveOverTime(null); approveProcessMapper.updateById(process); // int i = 0; // for (ApproveNode approveNode : list) { // int finalI = i; // if(i >= split.length){ // approveNode.setDeleteFlag(1); // }else{ // List<SysUser> collect = sysUsers.stream().filter(user -> user.getUserId().equals(Long.parseLong(split[finalI]))).collect(Collectors.toList()); // if(CollectionUtils.isEmpty(collect)){ // throw new RuntimeException("è¯·éæ©æ£ç¡®ç审æ¹äºº"); // } // approveNode.setApproveNodeUserId(collect.get(0).getUserId()); // approveNode.setApproveNodeUser(collect.get(0).getNickName()); // } // approveNodeMapper.updateById(approveNode); // i++; // } tempFileService.migrateTempFilesToFormal(approve.getId(), approveGetAndUpdateVo.getTempFileIds(), FileNameType.ApproveProcess.getValue()); List<ApproveNodeVO> nodes = request.getNodes(); if (CollectionUtils.isEmpty(nodes) && StringUtils.hasText(request.getApproveUserIds())) { nodes = new ArrayList<>(); for (String id : request.getApproveUserIds().split(",")) { ApproveNodeVO node = new ApproveNodeVO(); node.setUserId(Long.valueOf(id.trim())); node.setConditionOperator("ALWAYS"); nodes.add(node); } } if (!CollectionUtils.isEmpty(nodes)) { validateApprovers(nodes, tenantId()); UpdateWrapper<ApproveNode> oldNodes = new UpdateWrapper<>(); oldNodes.lambda().set(ApproveNode::getDeleteFlag, 1) .set(ApproveNode::getIsCurrent, 0) .eq(ApproveNode::getApproveProcessId, process.getApproveId()) .eq(ApproveNode::getTenantId, tenantId()); approveNodeMapper.update(null, oldNodes); approveNodeService.initApproveNodes(nodes, process.getApproveId(), tenantId()); } tempFileService.migrateTempFilesToFormal(process.getId(), request.getTempFileIds(), FileNameType.ApproveProcess.getValue()); } private ApproveProcess findOwnedByCode(String code) { ApproveProcess process = approveProcessMapper.selectOne(new LambdaQueryWrapper<ApproveProcess>() .eq(ApproveProcess::getApproveId, code) .eq(ApproveProcess::getApproveDelete, 0) .eq(ApproveProcess::getTenantId, tenantId()) .last("limit 1")); if (process == null) throw new RuntimeException("审æ¹ä¸åå¨"); return process; } private Long resolveDeptId(Long requested) { Long[] allowed = SecurityUtils.getDeptId(); if (requested == null) return SecurityUtils.getLoginUser().getCurrentDeptId(); if (allowed != null && Arrays.asList(allowed).contains(requested)) return requested; Long current = SecurityUtils.getLoginUser().getCurrentDeptId(); if (requested.equals(current)) return requested; throw new RuntimeException("æ æä½¿ç¨è¯¥ç³è¯·é¨é¨"); } private Date parseDate(String value) throws ParseException { return StringUtils.hasText(value) ? new SimpleDateFormat("yyyy-MM-dd").parse(value) : new Date(); } private Long tenantId() { return SecurityUtils.getLoginUser().getTenantId(); } } src/main/java/com/ruoyi/approve/vo/ApproveFlowDefinitionVO.java
¶Ô±ÈÐÂÎļþ @@ -0,0 +1,17 @@ package com.ruoyi.approve.vo; import com.ruoyi.approve.pojo.ApproveFlowDefinition; import com.ruoyi.approve.pojo.ApproveFlowNodeDefinition; import io.swagger.annotations.ApiModelProperty; import lombok.Data; import java.util.List; @Data public class ApproveFlowDefinitionVO { @ApiModelProperty(value = "æµç¨å®ä¹") private ApproveFlowDefinition definition; @ApiModelProperty(value = "æµç¨èç¹å®ä¹å表") private List<ApproveFlowNodeDefinition> nodes; } src/main/java/com/ruoyi/approve/vo/ApproveGetAndUpdateVo.java
@@ -1,31 +1,61 @@ package com.ruoyi.approve.vo; import com.ruoyi.sales.pojo.CommonFile; import io.swagger.annotations.ApiModelProperty; import lombok.Data; import javax.validation.constraints.NotBlank; import java.math.BigDecimal; import java.util.List; @Data public class ApproveGetAndUpdateVo { @ApiModelProperty(value = "临æ¶éä»¶IDå表") private List<String> tempFileIds; //审æ¹id @ApiModelProperty(value = "å®¡æ¹æµç¨ç¼å·") @NotBlank(message = "æµç¨ç¼å·ä¸è½ä¸ºç©º") private String id; //ç³è¯·äºç± @ApiModelProperty(value = "ç³è¯·äºç±") @NotBlank(message = "ç³è¯·äºç±ä¸è½ä¸ºç©º") private String approveReason; @ApiModelProperty(value = "审æ¹ç¨æ·IDå表ï¼å¤ä¸ªä»¥éå·åé") private String approveUserIds; @ApiModelProperty(value = "ç³è¯·ç¨æ·ID") private Long approveUser; @ApiModelProperty(value = "ç³è¯·æ¥æï¼æ ¼å¼ï¼yyyy-MM-dd") private String approveTime; @ApiModelProperty(value = "审æ¹ç¶æï¼0å¾ å®¡æ ¸ï¼1å®¡æ ¸ä¸ï¼2å®¡æ ¸å®æï¼3å®¡æ ¸æªéè¿ï¼4已鿰æäº¤") private Integer approveStatus; /** * 审æ¹ç±»å */ @ApiModelProperty(value = "审æ¹ç±»åï¼1èªç±ååï¼2请åï¼3éå®ï¼4æ¥éï¼5éè´ï¼6æ¥ä»·ï¼7åºåº") private Integer approveType; @ApiModelProperty(value = "å ³èä¸å¡ä¸»é®") private Long businessId; @ApiModelProperty(value = "ä¸å¡ç¼å·") private String businessNo; @ApiModelProperty(value = "审æ¹ä¸å¡æ é¢") private String businessTitle; @ApiModelProperty(value = "ä¸å¡éé¢") private BigDecimal amount; @ApiModelProperty(value = "ä¸å¡æ°æ®JSONå¿«ç §") private String businessData; @ApiModelProperty(value = "æµç¨å®ä¹ID") private Long flowDefinitionId; @ApiModelProperty(value = "审æ¹èç¹å表") private List<ApproveNodeVO> nodes; } src/main/java/com/ruoyi/approve/vo/ApproveNodeVO.java
¶Ô±ÈÐÂÎļþ @@ -0,0 +1,25 @@ package com.ruoyi.approve.vo; import io.swagger.annotations.ApiModelProperty; import lombok.Data; import javax.validation.constraints.NotNull; @Data public class ApproveNodeVO { @ApiModelProperty(value = "审æ¹ç¨æ·ID") @NotNull(message = "审æ¹äººä¸è½ä¸ºç©º") private Long userId; @ApiModelProperty(value = "审æ¹èç¹åç§°") private String nodeName; @ApiModelProperty(value = "æ¡ä»¶å段") private String conditionField; @ApiModelProperty(value = "æ¡ä»¶æä½ç¬¦") private String conditionOperator; @ApiModelProperty(value = "æ¡ä»¶å¼") private String conditionValue; } src/main/java/com/ruoyi/approve/vo/ApproveProcessVO.java
@@ -1,33 +1,61 @@ package com.ruoyi.approve.vo; import com.ruoyi.sales.pojo.CommonFile; import io.swagger.annotations.ApiModelProperty; import lombok.Data; import javax.validation.constraints.NotBlank; import java.math.BigDecimal; import java.util.List; @Data public class ApproveProcessVO { @ApiModelProperty(value = "临æ¶éä»¶IDå表") private List<String> tempFileIds; @ApiModelProperty(value = "å®¡æ¹æµç¨ä¸»é®") private Long id; @ApiModelProperty(value = "ç³è¯·é¨é¨ID") private Long approveDeptId; @ApiModelProperty(value = "ç³è¯·æ¥æï¼æ ¼å¼ï¼yyyy-MM-dd") private String approveTime; // ç³è¯·äºº @ApiModelProperty(value = "ç³è¯·ç¨æ·ID") private Long approveUser; // 审æ¹äºº @ApiModelProperty(value = "审æ¹ç¨æ·IDå表ï¼å¤ä¸ªä»¥éå·åé") private String approveUserIds; @ApiModelProperty(value = "ç³è¯·äºç±") private String approveReason; /** * 审æ¹ç±»å */ @ApiModelProperty(value = "审æ¹ç±»åï¼1èªç±ååï¼2请åï¼3éå®ï¼4æ¥éï¼5éè´ï¼6æ¥ä»·ï¼7åºåº") private Integer approveType; @ApiModelProperty(value = "å ³èä¸å¡ä¸»é®") private Long businessId; @ApiModelProperty(value = "ä¸å¡ç¼å·") private String businessNo; @ApiModelProperty(value = "审æ¹ä¸å¡æ é¢") @NotBlank(message = "å®¡æ¹æ é¢ä¸è½ä¸ºç©º") private String businessTitle; @ApiModelProperty(value = "ä¸å¡éé¢") private BigDecimal amount; @ApiModelProperty(value = "ä¸å¡æ°æ®JSONå¿«ç §") private String businessData; @ApiModelProperty(value = "æµç¨å®ä¹ID") private Long flowDefinitionId; @ApiModelProperty(value = "èªå®ä¹å®¡æ¹èç¹å表") private List<ApproveNodeVO> nodes; } src/main/resources/mapper/approve/ApproveLogMapper.xml
@@ -7,15 +7,19 @@ <resultMap id="BaseResultMap" type="com.ruoyi.approve.pojo.ApproveLog"> <id property="id" column="id" /> <result property="approveId" column="approve_id" /> <result property="approveProcessId" column="approve_process_id" /> <result property="approveNodeId" column="approve_node_id" /> <result property="approveNodeOrder" column="approve_node_order" /> <result property="approveUser" column="approve_user" /> <result property="approveUserName" column="approve_user_name" /> <result property="approveTime" column="approve_time" /> <result property="approveStatus" column="approve_status" /> <result property="approveRemark" column="approve_remark" /> <result property="tenantId" column="tenant_id" /> </resultMap> <sql id="Base_Column_List"> id,approve_id,approve_node_order,approve_user,approve_time,approve_status, approve_remark id,approve_id,approve_process_id,approve_node_id,approve_node_order,approve_user, approve_user_name,approve_time,approve_status,approve_remark,tenant_id </sql> </mapper> src/main/resources/mapper/approve/ApproveNodeMapper.xml
@@ -9,16 +9,24 @@ <result property="approveProcessId" column="approve_process_id" /> <result property="approveNodeOrder" column="approve_node_order" /> <result property="approveNodeUser" column="approve_node_user" /> <result property="approveNodeUserId" column="approve_node_user_id" /> <result property="approveNodeTime" column="approve_node_time" /> <result property="approveNodeStatus" column="approve_node_status" /> <result property="tenantId" column="tenant_id" /> <result property="deleteFlag" column="delete_flag" /> <result property="approveNodeReason" column="approve_node_reason" /> <result property="approveNodeRemark" column="approve_node_remark" /> <result property="approveNodeName" column="approve_node_name" /> <result property="conditionField" column="condition_field" /> <result property="conditionOperator" column="condition_operator" /> <result property="conditionValue" column="condition_value" /> <result property="isCurrent" column="is_current" /> </resultMap> <sql id="Base_Column_List"> id,approve_process_id,approve_node_order,approve_node_user,approve_node_time,approve_node_status, tenant_id,delete_flag,approve_node_reason,approve_node_remark tenant_id,delete_flag,approve_node_reason,approve_node_remark,approve_node_user_id, approve_node_name,condition_field,condition_operator,condition_value,is_current, create_user,create_time,update_user,update_time </sql> </mapper> src/main/resources/mapper/approve/ApproveProcessMapper.xml
@@ -20,12 +20,19 @@ <result property="tenantId" column="tenant_id" /> <result property="approveType" column="approve_type" /> <result property="approveRemark" column="approve_remark" /> <result property="businessId" column="business_id" /> <result property="businessNo" column="business_no" /> <result property="businessTitle" column="business_title" /> <result property="amount" column="amount" /> <result property="businessData" column="business_data" /> <result property="flowDefinitionId" column="flow_definition_id" /> </resultMap> <sql id="Base_Column_List"> id,approve_id,approve_user,approve_dept_id,approve_dept_name,approve_user_ids, approve_user_names,approve_reason,approve_time,approve_over_time,approve_status, approve_delete,tenant_id,approve_type,approve_remark approve_delete,tenant_id,approve_type,approve_remark,business_id,business_no, business_title,amount,business_data,flow_definition_id,create_time,update_time </sql> <select id="listPage" resultType="com.ruoyi.approve.pojo.ApproveProcess"> select * from approve_process where approve_delete = 0 @@ -38,5 +45,13 @@ <if test="req.approveType != null "> and approve_type = #{req.approveType} </if> <if test="req.tenantId != null"> and tenant_id = #{req.tenantId} </if> <if test="req.businessNo != null and req.businessNo != ''"> and (business_no like concat('%',#{req.businessNo},'%') or business_title like concat('%',#{req.businessNo},'%')) </if> order by create_time desc, id desc </select> </mapper>