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
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);
|
|
}
|
|
}
|
|
}
|