rk
4 小时以前 c74a6f59490cfb9a0ee37f70427739b74e7fbd58
server/services/src/main/java/com/doumee/service/business/impl/RevenueServiceImpl.java
@@ -10,14 +10,8 @@
import com.doumee.core.model.PageData;
import com.doumee.core.model.PageWrap;
import com.doumee.core.utils.Utils;
import com.doumee.dao.business.RevenueMapper;
import com.doumee.dao.business.WithdrawalOrdersMapper;
import com.doumee.dao.business.MemberMapper;
import com.doumee.dao.business.ShopInfoMapper;
import com.doumee.dao.business.model.Revenue;
import com.doumee.dao.business.model.ShopInfo;
import com.doumee.dao.business.model.Member;
import com.doumee.dao.business.model.WithdrawalOrders;
import com.doumee.dao.business.*;
import com.doumee.dao.business.model.*;
import com.doumee.dao.dto.RevenueQueryDTO;
import com.doumee.dao.vo.RevenueStatisticsVO;
import com.doumee.dao.vo.RevenueSummaryVO;
@@ -26,9 +20,15 @@
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import com.doumee.dao.dto.ShopRevenueQueryDTO;
import com.doumee.dao.vo.DriverKpiVO;
import com.doumee.dao.vo.DriverOrderTrendVO;
import com.doumee.dao.vo.DriverRewardHallVO;
import com.doumee.biz.system.OperationConfigBiz;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.stream.Collectors;
/**
 * 收支记录Service实现
@@ -49,6 +49,18 @@
    @Autowired
    private MemberMapper memberMapper;
    @Autowired
    private DriverInfoMapper driverInfoMapper;
    @Autowired
    private OrdersMapper ordersMapper;
    @Autowired
    private RewardRecordMapper rewardRecordMapper;
    @Autowired
    private OperationConfigBiz operationConfigBiz;
    @Override
    public Integer create(Revenue revenue) {
@@ -178,11 +190,11 @@
    @Override
    public RevenueStatisticsVO getDriverRevenueStatistics(Integer memberId) {
        Member member = memberMapper.selectById(memberId);
        if (member == null) {
            throw new BusinessException(ResponseStatus.DATA_EMPTY.getCode(), "用户不存在");
        DriverInfo driverInfo = driverInfoMapper.selectById(memberId);
        if (driverInfo == null) {
            throw new BusinessException(ResponseStatus.DATA_EMPTY.getCode(), "司机信息不存在");
        }
        return buildRevenueStatistics(memberId, Constants.ONE, member.getAmount());
        return buildRevenueStatistics(memberId, Constants.ONE, driverInfo.getBalance());
    }
    /**
@@ -350,4 +362,218 @@
        return vo;
    }
    @Override
    public DriverKpiVO getDriverKpi(Integer driverId, ShopRevenueQueryDTO query) {
        QueryWrapper<Orders> qw = new QueryWrapper<>();
        qw.lambda()
                .eq(Orders::getDeleted, Constants.ZERO)
                .eq(Orders::getType, Constants.ONE)
                .eq(Orders::getAcceptDriver, driverId)
                .in(Orders::getStatus,
                        Constants.OrderStatus.waitDeposit.getKey(),
                        Constants.OrderStatus.deposited.getKey(),
                        Constants.OrderStatus.accepted.getKey(),
                        Constants.OrderStatus.delivering.getKey(),
                        Constants.OrderStatus.arrived.getKey(),
                        Constants.OrderStatus.finished.getKey());
        if (query.getStartDate() != null) {
            qw.lambda().ge(Orders::getCreateTime, query.getStartDate());
        }
        if (query.getEndDate() != null) {
            qw.lambda().le(Orders::getCreateTime, Utils.Date.getEnd(query.getEndDate()));
        }
        List<Orders> orders = ordersMapper.selectList(qw);
        DriverKpiVO vo = new DriverKpiVO();
        vo.setTotalOrderCount(orders.size());
        // 总完成订单量
        long finishedCount = orders.stream()
                .filter(o -> Constants.equalsInteger(o.getStatus(), Constants.OrderStatus.finished.getStatus()))
                .count();
        vo.setFinishedOrderCount((int) finishedCount);
        // 总营收金额
        long totalRevenue = orders.stream()
                .mapToLong(o -> {
                    long total = o.getTotalAmount() != null ? o.getTotalAmount() : 0L;
                    long refund = o.getRefundAmount() != null ? o.getRefundAmount() : 0L;
                    return total - refund;
                }).sum();
        vo.setTotalRevenue(totalRevenue);
        // 司机分成金额
        long driverFee = orders.stream()
                .mapToLong(o -> o.getDriverFee() != null ? o.getDriverFee() : 0L)
                .sum();
        vo.setDriverFeeTotal(driverFee);
        // 退款单数
        long refundCount = orders.stream()
                .filter(o -> o.getRefundAmount() != null && o.getRefundAmount() > 0)
                .count();
        vo.setRefundOrderCount((int) refundCount);
        // 责任扣款总额:Revenue memberId=driverId, memberType=1, type=4
        QueryWrapper<Revenue> revQw = new QueryWrapper<>();
        revQw.lambda()
                .eq(Revenue::getMemberId, driverId)
                .eq(Revenue::getMemberType, Constants.ONE)
                .eq(Revenue::getType, Constants.FOUR)
                .eq(Revenue::getDeleted, Constants.ZERO);
        if (query.getStartDate() != null) {
            revQw.lambda().ge(Revenue::getCreateTime, query.getStartDate());
        }
        if (query.getEndDate() != null) {
            revQw.lambda().le(Revenue::getCreateTime, Utils.Date.getEnd(query.getEndDate()));
        }
        List<Revenue> deductRecords = revenueMapper.selectList(revQw);
        long deductTotal = deductRecords.stream()
                .mapToLong(r -> r.getAmount() != null ? r.getAmount() : 0L)
                .sum();
        vo.setDeductTotal(deductTotal);
        return vo;
    }
    @Override
    public List<DriverOrderTrendVO> getDriverOrderTrend(Integer driverId) {
        SimpleDateFormat sdf = new SimpleDateFormat("MM/dd");
        // 构建近7天日期列表
        List<String> dateList = new ArrayList<>();
        for (int i = 6; i >= 0; i--) {
            Calendar c = Calendar.getInstance();
            c.add(Calendar.DAY_OF_MONTH, -i);
            dateList.add(sdf.format(c.getTime()));
        }
        // 查询近7天订单
        Calendar startCal = Calendar.getInstance();
        startCal.add(Calendar.DAY_OF_MONTH, -6);
        startCal.set(Calendar.HOUR_OF_DAY, 0);
        startCal.set(Calendar.MINUTE, 0);
        startCal.set(Calendar.SECOND, 0);
        startCal.set(Calendar.MILLISECOND, 0);
        QueryWrapper<Orders> qw = new QueryWrapper<>();
        qw.lambda()
                .eq(Orders::getDeleted, Constants.ZERO)
                .eq(Orders::getAcceptDriver, driverId)
                .in(Orders::getStatus,
                        Constants.OrderStatus.accepted.getKey(),
                        Constants.OrderStatus.delivering.getKey(),
                        Constants.OrderStatus.arrived.getKey(),
                        Constants.OrderStatus.finished.getKey())
                .ge(Orders::getCreateTime, startCal.getTime());
        List<Orders> orders = ordersMapper.selectList(qw);
        // 按日期分组统计
        Map<String, Long> countMap = orders.stream()
                .collect(Collectors.groupingBy(o -> sdf.format(o.getCreateTime()), Collectors.counting()));
        List<DriverOrderTrendVO> result = new ArrayList<>();
        for (String date : dateList) {
            DriverOrderTrendVO item = new DriverOrderTrendVO();
            item.setDate(date);
            item.setOrderCount(countMap.getOrDefault(date, 0L).intValue());
            result.add(item);
        }
        return result;
    }
    @Override
    public DriverRewardHallVO getDriverRewardHall(Integer driverId) {
        // 查询已领取金额(status=1)
        QueryWrapper<RewardRecord> claimedQw = new QueryWrapper<>();
        claimedQw.select("IFNULL(SUM(AMOUNT), 0) as amount")
                .eq("DRIVER_ID", driverId)
                .eq("STATUS", Constants.ONE)
                .eq("DELETED", Constants.ZERO);
        Map<String, Object> claimedResult = rewardRecordMapper.selectMaps(claimedQw).stream().findFirst().orElse(null);
        long claimedAmount = claimedResult != null && claimedResult.get("amount") != null
                ? Long.parseLong(claimedResult.get("amount").toString()) : 0L;
        // 查询待领取金额(status=0)
        QueryWrapper<RewardRecord> pendingQw = new QueryWrapper<>();
        pendingQw.select("IFNULL(SUM(AMOUNT), 0) as amount")
                .eq("DRIVER_ID", driverId)
                .eq("STATUS", Constants.ZERO)
                .eq("DELETED", Constants.ZERO);
        Map<String, Object> pendingResult = rewardRecordMapper.selectMaps(pendingQw).stream().findFirst().orElse(null);
        long pendingAmount = pendingResult != null && pendingResult.get("amount") != null
                ? Long.parseLong(pendingResult.get("amount").toString()) : 0L;
        // 读取奖励规则配置
        com.doumee.dao.dto.OperationConfigDTO config = operationConfigBiz.getConfig();
        // 查询奖励记录列表(按主键、创建时间升序)
        List<RewardRecord> records = rewardRecordMapper.selectList(new QueryWrapper<RewardRecord>().lambda()
                .eq(RewardRecord::getDriverId, driverId)
                .eq(RewardRecord::getDeleted, Constants.ZERO)
                .orderByAsc(RewardRecord::getId)
                .orderByAsc(RewardRecord::getCreateTime));
        DriverRewardHallVO vo = new DriverRewardHallVO();
        vo.setClaimedAmount(claimedAmount);
        vo.setPendingAmount(pendingAmount);
        vo.setRegisterRewardOrderCount(config.getRegisterRewardOrderCount());
        vo.setRegisterRewardAmount(config.getRegisterRewardAmount());
        vo.setPlatformRewardOrderCount(config.getPlatformRewardOrderCount());
        vo.setPlatformRewardAmount(config.getPlatformRewardAmount());
        vo.setRecords(records);
        return vo;
    }
    @Override
    public void claimReward(Integer driverId, Integer rewardRecordId) {
        // 查询奖励记录
        RewardRecord record = rewardRecordMapper.selectById(rewardRecordId);
        if (record == null || Constants.equalsInteger(record.getDeleted(), Constants.ONE)) {
            throw new BusinessException(ResponseStatus.DATA_EMPTY.getCode(), "奖励记录不存在");
        }
        if (!Constants.equalsInteger(record.getDriverId(), driverId)) {
            throw new BusinessException(ResponseStatus.BAD_REQUEST.getCode(), "无权领取该奖励");
        }
        if (!Constants.equalsInteger(record.getStatus(), Constants.ZERO)) {
            throw new BusinessException(ResponseStatus.BAD_REQUEST.getCode(), "该奖励已领取");
        }
        Long rewardAmount = record.getAmount() != null ? record.getAmount() : 0L;
        if (rewardAmount <= 0) return;
        // 查询司机信息
        DriverInfo driver = driverInfoMapper.selectById(driverId);
        if (driver == null) {
            throw new BusinessException(ResponseStatus.DATA_EMPTY.getCode(), "司机信息不存在");
        }
        // 创建收益记录(type=3 平台奖励, optType=1 收入, vaildStatus=1 已入账)
        Revenue revenue = new Revenue();
        revenue.setMemberId(driver.getMemberId());
        revenue.setMemberType(Constants.ONE);
        revenue.setType(Constants.THREE);      // 平台奖励
        revenue.setOptType(Constants.ONE);     // 收入
        revenue.setAmount(rewardAmount);
        revenue.setVaildStatus(Constants.ONE); // 已入账
        revenue.setObjId(record.getOrderId());
        revenue.setObjType(Constants.ZERO);
        revenue.setStatus(Constants.ZERO);
        revenue.setDeleted(Constants.ZERO);
        revenue.setCreateTime(new Date());
        revenueMapper.insert(revenue);
        // 更新奖励记录:status=1已领取, claimTime, revenueId
        record.setStatus(Constants.ONE);
        record.setClaimTime(new Date());
        record.setRevenueId(revenue.getId());
        record.setUpdateTime(new Date());
        rewardRecordMapper.updateById(record);
        // 更新司机余额
        driverInfoMapper.update(new UpdateWrapper<DriverInfo>().lambda()
                .setSql("BALANCE = IFNULL(BALANCE, 0) + " + rewardAmount)
                .setSql("TOTAL_BALANCE = IFNULL(TOTAL_BALANCE, 0) + " + rewardAmount)
                .eq(DriverInfo::getId, driverId));
    }
}