package com.ruoyi.system.task; import cn.hutool.core.util.StrUtil; import com.ruoyi.common.constant.ServiceConstants; import com.ruoyi.common.utils.DateUtils; import com.ruoyi.common.utils.ServiceUtil; import com.ruoyi.common.utils.YPMsgUtils; import com.ruoyi.common.utils.uuid.IdUtils; import com.ruoyi.ss.clean.domain.Clean; import com.ruoyi.ss.clean.domain.CleanQuery; import com.ruoyi.ss.clean.domain.CleanVO; import com.ruoyi.ss.clean.service.ICleanService; import com.ruoyi.ss.device.service.DeviceService; import com.ruoyi.ss.order.domain.Order; import com.ruoyi.ss.order.domain.OrderVO; import com.ruoyi.ss.order.service.IOrderService; import com.ruoyi.ss.orderOper.service.IOrderOperService; import com.ruoyi.ss.pay.service.IWxPayService; import com.ruoyi.ss.payBill.domain.PayBill; import com.ruoyi.ss.payBill.domain.PayBillQuery; import com.ruoyi.ss.payBill.domain.enums.PayBillStatus; import com.ruoyi.ss.payBill.service.PayBillService; import com.ruoyi.ss.refund.domain.RefundDTO; import com.ruoyi.ss.refund.service.IRefundService; import com.ruoyi.ss.room.domain.Room; import com.ruoyi.ss.room.domain.RoomVO; import com.ruoyi.ss.room.service.IRoomService; import com.ruoyi.ss.user.domain.UserVO; import com.ruoyi.ss.user.service.IUserService; import com.ruoyi.system.iot.service.IotService; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; import org.springframework.transaction.annotation.Transactional; import org.springframework.transaction.support.TransactionTemplate; import javax.annotation.PostConstruct; import javax.annotation.Resource; import java.math.BigDecimal; import java.util.Date; import java.util.List; import java.util.Objects; import static com.ruoyi.common.constant.ServiceConstants.IS_REFUND_STATUS_PENDING; import static com.ruoyi.common.constant.ServiceConstants.IS_REFUND_STATUS_REFUNDED; import static com.ruoyi.common.utils.SecurityUtils.getUserId; /** * 定时任务调度测试 * * @author ruoyi */ @Slf4j @Component("ssTask") public class SsTask { @Resource private IOrderService orderService; @Autowired private ICleanService cleanService; @Autowired private IUserService userService; @Autowired private IRoomService roomService; @Resource private IWxPayService wxPayService; @Autowired private TransactionTemplate transactionTemplate; @Autowired private DeviceService smDeviceService; @Autowired private PayBillService paymentService; @Autowired private IOrderOperService orderOperService; @Autowired private IRefundService refundService; @Autowired private IotService iotService; /** * 1.启动时判断是否有未取消预约的订单 * 2.判断已完成的订单未退还押金的 * 3.启动时判断是否分账 */ @Transactional @PostConstruct public void init() { } /** * 结束订单处理 * 查询未结束已到期的订单,通知保洁,修改订单状态 */ public void orderEndHandler(){ log.info("-------------------【定时任务】结束订单处理---开始----------------"); List orderVOS = orderService.selectEndOrderList(); for (OrderVO orderVO: orderVOS) { if(!orderVO.getIsSendMsg()){//没有通知过去通知保洁。修改订单状态:已结束、通知状态:已通知 orderVO.setIsSendMsg(true); // todo 通知保洁, 发送短信 店铺id,保洁 String merchantPhone = orderVO.getMerchantPhone(); YPMsgUtils.sendClearMsg(orderVO.getRoomName(),merchantPhone); Clean clean = cleanService.buildClean(orderVO); int i = cleanService.insertEClean(clean); ServiceUtil.assertion(i==0,"生成保洁订单失败"); } updateOrderStatus(orderVO,ServiceConstants.ORDER_STATUS_COMPLETED); // todo 改变房间状态,改为未打扫 updateRoomStatus(orderVO,ServiceConstants.ROOM_STATUS_UNCLEANED); } log.info("-------------------【定时任务】结束订单处理---结束----------------"); } /** * 开始使用处理 * 查询待使用的订单,判断是否超过当前时间, * 如果超过当前时间修改订单状态:使用中 * 房间也更新状态为使用中 * 如果未超过当前时间则不修改 分成 user_divide 提现 */ public void orderStartHandler(){ log.info("-------------------【定时任务】开始使用处理---开始----------------"); List orderVOS = orderService.selectToeUsedOrderList(); for (OrderVO orderVO: orderVOS) { if(orderVO.getReserveStartTime().before(DateUtils.getNowDate()) && orderVO.getReserveEndTime().after(DateUtils.getNowDate())){ Boolean execute = transactionTemplate.execute(e -> { // 订单中的预定开始时间 是否已超过当前时间 updateOrderStatus(orderVO,ServiceConstants.ORDER_STATUS_IN_USE); // 改变房间状态,改为使用中 updateRoomStatus(orderVO,ServiceConstants.ROOM_STATUS_INUSE); // 发送一次房间的全开 用time 门打开 其他的用settime smDeviceService.roomAllDeviceSetTime(orderVO, "(到预约时间后)下单成功后房间全开"); return Boolean.TRUE; }); } } log.info("-------------------【定时任务】开始使用处理---结束----------------"); } /** * 自动完成打扫处理 */ public void autoCompleteCleaning(){ log.info("-------------------【定时任务】自动完成打扫处理---开始----------------"); CleanQuery cleanQuery = new CleanQuery(); cleanQuery.setStatus(ServiceConstants.STATUS_PENDING_CLEANING); List cleanVOS = cleanService.selectECleanList(cleanQuery); if(cleanVOS.isEmpty()){ return; } for (CleanVO clean: cleanVOS) { Boolean execute = transactionTemplate.execute(e -> { Long merchantId = clean.getMerchantId(); UserVO userVO = userService.selectUserById(merchantId); if(!Objects.isNull(userVO)){ Integer cleanDuration = userVO.getCleanDuration(); int i = DateUtils.timeDifferenceInMinutes(DateUtils.getNowDate(), clean.getStartTime()); if(i>=cleanDuration){ boolean i1 = cleanService.completeCleaning(clean.getCleanId()); log.info("【自动完成打扫】{}", i1? "失败" : "成功"); } } return Boolean.TRUE; }); } log.info("-------------------【定时任务】自动完成打扫处理---结束----------------"); } /** * 押金自动退还处理 30秒执行一次 * 查询所有智能押金模式下,还未退款的订单,根据实际退款时间退款 */ public void depositAutoRefund(){ log.info("-------------------【定时任务】押金自动退还处理---开始----------------"); List orderVOS = orderService.selectNotRefundedOrderList(); for (OrderVO orderVO: orderVOS) { if(orderVO.getIsRefund().equals(IS_REFUND_STATUS_PENDING)){ // todo 是否加锁?判空 // todo 更新订单是否退款状态 Boolean execute = transactionTemplate.execute(e -> { Order order = new Order(); order.setIsRefund(IS_REFUND_STATUS_REFUNDED); order.setOrderNo(orderVO.getOrderNo()); int i = orderService.updateRlOrderByOrderNo(order); ServiceUtil.assertion(i==0,"更新订单是否退款状态失败"); // 更新支付单状态为退款中 PayBill updatedPayBill = new PayBill(); updatedPayBill.setStatus(PayBillStatus.REFUNDING.getStatus()); PayBillQuery billQuery = new PayBillQuery(); billQuery.setPayId(orderVO.getPayId()); billQuery.setStatus(PayBillStatus.PAY_SUCCESS.getStatus()); int i2 = paymentService.updateByQuery(updatedPayBill,billQuery); ServiceUtil.assertion(i2 != 1, "修改支付订单状态失败"); // 增加退款中金额 int addRefunding = paymentService.addRefundingAmount(orderVO.getPayId(), orderVO.getDepositRefund()); ServiceUtil.assertion(addRefunding != 1, "记录退款中的金额失败"); // 记录订单履历 String desc = "押金模式自动退款金额:"+orderVO.getDepositRefund()+"元"; boolean b = orderOperService.recordOrderHistory(orderVO.getOrderNo(), ServiceConstants.ORDER_OPERATION_REFUND, orderVO.getStatus(), orderVO.getStatus(), orderVO.getPayFee(), orderVO.getPayFee(),null , null, desc); ServiceUtil.assertion(!b, "记录订单履历失败"); BigDecimal depositRefund = orderVO.getDepositRefund(); BigDecimal usedFee = orderVO.getPayFee();//已使用金额 orderVO.setPayFee(orderVO.getDeposit());//退款金额 // 保存退款记录 RefundDTO refundDTO = new RefundDTO(); refundDTO.setPayId(orderVO.getPayId()); refundDTO.setAmount(depositRefund); refundDTO.setReason(StrUtil.format("押金模式自动退款:押金=【{}】,已使用金额=【{}】,退还金额=【{}】", orderVO.getDeposit(),usedFee,depositRefund)); String refNo = refundService.saveRefund(refundDTO, null,orderVO); wxPayService.refund(orderVO,"订单结束,已使用金额:"+usedFee+",退还剩余金额:"+depositRefund, depositRefund,refNo,orderVO.getPayNo()); return Boolean.TRUE; }); } } log.info("-------------------【定时任务】押金自动退还处理---结束----------------"); } /** * 到期提醒 */ public void expirationReminder(){ log.info("-------------------【定时任务】到期提醒---开始----------------"); List orderVOS = orderService.selectExpirationReminderOrderList(); if(orderVOS.isEmpty()){ return; } for (OrderVO order : orderVOS) { Boolean execute = transactionTemplate.execute(e -> { int i = DateUtils.timeDifferenceInMinutes(DateUtils.getNowDate(), order.getReminderTime()); if(i<=5){ // 发送提醒命令 log.info("【到期提醒】发送提醒命令"); // 发送一次房间的全开 用time 门打开 其他的用settime UserVO userVO = userService.selectUserById(order.getMerchantId()); Integer reminder = userVO.getReminder(); long reminderSeconds = 5 * 60L; if(reminder != null){ reminderSeconds = reminder * 60L; } log.info("【到期提醒】,开始发送命令:{}秒之后后关闭", reminderSeconds); smDeviceService.roomAllDeviceSerVoice(order, reminderSeconds); // 更新订单 Order updateOrder = new Order(); updateOrder.setOrderNo(order.getOrderNo()); updateOrder.setIsReminded(true); int i1 = orderService.updateRlOrderByOrderNo(updateOrder); log.info("【到期提醒】更新订单状态{}", i1==0? "失败" : "成功"); } return Boolean.TRUE; }); } log.info("-------------------【定时任务】到期提醒---结束----------------"); } private void updateRoomStatus(OrderVO orderVO,String status) { Room room = new Room(); room.setRoomId(orderVO.getRoomId()); room.setStatus(status); int i = roomService.updateERoom(room); ServiceUtil.assertion(i==0,"更新房间状态失败"); } private void updateOrderStatus(OrderVO orderVO,String status) { orderVO.setStatus(status); int i = orderService.updateRlOrderByOrderNo(orderVO); ServiceUtil.assertion(i==0,"更新订单状态失败"); } }