You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

266 lines
11 KiB

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<String, RefundApprovalFlowConfig> 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<Integer> specificMarketIds = marketService.getSpecificMarketIdsUnderMarketDepartment();
// 为每个具体市场创建审批流程
for (Integer marketId : specificMarketIds) {
Market market = marketService.getMarketById(marketId);
if (market != null) {
List<RefundApprovalNode> flowNodes = createRefundFlowForMarket(market);
REFUND_APPROVAL_FLOW_CONFIG.put(marketId.toString(),
new RefundApprovalFlowConfig(market.getName() + "退款审批流程", flowNodes));
}
}
// 创建通用审批流程(用于没有特定配置的市场)
List<RefundApprovalNode> commonRefundFlow = createCommonRefundFlow();
REFUND_APPROVAL_FLOW_CONFIG.put("COMMON", new RefundApprovalFlowConfig("通用退款审批流程", commonRefundFlow));
log.info("退款审批流程配置初始化完成,共配置{}个流程", REFUND_APPROVAL_FLOW_CONFIG.size());
}
private List<RefundApprovalNode> createRefundFlowForMarket(Market market) {
Set<Integer> marketAndChildrenIds = new HashSet<>();
marketAndChildrenIds.add(market.getId());
marketAndChildrenIds.addAll(marketService.getAllChildrenIds(market.getId()));
List<RefundApprovalNode> 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<RefundApprovalNode> createCommonRefundFlow() {
List<RefundApprovalNode> 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<Integer> 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<String, RefundApprovalFlowConfig> getAllRefundFlowConfigs() {
return new HashMap<>(REFUND_APPROVAL_FLOW_CONFIG);
}
// 根据地区名称初始化审批流程配置
public void initializeFlowForMarketName(String marketName) {
Market market = marketService.getMarketByName(marketName);
if (market != null) {
List<RefundApprovalNode> flowNodes = createRefundFlowForMarket(market);
REFUND_APPROVAL_FLOW_CONFIG.put(market.getId().toString(),
new RefundApprovalFlowConfig(market.getName() + "退款审批流程", flowNodes));
log.info("为地区{}初始化退款审批流程配置", marketName);
}
}
}