| | |
| | | import com.doumee.dao.business.model.Orders; |
| | | import com.doumee.dao.business.model.OrdersDetail; |
| | | import com.doumee.dao.business.model.Revenue; |
| | | import com.doumee.dao.dto.*; |
| | | import com.doumee.dao.vo.AccountResponse; |
| | | import com.doumee.dao.vo.DriverCenterVO; |
| | | import com.doumee.dao.vo.DriverGrabOrderVO; |
| | | import com.doumee.dao.vo.DriverOrderDetailVO; |
| | | import com.doumee.dao.dto.AuditDTO; |
| | | import com.doumee.dao.dto.ChangeStatusDTO; |
| | | import com.doumee.dao.dto.DriverLoginRequest; |
| | | import com.doumee.dao.dto.DriverRegisterRequest; |
| | | import com.doumee.dao.dto.DriverVerifyRequest; |
| | | import com.doumee.dao.dto.DriverActiveOrderDTO; |
| | | import com.doumee.dao.dto.DriverGrabOrderDTO; |
| | | import com.doumee.core.utils.aliyun.AliSmsService; |
| | | import com.doumee.dao.business.model.Notice; |
| | | import com.doumee.service.business.DriverInfoService; |
| | | import com.doumee.service.business.NoticeService; |
| | | import com.alibaba.fastjson.JSONObject; |
| | | import com.github.yulichang.wrapper.MPJLambdaWrapper; |
| | | import org.apache.commons.lang3.RandomStringUtils; |
| | |
| | | |
| | | @Autowired |
| | | private OperationConfigBiz operationConfigBiz; |
| | | |
| | | @Autowired |
| | | private NoticeService noticeService; |
| | | |
| | | /** |
| | | * 发送订单站内信通知 |
| | | */ |
| | | private void sendOrderNotice(Integer memberId, Constants.MemberOrderNotify notify, Integer orderId, String... params) { |
| | | Notice notice = new Notice(); |
| | | notice.setUserType(0); // 0=会员 |
| | | notice.setUserId(memberId); |
| | | notice.setTitle(notify.getTitle()); |
| | | notice.setContent(notify.format(params)); |
| | | notice.setObjId(orderId); |
| | | notice.setObjType(0); // 0=订单 |
| | | notice.setStatus(0); // 0=未读 |
| | | notice.setIsdeleted(Constants.ZERO); |
| | | notice.setCreateDate(new Date()); |
| | | noticeService.create(notice); |
| | | } |
| | | |
| | | /** |
| | | * 发送门店站内信通知 |
| | | */ |
| | | private void sendShopNotice(Integer shopId, Constants.ShopOrderNotify notify, Integer orderId, String... params) { |
| | | Notice notice = new Notice(); |
| | | notice.setUserType(2); // 2=门店 |
| | | notice.setUserId(shopId); |
| | | notice.setTitle(notify.getTitle()); |
| | | notice.setContent(notify.format(params)); |
| | | notice.setObjId(orderId); |
| | | notice.setObjType(0); // 0=订单 |
| | | notice.setStatus(0); // 0=未读 |
| | | notice.setIsdeleted(Constants.ZERO); |
| | | notice.setCreateDate(new Date()); |
| | | noticeService.create(notice); |
| | | } |
| | | |
| | | @Override |
| | | public Integer create(DriverInfo driverInfo) { |
| | |
| | | .set(DriverInfo::getCardEndDate, request.getCardEndDate()) |
| | | .set(DriverInfo::getIdcardImg, request.getIdcardImg()) |
| | | .set(DriverInfo::getIdcardImgBack, request.getIdcardImgBack()) |
| | | .set(DriverInfo::getAuditStatus, Constants.ZERO) |
| | | .set(DriverInfo::getAliAccount, request.getAliAccount()) |
| | | .set(DriverInfo::getAliName, request.getAliName()) |
| | | .set(DriverInfo::getUpdateTime, now) |
| | | .set(DriverInfo::getAuditRemark, null) |
| | | .set(DriverInfo::getAuditTime, null) |
| | |
| | | log.setCreateTime(new Date()); |
| | | log.setDeleted(Constants.ZERO); |
| | | orderLogMapper.insert(log); |
| | | |
| | | // 通知会员:司机变更 |
| | | sendOrderNotice(order.getMemberId(), Constants.MemberOrderNotify.DRIVER_CHANGED, orderId, |
| | | "orderNo", order.getCode()); |
| | | } |
| | | |
| | | @Override |
| | | @Transactional(rollbackFor = Exception.class) |
| | | public void grabOrder(Integer driverId, Integer orderId) { |
| | | // 1. 校验司机 |
| | | DriverInfo driver = driverInfoMapper.selectById(driverId); |
| | | if (driver == null) { |
| | | throw new BusinessException(ResponseStatus.DATA_EMPTY.getCode(), "司机信息不存在"); |
| | | } |
| | | // 2. 校验司机接单状态 |
| | | if (!Constants.ONE.equals(driver.getAcceptingStatus())) { |
| | | throw new BusinessException(ResponseStatus.BAD_REQUEST.getCode(), "请先开启接单状态"); |
| | | } |
| | | if (!Integer.valueOf(3).equals(driver.getAuditStatus())) { |
| | | throw new BusinessException(ResponseStatus.BAD_REQUEST.getCode(), "司机审核未通过或未缴纳押金"); |
| | | } |
| | | if (driver.getDriverLevel() == null) { |
| | | throw new BusinessException(ResponseStatus.BAD_REQUEST.getCode(), "司机等级未设置"); |
| | | } |
| | | |
| | | // 3. 校验订单 |
| | | Orders order = ordersMapper.selectById(orderId); |
| | | if (order == null || Constants.ONE.equals(order.getDeleted())) { |
| | | throw new BusinessException(ResponseStatus.DATA_EMPTY.getCode(), "订单不存在"); |
| | | } |
| | | if (!Constants.ONE.equals(order.getType())) { |
| | | throw new BusinessException(ResponseStatus.BAD_REQUEST.getCode(), "仅异地寄存订单可抢单"); |
| | | } |
| | | if (!Constants.TWO.equals(order.getStatus())) { |
| | | throw new BusinessException(ResponseStatus.BAD_REQUEST.getCode(), "当前订单状态不允许抢单"); |
| | | } |
| | | |
| | | // 4. 校验司机等级 ≥ 订单等级 |
| | | if (order.getGoodLevel() != null && driver.getDriverLevel() < order.getGoodLevel()) { |
| | | throw new BusinessException(ResponseStatus.BAD_REQUEST.getCode(), "司机等级不足,无法抢该订单"); |
| | | } |
| | | |
| | | // 5. 原子更新:带 status=2 条件防止并发重复抢单 |
| | | Date now = new Date(); |
| | | int rows = ordersMapper.update(new UpdateWrapper<Orders>().lambda() |
| | | .set(Orders::getAcceptDriver, driverId) |
| | | .set(Orders::getAcceptTime, now) |
| | | .set(Orders::getAcceptType, 0) // 0=手动抢单 |
| | | .set(Orders::getStatus, Constants.OrderStatus.accepted.getStatus()) |
| | | .set(Orders::getUpdateTime, now) |
| | | .eq(Orders::getId, orderId) |
| | | .eq(Orders::getStatus, Constants.TWO)); |
| | | if (rows == 0) { |
| | | throw new BusinessException(ResponseStatus.BAD_REQUEST.getCode(), "抢单失败,订单已被抢或状态已变更"); |
| | | } |
| | | |
| | | // 6. 写入操作日志 |
| | | OrderLog log = new OrderLog(); |
| | | log.setOrderId(orderId); |
| | | log.setTitle("司机抢单"); |
| | | log.setLogInfo("司机【" + driver.getName() + "】抢单成功"); |
| | | log.setObjType(Constants.ORDER_LOG_DRIVER_PICKUP); |
| | | log.setOptUserId(driver.getMemberId()); |
| | | log.setOptUserType(Constants.ONE); |
| | | log.setOrderStatus(Constants.OrderStatus.accepted.getStatus()); |
| | | log.setCreateTime(now); |
| | | log.setDeleted(Constants.ZERO); |
| | | orderLogMapper.insert(log); |
| | | |
| | | // 7. 通知会员:司机已抢单 |
| | | sendOrderNotice(order.getMemberId(), Constants.MemberOrderNotify.WAIT_PICKUP_GRABBED, orderId, |
| | | "driverName", driver.getName()); |
| | | |
| | | // 通知存件门店:订单已抢单待取件 |
| | | if (order.getDepositShopId() != null) { |
| | | sendShopNotice(order.getDepositShopId(), Constants.ShopOrderNotify.WAIT_PICKUP, orderId, |
| | | "orderNo", order.getCode()); |
| | | } |
| | | } |
| | | |
| | | @Override |
| | | @Transactional |
| | | public void confirmPickup(Integer driverId, DriverPickupDTO dto) { |
| | | Integer orderId = dto.getOrderId(); |
| | | |
| | | // 1. 校验司机 |
| | | DriverInfo driver = driverInfoMapper.selectById(driverId); |
| | | if (driver == null) { |
| | | throw new BusinessException(ResponseStatus.DATA_EMPTY.getCode(), "司机信息不存在"); |
| | | } |
| | | |
| | | // 2. 校验订单 |
| | | Orders order = ordersMapper.selectById(orderId); |
| | | if (order == null || Constants.ONE.equals(order.getDeleted())) { |
| | | throw new BusinessException(ResponseStatus.DATA_EMPTY.getCode(), "订单不存在"); |
| | | } |
| | | if (!Constants.ONE.equals(order.getType())) { |
| | | throw new BusinessException(ResponseStatus.BAD_REQUEST.getCode(), "仅异地寄存订单支持此操作"); |
| | | } |
| | | if (!Constants.equalsInteger(order.getStatus(), Constants.OrderStatus.accepted.getStatus())) { |
| | | throw new BusinessException(ResponseStatus.BAD_REQUEST.getCode(), "当前订单状态不允许取件确认"); |
| | | } |
| | | if (!driverId.equals(order.getAcceptDriver())) { |
| | | throw new BusinessException(ResponseStatus.NOT_ALLOWED.getCode(), "无权操作该订单"); |
| | | } |
| | | |
| | | // 3. 保存取件图片 |
| | | Date now = new Date(); |
| | | if (dto.getImages() != null && !dto.getImages().isEmpty()) { |
| | | int sortNum = 0; |
| | | for (String url : dto.getImages()) { |
| | | Multifile multifile = new Multifile(); |
| | | multifile.setObjId(orderId); |
| | | multifile.setObjType(Constants.FileType.DRIVER_TAKE.getKey()); |
| | | multifile.setType(Constants.ZERO); |
| | | multifile.setFileurl(url); |
| | | multifile.setIsdeleted(Constants.ZERO); |
| | | multifile.setCreateDate(now); |
| | | multifile.setSortnum(sortNum++); |
| | | multifileMapper.insert(multifile); |
| | | } |
| | | } |
| | | |
| | | // 4. 更新订单状态为派送中(4) |
| | | ordersMapper.update(new UpdateWrapper<Orders>().lambda() |
| | | .set(Orders::getStatus, Constants.OrderStatus.delivering.getStatus()) |
| | | .set(Orders::getUpdateTime, now) |
| | | .eq(Orders::getId, orderId)); |
| | | |
| | | // 5. 写入操作日志 |
| | | OrderLog log = new OrderLog(); |
| | | log.setOrderId(orderId); |
| | | log.setTitle("司机完成取件"); |
| | | log.setLogInfo("司机【" + driver.getName() + "】完成取件,开始派送"); |
| | | log.setObjType(Constants.ORDER_LOG_DRIVER_PICKUP); |
| | | log.setOptUserId(driver.getMemberId()); |
| | | log.setOptUserType(Constants.ONE); |
| | | log.setOrderStatus(Constants.OrderStatus.delivering.getStatus()); |
| | | log.setCreateTime(now); |
| | | log.setDeleted(Constants.ZERO); |
| | | orderLogMapper.insert(log); |
| | | |
| | | // 通知会员:订单配送中 |
| | | sendOrderNotice(order.getMemberId(), Constants.MemberOrderNotify.DELIVERING, orderId, |
| | | "orderNo", order.getCode(), |
| | | "driverName", driver.getName()); |
| | | |
| | | // 通知取件门店:订单配送中 |
| | | if (order.getTakeShopId() != null) { |
| | | sendShopNotice(order.getTakeShopId(), Constants.ShopOrderNotify.DELIVERING, orderId, |
| | | "orderNo", order.getCode(), |
| | | "driverName", driver.getName()); |
| | | } |
| | | } |
| | | |
| | | private List<String> getFileUrls(Integer orderId, int objType, String prefix) { |