package com.stylefeng.guns.modular.system.util; import cn.hutool.core.io.FileUtil; import com.amazonaws.services.s3.AmazonS3; import com.amazonaws.services.s3.AmazonS3Client; import com.baomidou.mybatisplus.mapper.EntityWrapper; import com.stylefeng.guns.core.intercept.SessionHolderInterceptor; import com.stylefeng.guns.modular.system.dao.DriverWorkMapper; import com.stylefeng.guns.modular.system.model.Driver; import com.stylefeng.guns.modular.system.model.DriverWork; import com.stylefeng.guns.modular.system.service.IDriverService; import com.stylefeng.guns.modular.system.service.IUserCouponRecordService; import com.stylefeng.guns.modular.system.util.s3.S3Sample; import com.stylefeng.guns.modular.taxi.model.OrderTaxi; import com.stylefeng.guns.modular.taxi.service.IOrderTaxiService; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.scheduling.annotation.Scheduled; import org.springframework.stereotype.Component; import org.springframework.util.StringUtils; import javax.sound.sampled.AudioFormat; import javax.sound.sampled.AudioInputStream; import javax.sound.sampled.AudioSystem; import javax.sound.sampled.UnsupportedAudioFileException; import java.io.*; import java.nio.file.Files; import java.time.LocalDateTime; import java.time.ZoneOffset; import java.util.Date; import java.util.List; import java.util.stream.Collectors; /** * 定时任务工具类 */ @Slf4j @Component public class TaskUtil { @Autowired private IUserCouponRecordService userCouponRecordService; @Autowired private IOrderTaxiService orderTaxiService; @Autowired private AmazonS3Client s3; @Autowired private IDriverService driverService; @Autowired private PushUtil pushUtil; @Autowired private SessionHolderInterceptor sessionHolderInterceptor; @Autowired private DriverWorkMapper driverWorkMapper; /** * 5秒钟执行下载音频文件 */ @Scheduled(fixedRate = 5000) public void taskDownloadAudioFile() { List list = orderTaxiService.selectList(new EntityWrapper().eq("state", 1).notLike("audioLinkUrl", "http") .eq("isDelete", 1).eq("orderSource", 7).last(" and now() >= ADDDATE(insertTime, INTERVAL 5 SECOND)")); for (int i = 0; i < list.size(); i++) { try { OrderTaxi orderTaxi = list.get(i); String sessionId = orderTaxi.getAudioLinkUrl(); InputStream test = HttpPostTool.downloadFile(sessionId); try { BufferedInputStream bis = new BufferedInputStream(test); AudioInputStream audioInputStream = AudioSystem.getAudioInputStream(bis); AudioFormat format = audioInputStream.getFormat(); long frames = audioInputStream.getFrameLength(); double durationInSeconds = (frames + 0.0) / format.getFrameRate(); orderTaxi.setAudioTime(Double.valueOf(durationInSeconds).intValue()); }catch (Exception e){ System.err.println("下载音频失败:" + sessionId); e.printStackTrace(); orderTaxi.setAudioTime(0); } test = HttpPostTool.downloadFile(sessionId); File file = FileUtil.file("E:\\nginx\\nginx-1.18.0\\html\\upload\\audio\\" + sessionId + ".mp3"); FileUtil.writeFromStream(test, file); // S3Sample.putObject((AmazonS3) s3, file, sessionId); // orderTaxi.setAudioLinkUrl("https://obs-helf.cucloud.cn/zion/" + sessionId); orderTaxi.setAudioLinkUrl("https://ziangchuxing.com/upload/audio/" + sessionId + ".mp3"); orderTaxiService.updateById(orderTaxi); }catch (Exception e){ e.printStackTrace(); } } } /** * 15秒执行一轮推单 */ @Scheduled(fixedRate = 15000) public void taskPushOrder() { pushOrder(); } /** * 10秒定时取消大厅订单 */ @Scheduled(fixedRate = 10000) public void taskSecond() { //查询已经超过结束时间的待接订单 List list = orderTaxiService.selectList(new EntityWrapper().eq("state", 1).like("audioLinkUrl", "http") .eq("isDelete", 1).eq("orderSource", 7).eq("orderType", 3).last(" and now() >= endTime")); if(list.size() > 0){ log.info("执行取消大厅订单数量: " + list.size()); } for (OrderTaxi orderTaxi : list) { orderTaxi.setState(10); if (StringUtils.hasLength(orderTaxi.getPassengersPhone())) { // String s = MsgUtil.SendUserCancel(orderTaxi.getPassengersPhone()); // log.info("取消订单id:" + orderTaxi.getId() + ",短信发送状态:" + s); } orderTaxiService.updateById(orderTaxi); } } /** * 每隔一分钟去处理的定时任务 */ @Scheduled(fixedRate = 1000 * 60) public void taskMinute() { try { //修改过期的优惠券 userCouponRecordService.updateTimeOut(); } catch (Exception e) { e.printStackTrace(); } } /** * 定时推单逻辑 */ public void pushOrder(){ LocalDateTime localDateTime = LocalDateTime.now().plusSeconds(15); //获取到目前为止没有推出去的订单电招订单 List list = orderTaxiService.selectList(new EntityWrapper().eq("state", 1).like("audioLinkUrl", "http") .eq("isDelete", 1).eq("orderSource", 7).eq("orderType", 1)); //获取当前上班中的司机 List drivers = driverService.selectList(new EntityWrapper().eq("authState", 2).eq("state", 2) .ne("flag", 3).gt("balance", 20)); List collect1 = drivers.stream().map(Driver::getId).collect(Collectors.toList()); List driverWorks = driverWorkMapper.selectList(new EntityWrapper().in("driverId", collect1).eq("state", 1)); if(list.size() > 0){ log.info("开始执行间隔15秒的推单任务"); log.info("开始执行推单任务,司机数量:" + driverWorks.size() + ",订单数量:" + list.size()); int num = list.size() == 0 ? 0 : driverWorks.size() / list.size(); for (int i = 0; i < list.size(); i++) { OrderTaxi orderTaxi = list.get(i); //截取司机 List subList = null; if(i != list.size() - 1){ subList = driverWorks.subList(i * num, (i + 1) * num); }else{ subList = driverWorks.subList(i * num, driverWorks.size()); } for (DriverWork driver : subList) { pushUtil.pushOrderStateVedio(2, driver.getDriverId(), orderTaxi.getId(), 2, orderTaxi.getState(), 15, orderTaxi.getAudioLinkUrl()); } } //睡眠等待,然后将没有接单的订单放入大厅(提前1秒) long m = localDateTime.toEpochSecond(ZoneOffset.ofHours(8)) - LocalDateTime.now().toEpochSecond(ZoneOffset.ofHours(8)) - 1; log.info("推单结束,执行等待{}秒,查询订单是否被接", m); if(0 < m){ try { Thread.sleep(m * 1000); } catch (InterruptedException e) { throw new RuntimeException(e); } } List collect = list.stream().map(OrderTaxi::getId).collect(Collectors.toList()); List orderTaxis = orderTaxiService.selectList(new EntityWrapper().eq("state", 1).in("id", collect)); if(orderTaxis.size() > 0){ log.info("放入大厅订单数量:" + orderTaxis.size()); orderTaxis.forEach(orderTaxi -> { orderTaxi.setOrderType(3); orderTaxi.setEndTime(new Date(System.currentTimeMillis() + 1000 * 60 * 2)); }); orderTaxiService.updateBatchById(orderTaxis); } log.info("执行间隔15秒的推单任务结束"); } } }