| | |
| | | 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; |
| | |
| | | import java.math.BigDecimal; |
| | | import java.math.RoundingMode; |
| | | import java.util.*; |
| | | import java.text.SimpleDateFormat; |
| | | import java.util.concurrent.TimeUnit; |
| | | |
| | | /** |
| | |
| | | private AreasService areasService; |
| | | |
| | | @Autowired |
| | | private AreasMapper aareasMapper; |
| | | |
| | | @Autowired |
| | | private NoticeService noticeService; |
| | | |
| | | @Autowired |
| | |
| | | |
| | | @Autowired |
| | | private WxPayProperties wxPayProperties; |
| | | |
| | | @Autowired |
| | | private XyyConfig xyyConfig; |
| | | |
| | | @Autowired |
| | | private PrintService printService; |
| | | |
| | | @Override |
| | | public Integer create(Orders orders) { |
| | |
| | | .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()); |
| | |
| | | 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) { |
| | |
| | | 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()); |
| | | } |
| | | |
| | | // 计算每项物品费用:小计 = 单价 × 数量 × 天数 |
| | |
| | | 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. 逐项计算运费:起步价 + 超出部分阶梯价 |
| | |
| | | // 门店待处理订单:按业务环节区分门店角色 |
| | | 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)); |
| | |
| | | |
| | | // 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(); |
| | | } |
| | | } |
| | |
| | | // 异地寄存 → 待抢单 |
| | | 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(), |
| | |
| | | // 异地寄存 → 待抢单 |
| | | 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(), |
| | |
| | | * 供分页等已查询明细的业务场景复用,避免重复查询 |
| | | */ |
| | | 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); |
| | |
| | | } |
| | | } |
| | | |
| | | @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); |
| | | } |
| | | |
| | | } |