rk
7 小时以前 55642c818f14bf8cf52c98e6858014bd8dc3d3a7
server/services/src/main/java/com/doumee/service/business/impl/WithdrawalOrdersServiceImpl.java
@@ -10,15 +10,31 @@
import com.doumee.core.model.PageData;
import com.doumee.core.model.PageWrap;
import com.doumee.core.utils.Utils;
import com.doumee.dao.business.DriverInfoMapper;
import com.doumee.dao.business.RevenueMapper;
import com.doumee.dao.business.ShopInfoMapper;
import com.doumee.dao.business.WithdrawalOrdersMapper;
import com.doumee.dao.business.model.DriverInfo;
import com.doumee.dao.business.model.Revenue;
import com.doumee.dao.business.model.ShopInfo;
import com.doumee.dao.business.model.WithdrawalOrders;
import com.doumee.dao.dto.WithdrawalApproveDTO;
import com.doumee.dao.dto.WithdrawalDTO;
import com.doumee.dao.system.SystemUserMapper;
import com.doumee.dao.system.model.SystemUser;
import com.doumee.service.business.WithdrawalOrdersService;
import com.github.yulichang.wrapper.MPJLambdaWrapper;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.util.Arrays;
import java.util.Date;
import java.util.List;
import java.util.Objects;
import java.util.concurrent.ThreadLocalRandom;
/**
 * 提现申请记录Service实现
@@ -30,6 +46,18 @@
    @Autowired
    private WithdrawalOrdersMapper withdrawalOrdersMapper;
    @Autowired
    private SystemUserMapper systemUserMapper;
    @Autowired
    private ShopInfoMapper shopInfoMapper;
    @Autowired
    private DriverInfoMapper driverInfoMapper;
    @Autowired
    private RevenueMapper revenueMapper;
    @Override
    public Integer create(WithdrawalOrders withdrawalOrders) {
@@ -75,11 +103,19 @@
    @Override
    public WithdrawalOrders findById(Integer id) {
        WithdrawalOrders withdrawalOrders = withdrawalOrdersMapper.selectById(id);
        if (Objects.isNull(withdrawalOrders)) {
        WithdrawalOrders order = withdrawalOrdersMapper.selectById(id);
        if (Objects.isNull(order)) {
            throw new BusinessException(ResponseStatus.DATA_EMPTY);
        }
        return withdrawalOrders;
        // 查询审批人名称
        fillUpdateUserName(order);
        // 根据用户类型查询关联信息
        if (Constants.ONE.equals(order.getMemberType())) {
            fillMemberInfo(order);
        } else {
            fillShopInfo(order);
        }
        return order;
    }
    @Override
@@ -97,16 +133,52 @@
    @Override
    public PageData<WithdrawalOrders> findPage(PageWrap<WithdrawalOrders> pageWrap) {
        IPage<WithdrawalOrders> page = new Page<>(pageWrap.getPage(), pageWrap.getCapacity());
        QueryWrapper<WithdrawalOrders> queryWrapper = new QueryWrapper<>();
        MPJLambdaWrapper<WithdrawalOrders> queryWrapper = new MPJLambdaWrapper<>();
        Utils.MP.blankToNull(pageWrap.getModel());
        pageWrap.getModel().setDeleted(Constants.ZERO);
        queryWrapper.lambda().eq(WithdrawalOrders::getDeleted, pageWrap.getModel().getDeleted());
        queryWrapper.lambda().like(StringUtils.isNotBlank(pageWrap.getModel().getOutBillNo()), WithdrawalOrders::getOutBillNo, pageWrap.getModel().getOutBillNo());
        queryWrapper.lambda().eq(pageWrap.getModel().getMemberId() != null, WithdrawalOrders::getMemberId, pageWrap.getModel().getMemberId());
        queryWrapper.lambda().eq(pageWrap.getModel().getStatus() != null, WithdrawalOrders::getStatus, pageWrap.getModel().getStatus());
        queryWrapper.lambda().eq(pageWrap.getModel().getType() != null, WithdrawalOrders::getType, pageWrap.getModel().getType());
        queryWrapper.lambda().ge(pageWrap.getModel().getCreateStartTime() != null, WithdrawalOrders::getCreateTime, Utils.Date.getStart(pageWrap.getModel().getCreateStartTime()));
        queryWrapper.lambda().le(pageWrap.getModel().getCreateEndTime() != null, WithdrawalOrders::getCreateTime, Utils.Date.getEnd(pageWrap.getModel().getCreateEndTime()));
        // 公共:审批人名称
        queryWrapper.selectAll(WithdrawalOrders.class)
                .selectAs(SystemUser::getUsername, WithdrawalOrders::getUpdateUserName)
                .leftJoin(SystemUser.class, SystemUser::getId, WithdrawalOrders::getUserId);
        // 根据用户类型关联不同表
        Integer memberType = pageWrap.getModel().getMemberType();
        if (Constants.ONE.equals(memberType)) {
            // 司机端:关联 DriverInfo 表
            queryWrapper.selectAs(DriverInfo::getName, WithdrawalOrders::getMemberName)
                    .selectAs(DriverInfo::getTelephone, WithdrawalOrders::getMemberTelephone)
                    .leftJoin(DriverInfo.class, DriverInfo::getMemberId, WithdrawalOrders::getMemberId);
        } else {
            // 店铺端 / 不筛选:关联 ShopInfo 表
            queryWrapper.selectAs(ShopInfo::getName, WithdrawalOrders::getShopName)
                    .selectAs(ShopInfo::getLinkName, WithdrawalOrders::getLinkName)
                    .leftJoin(ShopInfo.class, ShopInfo::getId, WithdrawalOrders::getMemberId,
                            ext -> ext.eq(ShopInfo::getDeleted, Constants.ZERO));
        }
        queryWrapper.eq(WithdrawalOrders::getDeleted, pageWrap.getModel().getDeleted());
        if (memberType != null) {
            queryWrapper.eq(WithdrawalOrders::getMemberType, memberType);
        }
        if (StringUtils.isNotBlank(pageWrap.getModel().getOutBillNo())) {
            queryWrapper.like(WithdrawalOrders::getOutBillNo, pageWrap.getModel().getOutBillNo());
        }
        if (pageWrap.getModel().getMemberId() != null) {
            queryWrapper.eq(WithdrawalOrders::getMemberId, pageWrap.getModel().getMemberId());
        }
        if (pageWrap.getModel().getStatus() != null) {
            queryWrapper.eq(WithdrawalOrders::getStatus, pageWrap.getModel().getStatus());
        }
        if (pageWrap.getModel().getType() != null) {
            queryWrapper.eq(WithdrawalOrders::getType, pageWrap.getModel().getType());
        }
        if (pageWrap.getModel().getCreateStartTime() != null) {
            queryWrapper.ge(WithdrawalOrders::getCreateTime, Utils.Date.getStart(pageWrap.getModel().getCreateStartTime()));
        }
        if (pageWrap.getModel().getCreateEndTime() != null) {
            queryWrapper.le(WithdrawalOrders::getCreateTime, Utils.Date.getEnd(pageWrap.getModel().getCreateEndTime()));
        }
        for (PageWrap.SortData sortData : pageWrap.getSorts()) {
            if (sortData.getDirection().equalsIgnoreCase(PageWrap.DESC)) {
                queryWrapper.orderByDesc(sortData.getProperty());
@@ -114,8 +186,12 @@
                queryWrapper.orderByAsc(sortData.getProperty());
            }
        }
        return PageData.from(withdrawalOrdersMapper.selectPage(page, queryWrapper));
        return PageData.from(withdrawalOrdersMapper.selectJoinPage(page, WithdrawalOrders.class, queryWrapper));
    }
    @Override
    public long count(WithdrawalOrders withdrawalOrders) {
@@ -123,4 +199,257 @@
        return withdrawalOrdersMapper.selectCount(wrapper);
    }
    @Override
    public Long totalAmount(PageWrap<WithdrawalOrders> pageWrap) {
        QueryWrapper<WithdrawalOrders> queryWrapper = new QueryWrapper<>();
        queryWrapper.select("IFNULL(SUM(amount), 0) as amount");
        Utils.MP.blankToNull(pageWrap.getModel());
        queryWrapper.lambda().eq(WithdrawalOrders::getDeleted, Constants.ZERO);
        queryWrapper.lambda().in(WithdrawalOrders::getStatus, Arrays.asList(Constants.ZERO, Constants.ONE));
        if (pageWrap.getModel().getOutBillNo() != null) {
            queryWrapper.lambda().like(WithdrawalOrders::getOutBillNo, pageWrap.getModel().getOutBillNo());
        }
        if (pageWrap.getModel().getMemberId() != null) {
            queryWrapper.lambda().eq(WithdrawalOrders::getMemberId, pageWrap.getModel().getMemberId());
        }
        if (pageWrap.getModel().getStatus() != null) {
            queryWrapper.lambda().eq(WithdrawalOrders::getStatus, pageWrap.getModel().getStatus());
        }
        if (pageWrap.getModel().getType() != null) {
            queryWrapper.lambda().eq(WithdrawalOrders::getType, pageWrap.getModel().getType());
        }
        if (pageWrap.getModel().getCreateStartTime() != null) {
            queryWrapper.lambda().ge(WithdrawalOrders::getCreateTime, Utils.Date.getStart(pageWrap.getModel().getCreateStartTime()));
        }
        if (pageWrap.getModel().getCreateEndTime() != null) {
            queryWrapper.lambda().le(WithdrawalOrders::getCreateTime, Utils.Date.getEnd(pageWrap.getModel().getCreateEndTime()));
        }
        WithdrawalOrders result = withdrawalOrdersMapper.selectOne(queryWrapper);
        return result != null && result.getAmount() != null ? result.getAmount() : 0L;
    }
    @Override
    public void approve(WithdrawalApproveDTO dto) {
        if (dto == null || dto.getId() == null || dto.getStatus() == null) {
            throw new BusinessException(ResponseStatus.BAD_REQUEST.getCode(), "审批参数不完整");
        }
        if (!Constants.ONE.equals(dto.getStatus()) && !Constants.TWO.equals(dto.getStatus())) {
            throw new BusinessException(ResponseStatus.BAD_REQUEST.getCode(), "审批结果仅支持通过或拒绝");
        }
        WithdrawalOrders order = withdrawalOrdersMapper.selectById(dto.getId());
        if (Objects.isNull(order)) {
            throw new BusinessException(ResponseStatus.DATA_EMPTY);
        }
        if (!Constants.ZERO.equals(order.getStatus())) {
            throw new BusinessException(ResponseStatus.BAD_REQUEST.getCode(), "仅申请中的提现订单可审批");
        }
        // 获取当前登录用户
        Integer currentUserId = getCurrentUserId();
        Date now = new Date();
        WithdrawalOrders update = new WithdrawalOrders();
        update.setId(dto.getId());
        update.setStatus(dto.getStatus());
        update.setUserId(currentUserId);
        update.setApproveTime(now);
        update.setApproveRemark(dto.getApproveRemark());
        update.setUpdateTime(now);
        withdrawalOrdersMapper.updateById(update);
        // 驳回时退回余额
        if (Constants.TWO.equals(dto.getStatus())) {
            Long amountFen = order.getAmount() != null ? order.getAmount() : 0L;
            if (amountFen > 0 && order.getMemberId() != null) {
                if (Constants.equalsInteger(order.getMemberType(), Constants.ONE)) {
                    // 司机:通过 memberId 查 DriverInfo,退回 balance
                    DriverInfo driver = driverInfoMapper.selectOne(new QueryWrapper<DriverInfo>().lambda()
                            .eq(DriverInfo::getMemberId, order.getMemberId())
                            .eq(DriverInfo::getDeleted, Constants.ZERO)
                            .last("limit 1"));
                    if (driver != null) {
                        driverInfoMapper.update(new UpdateWrapper<DriverInfo>().lambda()
                                .setSql(" BALANCE = IFNULL(BALANCE, 0) + " + amountFen)
                                .eq(DriverInfo::getId, driver.getId()));
                    }
                } else if (Constants.equalsInteger(order.getMemberType(), Constants.TWO)) {
                    // 门店:通过 memberId 查 ShopInfo,退回 balance
                    ShopInfo shop = shopInfoMapper.selectOne(new QueryWrapper<ShopInfo>().lambda()
                            .eq(ShopInfo::getRegionMemberId, order.getMemberId())
                            .eq(ShopInfo::getDeleted, Constants.ZERO)
                            .last("limit 1"));
                    if (shop != null) {
                        shopInfoMapper.update(new UpdateWrapper<ShopInfo>().lambda()
                                .setSql(" BALANCE = IFNULL(BALANCE, 0) + " + amountFen)
                                .eq(ShopInfo::getId, shop.getId()));
                    }
                }
                // 创建退回 Revenue 记录
                Revenue revenue = new Revenue();
                revenue.setMemberId(order.getMemberId());
                revenue.setMemberType(order.getMemberType());
                revenue.setType(Constants.TWO); // 2=提现退回
                revenue.setOptType(Constants.ONE); // 1=收入
                revenue.setAmount(amountFen);
                revenue.setVaildStatus(Constants.ONE); // 已入账
                revenue.setObjId(order.getId());
                revenue.setObjType(Constants.ONE); // 1=提现业务
                revenue.setStatus(Constants.ZERO);
                revenue.setDeleted(Constants.ZERO);
                revenue.setCreateTime(now);
                revenueMapper.insert(revenue);
            }
        }
    }
    private Integer getCurrentUserId() {
        com.doumee.core.model.LoginUserInfo user =
                (com.doumee.core.model.LoginUserInfo) org.apache.shiro.SecurityUtils.getSubject().getPrincipal();
        return user != null ? user.getId() : null;
    }
    private void fillUpdateUserName(WithdrawalOrders order) {
        if (order.getUserId() != null) {
            SystemUser user = systemUserMapper.selectById(order.getUserId());
            if (user != null) {
                order.setUpdateUserName(user.getUsername());
            }
        }
    }
    private void fillShopInfo(WithdrawalOrders order) {
        if (order.getMemberId() != null) {
            ShopInfo shop = shopInfoMapper.selectById(order.getMemberId());
            if (shop != null && !Constants.ONE.equals(shop.getDeleted())) {
                order.setShopInfo(shop);
                order.setShopName(shop.getName());
                order.setLinkName(shop.getLinkName());
            }
        }
    }
    private void fillMemberInfo(WithdrawalOrders order) {
        if (order.getMemberId() != null) {
            DriverInfo driver = driverInfoMapper.selectOne(
                    new QueryWrapper<DriverInfo>().lambda()
                            .eq(DriverInfo::getMemberId, order.getMemberId())
                            .eq(DriverInfo::getDeleted, Constants.ZERO)
                            .last("limit 1"));
            if (driver != null) {
                order.setMemberName(driver.getName());
                order.setMemberTelephone(driver.getTelephone());
            }
        }
    }
    @Override
    public void applyDriverWithdrawal(WithdrawalDTO dto, Integer memberId) {
        DriverInfo driver = driverInfoMapper.selectOne(new QueryWrapper<DriverInfo>().lambda()
                .eq(DriverInfo::getMemberId, memberId)
                .eq(DriverInfo::getDeleted, Constants.ZERO)
                .last("limit 1"));
        if (driver == null) {
            throw new BusinessException(ResponseStatus.DATA_EMPTY.getCode(), "司机信息不存在");
        }
        long amountFen = dto.getAmount().multiply(new BigDecimal(100)).setScale(0, BigDecimal.ROUND_HALF_UP).longValue();
        long balance = driver.getBalance() != null ? driver.getBalance() : 0L;
        if (amountFen <= 0) {
            throw new BusinessException(ResponseStatus.BAD_REQUEST.getCode(), "提现金额必须大于0");
        }
        if (amountFen > balance) {
            throw new BusinessException(ResponseStatus.BAD_REQUEST.getCode(), "提现金额不能超过可用余额");
        }
        String billNo = generateBillNo();
        Date now = new Date();
        // 扣减司机余额
        driverInfoMapper.update(new UpdateWrapper<DriverInfo>().lambda()
                .setSql(" BALANCE = IFNULL(BALANCE, 0) - " + amountFen)
                .eq(DriverInfo::getId, driver.getId()));
        // 创建提现记录
        WithdrawalOrders order = new WithdrawalOrders();
        order.setMemberId(memberId);
        order.setMemberType(Constants.ONE);
        order.setAmount(amountFen);
        order.setStatus(Constants.ZERO);
        order.setType(Constants.ZERO);
        order.setOutBillNo(billNo);
        order.setAliAccount(dto.getAliAccount());
        order.setDeleted(Constants.ZERO);
        order.setCreateTime(now);
        order.setUpdateTime(now);
        order.setCreateUser(memberId);
        withdrawalOrdersMapper.insert(order);
        // 创建支出 Revenue 记录
        Revenue revenue = new Revenue();
        revenue.setMemberId(memberId);
        revenue.setMemberType(Constants.ONE);
        revenue.setType(Constants.ONE);
        revenue.setOptType(-Constants.ONE);
        revenue.setAmount(amountFen);
        revenue.setVaildStatus(Constants.ONE);
        revenue.setObjId(order.getId());
        revenue.setObjType(Constants.ONE);
        revenue.setStatus(Constants.ZERO);
        revenue.setDeleted(Constants.ZERO);
        revenue.setCreateTime(now);
        revenueMapper.insert(revenue);
    }
    @Override
    public void applyShopWithdrawal(WithdrawalDTO dto, Integer shopId) {
        ShopInfo shop = shopInfoMapper.selectById(shopId);
        if (shop == null) {
            throw new BusinessException(ResponseStatus.DATA_EMPTY);
        }
        long amountFen = dto.getAmount().multiply(new BigDecimal(100)).setScale(0, BigDecimal.ROUND_HALF_UP).longValue();
        long balance = shop.getBalance() != null ? shop.getBalance() : 0L;
        if (amountFen <= 0) {
            throw new BusinessException(ResponseStatus.BAD_REQUEST.getCode(), "提现金额必须大于0");
        }
        if (amountFen > balance) {
            throw new BusinessException(ResponseStatus.BAD_REQUEST.getCode(), "提现金额不能超过可用余额");
        }
        String billNo = generateBillNo();
        Date now = new Date();
        // 扣减门店余额
        shopInfoMapper.update(new UpdateWrapper<ShopInfo>().lambda()
                .setSql(" BALANCE = IFNULL(BALANCE, 0) - " + amountFen)
                .eq(ShopInfo::getId, shopId));
        // 创建提现记录
        WithdrawalOrders order = new WithdrawalOrders();
        order.setMemberId(shop.getRegionMemberId());
        order.setMemberType(Constants.TWO);
        order.setAmount(amountFen);
        order.setStatus(Constants.ZERO);
        order.setType(Constants.ZERO);
        order.setOutBillNo(billNo);
        order.setAliAccount(dto.getAliAccount());
        order.setDeleted(Constants.ZERO);
        order.setCreateTime(now);
        order.setUpdateTime(now);
        order.setCreateUser(shop.getRegionMemberId());
        withdrawalOrdersMapper.insert(order);
        // 创建支出 Revenue 记录
        Revenue revenue = new Revenue();
        revenue.setMemberId(shop.getRegionMemberId());
        revenue.setMemberType(Constants.TWO);
        revenue.setType(Constants.ONE); // 1=提现支出
        revenue.setOptType(-Constants.ONE); // -1=支出
        revenue.setAmount(amountFen);
        revenue.setVaildStatus(Constants.ONE); // 已入账
        revenue.setObjId(order.getId());
        revenue.setObjType(Constants.ONE); // 1=提现业务
        revenue.setStatus(Constants.ZERO);
        revenue.setDeleted(Constants.ZERO);
        revenue.setCreateTime(now);
        revenueMapper.insert(revenue);
    }
    private String generateBillNo() {
        SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMddHHmmss");
        String random = String.valueOf(ThreadLocalRandom.current().nextInt(100000, 999999));
        return "TX" + sdf.format(new Date()) + random;
    }
}