rk
10 小时以前 cf17c2f7012fc4351f66c71d66a4aa3a9fe9e34a
server/services/src/main/java/com/doumee/service/business/impl/OrdersServiceImpl.java
@@ -1,15 +1,19 @@
package com.doumee.service.business.impl;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.doumee.biz.system.AreasBiz;
import com.doumee.config.xyy.XyyConfig;
import com.doumee.config.xyy.dto.PrintRequest;
import com.doumee.biz.system.OperationConfigBiz;
import com.doumee.biz.system.SystemDictDataBiz;
import com.doumee.config.wx.WxMiniConfig;
import com.doumee.config.wx.WxPayProperties;
import com.doumee.config.wx.WxPayV3Service;
import com.doumee.core.utils.jpush.JPushUtil;
import com.wechat.pay.java.service.refund.model.Refund;
import com.doumee.core.constants.Constants;
import com.doumee.core.constants.ResponseStatus;
@@ -55,6 +59,7 @@
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.*;
import java.text.SimpleDateFormat;
import java.util.concurrent.TimeUnit;
/**
@@ -129,6 +134,9 @@
    private AreasService areasService;
    @Autowired
    private AreasMapper aareasMapper;
    @Autowired
    private NoticeService noticeService;
    @Autowired
@@ -139,6 +147,12 @@
    @Autowired
    private WxPayProperties wxPayProperties;
    @Autowired
    private XyyConfig xyyConfig;
    @Autowired
    private PrintService printService;
    @Override
    public Integer create(Orders orders) {
@@ -216,7 +230,6 @@
                .leftJoin("shop_info s2 on s2.id = t.TAKE_SHOP_ID");
                ;
        Utils.MP.blankToNull(pageWrap.getModel());
        pageWrap.getModel().setDeleted(Constants.ZERO);
        queryWrapper.eq(pageWrap.getModel().getDeleted() != null, Orders::getDeleted, pageWrap.getModel().getDeleted());
        queryWrapper.like(StringUtils.isNotBlank(pageWrap.getModel().getCode()), Orders::getCode, pageWrap.getModel().getCode());
        queryWrapper.like(StringUtils.isNotBlank(pageWrap.getModel().getDepositShopName()), "s1.name", pageWrap.getModel().getDepositShopName());
@@ -234,13 +247,7 @@
        queryWrapper.eq(pageWrap.getModel().getAcceptDriver() != null, Orders::getAcceptDriver, pageWrap.getModel().getAcceptDriver());
        queryWrapper.and(pageWrap.getModel().getShopId() != null, i -> i.eq(Orders::getDepositShopId, pageWrap.getModel().getShopId())
                .or().eq(Orders::getTakeShopId, pageWrap.getModel().getShopId()));
        for (PageWrap.SortData sortData : pageWrap.getSorts()) {
            if (sortData.getDirection().equalsIgnoreCase(PageWrap.DESC)) {
                queryWrapper.orderByDesc(sortData.getProperty());
            } else {
                queryWrapper.orderByAsc(sortData.getProperty());
            }
        }
        queryWrapper.orderByDesc(Orders::getId);
        PageData<Orders> pageData = PageData.from(ordersMapper.selectJoinPage(page, Orders.class, queryWrapper));
        for (Orders o : pageData.getRecords()) {
            if (o.getStatus() != null) {
@@ -368,7 +375,7 @@
        for (Category c : categories) {
            categoryNameMap.put(c.getId(), c.getName());
            categoryDetailMap.put(c.getId(), c.getDetail());
            categoryOtherFieldMap.put(c.getId(),c.getOtherField());
            categoryOtherFieldMap.put(c.getId(),c.getRemark());
        }
        // 计算每项物品费用:小计 = 单价 × 数量 × 天数
@@ -490,7 +497,7 @@
        for (Category c : categories) {
            categoryNameMap.put(c.getId(), c.getName());
            categoryDetailMap.put(c.getId(), c.getDetail());
            categoryOtherFieldMap.put(c.getId(),c.getOtherField());
            categoryOtherFieldMap.put(c.getId(),c.getRemark());
        }
        // 3. 逐项计算运费:起步价 + 超出部分阶梯价
@@ -1600,12 +1607,13 @@
        // 门店待处理订单:按业务环节区分门店角色
        if (combinedStatus != null && Constants.equalsInteger(combinedStatus, Constants.SEVEN)) {
            wrapper.and(w -> w
                    .and(w1 -> w1.eq(Orders::getDepositShopId, shopId)
                    .and(w1 -> w1.eq(Orders::getType, Constants.ZERO).eq(Orders::getDepositShopId, shopId)
                            .in(Orders::getStatus, Constants.OrderStatus.waitDeposit.getStatus(),
                                    Constants.OrderStatus.deposited.getStatus()))
                    .or(w2 -> w2.eq(Orders::getTakeShopId, shopId)
                            .in(Orders::getStatus, Constants.OrderStatus.delivering.getStatus(),
                                    Constants.OrderStatus.arrived.getStatus()))
                                    Constants.OrderStatus.arrived.getStatus())
                    .or(w3-> w3.eq(Orders::getType, Constants.ONE).eq(Orders::getDepositShopId, shopId)
                            .eq(Orders::getStatus, Constants.OrderStatus.waitDeposit.getStatus()))
                    .or(w2 -> w2.eq(Orders::getType, Constants.ONE).eq(Orders::getTakeShopId, shopId)
                            .eq(Orders::getStatus, Constants.OrderStatus.arrived.getStatus())))
            );
        } else {
            wrapper.and(w -> w.eq(Orders::getDepositShopId, shopId).or().eq(Orders::getTakeShopId, shopId));
@@ -2414,13 +2422,13 @@
        // 6. 押金支付完成后,若城市未开通则自动开通
        if (shopInfo.getAreaId() != null) {
            Areas shopArea = areasService.getById(shopInfo.getAreaId());
            Areas shopArea = aareasMapper.selectById(shopInfo.getAreaId());
            if (shopArea != null && shopArea.getParentId() != null) {
                Areas cityArea = areasService.getById(shopArea.getParentId());
                Areas cityArea = aareasMapper.selectById(shopArea.getParentId());
                if (cityArea != null && !Constants.equalsInteger(cityArea.getStatus(), Constants.ONE)) {
                    cityArea.setStatus(Constants.ONE);
                    cityArea.setEditDate(now);
                    areasService.updateById(cityArea);
                    aareasMapper.updateById(cityArea);
                    areasService.cacheData();
                }
            }
@@ -2758,6 +2766,8 @@
                // 异地寄存 → 待抢单
                sendOrderNotice(order.getMemberId(), Constants.MemberOrderNotify.WAIT_GRAB, order.getId(),
                        "orderNo", order.getCode());
                // 推送通知司机
                pushDriverNewOrder(order);
            } else {
                // 就地寄存 → 待取件提醒
                sendOrderNotice(order.getMemberId(), Constants.MemberOrderNotify.WAIT_PICKUP_REMIND, order.getId(),
@@ -2917,6 +2927,8 @@
                // 异地寄存 → 待抢单
                sendOrderNotice(order.getMemberId(), Constants.MemberOrderNotify.WAIT_GRAB, order.getId(),
                        "orderNo", order.getCode());
                // 推送通知司机
                pushDriverNewOrder(order);
            } else {
                // 就地寄存 → 待取件提醒
                sendOrderNotice(order.getMemberId(), Constants.MemberOrderNotify.WAIT_PICKUP_REMIND, order.getId(),
@@ -3580,7 +3592,10 @@
     * 供分页等已查询明细的业务场景复用,避免重复查询
     */
    private OverdueFeeVO calculateOverdueFeeInternal(Orders order, List<OrdersDetail> details) {
        if (CollectionUtils.isEmpty(details)) {
        if (CollectionUtils.isEmpty(details)||
                Constants.equalsInteger(order.getStatus(),Constants.ZERO)
        || Constants.equalsInteger(order.getStatus(),Constants.ONE)
        ) {
            OverdueFeeVO vo = new OverdueFeeVO();
            vo.setOverdue(false);
            vo.setOverdueDays(0);
@@ -4107,4 +4122,102 @@
        }
    }
    @Override
    public void printOrderLabel(Integer orderId, Integer shopId) {
        Orders orders = ordersMapper.selectById(orderId);
        if (orders == null) {
            throw new BusinessException(ResponseStatus.DATA_EMPTY.getCode(), "订单不存在");
        }
        if (!Constants.equalsInteger(orders.getDepositShopId(), shopId)) {
            throw new BusinessException(ResponseStatus.BAD_REQUEST.getCode(), "当前门店不是该订单的存件门店");
        }
        if (orders.getStatus() < 2 || orders.getStatus() > 5) {
            throw new BusinessException(ResponseStatus.BAD_REQUEST.getCode(), "当前订单状态不允许打印");
        }
        ShopInfo shop = shopInfoMapper.selectById(shopId);
        if (shop == null) {
            throw new BusinessException(ResponseStatus.DATA_EMPTY.getCode(), "存件门店不存在");
        }
        if (StringUtils.isBlank(shop.getPrinterSn())) {
            throw new BusinessException(ResponseStatus.BAD_REQUEST.getCode(), "存件门店未绑定打印机");
        }
        List<OrdersDetail> detailList = ordersDetailMapper.selectList(
                new QueryWrapper<OrdersDetail>().lambda().eq(OrdersDetail::getOrderId, orderId));
        // 拼接客户信息
        String userInfo = "";
        if (StringUtils.isNotBlank(orders.getTakeUser())) {
            String phone = orders.getTakePhone();
            userInfo = orders.getTakeUser();
            if (StringUtils.isNotBlank(phone) && phone.length() >= 4) {
                userInfo += "(" + phone.substring(phone.length() - 4) + ")";
            }
        }
        String content = printService.getPrintContent(shop.getName(), detailList, userInfo, orders.getCode(), orders.getRemark(),
                orders.getTakeLocationRemark(),
                orders.getPayTime() != null ? new SimpleDateFormat("yyyy-MM-dd HH:mm").format(orders.getPayTime()) : "",
                orders.getExpectedTakeTime() != null ? new SimpleDateFormat("yyyy-MM-dd HH:mm").format(orders.getExpectedTakeTime()) : "");
        if (StringUtils.isBlank(content)) {
            throw new BusinessException(ResponseStatus.BAD_REQUEST.getCode(), "打印内容为空");
        }
        PrintRequest request = new PrintRequest();
        xyyConfig.createRequestHeader(request);
        request.setSn(shop.getPrinterSn());
        request.setContent(content);
        request.setCopies(1);
        request.setVoice(2);
        request.setMode(0);
        com.doumee.config.xyy.vo.ObjectRestResponse<String> resp = printService.printLabel(request);
        if (resp.getCode() != 0) {
            throw new BusinessException(ResponseStatus.BAD_REQUEST.getCode(), "打印失败:" + resp.getMsg());
        }
        log.info("订单标签打印成功: orderId={}, orderIndex={}", orderId, resp.getData());
    }
    /**
     * 异地订单寄存成功后推送通知给司机
     * 1、未加急:推送同城且门店配送范围内接单中的司机
     * 2、加急:推送同城所有接单中的司机
     * 城市匹配:司机AREA_ID关联areas表,逐级parent_id找到城市级,与订单cityId匹配
     */
    private void pushDriverNewOrder(Orders order) {
        ShopInfo shop = shopInfoMapper.selectById(order.getDepositShopId());
        if (shop == null || shop.getLongitude() == null || shop.getLatitude() == null) {
            return;
        }
        String orderCityId = order.getCityId();
        if (StringUtils.isBlank(orderCityId)) {
            return;
        }
        String distSql = "(ST_Distance_Sphere(POINT(t.LONGITUDE, t.LATITUDE), POINT(" + shop.getLongitude() + ", " + shop.getLatitude() + ")) / 1000)";
        // MPJ关联查询:司机 → areas(区县) → areas_city(城市),匹配订单cityId
        MPJLambdaWrapper<DriverInfo> wrapper = new MPJLambdaWrapper<>();
        wrapper.selectAll(DriverInfo.class)
                .leftJoin(Areas.class,Areas::getId,DriverInfo::getAreaId)
                .eq(DriverInfo::getAcceptingStatus, Constants.ONE)
                .eq(DriverInfo::getStatus, Constants.ZERO)
                .eq(DriverInfo::getDeleted, Constants.ZERO)
                .eq(DriverInfo::getAuditStatus, Constants.THREE)
                .eq(Areas::getParentId, orderCityId);
        if (!Constants.equalsInteger(order.getIsUrgent(), Constants.ONE)) {
            // 未加急:门店配送范围内
            double rangeKm = shop.getDeliveryArea() != null ? shop.getDeliveryArea().doubleValue() : 5.0;
            wrapper.apply(distSql + " <= {0}", rangeKm);
        }
        List<DriverInfo> drivers = driverInfoMapper.selectJoinList(DriverInfo.class, wrapper);
        if (drivers.isEmpty()) {
            return;
        }
        List<String> aliases = new ArrayList<>();
        for (DriverInfo d : drivers) {
            aliases.add(org.springframework.util.DigestUtils.md5DigestAsHex(d.getTelephone().getBytes()));
        }
        String title = Constants.equalsInteger(order.getIsUrgent(), Constants.ONE) ? "新加急订单" : "新订单";
        String content = "订单号:" + order.getCode();
        java.util.Map<String, String> extras = new java.util.HashMap<>();
        extras.put("orderId", String.valueOf(order.getId()));
        extras.put("orderCode", order.getCode());
        extras.put("type", "new_order");
        JPushUtil.sendByAliases(aliases, title, content, extras);
    }
}