package com.example.demo.service.cash; import com.example.demo.Node.RefundApprovalNode; import com.example.demo.config.cash.RefundApprovalFlowConfig; import com.example.demo.domain.vo.cash.CashRecord; import com.example.demo.domain.vo.cash.Market; import com.example.demo.domain.vo.cash.RefundApprovalRecord; import com.example.demo.domain.vo.cash.User; import lombok.extern.slf4j.Slf4j; import org.springframework.stereotype.Service; import java.util.*; import java.util.concurrent.ConcurrentHashMap; import java.util.stream.Collectors; @Slf4j @Service public class RefundApprovalService { private final MarketService marketService; // 退款审批流程配置缓存 private static final Map REFUND_APPROVAL_FLOW_CONFIG = new ConcurrentHashMap<>(); // 角色定义 public static final String ROLE_REGIONAL_FINANCE = "REGIONAL_FINANCE"; public static final String ROLE_REGIONAL_MANAGER = "REGIONAL_MANAGER"; public static final String ROLE_HEADQUARTERS_FINANCE = "HEADQUARTERS_FINANCE"; public static final String ROLE_EXECUTOR = "EXECUTOR"; public static final String ROLE_SUBMITTER = "SUBMITTER"; public RefundApprovalService(MarketService marketService) { this.marketService = marketService; initializeRefundFlowConfigs(); } // 初始化退款审批流程配置(基于地区ID) private void initializeRefundFlowConfigs() { // 获取市场部下的所有具体市场ID Set specificMarketIds = marketService.getSpecificMarketIdsUnderMarketDepartment(); // 为每个具体市场创建审批流程 for (Integer marketId : specificMarketIds) { Market market = marketService.getMarketById(marketId); if (market != null) { List flowNodes = createRefundFlowForMarket(market); REFUND_APPROVAL_FLOW_CONFIG.put(marketId.toString(), new RefundApprovalFlowConfig(market.getName() + "退款审批流程", flowNodes)); } } // 创建通用审批流程(用于没有特定配置的市场) List commonRefundFlow = createCommonRefundFlow(); REFUND_APPROVAL_FLOW_CONFIG.put("COMMON", new RefundApprovalFlowConfig("通用退款审批流程", commonRefundFlow)); log.info("退款审批流程配置初始化完成,共配置{}个流程", REFUND_APPROVAL_FLOW_CONFIG.size()); } private List createRefundFlowForMarket(Market market) { Set marketAndChildrenIds = new HashSet<>(); marketAndChildrenIds.add(market.getId()); marketAndChildrenIds.addAll(marketService.getAllChildrenIds(market.getId())); List nodes = new ArrayList<>(); nodes.add(new RefundApprovalNode("地区财务审核", 1, new String[]{ROLE_REGIONAL_FINANCE}, marketAndChildrenIds, true)); nodes.add(new RefundApprovalNode("地区负责人审核", 2, new String[]{ROLE_REGIONAL_MANAGER}, marketAndChildrenIds, true)); nodes.add(new RefundApprovalNode("总部财务审核", 3, new String[]{ROLE_HEADQUARTERS_FINANCE}, null, true)); // 总部不限制地区 nodes.add(new RefundApprovalNode("执行人处理", 4, new String[]{ROLE_EXECUTOR}, null, true)); // 执行人不限制地区 return nodes; } private List createCommonRefundFlow() { List nodes = new ArrayList<>(); nodes.add(new RefundApprovalNode("地区财务审核", 1, new String[]{ROLE_REGIONAL_FINANCE}, null, true)); nodes.add(new RefundApprovalNode("地区负责人审核", 2, new String[]{ROLE_REGIONAL_MANAGER}, null, true)); nodes.add(new RefundApprovalNode("总部财务审核", 3, new String[]{ROLE_HEADQUARTERS_FINANCE}, null, true)); nodes.add(new RefundApprovalNode("执行人处理", 4, new String[]{ROLE_EXECUTOR}, null, true)); return nodes; } // 获取适合订单的审批流程(基于地区ID) private RefundApprovalFlowConfig getSuitableFlowConfig(CashRecord cashRecord) { Integer marketId = cashRecord.getPrimaryMarketId(); if (marketId != null) { // 优先根据具体地区ID获取流程 RefundApprovalFlowConfig specificConfig = REFUND_APPROVAL_FLOW_CONFIG.get(marketId.toString()); if (specificConfig != null) { return specificConfig; } // 如果该市场没有特定配置,查找父级市场的配置 Market market = marketService.getMarketById(marketId); if (market != null && market.getParentId() != null) { RefundApprovalFlowConfig parentConfig = REFUND_APPROVAL_FLOW_CONFIG.get(market.getParentId().toString()); if (parentConfig != null) { return parentConfig; } } } // 默认返回通用流程 return REFUND_APPROVAL_FLOW_CONFIG.get("COMMON"); } // 获取用户有权限审批的订单状态(基于地区ID) public List getUserVisibleStatuses(User user, CashRecord cashRecord) { if (!cashRecord.isRefundOrder()) { return new ArrayList<>(); } RefundApprovalFlowConfig flowConfig = getSuitableFlowConfig(cashRecord); if (flowConfig != null) { return flowConfig.getVisibleStatuses(user, cashRecord.getPrimaryMarketId()); } log.warn("未找到适合订单地区{}的退款审批流程配置", cashRecord.getPrimaryMarketId()); return new ArrayList<>(); } // 检查用户是否有权限审批指定订单(基于地区ID) public boolean canUserApproveOrder(User user, CashRecord cashRecord) { if (!cashRecord.isRefundOrder() || !cashRecord.isInApprovalProcess()) { return false; } RefundApprovalFlowConfig flowConfig = getSuitableFlowConfig(cashRecord); if (flowConfig != null) { return flowConfig.canUserApproveNode(user, cashRecord.getCurrentApprovalLevel(), cashRecord.getPrimaryMarketId()); } return false; } // 检查用户是否可以撤回订单(只有提交人可以在第一个审批节点前撤回) public boolean canUserWithdrawOrder(User user, CashRecord cashRecord) { if (!cashRecord.isRefundOrder()) { return false; } // 只有订单提交人才能撤回 boolean isSubmitter = cashRecord.getSubmitterId() != null && cashRecord.getSubmitterId().equals(user.getId()); return isSubmitter && cashRecord.canWithdraw(); } // 提交退款审批 public boolean submitRefundApproval(User user, CashRecord cashRecord, String approvalResult, String comments) { if (!canUserApproveOrder(user, cashRecord)) { log.warn("用户{}没有权限审批退款订单{}", user.getId(), cashRecord.getId()); return false; } // 创建审批记录 RefundApprovalRecord record = new RefundApprovalRecord(); record.setCashRecordId(cashRecord.getId()); record.setApprovalLevel(cashRecord.getCurrentApprovalLevel()); record.setApproverId(user.getId()); record.setApproverName(user.getName()); record.setApprovalResult(approvalResult); record.setComments(comments); record.setApprovalTime(new Date()); // 更新订单状态 boolean approved = "APPROVED".equals(approvalResult); Integer nextStatus = cashRecord.getNextStatus(approved); cashRecord.setStatus(nextStatus); cashRecord.setUpdateTime(new Date()); cashRecord.setAuditId(user.getId()); cashRecord.setAuditTime(new Date()); if (!approved) { cashRecord.setRejectReason(comments); } log.info("用户{}审批退款订单{},结果:{},新状态:{}", user.getName(), cashRecord.getId(), approvalResult, nextStatus); return true; } // 撤回退款订单(在第一个审批节点前) public boolean withdrawRefundOrder(User user, CashRecord cashRecord, String withdrawReason) { if (!canUserWithdrawOrder(user, cashRecord)) { log.warn("用户{}不能撤回退款订单{}", user.getId(), cashRecord.getId()); return false; } // 创建撤回记录 RefundApprovalRecord record = new RefundApprovalRecord(); record.setCashRecordId(cashRecord.getId()); record.setApprovalLevel(cashRecord.getCurrentApprovalLevel()); record.setApproverId(user.getId()); record.setApproverName(user.getName()); record.setIsWithdrawal(true); record.setWithdrawnBy(user.getId()); record.setWithdrawReason(withdrawReason); record.setWithdrawTime(new Date()); // 更新订单状态为撤回 boolean success = cashRecord.withdraw(); if (success) { cashRecord.setUpdateTime(new Date()); log.info("用户{}撤回退款订单{},原因:{}", user.getName(), cashRecord.getId(), withdrawReason); } return success; } // 重新提交撤回的退款订单 public boolean resubmitRefundOrder(User user, CashRecord cashRecord) { if (!cashRecord.canResubmit()) { log.warn("退款订单{}不能重新提交", cashRecord.getId()); return false; } // 检查用户是否是原提交人 boolean isSubmitter = cashRecord.getSubmitterId() != null && cashRecord.getSubmitterId().equals(user.getId()); if (!isSubmitter) { log.warn("用户{}不是订单{}的提交人,不能重新提交", user.getId(), cashRecord.getId()); return false; } boolean success = cashRecord.resubmit(); if (success) { cashRecord.setUpdateTime(new Date()); log.info("用户{}重新提交退款订单{}", user.getName(), cashRecord.getId()); } return success; } // 获取下一个审批节点信息 public RefundApprovalNode getNextApprovalNode(CashRecord cashRecord) { RefundApprovalFlowConfig flowConfig = getSuitableFlowConfig(cashRecord); if (flowConfig != null) { return flowConfig.getNextNode(cashRecord.getCurrentApprovalLevel()); } return null; } // 动态添加退款审批流程配置 public void addRefundFlowConfig(String marketId, RefundApprovalFlowConfig flowConfig) { REFUND_APPROVAL_FLOW_CONFIG.put(marketId, flowConfig); log.info("成功添加地区{}的退款审批流程配置:{}", marketId, flowConfig.getFlowName()); } // 获取所有退款审批流程配置 public Map getAllRefundFlowConfigs() { return new HashMap<>(REFUND_APPROVAL_FLOW_CONFIG); } // 根据地区名称初始化审批流程配置 public void initializeFlowForMarketName(String marketName) { Market market = marketService.getMarketByName(marketName); if (market != null) { List flowNodes = createRefundFlowForMarket(market); REFUND_APPROVAL_FLOW_CONFIG.put(market.getId().toString(), new RefundApprovalFlowConfig(market.getName() + "退款审批流程", flowNodes)); log.info("为地区{}初始化退款审批流程配置", marketName); } } }