package com.ycwl.basic.profitsharing.biz; import com.ycwl.basic.profitsharing.entity.ProfitSharingConfig; import com.ycwl.basic.profitsharing.entity.ProfitSharingRecord; import com.ycwl.basic.profitsharing.entity.ProfitSharingUser; import com.ycwl.basic.profitsharing.mapper.ProfitSharingRecordMapper; import com.ycwl.basic.profitsharing.repository.ProfitSharingRepository; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; import java.math.BigDecimal; import java.math.RoundingMode; import java.util.ArrayList; import java.util.Date; import java.util.List; import java.util.stream.Collectors; @Slf4j @Component public class ProfitSharingBiz { @Autowired private ProfitSharingRepository repository; @Autowired private ProfitSharingRecordMapper recordMapper; public void processProfitSharing(Long scenicId, Long orderId, BigDecimal amount) { ProfitSharingConfig config = repository.getScenicConfig(scenicId); if (config == null || config.getUsers() == null || config.getUsers().isEmpty()) { return; } List records = new ArrayList<>(); List alreadyProcessedUsers = new ArrayList<>(); // 先找出1,3的用户 config.getUsers().stream().filter(user -> user.getRateMode() == 1 || user.getRateMode() == 3).forEach(user -> { if (alreadyProcessedUsers.contains(user)) { return; } BigDecimal userAmount; BigDecimal wxAmount; BigDecimal manualAmount; if (user.getRateMode() == 1) { // 比例抽成 userAmount = amount.multiply(user.getRealRate()).divide(BigDecimal.valueOf(100), 2, RoundingMode.HALF_DOWN); wxAmount = amount.multiply(user.getWxRate()).divide(BigDecimal.valueOf(100), 2, RoundingMode.HALF_DOWN); manualAmount = userAmount.subtract(wxAmount); } else if (user.getRateMode() == 3) { // 固定抽成 userAmount = user.getRealRate(); wxAmount = user.getWxRate(); manualAmount = userAmount.subtract(wxAmount); } else { return; } ProfitSharingRecord record = new ProfitSharingRecord(); record.setScenicId(scenicId); record.setOrderId(orderId); record.setUserId(user.getId()); record.setUserName(user.getName()); record.setAmount(userAmount); record.setWxAmount(wxAmount); record.setManualAmount(manualAmount); record.setRateMode(user.getRateMode()); record.setWxRate(user.getWxRate()); record.setRealRate(user.getRealRate()); record.setOrderAmount(amount); record.setCreateTime(new Date()); records.add(record); alreadyProcessedUsers.add(user); }); final BigDecimal mode2RemainAmount = amount.subtract(records.stream().map(ProfitSharingRecord::getAmount).reduce(BigDecimal.ZERO, BigDecimal::add)); // 找出2的用户 config.getUsers().stream().filter(user -> user.getRateMode() == 2).forEach(user -> { if (alreadyProcessedUsers.contains(user)) { return; } BigDecimal userAmount; BigDecimal wxAmount; BigDecimal manualAmount; if (user.getRateMode() == 2) { // 扣除固定抽成后的动态比例 userAmount = mode2RemainAmount.multiply(user.getRealRate()).divide(BigDecimal.valueOf(100), 2, RoundingMode.HALF_DOWN); wxAmount = mode2RemainAmount.multiply(user.getWxRate()).divide(BigDecimal.valueOf(100), 2, RoundingMode.HALF_DOWN); manualAmount = userAmount.subtract(wxAmount); } else { return; } ProfitSharingRecord record = new ProfitSharingRecord(); record.setScenicId(scenicId); record.setOrderId(orderId); record.setUserId(user.getId()); record.setUserName(user.getName()); record.setAmount(userAmount); record.setWxAmount(wxAmount); record.setManualAmount(manualAmount); record.setRateMode(user.getRateMode()); record.setWxRate(user.getWxRate()); record.setRealRate(user.getRealRate()); record.setOrderAmount(amount); record.setCreateTime(new Date()); records.add(record); alreadyProcessedUsers.add(user); }); final BigDecimal mode4RemainAmount = amount.subtract(records.stream().map(ProfitSharingRecord::getAmount).reduce(BigDecimal.ZERO, BigDecimal::add)); // 找出4的用户 config.getUsers().stream().filter(user -> user.getRateMode() == 4).forEach(user -> { if (alreadyProcessedUsers.contains(user)) { return; } BigDecimal userAmount; BigDecimal wxAmount; BigDecimal manualAmount; if (user.getRateMode() == 4) { // 扣除其他所有类型抽成后的动态比例 userAmount = mode4RemainAmount.multiply(user.getRealRate()).divide(BigDecimal.valueOf(100), 2, RoundingMode.HALF_DOWN); wxAmount = mode4RemainAmount.multiply(user.getWxRate()).divide(BigDecimal.valueOf(100), 2, RoundingMode.HALF_DOWN); manualAmount = userAmount.subtract(wxAmount); } else { return; } ProfitSharingRecord record = new ProfitSharingRecord(); record.setScenicId(scenicId); record.setOrderId(orderId); record.setUserId(user.getId()); record.setUserName(user.getName()); record.setAmount(userAmount); record.setWxAmount(wxAmount); record.setManualAmount(manualAmount); record.setRateMode(user.getRateMode()); record.setWxRate(user.getWxRate()); record.setRealRate(user.getRealRate()); record.setOrderAmount(amount); record.setCreateTime(new Date()); records.add(record); alreadyProcessedUsers.add(user); }); final BigDecimal mode0RemainAmount = amount.subtract(records.stream().map(ProfitSharingRecord::getAmount).reduce(BigDecimal.ZERO, BigDecimal::add)); // 找出0的用户 List mode0User = config.getUsers().stream().filter(user -> user.getRateMode() == 0).collect(Collectors.toList()); mode0User.forEach(user -> { if (alreadyProcessedUsers.contains(user)) { return; } BigDecimal userAmount; BigDecimal wxAmount; BigDecimal manualAmount; if (user.getRateMode() == 0) { // 剩余比例 userAmount = mode0RemainAmount.divide(BigDecimal.valueOf(mode0User.size()), 2, RoundingMode.HALF_DOWN); wxAmount = mode0RemainAmount.divide(BigDecimal.valueOf(mode0User.size()), 2, RoundingMode.HALF_DOWN); manualAmount = userAmount.subtract(wxAmount); } else { return; } ProfitSharingRecord record = new ProfitSharingRecord(); record.setScenicId(scenicId); record.setOrderId(orderId); record.setUserId(user.getId()); record.setUserName(user.getName()); record.setAmount(userAmount); record.setWxAmount(wxAmount); record.setManualAmount(manualAmount); record.setRateMode(user.getRateMode()); record.setWxRate(user.getWxRate()); record.setRealRate(user.getRealRate()); record.setOrderAmount(amount); record.setCreateTime(new Date()); records.add(record); alreadyProcessedUsers.add(user); }); // 没有操作过的用户 config.getUsers().stream().filter(user -> !alreadyProcessedUsers.contains(user)).forEach(user -> { ProfitSharingRecord record = new ProfitSharingRecord(); record.setScenicId(scenicId); record.setOrderId(orderId); record.setUserId(user.getId()); record.setUserName(user.getName()); record.setAmount(BigDecimal.ZERO); record.setWxAmount(BigDecimal.ZERO); record.setManualAmount(BigDecimal.ZERO); record.setRateMode(user.getRateMode()); record.setWxRate(user.getWxRate()); record.setRealRate(user.getRealRate()); record.setOrderAmount(amount); record.setCreateTime(new Date()); records.add(record); alreadyProcessedUsers.add(user); }); final BigDecimal remainAmount = amount.subtract(records.stream().map(ProfitSharingRecord::getAmount).reduce(BigDecimal.ZERO, BigDecimal::add)); if (remainAmount.compareTo(BigDecimal.ZERO) < 0) { log.error("分账剩余金额不足!!! scenicId: {}, orderId: {}, amount: {}, config: {}", scenicId, orderId, amount, config); return; } if (remainAmount.compareTo(BigDecimal.ZERO) > 0) { ProfitSharingRecord record = new ProfitSharingRecord(); record.setScenicId(scenicId); record.setOrderId(orderId); record.setUserId(0L); record.setUserName("分账剩余"); record.setRateMode(-1); record.setAmount(remainAmount); record.setWxAmount(BigDecimal.ZERO); record.setManualAmount(remainAmount); record.setWxRate(BigDecimal.ZERO); record.setRealRate(BigDecimal.ZERO); record.setOrderAmount(amount); record.setCreateTime(new Date()); records.add(record); } recordMapper.batchInsert(records); } public void revokeProfitSharing(Long scenicId, Long orderId) { recordMapper.deleteByScenicIdAndOrderId(scenicId, orderId); } }